* Fixes for gcc and clang (while they can compile the code, the DLLs made aren't functional, but oh well).
* [2SF] Used more up-to-date asmjit, despite the ugly looking code.
--- a/src/in_2sf/XSFConfig_2SF.cpp
+++ b/src/in_2sf/XSFConfig_2SF.cpp
@@ -1,7 +1,7 @@
/*
* xSF - 2SF configuration
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-04-17
+ * Last modification on 2014-09-17
*
* Partially based on the vio*sf framework
*/
@@ -132,7 +132,7 @@
void XSFConfig_2SF::About(HWND parent)
{
- MessageBox(parent, (XSFConfig::commonName + L" v" + XSFConfig::versionNumber + L", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
+ MessageBoxW(parent, (XSFConfig::commonName + L" v" + XSFConfig::versionNumber + L", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
L"Utilizes modified " + String(EMU_DESMUME_NAME_AND_VERSION()).GetWStr() + L" for audio playback.").c_str(), (XSFConfig::commonName + L" v" + XSFConfig::versionNumber).c_str(), MB_OK);
}
--- a/src/in_2sf/XSFPlayer_2SF.cpp
+++ b/src/in_2sf/XSFPlayer_2SF.cpp
@@ -1,7 +1,7 @@
/*
* xSF - 2SF Player
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-04-23
+ * Last modification on 2014-09-17
*
* Based on a modified vio2sf v0.22c
*
@@ -28,7 +28,9 @@
bool Load2SF(XSFFile *xSFToLoad);
public:
XSFPlayer_2SF(const std::string &filename);
+#ifdef _MSC_VER
XSFPlayer_2SF(const std::wstring &filename);
+#endif
~XSFPlayer_2SF() { this->Terminate(); }
bool Load();
void GenerateSamples(std::vector<uint8_t> &buf, unsigned offset, unsigned samples);
@@ -43,10 +45,12 @@
return new XSFPlayer_2SF(fn);
}
+#ifdef _MSC_VER
XSFPlayer *XSFPlayer::Create(const std::wstring &fn)
{
return new XSFPlayer_2SF(fn);
}
+#endif
volatile bool execute = false;
@@ -142,7 +146,7 @@
{
if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
{
-#ifdef _WIN32
+#ifdef _MSC_VER
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue("_lib").GetWStr(), 4, 8));
#else
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue("_lib").GetAnsi(), 4, 8));
@@ -163,7 +167,7 @@
if (xSFToLoad->GetTagExists(libTag))
{
found = true;
-#ifdef _WIN32
+#ifdef _MSC_VER
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue(libTag).GetWStr(), 4, 8));
#else
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue(libTag).GetAnsi(), 4, 8));
@@ -188,10 +192,12 @@
this->xSF.reset(new XSFFile(filename, 4, 8));
}
+#ifdef _MSC_VER
XSFPlayer_2SF::XSFPlayer_2SF(const std::wstring &filename) : XSFPlayer()
{
this->xSF.reset(new XSFFile(filename, 4, 8));
}
+#endif
bool XSFPlayer_2SF::Load()
{
--- a/src/in_2sf/desmume/MMU.cpp
+++ b/src/in_2sf/desmume/MMU.cpp
@@ -433,7 +433,7 @@
MMU.texInfo.textureSlotAddr[ofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
break;
case 4: // BGB or BOBJ
- if (bank == VRAM_BANK_C)
+ if (bank == VRAM_BANK_C)
{
vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
MMU_vram_arm9(bank, VRAM_PAGE_BBG); // BBG
@@ -604,7 +604,7 @@
vram_arm7_map[0] = VRAM_PAGE_UNMAPPED;
vram_arm7_map[1] = VRAM_PAGE_UNMAPPED;
- for (int i = 0; i < VRAM_LCDC_PAGES; ++i)
+ for (unsigned i = 0; i < VRAM_LCDC_PAGES; ++i)
vram_lcdc_map[i] = VRAM_PAGE_UNMAPPED;
for (int i = 0; i < VRAM_ARM9_PAGES; ++i)
vram_arm9_map[i] = VRAM_PAGE_UNMAPPED;
@@ -636,8 +636,8 @@
return;
}
- //f irst, save the texture info so we can check it for changes and trigger purges of the texcache
- MMU_struct::TextureInfo oldTexInfo = MMU.texInfo;
+ // first, save the texture info so we can check it for changes and trigger purges of the texcache
+ //MMU_struct::TextureInfo oldTexInfo = MMU.texInfo;
// unmap everything
MMU_VRAM_unmap_all();
@@ -664,7 +664,7 @@
MMU_VRAMmapRefreshBank(VRAM_BANK_E);
// zero 21-jun-2012
// tomwi's streaming music demo sets A and D to ABG (the A is an accident).
- // in this case, D should get priority.
+ // in this case, D should get priority.
// this is somewhat risky. will it break other things?
MMU_VRAMmapRefreshBank(VRAM_BANK_A);
MMU_VRAMmapRefreshBank(VRAM_BANK_B);
@@ -1392,6 +1392,9 @@
{
case EDMAMode_Immediate:
this->triggered = true;
+ break;
+ default:
+ break;
}
if (this->triggered)
@@ -2244,7 +2247,7 @@
// The NDS7 register can be written to only from code executed in BIOS.
if (NDS_ARM7.instruct_adr > 0x3FFF)
return;
-
+
// hack for patched firmwares
if (val == 1)
{
--- a/src/in_2sf/desmume/MMU_timing.h
+++ b/src/in_2sf/desmume/MMU_timing.h
@@ -226,7 +226,7 @@
// in units of cycles of the current processor.
// this function replaces what used to be MMU_WAIT16 and MMU_WAIT32.
// this may have side effects, so don't call it more than necessary.
-template<int PROCNUM, MMU_ACCESS_TYPE AT, int READSIZE, MMU_ACCESS_DIRECTION DIRECTION, bool TIMING> inline uint32_t _MMU_accesstime(uint32_t addr, bool sequential)
+template<int PROCNUM, MMU_ACCESS_TYPE AT, int READSIZE, MMU_ACCESS_DIRECTION DIRECTION, bool TIMING> inline uint32_t _MMU_accesstime(uint32_t addr, bool /*sequential*/)
{
static const int MC = 1; // cached or tcm memory speed
static const int M32 = PROCNUM == ARMCPU_ARM9 ? 2 : 1; // access through 32-bit bus
--- a/src/in_2sf/desmume/NDSSystem.cpp
+++ b/src/in_2sf/desmume/NDSSystem.cpp
@@ -164,8 +164,6 @@
uint64_t nds_timer;
uint64_t nds_arm9_timer, nds_arm7_timer;
-static const uint64_t kNever = 0xFFFFFFFFFFFFFFFFULL;
-
struct TSequenceItem
{
uint64_t timestamp;
@@ -910,7 +908,7 @@
{
// read arm9 bios from inputfile and flag it if it succeeds
FILE *arm9inf = fopen(CommonSettings.ARM9BIOS, "rb");
- if (fread(MMU.ARM9_BIOS, 1, 4096, arm9inf) == 4096)
+ if (fread(MMU.ARM9_BIOS, 1, 4096, arm9inf) == 4096)
NDS_ARM9.BIOS_loaded = true;
fclose(arm9inf);
}
@@ -919,7 +917,7 @@
if (CommonSettings.SWIFromBIOS && NDS_ARM9.BIOS_loaded)
{
NDS_ARM9.swi_tab = 0;
-
+
// if we used routines from bios, apply patches
if (CommonSettings.PatchSWI3)
_MMU_write16<ARMCPU_ARM9>(0xFFFF07CC, 0x4770);
@@ -927,7 +925,7 @@
else
NDS_ARM9.swi_tab = ARM_swi_tab[ARMCPU_ARM9];
- if (!NDS_ARM9.BIOS_loaded)
+ if (!NDS_ARM9.BIOS_loaded)
{
// fake bios content, critical to normal operations, since we dont have a real bios.
// it'd be cool if we could write this in some kind of assembly language, inline or otherwise, without some bulky dependencies
@@ -1038,7 +1036,7 @@
PrepareBiosARM7();
PrepareBiosARM9();
- // according to smea, this is initialized to 3 by the time we get into a user game program. who does this?
+ // according to smea, this is initialized to 3 by the time we get into a user game program. who does this?
// well, the firmware load process is about to write a boot program into SIWRAM for the arm7. so we need it setup by now.
// but, this is a bit weird.. I would be expecting the bioses to do that. maybe we have some more detail to emulate.
// * is this setting the default, or does the bios do it before loading the firmware programs?
--- a/src/in_2sf/desmume/SPU.cpp
+++ b/src/in_2sf/desmume/SPU.cpp
@@ -851,7 +851,7 @@
if (INTERPOLATE_MODE != SPUInterpolation_None)
{
uint32_t loc = u32floor(chan->sampcnt);
-
+
int32_t a = static_cast<int32_t>(read16(loc * 2 + chan->addr));
if (loc < (chan->totlength << 1) - 1)
{
@@ -1450,7 +1450,7 @@
SPU_DefaultFetchSamples(&SPU_core->outbuf[0], spu_core_samples, synchmode, synchronizer.get());
}
-void SPU_Emulate_user(bool mix)
+void SPU_Emulate_user(bool /*mix*/)
{
static std::vector<int16_t> postProcessBuffer;
static size_t postProcessBufferSize = 0;
@@ -1494,7 +1494,7 @@
size_t SPU_DefaultPostProcessSamples(int16_t *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer)
{
size_t processedSampleCount = 0;
-
+
switch (synchMode)
{
case ESynchMode_DualSynchAsynch:
@@ -1509,7 +1509,7 @@
case ESynchMode_Synchronous:
processedSampleCount = theSynchronizer->output_samples(postProcessBuffer, requestedSampleCount);
}
-
+
return processedSampleCount;
}
@@ -1525,8 +1525,8 @@
void SNDDummyUnMuteAudio() {}
void SNDDummySetVolume(int) {}
void SNDDummyClearBuffer() {}
-void SNDDummyFetchSamples(int16_t *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer) {}
-size_t SNDDummyPostProcessSamples(int16_t *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer) { return 0; }
+void SNDDummyFetchSamples(int16_t *, size_t, ESynchMode, ISynchronizingAudioBuffer *) { }
+size_t SNDDummyPostProcessSamples(int16_t *, size_t, ESynchMode, ISynchronizingAudioBuffer *) { return 0; }
SoundInterface_struct SNDDummy =
{
--- a/src/in_2sf/desmume/SPU.h
+++ b/src/in_2sf/desmume/SPU.h
@@ -18,6 +18,7 @@
#pragma once
+#include <memory>
#include <iosfwd>
#include <string>
#include <cassert>
--- a/src/in_2sf/desmume/arm_instructions.cpp
+++ b/src/in_2sf/desmume/arm_instructions.cpp
@@ -3009,7 +3009,7 @@
}
else
mask = byte_mask & userMask;
-
+
u32 new_val = (cpu->CPSR.val & ~mask) | (operand & mask);
cpu->CPSR.val = (cpu->CPSR.val & ~mask) | (operand & mask);
cpu->changeCPSR();
@@ -6084,13 +6084,13 @@
// BKPT
// -----------------------------------------------------------------------------
-TEMPLATE static uint32_t FASTCALL OP_BKPT(uint32_t i)
+TEMPLATE static uint32_t FASTCALL OP_BKPT(uint32_t /*i*/)
{
/* ARM-ref
if (not overridden by debug hardware)
R14_abt = address of BKPT instruction + 4
SPSR_abt = CPSR
- CPSR[4:0] = 0b10111 // Enter Abort mode
+ CPSR[4:0] = 0b10111 // Enter Abort mode
CPSR[5] = 0 // Execute in ARM state
// CPSR[6] is unchanged
CPSR[7] = 1 // Disable normal interrupts
--- a/src/in_2sf/desmume/arm_jit.cpp
+++ b/src/in_2sf/desmume/arm_jit.cpp
@@ -34,7 +34,7 @@
#include "instruction_attributes.h"
#include "MMU.h"
#include "MMU_timing.h"
-#include "utils/AsmJit/AsmJit.h"
+#include "utils/AsmJit/asmjit.h"
#include "arm_jit.h"
#include "bios.h"
@@ -42,10 +42,10 @@
#define PROFILER_JIT_LEVEL 0
#if PROFILER_JIT_LEVEL > 0
-#include <algorithm>
+# include <algorithm>
#endif
-using namespace AsmJit;
+using namespace asmjit;
#if LOG_JIT_LEVEL > 0
#define LOG_JIT 1
@@ -53,20 +53,18 @@
#define printJIT(buf, val) \
{ \
JIT_COMMENT("printJIT(\""##buf"\", val);"); \
- GpVar txt = c.newGpVar(kX86VarTypeGpz); \
- GpVar data = c.newGpVar(kX86VarTypeGpz); \
- GpVar io = c.newGpVar(kX86VarTypeGpd); \
- c.lea(io, dword_ptr_abs(stdout)); \
- c.lea(txt, dword_ptr_abs(&buf)); \
+ GpVar txt = c.newGpVar(kVarTypeIntPtr); \
+ GpVar data = c.newGpVar(kVarTypeIntPtr); \
+ GpVar io = c.newGpVar(kVarTypeInt32); \
+ c.lea(io, x86::dword_ptr_abs(stdout)); \
+ c.lea(txt, x86::dword_ptr_abs(&buf)); \
c.mov(data, *reinterpret_cast<GpVar *>(&val)); \
- X86CompilerFuncCall* prn = c.call(reinterpret_cast<uintptr_t>(fprintf)); \
- prn->setPrototype(ASMJIT_CALL_CONV, FuncBuilder3<void, void *, void *, uint32_t>()); \
- prn->setArgument(0, io); \
- prn->setArgument(1, txt); \
- prn->setArgument(2, data); \
- X86CompilerFuncCall *prn_flush = c.call(reinterpret_cast<uintptr_t>(fflush)); \
- prn_flush->setPrototype(ASMJIT_CALL_CONV, FuncBuilder1<void, void *>()); \
- prn_flush->setArgument(0, io); \
+ auto prn = c.addCall(imm_ptr(fprintf), ASMJIT_CALL_CONV, FuncBuilder3<void, void *, void *, uint32_t>()); \
+ prn->setArg(0, io); \
+ prn->setArg(1, txt); \
+ prn->setArg(2, data); \
+ auto prn_flush = c.addCall(imm_ptr(fflush), ASMJIT_CALL_CONV, FuncBuilder1<void, void *>()); \
+ prn_flush->setArg(0, io); \
}
#else
#define LOG_JIT 0
@@ -237,7 +235,8 @@
static StaticCodeGenerator codegen;
static X86Compiler c(&codegen);
#else
-static X86Compiler c;
+static JitRuntime runtime;
+static X86Compiler c(&runtime);
#endif
static void emit_branch(int cond, Label to);
@@ -259,19 +258,19 @@
#define bb_next_instruction (bb_adr + bb_opcodesize)
#define bb_r15 (bb_adr + 2 * bb_opcodesize)
-#define cpu_ptr(x) dword_ptr(bb_cpu, offsetof(armcpu_t, x))
-#define cpu_ptr_byte(x, y) byte_ptr(bb_cpu, offsetof(armcpu_t, x) + y)
+#define cpu_ptr(x) x86::dword_ptr(bb_cpu, offsetof(armcpu_t, x))
+#define cpu_ptr_byte(x, y) x86::byte_ptr(bb_cpu, offsetof(armcpu_t, x) + y)
#define flags_ptr cpu_ptr_byte(CPSR.val, 3)
-#define reg_ptr(x) dword_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * (x))
-#define reg_pos_ptr(x) dword_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * REG_POS(i, (x)))
-#define reg_pos_ptrL(x) word_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * REG_POS(i, (x)))
-#define reg_pos_ptrH(x) word_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * REG_POS(i, (x)) + 2)
-#define reg_pos_ptrB(x) byte_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * REG_POS(i, (x)))
-#define reg_pos_thumb(x) dword_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * ((i >> (x)) & 0x7))
-#define reg_pos_thumbB(x) byte_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * ((i >> (x)) & 0x7))
-#define cp15_ptr(x) dword_ptr(bb_cp15, offsetof(armcp15_t, x))
-#define mmu_ptr(x) dword_ptr(bb_mmu, offsetof(MMU_struct, x))
-#define mmu_ptr_byte(x) byte_ptr(bb_mmu, offsetof(MMU_struct, x))
+#define reg_ptr(x) x86::dword_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * (x))
+#define reg_pos_ptr(x) x86::dword_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * REG_POS(i, (x)))
+#define reg_pos_ptrL(x) x86::word_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * REG_POS(i, (x)))
+#define reg_pos_ptrH(x) x86::word_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * REG_POS(i, (x)) + 2)
+#define reg_pos_ptrB(x) x86::byte_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * REG_POS(i, (x)))
+#define reg_pos_thumb(x) x86::dword_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * ((i >> (x)) & 0x7))
+#define reg_pos_thumbB(x) x86::byte_ptr(bb_cpu, offsetof(armcpu_t, R) + 4 * ((i >> (x)) & 0x7))
+#define cp15_ptr(x) x86::dword_ptr(bb_cp15, offsetof(armcp15_t, x))
+#define mmu_ptr(x) x86::dword_ptr(bb_mmu, offsetof(MMU_struct, x))
+#define mmu_ptr_byte(x) x86::byte_ptr(bb_mmu, offsetof(MMU_struct, x))
static inline uint32_t _REG_NUM(uint32_t i, uint32_t n) { return (i >> n) & 0x7; }
#ifndef ASMJIT_X64
@@ -281,8 +280,7 @@
// sequencer.reschedule = true;
#define changeCPSR \
{ \
- X86CompilerFuncCall *ctxCPSR = c.call(reinterpret_cast<void *>(NDS_Reschedule)); \
- ctxCPSR->setPrototype(ASMJIT_CALL_CONV, FuncBuilder0<void>()); \
+ auto ctxCPSR = c.addCall(imm_ptr(NDS_Reschedule), ASMJIT_CALL_CONV, FuncBuilder0<void>()); \
}
#if PROFILER_JIT_LEVEL > 0
@@ -306,8 +304,8 @@
static GpVar bb_profiler;
-#define profiler_counter_arm(opcode) qword_ptr(bb_profiler, offsetof(JIT_PROFILER, arm_count[INSTRUCTION_INDEX(opcode)]))
-#define profiler_counter_thumb(opcode) qword_ptr(bb_profiler, offsetof(JIT_PROFILER, thumb_count[opcode>>6]))
+#define profiler_counter_arm(opcode) x86::qword_ptr(bb_profiler, offsetof(JIT_PROFILER, arm_count[INSTRUCTION_INDEX(opcode)]))
+#define profiler_counter_thumb(opcode) x86::qword_ptr(bb_profiler, offsetof(JIT_PROFILER, thumb_count[opcode>>6]))
#if PROFILER_JIT_LEVEL > 1
struct PROFILER_ENTRY
@@ -327,18 +325,18 @@
#define SET_NZCV(sign) \
{ \
JIT_COMMENT("SET_NZCV"); \
- GpVar x = c.newGpVar(kX86VarTypeGpd); \
- GpVar y = c.newGpVar(kX86VarTypeGpd); \
+ GpVar x = c.newGpVar(kVarTypeInt32); \
+ GpVar y = c.newGpVar(kVarTypeInt32); \
c.sets(x.r8Lo()); \
c.setz(y.r8Lo()); \
- c.lea(x, ptr(y.r64(), x.r64(), kScale2Times)); \
+ c.lea(x, x86::ptr(y.r64(), x.r64(), 1)); \
if (sign) \
c.setnc(y.r8Lo()); \
else \
c.setc(y.r8Lo()); \
- c.lea(x, ptr(y.r64(), x.r64(), kScale2Times)); \
+ c.lea(x, x86::ptr(y.r64(), x.r64(), 1)); \
c.seto(y.r8Lo()); \
- c.lea(x, ptr(y.r64(), x.r64(), kScale2Times)); \
+ c.lea(x, x86::ptr(y.r64(), x.r64(), 1)); \
c.movzx(y, flags_ptr); \
c.shl(x, 4); \
c.and_(y, 0xF); \
@@ -352,14 +350,14 @@
#define SET_NZC \
{ \
JIT_COMMENT("SET_NZC"); \
- GpVar x = c.newGpVar(kX86VarTypeGpd); \
- GpVar y = c.newGpVar(kX86VarTypeGpd); \
+ GpVar x = c.newGpVar(kVarTypeInt32); \
+ GpVar y = c.newGpVar(kVarTypeInt32); \
c.sets(x.r8Lo()); \
c.setz(y.r8Lo()); \
- c.lea(x, ptr(y.r64(), x.r64(), kScale2Times)); \
+ c.lea(x, x86::ptr(y.r64(), x.r64(), 1)); \
if (cf_change) \
{ \
- c.lea(x, ptr(rcf.r64(), x.r64(), kScale2Times)); \
+ c.lea(x, x86::ptr(rcf.r64(), x.r64(), 1)); \
c.unuse(rcf); \
} \
c.movzx(y, flags_ptr); \
@@ -388,11 +386,11 @@
#define SET_NZ(clear_cv) \
{ \
JIT_COMMENT("SET_NZ"); \
- GpVar x = c.newGpVar(kX86VarTypeGpz); \
- GpVar y = c.newGpVar(kX86VarTypeGpz); \
+ GpVar x = c.newGpVar(kVarTypeIntPtr); \
+ GpVar y = c.newGpVar(kVarTypeIntPtr); \
c.sets(x.r8Lo()); \
c.setz(y.r8Lo()); \
- c.lea(x, ptr(y.r64(), x.r64(), kScale2Times)); \
+ c.lea(x, x86::ptr(y.r64(), x.r64(), 1)); \
c.movzx(y, flags_ptr); \
c.and_(y, clear_cv?0x0F:0x3F); \
c.shl(x, 6); \
@@ -404,7 +402,7 @@
#define SET_Q \
{ \
JIT_COMMENT("SET_Q"); \
- GpVar x = c.newGpVar(kX86VarTypeGpz); \
+ GpVar x = c.newGpVar(kVarTypeIntPtr); \
c.seto(x.r8Lo()); \
c.shl(x, 3); \
c.or_(flags_ptr, x.r8Lo()); \
@@ -414,19 +412,18 @@
#define S_DST_R15 \
{ \
JIT_COMMENT("S_DST_R15"); \
- GpVar SPSR = c.newGpVar(kX86VarTypeGpd); \
- GpVar tmp = c.newGpVar(kX86VarTypeGpd); \
+ GpVar SPSR = c.newGpVar(kVarTypeInt32); \
+ GpVar tmp = c.newGpVar(kVarTypeInt32); \
c.mov(SPSR, cpu_ptr(SPSR.val)); \
c.mov(tmp, SPSR); \
c.and_(tmp, 0x1F); \
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(armcpu_switchMode)); \
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder2<void, void *, uint8_t>()); \
- ctx->setArgument(0, bb_cpu); \
- ctx->setArgument(1, tmp); \
+ auto ctx = c.addCall(imm_ptr(armcpu_switchMode), ASMJIT_CALL_CONV, FuncBuilder2<void, void *, uint8_t>()); \
+ ctx->setArg(0, bb_cpu); \
+ ctx->setArg(1, tmp); \
c.mov(cpu_ptr(CPSR.val), SPSR); \
c.and_(SPSR, 1 << 5); \
c.shr(SPSR, 5); \
- c.lea(tmp, ptr_abs(reinterpret_cast<void *>(0xFFFFFFFC), SPSR.r64(), kScale2Times)); \
+ c.lea(tmp, x86::ptr_abs(0xFFFFFFFC, SPSR.r64(), 1)); \
c.and_(tmp, reg_ptr(15)); \
c.mov(cpu_ptr(next_instruction), tmp); \
c.unuse(tmp); \
@@ -438,7 +435,7 @@
JIT_COMMENT("LSL_IMM"); \
bool rhs_is_imm = false; \
uint32_t imm = (i >> 7) & 0x1F; \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
c.mov(rhs, reg_pos_ptr(0)); \
if (imm) \
c.shl(rhs, imm); \
@@ -449,14 +446,14 @@
bool rhs_is_imm = false; \
uint8_t cf_change = 0; \
GpVar rcf; \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
uint32_t imm = (i >> 7)&0x1F; \
c.mov(rhs, reg_pos_ptr(0)); \
if (imm) \
{ \
cf_change = 1; \
c.shl(rhs, imm); \
- rcf = c.newGpVar(kX86VarTypeGpd); \
+ rcf = c.newGpVar(kVarTypeInt32); \
c.setc(rcf.r8Lo()); \
}
@@ -464,7 +461,7 @@
JIT_COMMENT("LSR_IMM"); \
bool rhs_is_imm = false; \
uint32_t imm = (i >> 7) & 0x1F; \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
if (imm) \
{ \
c.mov(rhs, reg_pos_ptr(0)); \
@@ -478,8 +475,8 @@
JIT_COMMENT("S_LSR_IMM"); \
bool rhs_is_imm = false; \
uint8_t cf_change = 1; \
- GpVar rcf = c.newGpVar(kX86VarTypeGpd); \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar rcf = c.newGpVar(kVarTypeInt32); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
uint32_t imm = (i >> 7) & 0x1F; \
c.mov(rhs, reg_pos_ptr(0)); \
if (!imm) \
@@ -498,7 +495,7 @@
JIT_COMMENT("ASR_IMM"); \
bool rhs_is_imm = false; \
uint32_t imm = (i >> 7) & 0x1F; \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
c.mov(rhs, reg_pos_ptr(0)); \
if (!imm) \
imm = 31; \
@@ -509,8 +506,8 @@
JIT_COMMENT("S_ASR_IMM"); \
bool rhs_is_imm = false; \
uint8_t cf_change = 1; \
- GpVar rcf = c.newGpVar(kX86VarTypeGpd); \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar rcf = c.newGpVar(kVarTypeInt32); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
uint32_t imm = (i >> 7) & 0x1F; \
c.mov(rhs, reg_pos_ptr(0)); \
if (!imm) \
@@ -522,7 +519,7 @@
JIT_COMMENT("ROR_IMM"); \
bool rhs_is_imm = false; \
uint32_t imm = (i >> 7) & 0x1F; \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
c.mov(rhs, reg_pos_ptr(0)); \
if (!imm) \
{ \
@@ -537,8 +534,8 @@
JIT_COMMENT("S_ROR_IMM"); \
bool rhs_is_imm = false; \
uint8_t cf_change = 1; \
- GpVar rcf = c.newGpVar(kX86VarTypeGpd); \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar rcf = c.newGpVar(kVarTypeInt32); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
uint32_t imm = (i >> 7) & 0x1F; \
c.mov(rhs, reg_pos_ptr(0)); \
if (!imm) \
@@ -571,7 +568,7 @@
if ((i >> 8) & 0xF) \
{ \
cf_change = 1; \
- rcf = c.newGpVar(kX86VarTypeGpd); \
+ rcf = c.newGpVar(kVarTypeInt32); \
c.mov(rcf, BIT31(rhs)); \
} \
uint32_t rhs_first = rhs;
@@ -592,9 +589,9 @@
#define LSX_REG(name, x86inst, sign) \
JIT_COMMENT(#name); \
bool rhs_is_imm = false; \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
- GpVar imm = c.newGpVar(kX86VarTypeGpz); \
- GpVar tmp = c.newGpVar(kX86VarTypeGpz); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
+ GpVar imm = c.newGpVar(kVarTypeIntPtr); \
+ GpVar tmp = c.newGpVar(kVarTypeIntPtr); \
if (sign) \
c.mov(tmp, 31); \
else \
@@ -613,9 +610,9 @@
JIT_COMMENT(#name); \
bool rhs_is_imm = false; \
uint8_t cf_change = 1; \
- GpVar rcf = c.newGpVar(kX86VarTypeGpd); \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
- GpVar imm = c.newGpVar(kX86VarTypeGpz); \
+ GpVar rcf = c.newGpVar(kVarTypeInt32); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
+ GpVar imm = c.newGpVar(kVarTypeIntPtr); \
Label __zero = c.newLabel(); \
Label __lt32 = c.newLabel(); \
Label __done = c.newLabel(); \
@@ -662,8 +659,8 @@
#define ROR_REG \
JIT_COMMENT("ROR_REG"); \
bool rhs_is_imm = false; \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
- GpVar imm = c.newGpVar(kX86VarTypeGpz); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
+ GpVar imm = c.newGpVar(kVarTypeIntPtr); \
c.mov(rhs, reg_pos_ptr(0)); \
c.mov(imm, reg_pos_ptrB(8)); \
c.ror(rhs, imm.r8Lo());
@@ -672,9 +669,9 @@
JIT_COMMENT("S_ROR_REG"); \
bool rhs_is_imm = false; \
bool cf_change = 1; \
- GpVar rcf = c.newGpVar(kX86VarTypeGpd); \
- GpVar imm = c.newGpVar(kX86VarTypeGpz); \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar rcf = c.newGpVar(kVarTypeInt32); \
+ GpVar imm = c.newGpVar(kVarTypeIntPtr); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
Label __zero = c.newLabel(); \
Label __zero_1F = c.newLabel(); \
Label __done = c.newLabel(); \
@@ -707,7 +704,7 @@
{
if (population < alu_cycles)
{
- GpVar x = c.newGpVar(kX86VarTypeGpd);
+ GpVar x = c.newGpVar(kVarTypeInt32);
c.mov(x, alu_cycles);
c.cmp(mem_cycles, alu_cycles);
c.cmovl(mem_cycles, x);
@@ -722,7 +719,7 @@
// -----------------------------------------------------------------------------
#define OP_ARITHMETIC(arg, x86inst, symmetric, flags) \
arg; \
- GpVar lhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar lhs = c.newGpVar(kVarTypeInt32); \
if (REG_POS(i, 12) == REG_POS(i, 16)) \
c.x86inst(reg_pos_ptr(12), rhs); \
else if (symmetric && !rhs_is_imm) \
@@ -750,7 +747,7 @@
{ \
if (REG_POS(i, 12) == 15) \
{ \
- GpVar tmp = c.newGpVar(kX86VarTypeGpd); \
+ GpVar tmp = c.newGpVar(kVarTypeInt32); \
c.mov(tmp, reg_ptr(15)); \
c.mov(cpu_ptr(next_instruction), tmp); \
bb_constant_cycles += 2; \
@@ -760,7 +757,7 @@
#define OP_ARITHMETIC_R(arg, x86inst, flags) \
arg; \
- GpVar lhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar lhs = c.newGpVar(kVarTypeInt32); \
c.mov(lhs, rhs); \
c.x86inst(lhs, reg_pos_ptr(16)); \
c.mov(reg_pos_ptr(12), lhs); \
@@ -778,7 +775,7 @@
{ \
if (REG_POS(i, 12) == 15) \
{ \
- GpVar tmp = c.newGpVar(kX86VarTypeGpd); \
+ GpVar tmp = c.newGpVar(kVarTypeInt32); \
c.mov(cpu_ptr(next_instruction), lhs); \
bb_constant_cycles += 2; \
} \
@@ -796,7 +793,7 @@
} \
else \
{ \
- GpVar lhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar lhs = c.newGpVar(kVarTypeInt32); \
c.mov(lhs, reg_pos_ptr(16)); \
c.x86inst(lhs, rhs); \
c.mov(reg_pos_ptr(12), lhs); \
@@ -1046,7 +1043,7 @@
c.xor_(*reinterpret_cast<GpVar *>(&rhs), reg_pos_ptr(16)); \
else \
{ \
- GpVar x = c.newGpVar(kX86VarTypeGpd); \
+ GpVar x = c.newGpVar(kVarTypeInt32); \
c.mov(x, rhs); \
c.xor_(x, reg_pos_ptr(16)); \
} \
@@ -1095,7 +1092,7 @@
c.cmp(reg_pos_ptr(16), -rhs_imm); \
else \
{ \
- GpVar lhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar lhs = c.newGpVar(kVarTypeInt32); \
c.mov(lhs, reg_pos_ptr(16)); \
c.add(lhs, rhs); \
} \
@@ -1202,7 +1199,7 @@
{
if (sign)
{
- GpVar y = c.newGpVar(kX86VarTypeGpd);
+ GpVar y = c.newGpVar(kVarTypeInt32);
c.mov(y, x);
c.sar(x, 31);
c.xor_(x, y);
@@ -1214,12 +1211,12 @@
}
#define OP_MUL_(op, width, sign, accum, flags) \
- GpVar lhs = c.newGpVar(kX86VarTypeGpd); \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar lhs = c.newGpVar(kVarTypeInt32); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
GpVar hi; \
if (width) \
{ \
- hi = c.newGpVar(kX86VarTypeGpd); \
+ hi = c.newGpVar(kVarTypeInt32); \
c.xor_(hi, hi); \
} \
c.mov(lhs, reg_pos_ptr(0)); \
@@ -1281,13 +1278,13 @@
static int OP_SMLAL_S(uint32_t i) { OP_MUL_(c.imul(hi,lhs,rhs), 1, 1, 1, 1); }
#define OP_MULxy_(op, x, y, width, accum, flags) \
- GpVar lhs = c.newGpVar(kX86VarTypeGpd); \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar lhs = c.newGpVar(kVarTypeInt32); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
GpVar hi; \
c.movsx(lhs, reg_pos_ptr##x(0)); \
c.movsx(rhs, reg_pos_ptr##y(8)); \
if (width) \
- hi = c.newGpVar(kX86VarTypeGpd); \
+ hi = c.newGpVar(kVarTypeInt32); \
op; \
if (width && accum) \
{ \
@@ -1352,8 +1349,8 @@
// -----------------------------------------------------------------------------
#ifdef ASMJIT_X64
#define OP_SMxxW_(x, accum, flags) \
- GpVar lhs = c.newGpVar(kX86VarTypeGpz); \
- GpVar rhs = c.newGpVar(kX86VarTypeGpz); \
+ GpVar lhs = c.newGpVar(kVarTypeIntPtr); \
+ GpVar rhs = c.newGpVar(kVarTypeIntPtr); \
c.movsx(lhs, reg_pos_ptr##x(8)); \
c.movsxd(rhs, reg_pos_ptr(0)); \
c.imul(lhs, rhs); \
@@ -1366,9 +1363,9 @@
return 1;
#else
#define OP_SMxxW_(x, accum, flags) \
- GpVar lhs = c.newGpVar(kX86VarTypeGpd); \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
- GpVar hi = c.newGpVar(kX86VarTypeGpd); \
+ GpVar lhs = c.newGpVar(kVarTypeInt32); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
+ GpVar hi = c.newGpVar(kVarTypeInt32); \
c.movsx(lhs, reg_pos_ptr##x(8)); \
c.mov(rhs, reg_pos_ptr(0)); \
c.imul(hi, lhs, rhs); \
@@ -1393,7 +1390,7 @@
// -----------------------------------------------------------------------------
static int OP_MRS_CPSR(uint32_t i)
{
- GpVar x = c.newGpVar(kX86VarTypeGpd);
+ GpVar x = c.newGpVar(kVarTypeInt32);
c.mov(x, cpu_ptr(CPSR));
c.mov(reg_pos_ptr(12), x);
return 1;
@@ -1401,7 +1398,7 @@
static int OP_MRS_SPSR(uint32_t i)
{
- GpVar x = c.newGpVar(kX86VarTypeGpd);
+ GpVar x = c.newGpVar(kVarTypeInt32);
c.mov(x, cpu_ptr(SPSR));
c.mov(reg_pos_ptr(12), x);
return 1;
@@ -1409,14 +1406,14 @@
// TODO: SPSR: if(cpu->CPSR.bits.mode == USR || cpu->CPSR.bits.mode == SYS) return 1;
#define OP_MSR_(reg, args, sw) \
- GpVar operand = c.newGpVar(kX86VarTypeGpd); \
+ GpVar operand = c.newGpVar(kVarTypeInt32); \
args; \
c.mov(operand, rhs); \
switch ((i >> 16) & 0xF) \
{ \
case 0x1: /* bit 16 */ \
{ \
- GpVar mode = c.newGpVar(kX86VarTypeGpd); \
+ GpVar mode = c.newGpVar(kVarTypeInt32); \
Label __skip = c.newLabel(); \
c.mov(mode, cpu_ptr(CPSR)); \
c.and_(mode, 0x1F); \
@@ -1426,10 +1423,10 @@
{ \
c.mov(mode, rhs); \
c.and_(mode, 0x1F); \
- X86CompilerFuncCall* ctx = c.call(reinterpret_cast<void *>(armcpu_switchMode)); \
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder2<void, void *, uint8_t>()); \
- ctx->setArgument(0, bb_cpu); \
- ctx->setArgument(1, mode); \
+ auto ctx = c.addCall(imm_ptr(armcpu_switchMode), ASMJIT_CALL_CONV, \
+ FuncBuilder2<void, void *, uint8_t>()); \
+ ctx->setArg(0, bb_cpu); \
+ ctx->setArg(1, mode); \
} \
Mem xPSR_memB = cpu_ptr_byte(reg, 0); \
c.mov(xPSR_memB, operand.r8Lo()); \
@@ -1439,7 +1436,7 @@
} \
case 0x2: /* bit 17 */ \
{ \
- GpVar mode = c.newGpVar(kX86VarTypeGpd); \
+ GpVar mode = c.newGpVar(kVarTypeInt32); \
Label __skip = c.newLabel(); \
c.mov(mode, cpu_ptr(CPSR)); \
c.and_(mode, 0x1F); \
@@ -1454,7 +1451,7 @@
} \
case 0x4: /* bit 18 */ \
{ \
- GpVar mode = c.newGpVar(kX86VarTypeGpd); \
+ GpVar mode = c.newGpVar(kVarTypeInt32); \
Label __skip = c.newLabel(); \
c.mov(mode, cpu_ptr(CPSR)); \
c.and_(mode, 0x1F); \
@@ -1481,8 +1478,8 @@
static uint32_t byte_mask_USR = BIT19(i) ? 0xFF000000 : 0x00000000; \
\
Mem xPSR_mem = cpu_ptr(reg.val); \
- GpVar xPSR = c.newGpVar(kX86VarTypeGpd); \
- GpVar mode = c.newGpVar(kX86VarTypeGpd); \
+ GpVar xPSR = c.newGpVar(kVarTypeInt32); \
+ GpVar mode = c.newGpVar(kVarTypeInt32); \
Label __USR = c.newLabel(); \
Label __done = c.newLabel(); \
c.mov(mode, cpu_ptr(CPSR.val)); \
@@ -1495,10 +1492,10 @@
/* armcpu_switchMode */ \
c.mov(mode, rhs); \
c.and_(mode, 0x1F); \
- X86CompilerFuncCall* ctx = c.call(reinterpret_cast<void *>(armcpu_switchMode)); \
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder2<void, void *, uint8_t>()); \
- ctx->setArgument(0, bb_cpu); \
- ctx->setArgument(1, mode); \
+ auto ctx = c.addCall(imm_ptr(armcpu_switchMode), ASMJIT_CALL_CONV, \
+ FuncBuilder2<void, void *, uint8_t>()); \
+ ctx->setArg(0, bb_cpu); \
+ ctx->setArg(1, mode); \
} \
/* cpu->CPSR.val = (cpu->CPSR.val & ~byte_mask) | (operand & byte_mask); */ \
c.mov(xPSR, xPSR_mem); \
@@ -1602,8 +1599,8 @@
static uint32_t sub(uint32_t lhs, uint32_t rhs) { return lhs - rhs; }
#define OP_LDR_(mem_op, arg, sign_op, writeback) \
- GpVar adr = c.newGpVar(kX86VarTypeGpd); \
- GpVar dst = c.newGpVar(kX86VarTypeGpz); \
+ GpVar adr = c.newGpVar(kVarTypeInt32); \
+ GpVar dst = c.newGpVar(kVarTypeIntPtr); \
c.mov(adr, reg_pos_ptr(16)); \
c.lea(dst, reg_pos_ptr(12)); \
arg; \
@@ -1618,25 +1615,25 @@
} \
else if (writeback > 0) \
{ \
- GpVar tmp_reg = c.newGpVar(kX86VarTypeGpd); \
+ GpVar tmp_reg = c.newGpVar(kVarTypeInt32); \
c.mov(tmp_reg, adr); \
c.sign_op(tmp_reg, rhs); \
c.mov(reg_pos_ptr(16), tmp_reg); \
} \
} \
- uint32_t adr_first = sign_op(cpu->R[REG_POS(i,16)], rhs_first); \
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(mem_op##_tab[PROCNUM][classify_adr(adr_first, 0)])); \
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder2<uint32_t, uint32_t, uint32_t *>()); \
- ctx->setArgument(0, adr); \
- ctx->setArgument(1, dst); \
- ctx->setReturn(bb_cycles); \
+ uint32_t adr_first = sign_op(cpu->R[REG_POS(i, 16)], rhs_first); \
+ auto ctx = c.addCall(imm_ptr(mem_op##_tab[PROCNUM][classify_adr(adr_first, 0)]), ASMJIT_CALL_CONV, \
+ FuncBuilder2<uint32_t, uint32_t, uint32_t *>()); \
+ ctx->setArg(0, adr); \
+ ctx->setArg(1, dst); \
+ ctx->setRet(0, bb_cycles); \
if (REG_POS(i, 12) == 15) \
{ \
- GpVar tmp = c.newGpVar(kX86VarTypeGpd); \
+ GpVar tmp = c.newGpVar(kVarTypeInt32); \
c.mov(tmp, reg_ptr(15)); \
if (!PROCNUM) \
{ \
- GpVar thumb = c.newGpVar(kX86VarTypeGpz); \
+ GpVar thumb = c.newGpVar(kVarTypeIntPtr); \
c.movzx(thumb, reg_pos_ptrB(16)); \
c.and_(thumb, 1); \
c.shl(thumb, 5); \
@@ -1789,8 +1786,8 @@
#undef T
#define OP_STR_(mem_op, arg, sign_op, writeback) \
- GpVar adr = c.newGpVar(kX86VarTypeGpd); \
- GpVar data = c.newGpVar(kX86VarTypeGpd); \
+ GpVar adr = c.newGpVar(kVarTypeInt32); \
+ GpVar data = c.newGpVar(kVarTypeInt32); \
c.mov(adr, reg_pos_ptr(16)); \
c.mov(data, reg_pos_ptr(12)); \
arg; \
@@ -1805,18 +1802,18 @@
} \
else if (writeback > 0) \
{ \
- GpVar tmp_reg = c.newGpVar(kX86VarTypeGpd); \
+ GpVar tmp_reg = c.newGpVar(kVarTypeInt32); \
c.mov(tmp_reg, adr); \
c.sign_op(tmp_reg, rhs); \
c.mov(reg_pos_ptr(16), tmp_reg); \
} \
} \
uint32_t adr_first = sign_op(cpu->R[REG_POS(i,16)], rhs_first); \
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(mem_op##_tab[PROCNUM][classify_adr(adr_first, 1)])); \
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder2<uint32_t, uint32_t, uint32_t>()); \
- ctx->setArgument(0, adr); \
- ctx->setArgument(1, data); \
- ctx->setReturn(bb_cycles); \
+ auto ctx = c.addCall(imm_ptr(mem_op##_tab[PROCNUM][classify_adr(adr_first, 1)]), ASMJIT_CALL_CONV, \
+ FuncBuilder2<uint32_t, uint32_t, uint32_t>()); \
+ ctx->setArg(0, adr); \
+ ctx->setArg(1, data); \
+ ctx->setRet(0, bb_cycles); \
return 1;
static int OP_STR_P_IMM_OFF(uint32_t i) { OP_STR_(STR, IMM_OFF_12, add, 0); }
@@ -1925,7 +1922,7 @@
static int OP_LDRD_STRD_POST_INDEX(uint32_t i)
{
uint8_t Rd_num = REG_POS(i, 12);
-
+
if (Rd_num == 14)
{
printf("OP_LDRD_STRD_POST_INDEX: use R14!!!!\n");
@@ -1936,8 +1933,8 @@
printf("OP_LDRD_STRD_POST_INDEX: ERROR!!!!\n");
return 0; // TODO: exception
}
- GpVar Rd = c.newGpVar(kX86VarTypeGpd);
- GpVar addr = c.newGpVar(kX86VarTypeGpd);
+ GpVar Rd = c.newGpVar(kVarTypeInt32);
+ GpVar addr = c.newGpVar(kVarTypeInt32);
c.mov(Rd, reg_pos_ptr(16));
c.mov(addr, reg_pos_ptr(16));
@@ -1950,15 +1947,15 @@
}
else
{
- GpVar idx = c.newGpVar(kX86VarTypeGpd);
+ GpVar idx = c.newGpVar(kVarTypeInt32);
c.mov(idx, reg_pos_ptr(0));
BIT23(i) ? c.add(reg_pos_ptr(16), idx) : c.sub(reg_pos_ptr(16), idx);
}
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(BIT5(i) ? op_strd_tab[PROCNUM][Rd_num] : op_ldrd_tab[PROCNUM][Rd_num]));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder1<uint32_t, uint32_t>());
- ctx->setArgument(0, addr);
- ctx->setReturn(bb_cycles);
+ auto ctx = c.addCall(imm_ptr(BIT5(i) ? op_strd_tab[PROCNUM][Rd_num] : op_ldrd_tab[PROCNUM][Rd_num]),
+ ASMJIT_CALL_CONV, FuncBuilder1<uint32_t, uint32_t>());
+ ctx->setArg(0, addr);
+ ctx->setRet(0, bb_cycles);
emit_MMU_aluMemCycles(3, bb_cycles, 0);
return 1;
}
@@ -1966,7 +1963,7 @@
static int OP_LDRD_STRD_OFFSET_PRE_INDEX(uint32_t i)
{
uint8_t Rd_num = REG_POS(i, 12);
-
+
if (Rd_num == 14)
{
printf("OP_LDRD_STRD_OFFSET_PRE_INDEX: use R14!!!!\n");
@@ -1977,8 +1974,8 @@
printf("OP_LDRD_STRD_OFFSET_PRE_INDEX: ERROR!!!!\n");
return 0; // TODO: exception
}
- GpVar Rd = c.newGpVar(kX86VarTypeGpd);
- GpVar addr = c.newGpVar(kX86VarTypeGpd);
+ GpVar Rd = c.newGpVar(kVarTypeInt32);
+ GpVar addr = c.newGpVar(kVarTypeInt32);
c.mov(Rd, reg_pos_ptr(16));
c.mov(addr, reg_pos_ptr(16));
@@ -1994,10 +1991,10 @@
if (BIT5(i)) // Store
{
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(op_strd_tab[PROCNUM][Rd_num]));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder1<uint32_t, uint32_t>());
- ctx->setArgument(0, addr);
- ctx->setReturn(bb_cycles);
+ auto ctx = c.addCall(imm_ptr(op_strd_tab[PROCNUM][Rd_num]), ASMJIT_CALL_CONV,
+ FuncBuilder1<uint32_t, uint32_t>());
+ ctx->setArg(0, addr);
+ ctx->setRet(0, bb_cycles);
if (BIT21(i)) // W bit - writeback
c.mov(reg_pos_ptr(16), addr);
emit_MMU_aluMemCycles(3, bb_cycles, 0);
@@ -2006,10 +2003,10 @@
{
if (BIT21(i)) // W bit - writeback
c.mov(reg_pos_ptr(16), addr);
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(op_ldrd_tab[PROCNUM][Rd_num]));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder1<uint32_t, uint32_t>());
- ctx->setArgument(0, addr);
- ctx->setReturn(bb_cycles);
+ auto ctx = c.addCall(imm_ptr(op_ldrd_tab[PROCNUM][Rd_num]), ASMJIT_CALL_CONV,
+ FuncBuilder1<uint32_t, uint32_t>());
+ ctx->setArg(0, addr);
+ ctx->setRet(0, bb_cycles);
emit_MMU_aluMemCycles(3, bb_cycles, 0);
}
return 1;
@@ -2039,21 +2036,21 @@
static int op_swp_(uint32_t i, int b)
{
- GpVar addr = c.newGpVar(kX86VarTypeGpd);
- GpVar Rd = c.newGpVar(kX86VarTypeGpz);
- GpVar Rs = c.newGpVar(kX86VarTypeGpd);
+ GpVar addr = c.newGpVar(kVarTypeInt32);
+ GpVar Rd = c.newGpVar(kVarTypeIntPtr);
+ GpVar Rs = c.newGpVar(kVarTypeInt32);
c.mov(addr, reg_pos_ptr(16));
c.lea(Rd, reg_pos_ptr(12));
if (b)
c.movzx(Rs, reg_pos_ptrB(0));
else
c.mov(Rs, reg_pos_ptr(0));
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(op_swp_tab[b][PROCNUM]));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder3<uint32_t, uint32_t, uint32_t *, uint32_t>());
- ctx->setArgument(0, addr);
- ctx->setArgument(1, Rd);
- ctx->setArgument(2, Rs);
- ctx->setReturn(bb_cycles);
+ auto ctx = c.addCall(imm_ptr(op_swp_tab[b][PROCNUM]), ASMJIT_CALL_CONV,
+ FuncBuilder3<uint32_t, uint32_t, uint32_t *, uint32_t>());
+ ctx->setArg(0, addr);
+ ctx->setArg(1, Rd);
+ ctx->setArg(2, Rs);
+ ctx->setRet(0, bb_cycles);
emit_MMU_aluMemCycles(4, bb_cycles, 0);
return 1;
}
@@ -2247,30 +2244,30 @@
{
if (bitmask)
{
- GpVar n = c.newGpVar(kX86VarTypeGpd);
+ GpVar n = c.newGpVar(kVarTypeInt32);
c.mov(n, popcount(bitmask));
#ifdef ASMJIT_X64
- GpVar regs = c.newGpVar(kX86VarTypeGpz);
+ GpVar regs = c.newGpVar(kVarTypeIntPtr);
c.mov(regs, get_reg_list(bitmask, dir));
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(op_ldm_stm_tab[PROCNUM][store][dir > 0]));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder3<uint32_t, uint32_t, uint64_t, int>());
- ctx->setArgument(0, adr);
- ctx->setArgument(1, regs);
- ctx->setArgument(2, n);
+ auto ctx = c.addCall(imm_ptr(op_ldm_stm_tab[PROCNUM][store][dir > 0]), ASMJIT_CALL_CONV,
+ FuncBuilder3<uint32_t, uint32_t, uint64_t, int>());
+ ctx->setArg(0, adr);
+ ctx->setArg(1, regs);
+ ctx->setArg(2, n);
#else
// same prototype, but we have to handle splitting of a u64 arg manually
- GpVar regs_lo = c.newGpVar(kX86VarTypeGpd);
- GpVar regs_hi = c.newGpVar(kX86VarTypeGpd);
+ GpVar regs_lo = c.newGpVar(kVarTypeInt32);
+ GpVar regs_hi = c.newGpVar(kVarTypeInt32);
c.mov(regs_lo, get_reg_list(bitmask, dir) & 0xFFFFFFFF);
c.mov(regs_hi, get_reg_list(bitmask, dir) >> 32);
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(op_ldm_stm_tab[PROCNUM][store][dir > 0]));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder4<uint32_t, uint32_t, uint32_t, uint32_t, int>());
- ctx->setArgument(0, adr);
- ctx->setArgument(1, regs_lo);
- ctx->setArgument(2, regs_hi);
- ctx->setArgument(3, n);
+ auto ctx = c.addCall(imm_ptr(op_ldm_stm_tab[PROCNUM][store][dir > 0]), ASMJIT_CALL_CONV,
+ FuncBuilder4<uint32_t, uint32_t, uint32_t, uint32_t, int>());
+ ctx->setArg(0, adr);
+ ctx->setArg(1, regs_lo);
+ ctx->setArg(2, regs_hi);
+ ctx->setArg(3, n);
#endif
- ctx->setReturn(bb_cycles);
+ ctx->setRet(0, bb_cycles);
}
else
++bb_constant_cycles;
@@ -2284,7 +2281,7 @@
uint32_t bitmask = i & 0xFFFF;
uint32_t pop = popcount(bitmask);
- GpVar adr = c.newGpVar(kX86VarTypeGpd);
+ GpVar adr = c.newGpVar(kVarTypeInt32);
c.mov(adr, reg_pos_ptr(16));
if (before)
c.add(adr, 4*dir);
@@ -2296,7 +2293,7 @@
if (writeback)
{
-
+
if (store || !(i & (1 << REG_POS(i, 16))))
{
JIT_COMMENT("--- writeback");
@@ -2345,8 +2342,8 @@
//printf("ARM%c: %s R%d:%08X, bitmask %02X\n", PROCNUM?'7':'9', (store?"STM":"LDM"), REG_POS(i, 16), cpu->R[REG_POS(i, 16)], bitmask);
uint32_t adr_first = cpu->R[REG_POS(i, 16)];
- GpVar adr = c.newGpVar(kX86VarTypeGpd);
- GpVar oldmode = c.newGpVar(kX86VarTypeGpd);
+ GpVar adr = c.newGpVar(kVarTypeInt32);
+ GpVar oldmode = c.newGpVar(kVarTypeInt32);
c.mov(adr, reg_pos_ptr(16));
if (before)
@@ -2357,11 +2354,11 @@
//if((cpu->CPSR.bits.mode==USR)||(cpu->CPSR.bits.mode==SYS)) { printf("ERROR1\n"); return 1; }
//oldmode = armcpu_switchMode(cpu, SYS);
c.mov(oldmode, SYS);
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(armcpu_switchMode));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder2<uint32_t, uint8_t *, uint8_t>());
- ctx->setArgument(0, bb_cpu);
- ctx->setArgument(1, oldmode);
- ctx->setReturn(oldmode);
+ auto ctx = c.addCall(imm_ptr(armcpu_switchMode), ASMJIT_CALL_CONV,
+ FuncBuilder2<uint32_t, uint8_t *, uint8_t>());
+ ctx->setArg(0, bb_cpu);
+ ctx->setArg(1, oldmode);
+ ctx->setRet(0, oldmode);
}
call_ldm_stm(adr, bitmask, store, dir);
@@ -2369,10 +2366,10 @@
if (!bit15 || store)
{
//armcpu_switchMode(cpu, oldmode);
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(armcpu_switchMode));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder2<void, uint8_t *, uint8_t>());
- ctx->setArgument(0, bb_cpu);
- ctx->setArgument(1, oldmode);
+ auto ctx = c.addCall(imm_ptr(armcpu_switchMode), ASMJIT_CALL_CONV,
+ FuncBuilder2<void, uint8_t *, uint8_t>());
+ ctx->setArg(0, bb_cpu);
+ ctx->setArg(1, oldmode);
}
else
S_DST_R15;
@@ -2443,17 +2440,17 @@
static int op_bx(Mem srcreg, bool blx, bool test_thumb)
{
- GpVar dst = c.newGpVar(kX86VarTypeGpd);
+ GpVar dst = c.newGpVar(kVarTypeInt32);
c.mov(dst, srcreg);
if (test_thumb)
{
- GpVar mask = c.newGpVar(kX86VarTypeGpd);
+ GpVar mask = c.newGpVar(kVarTypeInt32);
GpVar thumb = dst;
- dst = c.newGpVar(kX86VarTypeGpd);
+ dst = c.newGpVar(kVarTypeInt32);
c.mov(dst, thumb);
c.and_(thumb, 1);
- c.lea(mask, ptr_abs(reinterpret_cast<void *>(0xFFFFFFFC), thumb.r64(), kScale2Times));
+ c.lea(mask, x86::ptr_abs(0xFFFFFFFC, thumb.r64(), 1));
c.shl(thumb, 5);
c.or_(cpu_ptr_byte(CPSR, 0), thumb.r8Lo());
c.and_(dst, mask);
@@ -2476,12 +2473,12 @@
// -----------------------------------------------------------------------------
static int OP_CLZ(uint32_t i)
{
- GpVar res = c.newGpVar(kX86VarTypeGpd);
+ GpVar res = c.newGpVar(kVarTypeInt32);
c.mov(res, 0x3F);
c.bsr(res, reg_pos_ptr(0));
c.xor_(res, 0x1F);
c.mov(reg_pos_ptr(12), res);
-
+
return 1;
}
@@ -2490,8 +2487,7 @@
// -----------------------------------------------------------------------------
#define maskPrecalc \
{ \
- X86CompilerFuncCall *ctxM = c.call(reinterpret_cast<void *>(maskPrecalc)); \
- ctxM->setPrototype(ASMJIT_CALL_CONV, FuncBuilder0<void>()); \
+ auto ctxM = c.addCall(imm_ptr(maskPrecalc), ASMJIT_CALL_CONV, FuncBuilder0<void>()); \
}
static int OP_MCR(uint32_t i)
{
@@ -2516,8 +2512,8 @@
uint8_t opcode1 = (i >> 21) & 0x7; // opcode1
uint8_t opcode2 = (i >> 5) & 0x7; // opcode2
- GpVar bb_cp15 = c.newGpVar(kX86VarTypeGpz);
- GpVar data = c.newGpVar(kX86VarTypeGpd);
+ GpVar bb_cp15 = c.newGpVar(kVarTypeIntPtr);
+ GpVar data = c.newGpVar(kVarTypeInt32);
c.mov(data, reg_pos_ptr(12));
c.mov(bb_cp15, reinterpret_cast<uintptr_t>(&cp15));
@@ -2527,17 +2523,17 @@
case 1:
if (!opcode1 && !opcode2 && !CRm)
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
// On the NDS bit0,2,7,12..19 are R/W, Bit3..6 are always set, all other bits are always zero.
//MMU.ARM9_RW_MODE = BIT7(val);
- GpVar bb_mmu = c.newGpVar(kX86VarTypeGpz);
+ GpVar bb_mmu = c.newGpVar(kVarTypeIntPtr);
c.mov(bb_mmu, reinterpret_cast<uintptr_t>(&MMU));
Mem rwmode = mmu_ptr_byte(ARM9_RW_MODE);
Mem ldtbit = cpu_ptr_byte(LDTBit, 0);
c.test(data, 1 << 7);
c.setnz(rwmode);
//cpu->intVector = 0xFFFF0000 * (BIT13(val));
- GpVar vec = c.newGpVar(kX86VarTypeGpd);
+ GpVar vec = c.newGpVar(kVarTypeInt32);
c.mov(tmp, 0xFFFF0000);
c.xor_(vec, vec);
c.test(data, 1 << 13);
@@ -2696,7 +2692,7 @@
{
//MMU.DTCMRegion = DTCMRegion = val & 0x0FFFF000;
c.and_(data, 0x0FFFF000);
- GpVar bb_mmu = c.newGpVar(kX86VarTypeGpz);
+ GpVar bb_mmu = c.newGpVar(kVarTypeIntPtr);
c.mov(bb_mmu, reinterpret_cast<uintptr_t>(&MMU));
c.mov(mmu_ptr(DTCMRegion), data);
c.mov(cp15_ptr(DTCMRegion), data);
@@ -2706,7 +2702,7 @@
{
//ITCMRegion = val;
//ITCM base is not writeable!
- GpVar bb_mmu = c.newGpVar(kX86VarTypeGpz);
+ GpVar bb_mmu = c.newGpVar(kVarTypeIntPtr);
c.mov(bb_mmu, reinterpret_cast<uintptr_t>(&MMU));
c.mov(mmu_ptr(ITCMRegion), 0);
c.mov(cp15_ptr(ITCMRegion), data);
@@ -2751,11 +2747,11 @@
uint8_t opcode1 = (i >> 21) & 0x7; // opcode1
uint8_t opcode2 = (i >> 5) & 0x7; // opcode2
- GpVar bb_cp15 = c.newGpVar(kX86VarTypeGpz);
- GpVar data = c.newGpVar(kX86VarTypeGpd);
+ GpVar bb_cp15 = c.newGpVar(kVarTypeIntPtr);
+ GpVar data = c.newGpVar(kVarTypeInt32);
c.mov(bb_cp15, (uintptr_t)&cp15);
-
+
bool bUnknown = false;
switch (CRn)
{
@@ -2960,32 +2956,30 @@
// TODO:
return 0;
#else
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(ARM_swi_tab[PROCNUM][swinum]));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder0<uint32_t>());
- ctx->setReturn(bb_cycles);
+ auto ctx = c.addCall(imm_ptr(ARM_swi_tab[PROCNUM][swinum]), ASMJIT_CALL_CONV, FuncBuilder0<uint32_t>());
+ ctx->setRet(0, bb_cycles);
c.add(bb_cycles, 3);
return 1;
#endif
}
- GpVar oldCPSR = c.newGpVar(kX86VarTypeGpd);
- GpVar mode = c.newGpVar(kX86VarTypeGpd);
+ GpVar oldCPSR = c.newGpVar(kVarTypeInt32);
+ GpVar mode = c.newGpVar(kVarTypeInt32);
Mem CPSR = cpu_ptr(CPSR.val);
JIT_COMMENT("store CPSR to x86 stack");
c.mov(oldCPSR, CPSR);
JIT_COMMENT("enter SVC mode");
c.mov(mode, imm(SVC));
- X86CompilerFuncCall* ctx = c.call(reinterpret_cast<void *>(armcpu_switchMode));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder2<void, void *, uint8_t>());
- ctx->setArgument(0, bb_cpu);
- ctx->setArgument(1, mode);
+ auto ctx = c.addCall(imm_ptr(armcpu_switchMode), ASMJIT_CALL_CONV, FuncBuilder2<void, void *, uint8_t>());
+ ctx->setArg(0, bb_cpu);
+ ctx->setArg(1, mode);
c.unuse(mode);
JIT_COMMENT("store next instruction address to R14");
c.mov(reg_ptr(14), bb_next_instruction);
JIT_COMMENT("save old CPSR as new SPSR");
c.mov(cpu_ptr(SPSR.val), oldCPSR);
JIT_COMMENT("CPSR: clear T, set I");
- GpVar _cpsr = c.newGpVar(kX86VarTypeGpd);
+ GpVar _cpsr = c.newGpVar(kVarTypeInt32);
c.mov(_cpsr, CPSR);
c.and_(_cpsr, ~(1 << 5)); /* clear T */
c.or_(_cpsr, 1 << 7); /* set I */
@@ -2993,7 +2987,7 @@
c.unuse(_cpsr);
JIT_COMMENT("set next instruction");
c.mov(cpu_ptr(next_instruction), imm(cpu->intVector + 0x08));
-
+
return 1;
}
@@ -3008,14 +3002,14 @@
// THUMB
// -----------------------------------------------------------------------------
#define OP_SHIFTS_IMM(x86inst) \
- GpVar rcf = c.newGpVar(kX86VarTypeGpd); \
+ GpVar rcf = c.newGpVar(kVarTypeInt32); \
uint8_t cf_change = 1; \
uint32_t rhs = (i >> 6) & 0x1F; \
if (_REG_NUM(i, 0) == _REG_NUM(i, 3)) \
c.x86inst(reg_pos_thumb(0), rhs); \
else \
{ \
- GpVar lhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar lhs = c.newGpVar(kVarTypeInt32); \
c.mov(lhs, reg_pos_thumb(3)); \
c.x86inst(lhs, rhs); \
c.mov(reg_pos_thumb(0), lhs); \
@@ -3027,8 +3021,8 @@
#define OP_SHIFTS_REG(x86inst, bit) \
uint8_t cf_change = 1; \
- GpVar imm = c.newGpVar(kX86VarTypeGpz); \
- GpVar rcf = c.newGpVar(kX86VarTypeGpd); \
+ GpVar imm = c.newGpVar(kVarTypeIntPtr); \
+ GpVar rcf = c.newGpVar(kVarTypeInt32); \
Label __eq32 = c.newLabel(); \
Label __ls32 = c.newLabel(); \
Label __zero = c.newLabel(); \
@@ -3065,7 +3059,7 @@
return 1;
#define OP_LOGIC(x86inst, _conv) \
- GpVar rhs = c.newGpVar(kX86VarTypeGpd); \
+ GpVar rhs = c.newGpVar(kVarTypeInt32); \
c.mov(rhs, reg_pos_thumb(3)); \
if (_conv == 1) \
c.not_(rhs); \
@@ -3082,7 +3076,7 @@
c.cmp(reg_pos_thumb(0), 0);
else
{
- GpVar rhs = c.newGpVar(kX86VarTypeGpd);
+ GpVar rhs = c.newGpVar(kVarTypeInt32);
c.mov(rhs, reg_pos_thumb(3));
c.mov(reg_pos_thumb(0), rhs);
c.cmp(rhs, 0);
@@ -3094,7 +3088,7 @@
static int OP_LSL_REG(uint32_t i) { OP_SHIFTS_REG(shl, 0); }
static int OP_LSR_0(uint32_t i)
{
- GpVar rcf = c.newGpVar(kX86VarTypeGpd);
+ GpVar rcf = c.newGpVar(kVarTypeInt32);
c.test(reg_pos_thumb(3), 1 << 31);
c.setnz(rcf.r8Lo());
SET_NZC_SHIFTS_ZERO(1);
@@ -3106,8 +3100,8 @@
static int OP_ASR_0(uint32_t i)
{
uint8_t cf_change = 1;
- GpVar rcf = c.newGpVar(kX86VarTypeGpd);
- GpVar rhs = c.newGpVar(kX86VarTypeGpd);
+ GpVar rcf = c.newGpVar(kVarTypeInt32);
+ GpVar rhs = c.newGpVar(kVarTypeInt32);
if (_REG_NUM(i, 0) == _REG_NUM(i, 3))
c.sar(reg_pos_thumb(0), 31);
else
@@ -3121,15 +3115,15 @@
return 1;
}
static int OP_ASR(uint32_t i) { OP_SHIFTS_IMM(sar); }
-static int OP_ASR_REG(uint32_t i)
+static int OP_ASR_REG(uint32_t i)
{
uint8_t cf_change = 1;
Label __gr0 = c.newLabel();
Label __lt32 = c.newLabel();
Label __done = c.newLabel();
Label __setFlags = c.newLabel();
- GpVar imm = c.newGpVar(kX86VarTypeGpz);
- GpVar rcf = c.newGpVar(kX86VarTypeGpd);
+ GpVar imm = c.newGpVar(kVarTypeIntPtr);
+ GpVar rcf = c.newGpVar(kVarTypeInt32);
c.mov(imm, reg_pos_thumb(3));
c.and_(imm, 0xFF);
c.jnz(__gr0);
@@ -3161,8 +3155,8 @@
static int OP_ROR_REG(uint32_t i)
{
uint8_t cf_change = 1;
- GpVar imm = c.newGpVar(kX86VarTypeGpz);
- GpVar rcf = c.newGpVar(kX86VarTypeGpd);
+ GpVar imm = c.newGpVar(kVarTypeIntPtr);
+ GpVar rcf = c.newGpVar(kVarTypeInt32);
Label __zero = c.newLabel();
Label __zero_1F = c.newLabel();
Label __done = c.newLabel();
@@ -3208,7 +3202,7 @@
c.neg(reg_pos_thumb(0));
else
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(3));
c.neg(tmp);
c.mov(reg_pos_thumb(0), tmp);
@@ -3220,13 +3214,13 @@
//-----------------------------------------------------------------------------
// ADD
//-----------------------------------------------------------------------------
-static int OP_ADD_IMM3(uint32_t i)
+static int OP_ADD_IMM3(uint32_t i)
{
uint32_t imm3 = (i >> 6) & 0x07;
if (!imm3) // mov 2
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(3));
c.mov(reg_pos_thumb(0), tmp);
c.cmp(tmp, 0);
@@ -3237,7 +3231,7 @@
c.add(reg_pos_thumb(0), imm3);
else
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(3));
c.add(tmp, imm3);
c.mov(reg_pos_thumb(0), tmp);
@@ -3250,14 +3244,14 @@
c.add(reg_pos_thumb(8), (i & 0xFF));
SET_NZCV(0);
- return 1;
-}
-static int OP_ADD_REG(uint32_t i)
+ return 1;
+}
+static int OP_ADD_REG(uint32_t i)
{
//cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
if (_REG_NUM(i, 0) == _REG_NUM(i, 3))
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(6));
c.add(reg_pos_thumb(0), tmp);
}
@@ -3265,26 +3259,26 @@
{
if (_REG_NUM(i, 0) == _REG_NUM(i, 6))
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(3));
c.add(reg_pos_thumb(0), tmp);
}
else
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(3));
c.add(tmp, reg_pos_thumb(6));
c.mov(reg_pos_thumb(0), tmp);
}
}
SET_NZCV(0);
- return 1;
+ return 1;
}
static int OP_ADD_SPE(uint32_t i)
{
uint32_t Rd = _REG_NUM(i, 0) | ((i >> 4) & 8);
//cpu->R[Rd] += cpu->R[REG_POS(i, 3)];
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_ptr(Rd));
c.add(tmp, reg_pos_ptr(3));
c.mov(reg_ptr(Rd), tmp);
@@ -3306,7 +3300,7 @@
{
uint32_t imm = (i & 0xFF) << 2;
//cpu->R[REG_NUM(i, 8)] = cpu->R[13] + ((i&0xFF)<<2);
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_ptr(13));
if (imm)
c.add(tmp, imm);
@@ -3327,7 +3321,7 @@
c.sub(reg_pos_thumb(0), imm3);
else
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(3));
c.sub(tmp, imm3);
c.mov(reg_pos_thumb(0), tmp);
@@ -3340,26 +3334,26 @@
//cpu->R[REG_NUM(i, 8)] -= imm8;
c.sub(reg_pos_thumb(8), i & 0xFF);
SET_NZCV(1);
- return 1;
+ return 1;
}
static int OP_SUB_REG(uint32_t i)
{
- // cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)] - cpu->R[REG_NUM(i, 6)];
+ //cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)] - cpu->R[REG_NUM(i, 6)];
if (_REG_NUM(i, 0) == _REG_NUM(i, 3))
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(6));
c.sub(reg_pos_thumb(0), tmp);
}
else
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(3));
c.sub(tmp, reg_pos_thumb(6));
c.mov(reg_pos_thumb(0), tmp);
}
SET_NZCV(1);
- return 1;
+ return 1;
}
// -----------------------------------------------------------------------------
@@ -3367,7 +3361,7 @@
// -----------------------------------------------------------------------------
static int OP_ADC_REG(uint32_t i)
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(3));
GET_CARRY(0);
c.adc(reg_pos_thumb(0), tmp);
@@ -3380,7 +3374,7 @@
// -----------------------------------------------------------------------------
static int OP_SBC_REG(uint32_t i)
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(3));
GET_CARRY(1);
c.sbb(reg_pos_thumb(0), tmp);
@@ -3403,7 +3397,7 @@
{
uint32_t Rd = _REG_NUM(i, 0) | ((i >> 4) & 8);
//cpu->R[Rd] = cpu->R[REG_POS(i, 3)];
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_ptr(3));
c.mov(reg_ptr(Rd), tmp);
if (Rd == 15)
@@ -3411,13 +3405,13 @@
c.mov(cpu_ptr(next_instruction), tmp);
bb_constant_cycles += 2;
}
-
+
return 1;
}
static int OP_MVN(uint32_t i)
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(3));
c.not_(tmp);
c.cmp(tmp, 0);
@@ -3431,7 +3425,7 @@
// -----------------------------------------------------------------------------
static int OP_MUL_REG(uint32_t i)
{
- GpVar lhs = c.newGpVar(kX86VarTypeGpd);
+ GpVar lhs = c.newGpVar(kVarTypeInt32);
c.mov(lhs, reg_pos_thumb(0));
c.imul(lhs, reg_pos_thumb(3));
c.cmp(lhs, 0);
@@ -3456,7 +3450,7 @@
static int OP_CMP(uint32_t i)
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(3));
c.cmp(reg_pos_thumb(0), tmp);
SET_NZCV(1);
@@ -3466,7 +3460,7 @@
static int OP_CMP_SPE(uint32_t i)
{
uint32_t Rn = (i & 7) | ((i >> 4) & 8);
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_ptr(3));
c.cmp(reg_ptr(Rn), tmp);
SET_NZCV(1);
@@ -3475,7 +3469,7 @@
static int OP_CMN(uint32_t i)
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(0));
c.add(tmp, reg_pos_thumb(3));
SET_NZCV(0);
@@ -3487,7 +3481,7 @@
// -----------------------------------------------------------------------------
static int OP_TST(uint32_t i)
{
- GpVar tmp = c.newGpVar(kX86VarTypeGpd);
+ GpVar tmp = c.newGpVar(kVarTypeInt32);
c.mov(tmp, reg_pos_thumb(3));
c.test(reg_pos_thumb(0), tmp);
SET_NZ(0);
@@ -3498,8 +3492,8 @@
// STR / LDR / STRB / LDRB
// -----------------------------------------------------------------------------
#define STR_THUMB(mem_op, offset) \
- GpVar addr = c.newGpVar(kX86VarTypeGpd); \
- GpVar data = c.newGpVar(kX86VarTypeGpd); \
+ GpVar addr = c.newGpVar(kVarTypeInt32); \
+ GpVar data = c.newGpVar(kVarTypeInt32); \
uint32_t adr_first = cpu->R[_REG_NUM(i, 3)]; \
\
c.mov(addr, reg_pos_thumb(3)); \
@@ -3517,16 +3511,16 @@
adr_first += cpu->R[_REG_NUM(i, 6)]; \
} \
c.mov(data, reg_pos_thumb(0)); \
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(mem_op##_tab[PROCNUM][classify_adr(adr_first, 1)])); \
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder2<void, uint32_t, uint32_t>()); \
- ctx->setArgument(0, addr); \
- ctx->setArgument(1, data); \
- ctx->setReturn(bb_cycles); \
+ auto ctx = c.addCall(imm_ptr(mem_op##_tab[PROCNUM][classify_adr(adr_first, 1)]), ASMJIT_CALL_CONV, \
+ FuncBuilder2<void, uint32_t, uint32_t>()); \
+ ctx->setArg(0, addr); \
+ ctx->setArg(1, data); \
+ ctx->setRet(0, bb_cycles); \
return 1;
#define LDR_THUMB(mem_op, offset) \
- GpVar addr = c.newGpVar(kX86VarTypeGpd); \
- GpVar data = c.newGpVar(kX86VarTypeGpz); \
+ GpVar addr = c.newGpVar(kVarTypeInt32); \
+ GpVar data = c.newGpVar(kVarTypeIntPtr); \
uint32_t adr_first = cpu->R[_REG_NUM(i, 3)]; \
\
c.mov(addr, reg_pos_thumb(3)); \
@@ -3544,16 +3538,16 @@
adr_first += cpu->R[_REG_NUM(i, 6)]; \
} \
c.lea(data, reg_pos_thumb(0)); \
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(mem_op##_tab[PROCNUM][classify_adr(adr_first, 0)])); \
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder2<void, uint32_t, uint32_t *>()); \
- ctx->setArgument(0, addr); \
- ctx->setArgument(1, data); \
- ctx->setReturn(bb_cycles); \
+ auto ctx = c.addCall(imm_ptr(mem_op##_tab[PROCNUM][classify_adr(adr_first, 0)]), ASMJIT_CALL_CONV, \
+ FuncBuilder2<void, uint32_t, uint32_t *>()); \
+ ctx->setArg(0, addr); \
+ ctx->setArg(1, data); \
+ ctx->setRet(0, bb_cycles); \
return 1;
static int OP_STRB_IMM_OFF(uint32_t i) { STR_THUMB(STRB, (i >> 6) & 0x1F); }
static int OP_LDRB_IMM_OFF(uint32_t i) { LDR_THUMB(LDRB, (i >> 6) & 0x1F); }
-static int OP_STRB_REG_OFF(uint32_t i) { STR_THUMB(STRB, -1); }
+static int OP_STRB_REG_OFF(uint32_t i) { STR_THUMB(STRB, -1); }
static int OP_LDRB_REG_OFF(uint32_t i) { LDR_THUMB(LDRB, -1); }
static int OP_LDRSB_REG_OFF(uint32_t i) { LDR_THUMB(LDRSB, -1); }
@@ -3573,17 +3567,17 @@
uint32_t imm = (i & 0xFF) << 2;
uint32_t adr_first = cpu->R[13] + imm;
- GpVar addr = c.newGpVar(kX86VarTypeGpd);
+ GpVar addr = c.newGpVar(kVarTypeInt32);
c.mov(addr, reg_ptr(13));
if (imm)
c.add(addr, imm);
- GpVar data = c.newGpVar(kX86VarTypeGpd);
+ GpVar data = c.newGpVar(kVarTypeInt32);
c.mov(data, reg_pos_thumb(8));
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(STR_tab[PROCNUM][classify_adr(adr_first, 1)]));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder2<void, uint32_t, uint32_t>());
- ctx->setArgument(0, addr);
- ctx->setArgument(1, data);
- ctx->setReturn(bb_cycles);
+ auto ctx = c.addCall(imm_ptr(STR_tab[PROCNUM][classify_adr(adr_first, 1)]), ASMJIT_CALL_CONV,
+ FuncBuilder2<void, uint32_t, uint32_t>());
+ ctx->setArg(0, addr);
+ ctx->setArg(1, data);
+ ctx->setRet(0, bb_cycles);
return 1;
}
@@ -3591,18 +3585,18 @@
{
uint32_t imm = (i & 0xFF) << 2;
uint32_t adr_first = cpu->R[13] + imm;
-
- GpVar addr = c.newGpVar(kX86VarTypeGpd);
+
+ GpVar addr = c.newGpVar(kVarTypeInt32);
c.mov(addr, reg_ptr(13));
if (imm)
c.add(addr, imm);
- GpVar data = c.newGpVar(kX86VarTypeGpz);
+ GpVar data = c.newGpVar(kVarTypeIntPtr);
c.lea(data, reg_pos_thumb(8));
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(LDR_tab[PROCNUM][classify_adr(adr_first, 0)]));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder2<void, uint32_t, uint32_t *>());
- ctx->setArgument(0, addr);
- ctx->setArgument(1, data);
- ctx->setReturn(bb_cycles);
+ auto ctx = c.addCall(imm_ptr(LDR_tab[PROCNUM][classify_adr(adr_first, 0)]), ASMJIT_CALL_CONV,
+ FuncBuilder2<void, uint32_t, uint32_t *>());
+ ctx->setArg(0, addr);
+ ctx->setArg(1, data);
+ ctx->setRet(0, bb_cycles);
return 1;
}
@@ -3610,15 +3604,15 @@
{
uint32_t imm = (i & 0xFF) << 2;
uint32_t adr_first = (bb_r15 & 0xFFFFFFFC) + imm;
- GpVar addr = c.newGpVar(kX86VarTypeGpd);
- GpVar data = c.newGpVar(kX86VarTypeGpz);
+ GpVar addr = c.newGpVar(kVarTypeInt32);
+ GpVar data = c.newGpVar(kVarTypeIntPtr);
c.mov(addr, adr_first);
c.lea(data, reg_pos_thumb(8));
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(LDR_tab[PROCNUM][classify_adr(adr_first, 0)]));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder2<void, uint32_t, uint32_t *>());
- ctx->setArgument(0, addr);
- ctx->setArgument(1, data);
- ctx->setReturn(bb_cycles);
+ auto ctx = c.addCall(imm_ptr(LDR_tab[PROCNUM][classify_adr(adr_first, 0)]), ASMJIT_CALL_CONV,
+ FuncBuilder2<void, uint32_t, uint32_t *>());
+ ctx->setArg(0, addr);
+ ctx->setArg(1, data);
+ ctx->setRet(0, bb_cycles);
return 1;
}
@@ -3633,7 +3627,7 @@
//if (BIT_N(i, _REG_NUM(i, 8)))
// printf("WARNING - %sIA with Rb in Rlist (THUMB)\n", store?"STM":"LDM");
- GpVar adr = c.newGpVar(kX86VarTypeGpd);
+ GpVar adr = c.newGpVar(kVarTypeInt32);
c.mov(adr, reg_pos_thumb(8));
call_ldm_stm(adr, bitmask, store, 1);
@@ -3672,7 +3666,7 @@
uint32_t pop = popcount(bitmask);
int dir = store ? -1 : 1;
- GpVar adr = c.newGpVar(kX86VarTypeGpd);
+ GpVar adr = c.newGpVar(kVarTypeInt32);
c.mov(adr, reg_ptr(13));
if (store)
c.sub(adr, 4);
@@ -3720,7 +3714,7 @@
static int OP_BLX(uint32_t i)
{
- GpVar dst = c.newGpVar(kX86VarTypeGpd);
+ GpVar dst = c.newGpVar(kVarTypeInt32);
c.mov(dst, reg_ptr(14));
c.add(dst, (i & 0x7FF) << 1);
c.and_(dst, 0xFFFFFFFC);
@@ -3738,9 +3732,9 @@
return 1;
}
-static int OP_BL_11(uint32_t i)
-{
- GpVar dst = c.newGpVar(kX86VarTypeGpd);
+static int OP_BL_11(uint32_t i)
+{
+ GpVar dst = c.newGpVar(kVarTypeInt32);
c.mov(dst, reg_ptr(14));
c.add(dst, (i & 0x7FF) << 1);
c.mov(cpu_ptr(instruct_adr), dst);
@@ -3750,8 +3744,8 @@
static int op_bx_thumb(Mem srcreg, bool blx, bool test_thumb)
{
- GpVar dst = c.newGpVar(kX86VarTypeGpd);
- GpVar thumb = c.newGpVar(kX86VarTypeGpd);
+ GpVar dst = c.newGpVar(kVarTypeInt32);
+ GpVar thumb = c.newGpVar(kVarTypeInt32);
c.mov(dst, srcreg);
c.mov(thumb, dst); // * cpu->CPSR.bits.T = BIT0(Rm);
c.and_(thumb, 1); // *
@@ -3759,14 +3753,14 @@
c.mov(reg_ptr(14), bb_next_instruction | 1);
if (test_thumb)
{
- GpVar mask = c.newGpVar(kX86VarTypeGpd);
- c.lea(mask, ptr_abs(reinterpret_cast<void *>(0xFFFFFFFC), thumb.r64(), kScale2Times));
+ GpVar mask = c.newGpVar(kVarTypeInt32);
+ c.lea(mask, x86::ptr_abs(0xFFFFFFFC, thumb.r64(), 1));
c.and_(dst, mask);
}
else
c.and_(dst, 0xFFFFFFFE);
-
- GpVar tmp = c.newGpVar(kX86VarTypeGpd); // *
+
+ GpVar tmp = c.newGpVar(kVarTypeInt32); // *
c.mov(tmp, cpu_ptr_byte(CPSR, 0)); // *
c.and_(tmp, ~(1 << 5)); // *
c.shl(thumb, 5); // *
@@ -3892,7 +3886,7 @@
{
if (bb_thumb)
return false;
-
+
return !(CONDITION(opcode) == 0xE || (CONDITION(opcode) == 0xF && CODE(opcode) == 5));
}
@@ -3904,7 +3898,7 @@
{
if ((x & BRANCH_SWI) && !cpu->swi_tab)
return 3;
-
+
return 0;
}
if (instr_is_branch(opcode) && !(instr_attributes(opcode) & (BRANCH_ALWAYS | BRANCH_LDM)))
@@ -3968,14 +3962,14 @@
}
else
{
- GpVar x = c.newGpVar(kX86VarTypeGpz);
+ GpVar x = c.newGpVar(kVarTypeIntPtr);
c.movzx(x, flags_ptr);
c.and_(x, 0xF0);
#if defined(_M_X64) || defined(__x86_64__)
c.add(x, offsetof(armcpu_t,cond_table) + cond);
- c.test(byte_ptr(bb_cpu, x), 1);
+ c.test(x86::byte_ptr(bb_cpu, x), 1);
#else
- c.test(byte_ptr_abs((void *)(arm_cond_table + cond), x, kScaleNone), 1);
+ c.test(x86::byte_ptr_abs(reinterpret_cast<Ptr>(&arm_cond_table[0]) + cond, x, 0), 1);
#endif
c.unuse(x);
c.jz(to);
@@ -3989,13 +3983,12 @@
return;
JIT_COMMENT("call interpreter");
- GpVar arg = c.newGpVar(kX86VarTypeGpd);
+ GpVar arg = c.newGpVar(kVarTypeInt32);
c.mov(arg, opcode);
OpFunc f = bb_thumb ? thumb_instructions_set[PROCNUM][opcode >> 6] : arm_instructions_set[PROCNUM][INSTRUCTION_INDEX(opcode)];
- X86CompilerFuncCall *ctx = c.call(reinterpret_cast<void *>(f));
- ctx->setPrototype(ASMJIT_CALL_CONV, FuncBuilder1<uint32_t, uint32_t>());
- ctx->setArgument(0, arg);
- ctx->setReturn(bb_cycles);
+ auto ctx = c.addCall(imm_ptr(f), ASMJIT_CALL_CONV, FuncBuilder1<uint32_t, uint32_t>());
+ ctx->setArg(0, arg);
+ ctx->setRet(0, bb_cycles);
}
static void _armlog(uint8_t proc, uint32_t addr, uint32_t opcode)
@@ -4003,7 +3996,7 @@
#if 0
#if 0
fprintf(stderr, "\t\t;R0:%08X R1:%08X R2:%08X R3:%08X R4:%08X R5:%08X R6:%08X R7:%08X R8:%08X R9:%08X\n\t\t;R10:%08X R11:%08X R12:%08X R13:%08X R14:%08X R15:%08X| next %08X, N:%i Z:%i C:%i V:%i\n",
- cpu->R[0], cpu->R[1], cpu->R[2], cpu->R[3], cpu->R[4], cpu->R[5], cpu->R[6], cpu->R[7],
+ cpu->R[0], cpu->R[1], cpu->R[2], cpu->R[3], cpu->R[4], cpu->R[5], cpu->R[6], cpu->R[7],
cpu->R[8], cpu->R[9], cpu->R[10], cpu->R[11], cpu->R[12], cpu->R[13], cpu->R[14], cpu->R[15],
cpu->next_instruction, cpu->CPSR.bits.N, cpu->CPSR.bits.Z, cpu->CPSR.bits.C, cpu->CPSR.bits.V);
#endif
@@ -4014,7 +4007,7 @@
else
des_arm_instructions_set[INDEX22(opcode)](addr, opcode, dasmbuf);
#undef INDEX22
- fprintf(stderr, "%s%c %08X\t%08X \t%s\n", cpu->CPSR.bits.T?"THUMB":"ARM", proc?'7':'9', addr, opcode, dasmbuf);
+ fprintf(stderr, "%s%c %08X\t%08X \t%s\n", cpu->CPSR.bits.T?"THUMB":"ARM", proc?'7':'9', addr, opcode, dasmbuf);
#endif
}
@@ -4026,7 +4019,7 @@
uint32_t interpreted_cycles = 0;
uint32_t start_adr = cpu->instruct_adr;
uint32_t opcode = 0;
-
+
bb_thumb = cpu->CPSR.bits.T;
bb_opcodesize = bb_thumb ? 2 : 4;
@@ -4041,22 +4034,22 @@
fprintf(stderr, "adr %08Xh %s%c\n", start_adr, ARMPROC.CPSR.bits.T ? "THUMB":"ARM", PROCNUM?'7':'9');
#endif
- c.clear();
- c.newFunc(ASMJIT_CALL_CONV, FuncBuilder0<int>());
+ c.reset();
+ c.addFunc(ASMJIT_CALL_CONV, FuncBuilder0<int>());
c.getFunc()->setHint(kFuncHintNaked, true);
c.getFunc()->setHint(kX86FuncHintPushPop, true);
-
+
JIT_COMMENT("CPU ptr");
- bb_cpu = c.newGpVar(kX86VarTypeGpz);
+ bb_cpu = c.newGpVar(kVarTypeIntPtr);
c.mov(bb_cpu, (uintptr_t)&ARMPROC);
JIT_COMMENT("reset bb_total_cycles");
- bb_total_cycles = c.newGpVar(kX86VarTypeGpz);
+ bb_total_cycles = c.newGpVar(kVarTypeIntPtr);
c.mov(bb_total_cycles, 0);
-#if (PROFILER_JIT_LEVEL > 0)
+#if PROFILER_JIT_LEVEL > 0
JIT_COMMENT("Profiler ptr");
- bb_profiler = c.newGpVar(kX86VarTypeGpz);
+ bb_profiler = c.newGpVar(kVarTypeIntPtr);
c.mov(bb_profiler, reinterpret_cast<uintptr_t>(&profiler_counter[PROCNUM]));
#endif
@@ -4081,12 +4074,12 @@
uint32_t cycles = instr_cycles(opcode);
bEndBlock = i >= CommonSettings.jit_max_block_size - 1 || instr_is_branch(opcode);
-
+
#if LOG_JIT
if (instr_is_conditional(opcode) && cycles > 1 || !cycles)
has_variable_cycles = true;
#endif
- bb_cycles = c.newGpVar(kX86VarTypeGpz);
+ bb_cycles = c.newGpVar(kVarTypeIntPtr);
bb_constant_cycles += instr_is_conditional(opcode) ? 1 : cycles;
@@ -4111,11 +4104,11 @@
if (!bEndBlock)
sync_r15(opcode, 0, 0);
emit_armop_call(opcode);
-
+
if (!cycles)
{
JIT_COMMENT("variable cycles");
- c.lea(bb_total_cycles, ptr(bb_total_cycles.r64(), bb_cycles.r64(), kScaleNone));
+ c.lea(bb_total_cycles, x86::ptr(bb_total_cycles.r64(), bb_cycles.r64(), 0));
}
c.bind(skip);
}
@@ -4126,16 +4119,16 @@
if (!cycles)
{
JIT_COMMENT("variable cycles");
- c.lea(bb_total_cycles, ptr(bb_total_cycles.r64(), bb_cycles.r64(), kScaleNone));
+ c.lea(bb_total_cycles, x86::ptr(bb_total_cycles.r64(), bb_cycles.r64(), 0));
}
}
interpreted_cycles += op_decode[PROCNUM][bb_thumb]();
}
-
+
if (!instr_does_prefetch(opcode))
{
JIT_COMMENT("!instr_does_prefetch: copy next_instruction (%08X) to instruct_adr (%08X)", cpu->next_instruction, cpu->instruct_adr);
- GpVar x = c.newGpVar(kX86VarTypeGpd);
+ GpVar x = c.newGpVar(kVarTypeInt32);
c.mov(x, cpu_ptr(next_instruction));
c.mov(cpu_ptr(instruct_adr), x);
c.unuse(x);
@@ -4151,9 +4144,9 @@
#if PROFILER_JIT_LEVEL > 1
JIT_COMMENT("*** profiler - cycles");
uint32_t padr = (start_adr & 0x07FFFFFE) >> 1;
- bb_profiler_entry = c.newGpVar(kX86VarTypeGpz);
+ bb_profiler_entry = c.newGpVar(kVarTypeIntPtr);
c.mov(bb_profiler_entry, reinterpret_cast<uintptr_t>(&profiler_entry[PROCNUM][padr]));
- c.add(dword_ptr(bb_profiler_entry, offsetof(PROFILER_ENTRY, cycles)), bb_total_cycles);
+ c.add(X86Mem(bb_profiler_entry, offsetof(PROFILER_ENTRY, cycles), 4), bb_total_cycles);
profiler_entry[PROCNUM][padr].addr = start_adr;
#endif
@@ -4164,9 +4157,9 @@
c.endFunc();
ArmOpCompiled f = static_cast<ArmOpCompiled>(c.make());
- if(c.getError())
- {
- fprintf(stderr, "JIT error: %s\n", getErrorString(c.getError()));
+ if (c.getError())
+ {
+ fprintf(stderr, "JIT error: %s\n", ErrorUtil::asString(c.getError()));
f = op_decode[PROCNUM][bb_thumb];
}
#if LOG_JIT
@@ -4174,7 +4167,7 @@
fprintf(stderr, "Block address %08lX\n\n", baddr);
fflush(stderr);
#endif
-
+
JIT_COMPILED_FUNC(start_adr, PROCNUM) = reinterpret_cast<uintptr_t>(f);
return interpreted_cycles;
}
@@ -4219,7 +4212,7 @@
printf("JIT max block size %d instruction(s)\n", CommonSettings.jit_max_block_size);
#ifdef MAPPED_JIT_FUNCS
// these pointers are allocated by asmjit and need freeing
- #define JITFREE(x) for (size_t iii = 0; iii < ARRAY_SIZE((x)); ++iii) if ((x)[iii]) AsmJit::MemoryManager::getGlobal()->free(reinterpret_cast<void *>((x)[iii])); memset((x), 0, sizeof((x)));
+ #define JITFREE(x) for (size_t iii = 0; iii < ARRAY_SIZE((x)); ++iii) if ((x)[iii]) runtime.getMemMgr()->release(reinterpret_cast<void *>((x)[iii])); memset((x), 0, sizeof((x)));
JITFREE(JIT.MAIN_MEM);
JITFREE(JIT.SWIRAM);
JITFREE(JIT.ARM9_ITCM);
@@ -4243,7 +4236,7 @@
#endif
}
- c.clear();
+ c.reset();
#if PROFILER_JIT_LEVEL > 0
reconstruct(&profiler_counter[0]);
@@ -4284,8 +4277,8 @@
auto arm_info = std::unique_ptr<PROFILER_COUNTER_INFO[]>(new PROFILER_COUNTER_INFO[4096]);
auto thumb_info = std::unique_ptr<PROFILER_COUNTER_INFO[]>(new PROFILER_COUNTER_INFO[1024]);
- memset(arm_info, 0, sizeof(PROFILER_COUNTER_INFO) * 4096);
- memset(thumb_info, 0, sizeof(PROFILER_COUNTER_INFO) * 1024);
+ memset(&arm_info[0], 0, sizeof(PROFILER_COUNTER_INFO) * 4096);
+ memset(&thumb_info[0], 0, sizeof(PROFILER_COUNTER_INFO) * 1024);
// ARM
last[0] = 0;
@@ -4331,8 +4324,8 @@
}
}
- std::qsort(arm_info, last[0], sizeof(PROFILER_COUNTER_INFO), (int (*)(const void *, const void *))pcmp);
- std::qsort(thumb_info, last[1], sizeof(PROFILER_COUNTER_INFO), (int (*)(const void *, const void *))pcmp);
+ std::qsort(&arm_info[0], last[0], sizeof(PROFILER_COUNTER_INFO), (int (*)(const void *, const void *))pcmp);
+ std::qsort(&thumb_info[0], last[1], sizeof(PROFILER_COUNTER_INFO), (int (*)(const void *, const void *))pcmp);
char buf[MAX_PATH] = { 0 };
sprintf(buf, "\\desmume_jit%c_counter.profiler", !proc ? '9' : '7');
@@ -4355,7 +4348,7 @@
fprintf(fp, "%30s: %20ld\n", arm_info[i].name, arm_info[i].count);
fprintf(fp, "\n");
}
-
+
if (last[1])
{
fprintf(fp, "========================================== THUMB ==========================================\n");
--- a/src/in_2sf/desmume/armcpu.cpp
+++ b/src/in_2sf/desmume/armcpu.cpp
@@ -71,7 +71,7 @@
#if defined(_M_X64) || defined(__x86_64__)
memcpy(&armcpu->cond_table[0], &arm_cond_table[0], sizeof(arm_cond_table));
#endif
-
+
armcpu->LDTBit = !armcpu->proc_ID; // Si ARM9 utiliser le syte v5 pour le load
armcpu->intVector = 0xFFFF0000 * !armcpu->proc_ID;
armcpu->waitIRQ = false;
--- a/src/in_2sf/desmume/cp15.cpp
+++ b/src/in_2sf/desmume/cp15.cpp
@@ -274,7 +274,7 @@
}
return false;
case 3:
- if (!opcode1 && ~opcode2 && !CRm)
+ if (!opcode1 && ~static_cast<int8_t>(opcode2) && !CRm)
{
*R = this->writeBuffCtrl;
return true;
--- a/src/in_2sf/desmume/debug.cpp
+++ /dev/null
@@ -1,411 +1,1 @@
-/* Copyright (C) 2008 Guillaume Duhamel
- Copyright (C) 2009-2010 DeSmuME team
- This file is part of DeSmuME
-
- DeSmuME is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DeSmuME is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <algorithm>
-#include <cstdarg>
-#include <cstdio>
-
-#include "debug.h"
-#include "MMU.h"
-#include "armcpu.h"
-#include "arm_instructions.h"
-#include "thumb_instructions.h"
-#include "cp15.h"
-#include "NDSSystem.h"
-#include "utils/xstring.h"
-//#include "movie.h"
-
-#ifdef HAVE_LUA
-#include "lua-engine.h"
-#endif
-
-armcpu_t* TDebugEventData::cpu() { return procnum==0?&NDS_ARM9:&NDS_ARM7; }
-
-TDebugEventData DebugEventData;
-uint32_t debugFlag;
-
-//DEBUG CONFIGURATION
-const bool debug_acl = false;
-
-static bool acl_check_access(uint32_t adr, uint32_t access) {
-
- //non-user modes get separate access handling, so check that here
- if(NDS_ARM9.CPSR.bits.mode != USR)
- access |= 1;
-
- if (armcp15_isAccessAllowed((armcp15_t *)NDS_ARM9.coproc[15],adr,access)==false) {
- HandleDebugEvent(DEBUG_EVENT_ACL_EXCEPTION);
- }
- return true;
-}
-
-void HandleDebugEvent_ACL_Exception()
-{
- printf("ACL EXCEPTION!\n");
- if(DebugEventData.memAccessType == MMU_AT_CODE)
- armcpu_exception(DebugEventData.cpu(),EXCEPTION_PREFETCH_ABORT);
- else if(DebugEventData.memAccessType == MMU_AT_DATA)
- armcpu_exception(DebugEventData.cpu(),EXCEPTION_DATA_ABORT);
-}
-
-
-/*static bool CheckRange(uint32_t adr, uint32_t min, uint32_t len)
-{
- return (adr>=min && adr<min+len);
-}*/
-
-void HandleDebugEvent_Read()
-{
- if(!debug_acl) return;
- if(DebugEventData.procnum != ARMCPU_ARM9) return; //acl only valid on arm9
- acl_check_access(DebugEventData.addr,CP15_ACCESS_READ);
-}
-
-void HandleDebugEvent_Write()
-{
- if(!debug_acl) return;
- if(DebugEventData.procnum != ARMCPU_ARM9) return; //acl only valid on arm9
- acl_check_access(DebugEventData.addr,CP15_ACCESS_WRITE);
-}
-
-void HandleDebugEvent_Execute()
-{
- //HACKY BREAKPOINTS!
- //extern bool nds_debug_continuing[2];
- //if(!nds_debug_continuing[DebugEventData.procnum]) //dont keep hitting the same breakpoint
- //{
- // if((DebugEventData.addr & 0xFFFFFFF0) == 0x02000000)
- // {
- // void NDS_debug_break();
- // NDS_debug_break();
- // }
- //}
- if(!debug_acl) return;
- if(DebugEventData.procnum != ARMCPU_ARM9) return; //acl only valid on arm9
- acl_check_access(DebugEventData.addr,CP15_ACCESS_EXECUTE);
-}
-
-//------------------------------------------------
-DebugStatistics DEBUG_statistics;
-
-DebugStatistics::DebugStatistics()
-{
-}
-
-DebugStatistics::InstructionHits::InstructionHits()
-{
- memset(&arm,0,sizeof(arm));
- memset(&thumb,0,sizeof(thumb));
-}
-
-
-static DebugStatistics::InstructionHits combinedHits[2];
-
-template<int proc, int which>
-static bool debugStatsSort(int num1, int num2) {
- if(which==0) {
- if(combinedHits[proc].arm[num2] == combinedHits[proc].arm[num1]) return false;
- if(combinedHits[proc].arm[num1] == 0xFFFFFFFF) return false;
- if(combinedHits[proc].arm[num2] == 0xFFFFFFFF) return true;
- return combinedHits[proc].arm[num2] < combinedHits[proc].arm[num1];
- }
- else {
- if(combinedHits[proc].thumb[num2] == combinedHits[proc].thumb[num1]) return false;
- if(combinedHits[proc].thumb[num1] == 0xFFFFFFFF) return false;
- if(combinedHits[proc].thumb[num2] == 0xFFFFFFFF) return true;
- return combinedHits[proc].thumb[num2] < combinedHits[proc].thumb[num1];
- }
-}
-
-void DebugStatistics::print()
-{
- //consolidate opcodes with the same names
- for(int i=0;i<2;i++) {
- combinedHits[i] = DEBUG_statistics.instructionHits[i];
-
- for(int j=0;j<4096;j++) {
- if(combinedHits[i].arm[j] == 0xFFFFFFFF)
- continue;
- std::string name = arm_instruction_names[j];
- for(int k=j+1;k<4096;k++) {
- if(combinedHits[i].arm[k] == 0xFFFFFFFF)
- continue;
- if(name == arm_instruction_names[k]) {
- //printf("combining %s with %d and %d\n",name.c_str(),combinedHits[i].arm[j],combinedHits[i].arm[k]);
- combinedHits[i].arm[j] += combinedHits[i].arm[k];
- combinedHits[i].arm[k] = 0xFFFFFFFF;
- }
-
- }
- }
-
- for(int j=0;j<1024;j++) {
- if(combinedHits[i].thumb[j] == 0xFFFFFFFF)
- continue;
- std::string name = thumb_instruction_names[j];
- for(int k=j+1;k<1024;k++) {
- if(combinedHits[i].thumb[k] == 0xFFFFFFFF)
- continue;
- if(name == thumb_instruction_names[k]) {
- //printf("combining %s with %d and %d\n",name.c_str(),combinedHits[i].arm[j],combinedHits[i].arm[k]);
- combinedHits[i].thumb[j] += combinedHits[i].thumb[k];
- combinedHits[i].thumb[k] = 0xFFFFFFFF;
- }
-
- }
- }
- }
-
- InstructionHits sorts[2];
- for(int i=0;i<2;i++) {
- for(int j=0;j<4096;j++) sorts[i].arm[j] = j;
- for(int j=0;j<1024;j++) sorts[i].thumb[j] = j;
- }
- std::sort(sorts[0].arm, sorts[0].arm+4096, debugStatsSort<0,0>);
- std::sort(sorts[0].thumb, sorts[0].thumb+1024, debugStatsSort<0,1>);
- std::sort(sorts[1].arm, sorts[1].arm+4096, debugStatsSort<1,0>);
- std::sort(sorts[1].thumb, sorts[1].thumb+1024, debugStatsSort<1,1>);
-
- for(int i=0;i<2;i++) {
- printf("Top arm instructions for ARM%d:\n",7+i*2);
- for(int j=0;j<10;j++) {
- int val = sorts[i].arm[j];
- printf("%08d: %s\n", combinedHits[i].arm[val], arm_instruction_names[val]);
- }
- printf("Top thumb instructions for ARM%d:\n",7+i*2);
- for(int j=0;j<10;j++) {
- int val = sorts[i].thumb[j];
- printf("%08d: %s\n", combinedHits[i].thumb[val], thumb_instruction_names[val]);
- }
- }
-}
-
-void DebugStatistics::printSequencerExecutionCounters()
-{
- for(int i=0;i<21;i++) printf("%06d ",sequencerExecutionCounters[i]);
- printf("\n");
-}
-
-void DEBUG_reset()
-{
- //for now, just enable all debugging in developer builds
-#ifdef DEVELOPER
- debugFlag = 1;
-#endif
-
- DEBUG_Notify = DebugNotify();
- DEBUG_statistics = DebugStatistics();
- printf("DEBUG_reset: %08X\n",&DebugStatistics::print); //force a reference to this function
-}
-
-/*static void DEBUG_dumpMemory_fill(EMUFILE *fp, uint32_t size)
-{
- static std::vector<uint8_t> buf;
- buf.resize(size);
- memset(&buf[0],0,size);
- fp->fwrite(&buf[0],size);
-}*/
-
-void DEBUG_dumpMemory(EMUFILE* fp)
-{
- fp->fseek(0x000000,SEEK_SET); fp->fwrite(MMU.MAIN_MEM,0x800000); //arm9 main mem (8192K)
- fp->fseek(0x900000,SEEK_SET); fp->fwrite(MMU.ARM9_DTCM,0x4000); //arm9 DTCM (16K)
- fp->fseek(0xA00000,SEEK_SET); fp->fwrite(MMU.ARM9_ITCM,0x8000); //arm9 ITCM (32K)
- fp->fseek(0xB00000,SEEK_SET); fp->fwrite(MMU.ARM9_LCD,0xA4000); //LCD mem 656K
- fp->fseek(0xC00000,SEEK_SET); fp->fwrite(MMU.ARM9_VMEM,0x800); //OAM
- fp->fseek(0xD00000,SEEK_SET); fp->fwrite(MMU.ARM7_ERAM,0x10000); //arm7 WRAM (64K)
- fp->fseek(0xE00000,SEEK_SET); fp->fwrite(MMU.ARM7_WIRAM,0x10000); //arm7 wifi RAM ?
- fp->fseek(0xF00000,SEEK_SET); fp->fwrite(MMU.SWIRAM,0x8000); //arm9/arm7 shared WRAM (32KB)
-}
-
-//----------------------------------------------------
-
-std::vector<Logger *> Logger::channels;
-
-
-static void defaultCallback(const Logger& logger, const char * message) {
- logger.getOutput() << message;
-}
-
-Logger::Logger() {
- out = &std::cout;
- callback = defaultCallback;
- flags = 0;
-}
-
-Logger::~Logger() {
- for(int i=0;i<(int)channels.size();i++)
- delete channels[i];
-}
-
-void Logger::vprintf(const char * format, va_list l, const char * file, unsigned int line) {
- char buffer[1024];
- char * cur = buffer;
-
- if (flags & Logger::FILE) cur += sprintf(cur, "%s:", file);
- if (flags & Logger::LINE) cur += sprintf(cur, "%d:", line);
- if (flags) cur += sprintf(cur, " ");
-
- ::vsnprintf(cur, 1024, format, l);
- callback(*this, buffer);
-}
-
-void Logger::setOutput(std::ostream * o) {
- out = o;
-}
-
-void Logger::setCallback(void (*cback)(const Logger& logger, const char * message)) {
- callback = cback;
-}
-
-void Logger::setFlag(unsigned int flag) {
- this->flags = flag;
-}
-
-void Logger::fixSize(unsigned int channel) {
- while(channel >= channels.size()) {
- channels.push_back(new Logger());
- }
-}
-
-std::ostream& Logger::getOutput() const {
- return *out;
-}
-
-void Logger::log(unsigned int channel, const char * file, unsigned int line, const char * format, ...) {
- fixSize(channel);
-
- va_list l;
- va_start(l, format);
- channels[channel]->vprintf(format, l, file, line);
- va_end(l);
-}
-
-void Logger::log(unsigned int channel, const char *, unsigned int, std::ostream& os) {
- fixSize(channel);
-
- channels[channel]->setOutput(&os);
-}
-
-void Logger::log(unsigned int channel, const char *, unsigned int, unsigned int flag) {
- fixSize(channel);
-
- channels[channel]->setFlag(flag);
-}
-
-void Logger::log(unsigned int channel, const char *, unsigned int, void (*callback)(const Logger& logger, const char * message)) {
- fixSize(channel);
-
- channels[channel]->setCallback(callback);
-}
-
-void IdeasLog(armcpu_t* cpu)
-{
- uint32_t adr = cpu->R[0];
- for(;;) {
- uint8_t c = _MMU_read08(cpu->proc_ID, MMU_AT_DEBUG, adr);
- adr++;
- if(!c) break;
- printf("%c",c);
- }
- //don't emit a newline. that is a pain in the butt.
-}
-
-void NocashMessage(armcpu_t* cpu)
-{
- uint32_t adr = cpu->instruct_adr + 6;
-
- std::string todo;
- for(;;) {
- uint8_t c = _MMU_read08(cpu->proc_ID, MMU_AT_DEBUG, adr);
- adr++;
- if(!c) break;
- todo.push_back(c);
- }
-
- //r0,r1,r2,...,r15 show register content (displayed as 32bit Hex number)
- //sp,lr,pc alias for r13,r14,r15
- //scanline show current scanline number
- //frame show total number of frames since coldboot
- //totalclks show total number of clock cycles since coldboot
- //lastclks show number of cycles since previous lastclks (or zeroclks)
- //zeroclks resets the 'lastclks' counter
-
- //this is very inefficiently coded!
- char tmp[100];
- todo = mass_replace(todo,"%sp%","%r13%");
- todo = mass_replace(todo,"%lr%","%r14%");
- todo = mass_replace(todo,"%pc%","%r15%");
- sprintf(tmp,"%08X",cpu->R[0]); todo = mass_replace(todo,"%r0%",tmp);
- sprintf(tmp,"%08X",cpu->R[1]); todo = mass_replace(todo,"%r1%",tmp);
- sprintf(tmp,"%08X",cpu->R[2]); todo = mass_replace(todo,"%r2%",tmp);
- sprintf(tmp,"%08X",cpu->R[3]); todo = mass_replace(todo,"%r3%",tmp);
- sprintf(tmp,"%08X",cpu->R[4]); todo = mass_replace(todo,"%r4%",tmp);
- sprintf(tmp,"%08X",cpu->R[5]); todo = mass_replace(todo,"%r5%",tmp);
- sprintf(tmp,"%08X",cpu->R[6]); todo = mass_replace(todo,"%r6%",tmp);
- sprintf(tmp,"%08X",cpu->R[7]); todo = mass_replace(todo,"%r7%",tmp);
- sprintf(tmp,"%08X",cpu->R[8]); todo = mass_replace(todo,"%r8%",tmp);
- sprintf(tmp,"%08X",cpu->R[9]); todo = mass_replace(todo,"%r9%",tmp);
- sprintf(tmp,"%08X",cpu->R[10]); todo = mass_replace(todo,"%r10%",tmp);
- sprintf(tmp,"%08X",cpu->R[11]); todo = mass_replace(todo,"%r11%",tmp);
- sprintf(tmp,"%08X",cpu->R[12]); todo = mass_replace(todo,"%r12%",tmp);
- sprintf(tmp,"%08X",cpu->R[13]); todo = mass_replace(todo,"%r13%",tmp);
- sprintf(tmp,"%08X",cpu->R[14]); todo = mass_replace(todo,"%r14%",tmp);
- sprintf(tmp,"%08X",cpu->R[15]); todo = mass_replace(todo,"%r15%",tmp);
- sprintf(tmp,"%d",nds.VCount); todo = mass_replace(todo,"%scanline%",tmp);
- /*sprintf(tmp,"%d",currFrameCounter); */todo = mass_replace(todo,"%frame%",tmp);
- sprintf(tmp,"%lld",nds_timer); todo = mass_replace(todo,"%totalclks%",tmp);
-
- printf("%s",todo.c_str());
-}
-
-//-------
-DebugNotify DEBUG_Notify;
-
-//enable bits arent being used right now.
-//if you want exhaustive logging, move the print before the early return (or comment the early return)
-
-//the intent of this system is to provide a compact dialog box showing which debug notifies have been
-//triggered in this frame (with a glowing LED!) and which debug notifies have been triggered EVER
-//which can be cleared, like a clip indicator in an audio tool.
-//obviously all this isnt implemented yet.
-
-void DebugNotify::NextFrame()
-{
-#ifdef DEVELOPER
- pingBits.reset();
-#endif
-}
-
-void DebugNotify::ReadBeyondEndOfCart(uint32_t addr, uint32_t romsize)
-{
-#ifdef DEVELOPER
- if(!ping(DEBUG_NOTIFY_READ_BEYOND_END_OF_CART)) return;
- INFO("Reading beyond end of cart! ... %08X >= %08X\n",addr,romsize);
-#endif
-}
-
-bool DebugNotify::ping(EDEBUG_NOTIFY which)
-{
- bool wasPinged = pingBits[(int)which];
- pingBits[(int)which] = true;
- return !wasPinged;
-}
-
--- a/src/in_2sf/desmume/debug.h
+++ /dev/null
@@ -1,217 +1,1 @@
-/* Copyright (C) 2008 Guillaume Duhamel
- Copyright (C) 2009-2010 DeSmuME team
- This file is part of DeSmuME
-
- DeSmuME is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DeSmuME is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#ifndef DEBUG_H
-#define DEBUG_H
-
-#include <vector>
-#include <iostream>
-#include <bitset>
-#include <cstdarg>
-
-#include "types.h"
-#include "mem.h"
-#include "emufile.h"
-
-struct DebugStatistics
-{
- DebugStatistics();
- struct InstructionHits {
- InstructionHits();
- uint32_t thumb[1024];
- uint32_t arm[4096];
- } instructionHits[2]; //one for each cpu
-
- int32_t sequencerExecutionCounters[32];
-
- void print();
- void printSequencerExecutionCounters();
-};
-
-extern DebugStatistics DEBUG_statistics;
-
-void DEBUG_reset();
-void DEBUG_dumpMemory(EMUFILE* fp);
-
-struct armcpu_t;
-
-class Logger {
-protected:
- void (*callback)(const Logger& logger, const char * format);
- std::ostream * out;
- unsigned int flags;
-
- static std::vector<Logger *> channels;
-
- static void fixSize(unsigned int channel);
-public:
- Logger();
- ~Logger();
-
- void vprintf(const char * format, va_list l, const char * filename, unsigned int line);
- void setOutput(std::ostream * o);
- void setCallback(void (*cback)(const Logger& logger, const char * message));
- void setFlag(unsigned int flag);
-
- std::ostream& getOutput() const;
-
- static const int LINE = 1;
- static const int FILE = 2;
-
- static void log(unsigned int channel, const char * file, unsigned int line, const char * format, ...);
- static void log(unsigned int channel, const char * file, unsigned int line, std::ostream& os);
- static void log(unsigned int channel, const char * file, unsigned int line, unsigned int flag);
- static void log(unsigned int channel, const char * file, unsigned int line, void (*callback)(const Logger& logger, const char * message));
-};
-
-#if defined(DEBUG) || defined(GPUDEBUG) || defined(DIVDEBUG) || defined(SQRTDEBUG) || defined(DMADEBUG) || defined(DEVELOPER)
-#define LOGC(channel, ...) Logger::log(channel, __FILE__, __LINE__, __VA_ARGS__)
-#else
-#define LOGC(...) {}
-#endif
-
-#ifdef DEBUG
-#define LOG(...) LOGC(0, __VA_ARGS__)
-#else
-#define LOG(...) {}
-#endif
-
-#ifdef GPUDEBUG
-#define GPULOG(...) LOGC(1, __VA_ARGS__)
-#else
-#define GPULOG(...) {}
-#endif
-
-#ifdef DIVDEBUG
-#define DIVLOG(...) LOGC(2, __VA_ARGS__)
-#else
-#define DIVLOG(...) {}
-#endif
-
-#ifdef SQRTDEBUG
-#define SQRTLOG(...) LOGC(3, __VA_ARGS__)
-#else
-#define SQRTLOG(...) {}
-#endif
-
-#ifdef DMADEBUG
-#define DMALOG(...) LOGC(4, __VA_ARGS__)
-#else
-#define DMALOG(...) {}
-#endif
-
-#ifdef CFLASHDEBUG
-#define CFLASHLOG(...) LOGC(5, __VA_ARGS__)
-#else
-#define CFLASHLOG(...) {}
-#endif
-
-#ifdef UNTESTEDOPCODEDEBUG
-#define UNTESTEDOPCODELOG(...) LOGC(6, __VA_ARGS__)
-#else
-#define UNTESTEDOPCODELOG(...) {}
-#endif
-
-
-#ifdef DEVELOPER
-#define PROGINFO(...) LOGC(7, __VA_ARGS__)
-#else
-#define PROGINFO(...) {}
-#endif
-
-
-#define INFOC(channel, ...) Logger::log(channel, __FILE__, __LINE__, __VA_ARGS__)
-#define INFO(...) INFOC(10, __VA_ARGS__)
-
-void IdeasLog(armcpu_t* cpu);
-void NocashMessage(armcpu_t* cpu);
-
-enum EDEBUG_EVENT
-{
- DEBUG_EVENT_READ=1, //read from arm9 or arm7 bus, including cpu prefetch
- DEBUG_EVENT_WRITE=2, //write on arm9 or arm7 bus
- DEBUG_EVENT_EXECUTE=4, //prefetch on arm9 or arm7, triggered after the read event
- DEBUG_EVENT_ACL_EXCEPTION=8, //acl exception on arm9
-};
-
-enum EDEBUG_NOTIFY
-{
- DEBUG_NOTIFY_READ_BEYOND_END_OF_CART,
- DEBUG_NOTIFY_MAX
-};
-
-class DebugNotify
-{
-public:
- void NextFrame();
- void ReadBeyondEndOfCart(uint32_t addr, uint32_t romsize);
-private:
- std::bitset<DEBUG_NOTIFY_MAX> pingBits;
- std::bitset<DEBUG_NOTIFY_MAX> enableBits;
- bool ping(EDEBUG_NOTIFY which);
-};
-
-extern DebugNotify DEBUG_Notify;
-struct armcpu_t;
-
-//information about a debug event will be stuffed into here by the generator
-struct TDebugEventData
-{
- MMU_ACCESS_TYPE memAccessType;
- uint32_t procnum, addr, size, val;
- armcpu_t* cpu();
-};
-
-extern TDebugEventData DebugEventData;
-
-//bits in here are set according to what debug handlers are installed?
-//for now it is just a single bit
-extern uint32_t debugFlag;
-
-inline bool CheckDebugEvent(EDEBUG_EVENT)
-{
- //for now, debug events are only handled in dev+ builds
-#ifndef DEVELOPER
- return false;
-#else
- if(!debugFlag) return false;
-
- return true;
-#endif
-}
-
-void HandleDebugEvent_Read();
-void HandleDebugEvent_Write();
-void HandleDebugEvent_Execute();
-void HandleDebugEvent_ACL_Exception();
-
-inline void HandleDebugEvent(EDEBUG_EVENT event)
-{
- switch(event)
- {
- case DEBUG_EVENT_READ: HandleDebugEvent_Read(); return;
- case DEBUG_EVENT_WRITE: HandleDebugEvent_Write(); return;
- case DEBUG_EVENT_EXECUTE: HandleDebugEvent_Execute(); return;
- case DEBUG_EVENT_ACL_EXCEPTION: HandleDebugEvent_ACL_Exception(); return;
- }
-}
-
-#endif
-
--- a/src/in_2sf/desmume/emufile.h
+++ b/src/in_2sf/desmume/emufile.h
@@ -37,7 +37,6 @@
#include "types.h"
#if defined(_MSC_VER) || defined(__MINGW32__)
-# include "windowsh_wrapper.h"
# include <io.h>
#else
# include <unistd.h>
--- a/src/in_2sf/desmume/firmware.cpp
+++ b/src/in_2sf/desmume/firmware.cpp
@@ -152,7 +152,7 @@
uint32_t CFIRMWARE::decrypt(const uint8_t *in, std::unique_ptr<uint8_t[]> &out)
{
uint32_t curBlock[2] = { 0 };
-
+
uint32_t xIn = 4, xOut = 0;
memcpy(curBlock, in, 8);
--- a/src/in_2sf/desmume/metaspu/SoundTouch/AAFilter.cpp
+++ b/src/in_2sf/desmume/metaspu/SoundTouch/AAFilter.cpp
@@ -45,7 +45,6 @@
#include <vector>
#include <cassert>
#include "AAFilter.h"
-#include "FIRFilter.h"
using namespace soundtouch;
--- a/src/in_2sf/desmume/metaspu/SoundTouch/FIFOSampleBuffer.cpp
+++ b/src/in_2sf/desmume/metaspu/SoundTouch/FIFOSampleBuffer.cpp
@@ -59,7 +59,7 @@
this->samplesInBuffer = 0;
this->bufferPos = 0;
this->channels = numChannels;
- this->ensureCapacity(32); // allocate initial capacity
+ this->ensureCapacity(32); // allocate initial capacity
}
// Sets number of channels, 1 = mono, 2 = stereo
@@ -218,10 +218,10 @@
/// allow trimming (downwards) amount of samples in pipeline.
/// Returns adjusted amount of samples
-uint32_t FIFOSampleBuffer::adjustAmountOfSamples(uint32_t numSamples)
-{
- if (numSamples < this->samplesInBuffer)
- this->samplesInBuffer = numSamples;
+uint32_t FIFOSampleBuffer::adjustAmountOfSamples(uint32_t numSmpls)
+{
+ if (numSmpls < this->samplesInBuffer)
+ this->samplesInBuffer = numSmpls;
return this->samplesInBuffer;
}
--- a/src/in_2sf/desmume/metaspu/SoundTouch/FIFOSamplePipe.h
+++ b/src/in_2sf/desmume/metaspu/SoundTouch/FIFOSamplePipe.h
@@ -207,9 +207,9 @@
/// allow trimming (downwards) amount of samples in pipeline.
/// Returns adjusted amount of samples
- virtual uint32_t adjustAmountOfSamples(uint32_t numSamples)
- {
- return this->output->adjustAmountOfSamples(numSamples);
+ virtual uint32_t adjustAmountOfSamples(uint32_t numSmpls)
+ {
+ return this->output->adjustAmountOfSamples(numSmpls);
}
};
--- a/src/in_2sf/desmume/metaspu/SoundTouch/RateTransposer.cpp
+++ b/src/in_2sf/desmume/metaspu/SoundTouch/RateTransposer.cpp
@@ -40,7 +40,6 @@
#include <stdexcept>
#include "RateTransposer.h"
-#include "AAFilter.h"
using namespace soundtouch;
@@ -137,7 +136,7 @@
return this->pAAFilter.get();
}
-// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
+// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
// iRate, larger faster iRates.
void RateTransposer::setRate(float newRate)
{
@@ -192,7 +191,7 @@
// If the parameter 'uRate' value is larger than 'SCALE', first apply the
// anti-alias filter to remove high frequencies (prevent them from folding
// over the lover frequencies), then transpose. */
-
+
// Add the new samples to the end of the storeBuffer */
this->storeBuffer.putSamples(src, nSamples);
@@ -407,7 +406,7 @@
return i;
}
-// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
+// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
// iRate, larger faster iRates.
void RateTransposerInteger::setRate(float newRate)
{
--- a/src/in_2sf/desmume/metaspu/SoundTouch/SoundTouch.cpp
+++ b/src/in_2sf/desmume/metaspu/SoundTouch/SoundTouch.cpp
@@ -77,8 +77,6 @@
#include <cstring>
#include <cstdio>
#include "SoundTouch.h"
-#include "TDStretch.h"
-#include "RateTransposer.h"
#include "cpu_detect.h"
using namespace soundtouch;
@@ -144,7 +142,7 @@
this->pTDStretch->setTempo(this->tempo);
#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
- if (this->rate <= 1.0f)
+ if (this->rate <= 1.0f)
{
if (this->output != this->pTDStretch.get())
{
@@ -256,7 +254,7 @@
{
// Enough new samples have appeared into the output!
// As samples come from processing with bigger chunks, now truncate it
- // back to maximum "nOut" samples to improve duration accuracy
+ // back to maximum "nOut" samples to improve duration accuracy
this->adjustAmountOfSamples(nOut);
// finish
--- a/src/in_2sf/desmume/metaspu/SoundTouch/SoundTouch.h
+++ b/src/in_2sf/desmume/metaspu/SoundTouch/SoundTouch.h
@@ -73,6 +73,8 @@
#include <memory>
#include "FIFOSamplePipe.h"
+#include "RateTransposer.h"
+#include "TDStretch.h"
namespace soundtouch
{
@@ -114,31 +116,28 @@
const int32_t SETTING_OVERLAP_MS = 5;
/// Call "getSetting" with this ID to query nominal average processing sequence
-/// size in samples. This value tells approcimate value how many input samples
+/// size in samples. This value tells approcimate value how many input samples
/// SoundTouch needs to gather before it does DSP processing run for the sample batch.
///
-/// Notices:
+/// Notices:
/// - This is read-only parameter, i.e. setSetting ignores this parameter
/// - Returned value is approximate average value, exact processing batch
/// size may wary from time to time
-/// - This parameter value is not constant but may change depending on
+/// - This parameter value is not constant but may change depending on
/// tempo/pitch/rate/samplerate settings.
const int32_t SETTING_NOMINAL_INPUT_SEQUENCE = 6;
-/// Call "getSetting" with this ID to query nominal average processing output
-/// size in samples. This value tells approcimate value how many output samples
+/// Call "getSetting" with this ID to query nominal average processing output
+/// size in samples. This value tells approcimate value how many output samples
/// SoundTouch outputs once it does DSP processing run for a batch of input samples.
-///
-/// Notices:
+///
+/// Notices:
/// - This is read-only parameter, i.e. setSetting ignores this parameter
/// - Returned value is approximate average value, exact processing batch
/// size may wary from time to time
-/// - This parameter value is not constant but may change depending on
+/// - This parameter value is not constant but may change depending on
/// tempo/pitch/rate/samplerate settings.
const int32_t SETTING_NOMINAL_OUTPUT_SEQUENCE = 7;
-
-class RateTransposer;
-class TDStretch;
class SoundTouch : public FIFOProcessor
{
--- a/src/in_2sf/desmume/metaspu/SoundTouch/TDStretch.cpp
+++ b/src/in_2sf/desmume/metaspu/SoundTouch/TDStretch.cpp
@@ -44,9 +44,9 @@
#include "XSFCommon.h"
#include <stdexcept>
+#include <limits>
#include <cstring>
#include <cstdlib>
-#include <climits>
#include <cassert>
#include "STTypes.h"
#include "cpu_detect.h"
@@ -129,7 +129,7 @@
// if zero, use automatic setting
this->bAutoSeqSetting = true;
- if (aSeekWindowMS > 0)
+ if (aSeekWindowMS > 0)
{
this->seekWindowMs = aSeekWindowMS;
this->bAutoSeekSetting = false;
@@ -232,7 +232,7 @@
// value over the overlapping period
int32_t TDStretch::seekBestOverlapPositionFull(const SAMPLETYPE *refPos)
{
- double bestCorr = FLT_MIN;
+ double bestCorr = std::numeric_limits<float>::min();
int32_t bestOffs = 0;
// Scans for the best correlation value by testing each possible position
@@ -267,7 +267,7 @@
// value over the overlapping period
int32_t TDStretch::seekBestOverlapPositionQuick(const SAMPLETYPE *refPos)
{
- double bestCorr = FLT_MIN;
+ double bestCorr = std::numeric_limits<float>::min();
int32_t bestOffs = _scanOffsets[0][0], corrOffset = 0;
// Scans for the best correlation value using four-pass hierarchical search.
@@ -308,7 +308,7 @@
return bestOffs;
}
-/// clear cross correlation routine state if necessary
+/// clear cross correlation routine state if necessary
void TDStretch::clearCrossCorrState()
{
// default implementation is empty.
@@ -352,7 +352,7 @@
// Update seek window lengths
this->seekWindowLength = (this->sampleRate * this->sequenceMs) / 1000;
- if (this->seekWindowLength < 2 * this->overlapLength)
+ if (this->seekWindowLength < 2 * this->overlapLength)
this->seekWindowLength = 2 * this->overlapLength;
this->seekLength = (this->sampleRate * this->seekWindowMs) / 1000;
}
@@ -472,7 +472,7 @@
// Operator 'new' is overloaded so that it automatically creates a suitable instance
// depending on if we've a MMX/SSE/etc-capable CPU available or not.
-void *TDStretch::operator new(size_t s)
+void *TDStretch::operator new(size_t /*s*/)
{
// Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
//assert(false);
@@ -480,7 +480,7 @@
throw std::runtime_error("Don't use 'new TDStretch', use 'newInstance' member instead!");
}
-TDStretch * TDStretch::newInstance()
+TDStretch *TDStretch::newInstance()
{
uint32_t uExtensions = detectCPUextensions();
@@ -537,8 +537,8 @@
assert(aoverlapMs >= 0);
// calculate overlap length so that it's power of 2 - thus it's easy to do
- // integer division by right-shifting. Term "-1" at end is to account for
- // the extra most significatnt bit left unused in result by signed multiplication
+ // integer division by right-shifting. Term "-1" at end is to account for
+ // the extra most significatnt bit left unused in result by signed multiplication
this->overlapDividerBits = _getClosest2Power((this->sampleRate * aoverlapMs) / 1000.0) - 1;
if (this->overlapDividerBits > 9)
this->overlapDividerBits = 9;
@@ -558,7 +558,7 @@
{
long corr = 0, norm = 0;
// Same routine for stereo and mono. For stereo, unroll loop for better
- // efficiency and gives slightly better resolution against rounding.
+ // efficiency and gives slightly better resolution against rounding.
// For mono it same routine, just unrolls loop by factor of 4
for (int32_t i = 0; i < this->overlapLength; i += 4)
{
@@ -566,7 +566,7 @@
norm += (mixingPos[i] * mixingPos[i] + mixingPos[i + 1] * mixingPos[i + 1] + mixingPos[i + 2] * mixingPos[i + 2] + mixingPos[i + 3] * mixingPos[i + 3]) >> this->overlapDividerBits;
}
- // Normalize result by dividing by sqrt(norm) - this step is easiest
+ // Normalize result by dividing by sqrt(norm) - this step is easiest
// done using floating point operation
if (!norm)
norm = 1; // to avoid div by zero
--- a/src/in_2sf/desmume/metaspu/SoundTouch/TDStretch.h
+++ b/src/in_2sf/desmume/metaspu/SoundTouch/TDStretch.h
@@ -4,7 +4,7 @@
/// while maintaining the original pitch by using a time domain WSOLA-like method
/// with several performance-increasing tweaks.
///
-/// Note : MMX/SSE optimized functions reside in separate, platform-specific files
+/// Note : MMX/SSE optimized functions reside in separate, platform-specific files
/// 'mmx_optimized.cpp' and 'sse_optimized.cpp'
///
/// Author : Copyright (c) Olli Parviainen
@@ -44,13 +44,13 @@
#pragma once
#include <memory>
-#include "RateTransposer.h"
+#include "FIFOSampleBuffer.h"
namespace soundtouch
{
/// Default values for sound processing parameters:
-/// Notice that the default parameters are tuned for contemporary popular music
+/// Notice that the default parameters are tuned for contemporary popular music
/// processing. For speech processing applications these parameters suit better:
/// #define DEFAULT_SEQUENCE_MS 40
/// #define DEFAULT_SEEKWINDOW_MS 15
@@ -76,26 +76,26 @@
/// according to tempo setting (recommended)
const int32_t USE_AUTO_SEEKWINDOW_LEN = 0;
-/// Seeking window default length in milliseconds for algorithm that finds the best possible
-/// overlapping location. This determines from how wide window the algorithm may look for an
-/// optimal joining location when mixing the sound sequences back together.
+/// Seeking window default length in milliseconds for algorithm that finds the best possible
+/// overlapping location. This determines from how wide window the algorithm may look for an
+/// optimal joining location when mixing the sound sequences back together.
///
/// The bigger this window setting is, the higher the possibility to find a better mixing
/// position will become, but at the same time large values may cause a "drifting" artifact
/// because consequent sequences will be taken at more uneven intervals.
///
-/// If there's a disturbing artifact that sounds as if a constant frequency was drifting
+/// If there's a disturbing artifact that sounds as if a constant frequency was drifting
/// around, try reducing this setting.
///
/// Increasing this value increases computational burden & vice versa.
//#define DEFAULT_SEEKWINDOW_MS 15
const int32_t DEFAULT_SEEKWINDOW_MS = USE_AUTO_SEEKWINDOW_LEN;
-/// Overlap length in milliseconds. When the chopped sound sequences are mixed back together,
-/// to form a continuous sound stream, this parameter defines over how long period the two
-/// consecutive sequences are let to overlap each other.
-///
-/// This shouldn't be that critical parameter. If you reduce the DEFAULT_SEQUENCE_MS setting
+/// Overlap length in milliseconds. When the chopped sound sequences are mixed back together,
+/// to form a continuous sound stream, this parameter defines over how long period the two
+/// consecutive sequences are let to overlap each other.
+///
+/// This shouldn't be that critical parameter. If you reduce the DEFAULT_SEQUENCE_MS setting
/// by a large amount, you might wish to try a smaller value on this.
///
/// Increasing this value increases computational burden & vice versa.
--- a/src/in_2sf/desmume/metaspu/SoundTouch/mmx_optimized.cpp
+++ b/src/in_2sf/desmume/metaspu/SoundTouch/mmx_optimized.cpp
@@ -1,15 +1,15 @@
////////////////////////////////////////////////////////////////////////////////
///
-/// MMX optimized routines. All MMX optimized functions have been gathered into
-/// this single source code file, regardless to their class or original source
-/// code file, in order to ease porting the library to other compiler and
+/// MMX optimized routines. All MMX optimized functions have been gathered into
+/// this single source code file, regardless to their class or original source
+/// code file, in order to ease porting the library to other compiler and
/// processor platforms.
///
/// The MMX-optimizations are programmed using MMX compiler intrinsics that
/// are supported both by Microsoft Visual C++ and GCC compilers, so this file
/// should compile with both toolsets.
///
-/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
+/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
/// 6.0 processor pack" update to support compiler intrinsic syntax. The update
/// is available for download at Microsoft Developers Network, see here:
/// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx
@@ -74,7 +74,7 @@
__m64 normaccu, accu;
normaccu = accu = _mm_setzero_si64();
- // Process 4 parallel sets of 2 * stereo samples or 4 * mono samples
+ // Process 4 parallel sets of 2 * stereo samples or 4 * mono samples
// during each round for improved CPU-level parallellization.
for (int32_t i = 0; i < this->channels * this->overlapLength / 16; ++i)
{
@@ -109,7 +109,7 @@
// Clear MMS state
_m_empty();
- // Normalize result by dividing by sqrt(norm) - this step is easiest
+ // Normalize result by dividing by sqrt(norm) - this step is easiest
// done using floating point operation
if (!norm)
norm = 1; // to avoid div by zero
@@ -210,7 +210,7 @@
this->filterCoeffsUnalign.reset(new short[2 * newLength + 8]);
this->filterCoeffsAlign = reinterpret_csat<short *>(SOUNDTOUCH_ALIGN_POINTER_16(this->filterCoeffsUnalign.get()));
- // rearrange the filter coefficients for mmx routines
+ // rearrange the filter coefficients for mmx routines
for (uint32_t i = 0; i < length; i += 4)
{
this->filterCoeffsAlign[2 * i ] = coeffs[i];
--- a/src/in_2sf/desmume/metaspu/SoundTouch/sse_optimized.cpp
+++ b/src/in_2sf/desmume/metaspu/SoundTouch/sse_optimized.cpp
@@ -51,6 +51,7 @@
//
////////////////////////////////////////////////////////////////////////////////
+#include <cmath>
#include "cpu_detect.h"
#include "STTypes.h"
--- a/src/in_2sf/desmume/metaspu/metaspu.cpp
+++ b/src/in_2sf/desmume/metaspu/metaspu.cpp
@@ -19,7 +19,7 @@
#include <queue>
#include <vector>
-#include <cassert>
+#include <cmath>
#include "../types.h"
#include "metaspu.h"
--- a/src/in_2sf/desmume/types.h
+++ b/src/in_2sf/desmume/types.h
@@ -18,6 +18,7 @@
#pragma once
+#include <cstddef>
#include <cstdint>
#ifdef _WINDOWS
@@ -72,6 +73,7 @@
#define CACHE_ALIGN DS_ALIGN(32)
#ifdef __MINGW32__
+# undef FASTCALL
# define FASTCALL __attribute__((fastcall))
# define ASMJIT_CALL_CONV kX86FuncConvGccFastCall
#elif defined (__i386__) && !defined(__clang__)
@@ -79,10 +81,10 @@
# define ASMJIT_CALL_CONV kX86FuncConvGccRegParm3
#elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
# define FASTCALL
-# define ASMJIT_CALL_CONV kX86FuncConvDefault
+# define ASMJIT_CALL_CONV kX86FuncConvCDecl
#else
# define FASTCALL
-# define ASMJIT_CALL_CONV kX86FuncConvDefault
+# define ASMJIT_CALL_CONV kX86FuncConvCDecl
#endif
/*----------------------*/
@@ -129,8 +131,8 @@
// fairly standard for loop macros
#define MACRODO1(TRICK, TODO) { int X = TRICK; TODO; }
-#define MACRODO2(X, TODO) { MACRODO1((X), TODO) MACRODO1(((X) + 1), TODO) }
-#define MACRODO4(X, TODO) { MACRODO2((X), TODO) MACRODO2(((X) + 2), TODO) }
+#define MACRODO2(TRICK, TODO) { MACRODO1((TRICK), TODO) MACRODO1(((TRICK) + 1), TODO) }
+#define MACRODO4(TRICK, TODO) { MACRODO2((TRICK), TODO) MACRODO2(((TRICK) + 2), TODO) }
template<typename T> inline void reconstruct(T *t)
{
--- a/src/in_2sf/desmume/utils/AsmJit/AsmJit.h
+++ b/src/in_2sf/desmume/utils/AsmJit/AsmJit.h
@@ -1,338 +1,375 @@
// [AsmJit]
-// Complete JIT Assembler for C++ Language.
+// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
-// Zlib - See COPYING file in this package.
+// Zlib - See LICENSE.md file in the package.
#pragma once
+// ============================================================================
+// [asmjit_mainpage]
+// ============================================================================
+
//! @mainpage
//!
-//! @brief AsmJit is a 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 a cross-platform 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 and 64-bit).
-//!
-//! @section AsmJit_Main_Introduction 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_Core and @ref AsmJit_Compiler
-//! sections.
-//!
-//! There is also class named @c AsmJit::Compiler that allows to develop
-//! cross-platform 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.
-//!
-//! Everything in AsmJit library is in @c AsmJit namespace.
+//! AsmJit - Complete x86/x64 JIT and Remote Assembler for C++.
+//!
+//! AsmJit is a complete JIT and remote assembler for C++ language. It can
+//! generate native code for x86 and x64 architectures having support for
+//! a full instruction set, from legacy MMX to the newest AVX2. It has a
+//! type-safe API that allows C++ compiler to do a semantic checks at
+//! compile-time even before the assembled code is generated or run.
+//!
+//! AsmJit is not a virtual machine (VM). It doesn't have functionality to
+//! implement VM out of the box; however, it can be be used as a JIT backend
+//! for your own VM. The usage of AsmJit is not limited at all; it's suitable
+//! for multimedia, VM backends or remote code generation.
+//!
+//! @section AsmJit_Concepts Code Generation Concepts
+//!
+//! AsmJit has two completely different code generation concepts. The difference
+//! is in how the code is generated. The first concept, also referred as the low
+//! level concept, is called 'Assembler' and it's the same as writing RAW
+//! assembly by using physical registers directly. In this case AsmJit does only
+//! instruction encoding, verification and relocation.
+//!
+//! The second concept, also referred as the high level concept, is called
+//! 'Compiler'. Compiler lets you use virtually unlimited number of registers
+//! (called variables) significantly simplifying the code generation process.
+//! Compiler allocates these virtual registers to physical registers after the
+//! code generation is done. This requires some extra effort - Compiler has to
+//! generate information for each node (instruction, function declaration,
+//! function call) in the code, perform a variable liveness analysis and
+//! translate the code having variables into code having only registers.
+//!
+//! In addition, Compiler understands functions and function calling conventions.
+//! It has been designed in a way that the code generated is always a function
+//! having prototype like in a programming language. By having a function
+//! prototype the Compiler is able to insert prolog and epilog to a function
+//! being generated and it is able to call a function inside a generated one.
+//!
+//! There is no conclusion on which concept is better. Assembler brings full
+//! control on how the code is generated, while Compiler makes the generation
+//! more portable.
//!
//! @section AsmJit_Main_CodeGeneration Code Generation
//!
-//! - @ref AsmJit_Core "Assembler core" - Operands, intrinsics and low-level assembler.
-//! - @ref AsmJit_Compiler "Compiler" - High level code generation.
-//! - @ref AsmJit_CpuInfo "Cpu Information" - Get information about host processor.
-//! - @ref AsmJit_Logging "Logging" - Logging and error handling.
-//! - @ref AsmJit_MemoryManagement "Memory Management" - Virtual memory management.
-//!
-//! @section AsmJit_Main_Configuration Configuration, Definitions and Utilities
-//!
-//! - @ref AsmJit_Config "Configuration" - Macros used to configure AsmJit.
+//! - \ref asmjit_base_general "Assembler core" - Operands, intrinsics and low-level assembler.
+//! - \ref asmjit_compiler "Compiler" - High level code generation.
+//! - \ref asmjit_cpuinfo "Cpu Information" - Get information about host processor.
+//! - \ref asmjit_logging "Logging" - Logging and error handling.
+//! - \ref AsmJit_MemoryManagement "Memory Management" - Virtual memory management.
//!
//! @section AsmJit_Main_HomePage AsmJit Homepage
//!
-//! - http://code.google.com/p/asmjit/
-//!
-//! @section AsmJit_Main_ResourcesX86 External X86/X64 Assembler 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)
-//!
-//! @section AsmJit_Main_Terminology Terminology
-//!
-//! - <b>Non-volatile (preserved) register</b> - Register that can't be changed
-//! by callee (callee must save and restore it if it want to use it inside).
-//!
-//! - <b>Volatile (non-preserved) register</b> - The opossite. Register that can
-//! be freely used by callee. The caller must free all registers before calling
-//! other function.
-
-
-//! @defgroup AsmJit_Core Assembler core (operands, intrinsics and low-level assembler).
-//!
-//! Contains classes related to @c AsmJit::Assembler that're directly used
-//! to generate machine code stream. It's one of oldest and fastest method
-//! to generate machine code using AsmJit library.
-//!
-//! - See @c AsmJit::Assembler class for low level code generation
-//! documentation.
-//! - See @c AsmJit::Operand for AsmJit operand's overview.
-//!
-//! @section AsmJit_Core_Registers 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
+//! - https://github.com/kobalicek/asmjit
+
+// ============================================================================
+// [asmjit_base]
+// ============================================================================
+
+//! \defgroup asmjit_base AsmJit
+//!
+//! \brief AsmJit.
+
+// ============================================================================
+// [asmjit_base_general]
+// ============================================================================
+
+//! \defgroup asmjit_base_general AsmJit General API
+//! \ingroup asmjit_base
+//!
+//! \brief AsmJit general API.
+//!
+//! Contains all `asmjit` classes and helper functions that are architecture
+//! independent or abstract. Abstract classes are implemented by the backend,
+//! for example `Assembler` is implemented by `X86Assembler`.
+//!
+//! - See `Assembler` for low level code generation documentation.
+//! - See `Compiler` for high level code generation documentation.
+//! - See `Operand` for operand's overview.
+//!
+//! Logging and Error Handling
+//! --------------------------
+//!
+//! AsmJit contains robust interface that can be used to log the generated code
+//! and to handle possible errors. Base logging interface is defined in `Logger`
+//! class that is abstract and can be overridden. AsmJit contains two loggers
+//! that can be used out of the box - `FileLogger` that logs into a pure C
+//! `FILE*` stream and `StringLogger` that just concatenates all log messages
+//! by using a `StringBuilder` class.
+//!
+//! The following snippet shows how to setup a logger that logs to `stderr`:
+//!
+//! ~~~
+//! // `FileLogger` instance.
+//! FileLogger logger(stderr);
+//!
+//! // `Compiler` or any other `CodeGen` interface.
+//! host::Compiler c;
+//!
+//! // use `setLogger` to replace the `CodeGen` logger.
+//! c.setLogger(&logger);
+//! ~~~
+//!
+//! \sa \ref Logger, \ref FileLogger, \ref StringLogger.
+
+// ============================================================================
+// [asmjit_base_compiler]
+// ============================================================================
+
+//! \defgroup asmjit_base_compiler AsmJit Compiler
+//! \ingroup asmjit_base
+//!
+//! \brief AsmJit code-tree used by Compiler.
+//!
+//! AsmJit intermediate code-tree is a double-linked list that is made of nodes
+//! that represent assembler instructions, directives, labels and high-level
+//! constructs compiler is using to represent functions and function calls. The
+//! node list can only be used together with \ref Compiler.
+//!
+//! TODO
+
+// ============================================================================
+// [asmjit_base_util]
+// ============================================================================
+
+//! \defgroup asmjit_base_util AsmJit Utilities
+//! \ingroup asmjit_base
+//!
+//! \brief AsmJit utility classes.
+//!
+//! AsmJit contains numerous utility classes that are needed by the library
+//! itself. The most useful ones have been made public and are now exported.
+//!
+//! POD Containers
+//! --------------
+//!
+//! POD containers are used by AsmJit to manage its own data structures. The
+//! following classes can be used by AsmJit consumers:
+//!
+//! - \ref PodVector - Simple growing array-like container for POD data.
+//! - \ref StringBuilder - Simple string builder that can append string
+//! and integers.
+//!
+//! Zone Memory Allocator
+//! ---------------------
+//!
+//! Zone memory allocator is an incremental memory allocator that can be used
+//! to allocate data of short life-time. It has much better performance
+//! characteristics than all other allocators, because the only thing it can do
+//! is to increment a pointer and return its previous address. See \ref Zone
+//! for more details.
+//!
+//! CPU Ticks
+//! ---------
+//!
+//! CPU Ticks is a simple helper that can be used to do basic benchmarks. See
+//! \ref CpuTicks class for more details.
+//!
+//! Integer Utilities
+//! -----------------
+//!
+//! Integer utilities are all implemented by a static class \ref IntUtil.
+//! There are utilities for bit manipulation and bit counting, utilities to get
+//! an integer minimum / maximum and various other helpers required to perform
+//! alignment checks and binary casting from float to integer and vica versa.
+//!
+//! Vector Utilities
+//! ----------------
+//!
+//! SIMD code generation often requires to embed constants after each function
+//! or a block of functions generated. AsmJit contains classes `Vec64`,
+//! `Vec128` and `Vec256` that can be used to prepare data useful when
+//! generating SIMD code.
+//!
+//! X86/X64 code generator contains member functions `dmm`, `dxmm` and `dymm`
+//! which can be used to embed 64-bit, 128-bit and 256-bit data structures into
+//! machine code (both assembler and compiler are supported).
+//!
+//! \note Compiler contains a constant pool, which should be used instead of
+//! embedding constants manually after the function body.
+
+// ============================================================================
+// [asmjit_x86]
+// ============================================================================
+
+//! \defgroup asmjit_x86 X86/X64
+//!
+//! \brief X86/X64 module
+
+// ============================================================================
+// [asmjit_x86_general]
+// ============================================================================
+
+//! \defgroup asmjit_x86_general X86/X64 General API
+//! \ingroup asmjit_x86
+//!
+//! \brief X86/X64 general API.
+//!
+//! X86/X64 Registers
+//! -----------------
+//!
+//! There are static objects that represents X86 and X64 registers. They can
+//! be used directly (like `eax`, `mm`, `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
-//!
-//! @section AsmJit_Core_Addressing Addressing
+//! - `asmjit::gpb_lo()` - Get Gpb-lo register.
+//! - `asmjit::gpb_hi()` - Get Gpb-hi register.
+//! - `asmjit::gpw()` - Get Gpw register.
+//! - `asmjit::gpd()` - Get Gpd register.
+//! - `asmjit::gpq()` - Get Gpq Gp register.
+//! - `asmjit::gpz()` - Get Gpd/Gpq register.
+//! - `asmjit::fp()` - Get Fp register.
+//! - `asmjit::mm()` - Get Mm register.
+//! - `asmjit::xmm()` - Get Xmm register.
+//! - `asmjit::ymm()` - Get Ymm register.
+//!
+//! X86/X64 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
+//! `BaseMem` class. These functions are used to make operands that represents
+//! memory addresses:
+//!
+//! - `asmjit::ptr()`
+//! - `asmjit::byte_ptr()`
+//! - `asmjit::word_ptr()`
+//! - `asmjit::dword_ptr()`
+//! - `asmjit::qword_ptr()`
+//! - `asmjit::tword_ptr()`
+//! - `asmjit::oword_ptr()`
+//! - `asmjit::yword_ptr()`
+//! - `asmjit::zword_ptr()`
+//!
+//! Most useful function to make pointer should be `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::Assembler::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).
-//!
-//! @section AsmJit_Core_Immediates 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::Compiler.
-
-
-//! @defgroup AsmJit_Compiler Compiler (high-level code generation).
-//!
-//! Contains classes related to @c AsmJit::Compiler that can be used
-//! to generate code using high-level constructs.
-//!
-//! - See @c Compiler class for high level code generation
-//! documentation - calling conventions, function declaration
-//! and variables management.
-
-//! @defgroup AsmJit_Config Configuration.
-//!
-//! Contains macros that can be redefined to fit into any project.
-
-
-//! @defgroup AsmJit_CpuInfo CPU information.
-//!
-//! 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::getCpuInfo()
-//! 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 information through @c AsmJit::cpuid(), but
-//! there is also small multiplatform code to detect number of processors
-//! (or cores) through 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);
+//! register operand or by instruction itself). For example `asmjit::ptr()`
+//! can't be used with `Assembler::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 `[base + displacement]` and complex
+//! address forms `[base + index * scale + displacement]`.
+//!
+//! X86/X64 Immediates
+//! ------------------
+//!
+//! Immediate values are constants thats passed directly after instruction
+//! opcode. To create such value use `imm()` or `imm_u()` methods to create
+//! signed or unsigned immediate value.
+//!
+//! X86/X64 CPU Information
+//! -----------------------
+//!
+//! The CPUID instruction can be used to get an exhaustive information about
+//! the host X86/X64 processor. AsmJit contains utilities that can get the most
+//! important information related to the features supported by the CPU and the
+//! host operating system, in addition to host processor name and number of
+//! cores. Class `X86CpuInfo` extends `CpuInfo` and provides functionality
+//! specific to X86 and X64.
+//!
+//! By default AsmJit queries the CPU information after the library is loaded
+//! and the queried information is reused by all instances of `JitRuntime`.
+//! The global instance of `X86CpuInfo` can't be changed, because it will affect
+//! the code generation of all `Runtime`s. If there is a need to have a
+//! specific CPU information which contains modified features or processor
+//! vendor it's possible by creating a new instance of `X86CpuInfo` and setting
+//! up its members. `X86CpuUtil::detect` can be used to detect CPU features into
+//! an existing `X86CpuInfo` instance - it may become handly if only one property
+//! has to be turned on/off.
+//!
+//! If the high-level interface `X86CpuInfo` offers is not enough there is also
+//! `X86CpuUtil::callCpuId` helper that can be used to call CPUID instruction
+//! with a given parameters and to consume the output.
+//!
+//! Cpu detection is important when generating a JIT code that may or may not
+//! use certain CPU features. For example there used to be a SSE/SSE2 detection
+//! in the past and today there is often AVX/AVX2 detection.
+//!
+//! The example below shows how to detect SSE2:
+//!
+//! ~~~
+//! using namespace asmjit;
+//!
+//! // Get `X86CpuInfo` global instance.
+//! const X86CpuInfo* cpuInfo = X86CpuInfo::getHost();
+//!
+//! if (cpuInfo->hasFeature(kX86CpuFeatureSse2)) {
+//! // Processor has SSE2.
+//! }
+//! else if (cpuInfo->hasFeature(kX86CpuFeatureMmx)) {
+//! // Processor doesn't have SSE2, but has MMX.
+//! }
+//! else {
+//! // Processor is archaic; it's a wonder AsmJit works here!
+//! }
+//! ~~~
+//!
+//! The next example shows how to call `CPUID` directly:
+//!
+//! ~~~
+//! using namespace asmjit;
+//!
+//! // Call cpuid, first two arguments are passed in Eax/Ecx.
+//! X86CpuId out;
+//! X86CpuUtil::callCpuId(0, 0, &out);
+//!
+//! // If Eax argument is 0, Ebx, Ecx and Edx registers are filled with a cpu vendor.
+//! char cpuVendor[13];
+//! ::memcpy(cpuVendor, &out.ebx, 4);
+//! ::memcpy(cpuVendor + 4, &out.edx, 4);
+//! ::memcpy(cpuVendor + 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::getCpuInfo(), please read processor manuals provided by Intel,
-//! AMD or other manufacturers for cpuid instruction details.
-//!
-//! Example of using @c AsmJit::getCpuInfo():
-//!
-//! @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 = getCpuInfo();
-//!
-//! // Now you are able to get specific features.
-//!
-//! // Processor has SSE2
-//! if (i->features & kX86FeatureSse2)
-//! {
-//! // your code...
-//! }
-//! // Processor has MMX
-//! else if (i->features & kX86Feature_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_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 Assembler. If you are using
-//! @c Compiler and you want to log messages in correct assembler order,
-//! you should look at @ref Compiler::comment() method. It allows you to
-//! insert text message into items stream so the @c Compiler is able to
-//! send messages to @ref Assembler in correct order.
-//!
-//! @sa @c AsmJit::Logger, @c AsmJit::FileLogger.
-
-
-//! @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 cross-platform 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_ASSERT
-//! @brief Assertion macro. Default implementation calls
-//! @c AsmJit::assertionFailure() function.
-
-//! @}
-
-
-//! @namespace AsmJit
-//! @brief Main AsmJit library namespace.
-//!
-//! There are not other namespaces used in AsmJit library.
-
-// ----------------------------------------------------------------------------
-// [Dependencies - Core]
-// ----------------------------------------------------------------------------
-
-#include "core.h"
-
-// ----------------------------------------------------------------------------
-// [Dependencies - X86 / X64]
-// ----------------------------------------------------------------------------
-
-#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
+//!
+//! // Print a CPU vendor retrieved from CPUID.
+//! ::printf("%s", cpuVendor);
+//! ~~~
+
+// ============================================================================
+// [asmjit_x86_compiler]
+// ============================================================================
+
+//! \defgroup asmjit_x86_compiler X86/X64 Code-Tree
+//! \ingroup asmjit_x86
+//!
+//! \brief X86/X64 code-tree and helpers.
+
+// ============================================================================
+// [asmjit_x86_inst]
+// ============================================================================
+
+//! \defgroup asmjit_x86_inst X86/X64 Instructions
+//! \ingroup asmjit_x86
+//!
+//! \brief X86/X64 low-level instruction definitions.
+
+// ============================================================================
+// [asmjit_x86_util]
+// ============================================================================
+
+//! \defgroup asmjit_x86_util X86/X64 Utilities
+//! \ingroup asmjit_x86
+//!
+//! \brief X86/X64 utility classes.
+
+// ============================================================================
+// [asmjit_contrib]
+// ============================================================================
+
+//! \defgroup asmjit_contrib Contributions
+//!
+//! \brief Contributions.
+
+// [Dependencies - Base]
+#include "base.h"
+
+// [Dependencies - X86/X64]
+#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
#include "x86.h"
-#endif // ASMJIT_X86 || ASMJIT_X64
-
+#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64
+
+// [Dependencies - Host]
+#include "host.h"
+
--- a/src/in_2sf/desmume/utils/AsmJit/COPYING.txt
+++ /dev/null
@@ -1,18 +1,1 @@
-Copyright (c) 2008-2012, Petr Kobalicek <kobalicek.petr@gmail.com>
-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.
-
--- a/src/in_2sf/desmume/utils/AsmJit/Config.h
+++ b/src/in_2sf/desmume/utils/AsmJit/Config.h
@@ -1,61 +1,49 @@
// [AsmJit]
-// Complete JIT Assembler for C++ Language.
+// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
-// Zlib - See COPYING file in this package.
+// Zlib - See LICENSE.md file in the package.
#pragma once
-// This file is designed to be modifyable. Platform specific changes should
-// be applied to this file so it's guaranteed that never versions of AsmJit
-// library will never overwrite generated config files.
+// This file can be used to modify built-in features of AsmJit. AsmJit is by
+// default compiled only for host processor to enable JIT compilation. Both
+// Assembler and Compiler code generators are compiled by default.
//
-// So modify this file by your build system or by hand.
+// ASMJIT_BUILD_... flags can be defined to build additional backends that can
+// be used for remote code generation.
+//
+// ASMJIT_DISABLE_... flags can be defined to disable standard features. These
+// are handy especially when building asmjit statically and some features are
+// not needed or unwanted (like Compiler).
// ============================================================================
-// [AsmJit - OS]
+// [AsmJit - Build-Type]
// ============================================================================
-// Provides definitions about your operating system. It's detected by default,
-// so override it if you have problems with automatic detection.
-//
-// #define ASMJIT_WINDOWS
-// #define ASMJIT_POSIX
+#define ASMJIT_EMBED // Asmjit is embedded (implies ASMJIT_STATIC).
+// #define ASMJIT_STATIC // Define to enable static-library build.
// ============================================================================
-// [AsmJit - Architecture]
+// [AsmJit - Build-Mode]
// ============================================================================
-// 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
+// #define ASMJIT_DEBUG // Define to enable debug-mode.
+// #define ASMJIT_RELEASE // Define to enable release-mode.
+// #define ASMJIT_TRACE // Define to enable tracing.
// ============================================================================
-// [AsmJit - API]
+// [AsmJit - Features]
// ============================================================================
-// If you are embedding AsmJit library into your project (statically), undef
-// ASMJIT_API macro.
-#define ASMJIT_API
+// If none of these is defined AsmJit will select host architecture by default.
+// #define ASMJIT_BUILD_X86 // Define to enable x86 instruction set (32-bit).
+// #define ASMJIT_BUILD_X64 // Define to enable x64 instruction set (64-bit).
+// #define ASMJIT_BUILD_HOST // Define to enable host instruction set.
-// ============================================================================
-// [AsmJit - Memory Management]
-// ============================================================================
+// AsmJit features are enabled by default.
+// #define ASMJIT_DISABLE_COMPILER // Disable Compiler (completely).
+// #define ASMJIT_DISABLE_LOGGER // Disable Logger (completely).
+// #define ASMJIT_DISABLE_NAMES // Disable everything that uses strings
+ // (instruction names, error names, ...).
-// #define ASMJIT_MALLOC ::malloc
-// #define ASMJIT_REALLOC ::realloc
-// #define ASMJIT_FREE ::free
-
-// ============================================================================
-// [AsmJit - Debug]
-// ============================================================================
-
-// Turn debug on/off (to bypass autodetection)
-// #define ASMJIT_DEBUG
-// #define ASMJIT_NO_DEBUG
-
-// Setup custom assertion code.
-// #define ASMJIT_ASSERT(exp) do { if (!(exp)) ::AsmJit::assertionFailure(__FILE__, __LINE__, #exp); } while(0)
-
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/LICENSE.md
@@ -1,1 +1,19 @@
+AsmJit - Complete x86/x64 JIT and Remote Assembler for C++
+Copyright (c) 2008-2014, Petr Kobalicek <kobalicek.petr@gmail.com>
+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.
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/apibegin.h
@@ -1,1 +1,50 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+#ifndef _ASMJIT_BUILD_H
+# include "build.h"
+#endif // !_ASMJIT_BUILD_H
+
+// ============================================================================
+// [MSVC]
+// ============================================================================
+
+#ifdef _MSC_VER
+// Disable some warnings we know about
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+# pragma warning(disable: 4201) // nameless struct/union
+# pragma warning(disable: 4244) // '+=' : conversion from 'int' to 'x', possible
+ // loss of data
+# 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
+# pragma warning(disable: 4480) // specifying underlying type for enum
+# pragma warning(disable: 4800) // forcing value to bool 'true' or 'false'
+
+// Rename symbols.
+# ifndef vsnprintf
+# define ASMJIT_DEFINED_VSNPRINTF
+# define vsnprintf _vsnprintf
+# endif // !vsnprintf
+# ifndef snprintf
+# define ASMJIT_DEFINED_SNPRINTF
+# define snprintf _snprintf
+# endif // !snprintf
+#endif // _MSC_VER
+
+// ============================================================================
+// [GNUC]
+// ============================================================================
+
+#if defined(__GNUC__) && !defined(__clang__)
+# if __GNUC__ >= 4 && !defined(__MINGW32__)
+# pragma GCC visibility push(hidden)
+# endif // __GNUC__ >= 4
+#endif // __GNUC__
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/apiend.h
@@ -1,1 +1,34 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+// ============================================================================
+// [MSVC]
+// ============================================================================
+
+#ifdef _MSC_VER
+// Pop disabled warnings by ApiBegin.h
+# pragma warning(pop)
+// Rename symbols back.
+# ifdef ASMJIT_DEFINED_VSNPRINTF
+# undef ASMJIT_DEFINED_VSNPRINTF
+# undef vsnprintf
+# endif // ASMJIT_DEFINED_VSNPRINTF
+# ifdef ASMJIT_DEFINED_SNPRINTF
+# undef ASMJIT_DEFINED_SNPRINTF
+# undef snprintf
+# endif // ASMJIT_DEFINED_SNPRINTF
+#endif // _MSC_VER
+
+// ============================================================================
+// [GNUC]
+// ============================================================================
+
+#if defined(__GNUC__) && !defined(__clang__)
+# if __GNUC__ >= 4 && !defined(__MINGW32__)
+# pragma GCC visibility pop
+# endif // __GNUC__ >= 4
+#endif // __GNUC__
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base.h
@@ -1,1 +1,30 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "build.h"
+
+#include "base/assembler.h"
+#include "base/codegen.h"
+#include "base/compiler.h"
+#include "base/constpool.h"
+#include "base/containers.h"
+#include "base/cpuinfo.h"
+#include "base/cputicks.h"
+#include "base/error.h"
+#include "base/globals.h"
+#include "base/intutil.h"
+#include "base/lock.h"
+#include "base/logger.h"
+#include "base/operand.h"
+#include "base/runtime.h"
+#include "base/string.h"
+#include "base/vectypes.h"
+#include "base/vmem.h"
+#include "base/zone.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/assembler.cpp
@@ -1,1 +1,388 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Dependencies - AsmJit]
+#include "../base/assembler.h"
+#include "../base/intutil.h"
+#include "../base/vmem.h"
+
+// [Dependenceis - C]
+#include <cstdarg>
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [asmjit::Assembler - Construction / Destruction]
+// ============================================================================
+
+Assembler::Assembler(Runtime* runtime) :
+ CodeGen(runtime),
+ _buffer(nullptr),
+ _end(nullptr),
+ _cursor(nullptr),
+ _trampolineSize(0),
+ _comment(nullptr),
+ _unusedLinks(nullptr) {}
+
+Assembler::~Assembler() {
+ reset(true);
+}
+
+// ============================================================================
+// [asmjit::Assembler - Clear / Reset]
+// ============================================================================
+
+void Assembler::reset(bool releaseMemory) {
+ // CodeGen members.
+ _baseAddress = kNoBaseAddress;
+ _instOptions = 0;
+ _error = kErrorOk;
+
+ _baseZone.reset(releaseMemory);
+
+ // Assembler members.
+ if (releaseMemory && _buffer) {
+ ASMJIT_FREE(_buffer);
+ _buffer = nullptr;
+ _end = nullptr;
+ }
+
+ _cursor = _buffer;
+ _trampolineSize = 0;
+
+ _comment = nullptr;
+ _unusedLinks = nullptr;
+
+ _labelList.reset(releaseMemory);
+ _relocList.reset(releaseMemory);
+}
+
+// ============================================================================
+// [asmjit::Assembler - Buffer]
+// ============================================================================
+
+Error Assembler::_grow(size_t n) {
+ size_t capacity = getCapacity();
+ size_t after = getOffset() + n;
+
+ // Overflow.
+ if (n > IntUtil::maxUInt<uintptr_t>() - capacity)
+ return setError(kErrorNoHeapMemory);
+
+ // Grow is called when allocation is needed, so it shouldn't happen, but on
+ // the other hand it is simple to catch and it's not an error.
+ if (after <= capacity)
+ return kErrorOk;
+
+ if (capacity < kMemAllocOverhead)
+ capacity = kMemAllocOverhead;
+ else
+ capacity += kMemAllocOverhead;
+
+ do {
+ size_t oldCapacity = capacity;
+
+ if (capacity < kMemAllocGrowMax)
+ capacity *= 2;
+ else
+ capacity += kMemAllocGrowMax;
+
+ // Overflow.
+ if (oldCapacity > capacity)
+ return setError(kErrorNoHeapMemory);
+ } while (capacity - kMemAllocOverhead < after);
+
+ capacity -= kMemAllocOverhead;
+ return _reserve(capacity);
+}
+
+Error Assembler::_reserve(size_t n) {
+ size_t capacity = getCapacity();
+ if (n <= capacity)
+ return kErrorOk;
+
+ uint8_t* newBuffer;
+ if (!_buffer)
+ newBuffer = static_cast<uint8_t*>(ASMJIT_ALLOC(n));
+ else
+ newBuffer = static_cast<uint8_t*>(ASMJIT_REALLOC(_buffer, n));
+
+ if (!newBuffer)
+ return setError(kErrorNoHeapMemory);
+
+ size_t offset = getOffset();
+
+ _buffer = newBuffer;
+ _end = _buffer + n;
+ _cursor = newBuffer + offset;
+
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::Assembler - Label]
+// ============================================================================
+
+Error Assembler::_registerIndexedLabels(size_t index) {
+ size_t i = _labelList.getLength();
+ if (index < i)
+ return kErrorOk;
+
+ if (_labelList._grow(index - i) != kErrorOk)
+ return setError(kErrorNoHeapMemory);
+
+ LabelData data;
+ data.offset = -1;
+ data.links = nullptr;
+
+ do {
+ _labelList.append(data);
+ } while (++i < index);
+
+ return kErrorOk;
+}
+
+Error Assembler::_newLabel(Label* dst) {
+ dst->_label.op = kOperandTypeLabel;
+ dst->_label.size = 0;
+ dst->_label.id = OperandUtil::makeLabelId(static_cast<uint32_t>(_labelList.getLength()));
+
+ LabelData data;
+ data.offset = -1;
+ data.links = nullptr;
+
+ if (_labelList.append(data) != kErrorOk)
+ goto _NoMemory;
+ return kErrorOk;
+
+_NoMemory:
+ dst->_label.id = kInvalidValue;
+ return setError(kErrorNoHeapMemory);
+}
+
+LabelLink* Assembler::_newLabelLink() {
+ LabelLink* link = _unusedLinks;
+
+ if (link) {
+ _unusedLinks = link->prev;
+ }
+ else {
+ link = _baseZone.allocT<LabelLink>();
+ if (!link)
+ return nullptr;
+ }
+
+ link->prev = nullptr;
+ link->offset = 0;
+ link->displacement = 0;
+ link->relocId = -1;
+
+ return link;
+}
+
+Error Assembler::bind(const Label& label) {
+ // Get label data based on label id.
+ uint32_t index = label.getId();
+ LabelData* data = getLabelData(index);
+
+ // Label can be bound only once.
+ if (data->offset != -1)
+ return setError(kErrorLabelAlreadyBound);
+
+#ifndef ASMJIT_DISABLE_LOGGER
+ if (_logger)
+ _logger->logFormat(kLoggerStyleLabel, "L%u:\n", index);
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ Error error = kErrorOk;
+ size_t pos = getOffset();
+
+ LabelLink* link = data->links;
+ LabelLink* prev = nullptr;
+
+ while (link) {
+ intptr_t offset = link->offset;
+
+ if (link->relocId != -1) {
+ // Handle RelocData - We have to update RelocData information instead of
+ // patching the displacement in LabelData.
+ _relocList[link->relocId].data += static_cast<Ptr>(pos);
+ }
+ else {
+ // Not using relocId, this means that we are overwriting a real
+ // displacement in the binary stream.
+ int32_t patchedValue = static_cast<int32_t>(
+ static_cast<intptr_t>(pos) - offset + link->displacement);
+
+ // Size of the value we are going to patch. Only BYTE/DWORD is allowed.
+ uint32_t size = getByteAt(offset);
+ ASMJIT_ASSERT(size == 1 || size == 4);
+
+ if (size == 4) {
+ setInt32At(offset, patchedValue);
+ }
+ else {
+ ASMJIT_ASSERT(size == 1);
+ if (IntUtil::isInt8(patchedValue))
+ setByteAt(offset, static_cast<uint8_t>(patchedValue & 0xFF));
+ else
+ error = kErrorIllegalDisplacement;
+ }
+ }
+
+ prev = link->prev;
+ link = prev;
+ }
+
+ // Chain unused links.
+ link = data->links;
+ if (link) {
+ if (!prev)
+ prev = link;
+
+ prev->prev = _unusedLinks;
+ _unusedLinks = link;
+ }
+
+ // Set as bound (offset is zero or greater and no links).
+ data->offset = pos;
+ data->links = nullptr;
+
+ if (error != kErrorOk)
+ return setError(error);
+
+ return error;
+}
+
+// ============================================================================
+// [asmjit::Assembler - Embed]
+// ============================================================================
+
+Error Assembler::embed(const void* data, uint32_t size) {
+ if (getRemainingSpace() < size) {
+ Error error = _grow(size);
+ if (error != kErrorOk)
+ return setError(error);
+ }
+
+ uint8_t* cursor = getCursor();
+ ::memcpy(cursor, data, size);
+ setCursor(cursor + size);
+
+#if !defined(ASMJIT_DISABLE_LOGGER)
+ if (_logger)
+ _logger->logBinary(kLoggerStyleData, data, size);
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::Assembler - Reloc]
+// ============================================================================
+
+size_t Assembler::relocCode(void* dst, Ptr baseAddress) const {
+ if (baseAddress == kNoBaseAddress)
+ baseAddress = hasBaseAddress() ? getBaseAddress() : static_cast<Ptr>(reinterpret_cast<uintptr_t>(dst));
+ else if (getBaseAddress() != baseAddress)
+ return 0;
+
+ return _relocCode(dst, baseAddress);
+}
+
+// ============================================================================
+// [asmjit::Assembler - Make]
+// ============================================================================
+
+void* Assembler::make() {
+ // Do nothing on error condition or if no instruction has been emitted.
+ if (_error != kErrorOk || getCodeSize() == 0)
+ return nullptr;
+
+ void* p;
+ Error error = _runtime->add(&p, this);
+
+ if (error != kErrorOk)
+ setError(error);
+
+ return p;
+}
+
+// ============================================================================
+// [asmjit::Assembler - Emit (Helpers)]
+// ============================================================================
+
+#define NA noOperand
+
+Error Assembler::emit(uint32_t code) {
+ return _emit(code, NA, NA, NA, NA);
+}
+
+Error Assembler::emit(uint32_t code, const Operand& o0) {
+ return _emit(code, o0, NA, NA, NA);
+}
+
+Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1) {
+ return _emit(code, o0, o1, NA, NA);
+}
+
+Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2) {
+ return _emit(code, o0, o1, o2, NA);
+}
+
+Error Assembler::emit(uint32_t code, int o0) {
+ Imm imm(o0);
+ return _emit(code, imm, NA, NA, NA);
+}
+
+Error Assembler::emit(uint32_t code, uint64_t o0) {
+ Imm imm(o0);
+ return _emit(code, imm, NA, NA, NA);
+}
+
+Error Assembler::emit(uint32_t code, const Operand& o0, int o1) {
+ Imm imm(o1);
+ return _emit(code, o0, imm, NA, NA);
+}
+
+Error Assembler::emit(uint32_t code, const Operand& o0, uint64_t o1) {
+ Imm imm(o1);
+ return _emit(code, o0, imm, NA, NA);
+}
+
+Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, int o2) {
+ Imm imm(o2);
+ return _emit(code, o0, o1, imm, NA);
+}
+
+Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2) {
+ Imm imm(o2);
+ return _emit(code, o0, o1, imm, NA);
+}
+
+Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3) {
+ Imm imm(o3);
+ return _emit(code, o0, o1, o2, imm);
+}
+
+Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3) {
+ Imm imm(o3);
+ return _emit(code, o0, o1, o2, imm);
+}
+
+#undef NA
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/assembler.h
@@ -1,1 +1,536 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../base/codegen.h"
+#include "../base/containers.h"
+#include "../base/error.h"
+#include "../base/logger.h"
+#include "../base/operand.h"
+#include "../base/runtime.h"
+#include "../base/zone.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::kInstId]
+// ============================================================================
+
+//! Instruction codes (stub).
+ASMJIT_ENUM(kInstId) {
+ //! No instruction.
+ kInstIdNone = 0
+};
+
+// ============================================================================
+// [asmjit::kInstOptions]
+// ============================================================================
+
+//! Instruction options (stub).
+ASMJIT_ENUM(kInstOptions) {
+ //! No instruction options.
+ kInstOptionNone = 0x00,
+
+ //! Emit short form of the instruction.
+ //!
+ //! X86/X64:
+ //!
+ //! Short form is mostly related to jmp and jcc instructions, but can be used
+ //! by other instructions supporting 8-bit or 32-bit immediates. This option
+ //! can be dangerous if the short jmp/jcc is required, but not encodable due
+ //! to large displacement, in such case an error happens and the whole
+ //! assembler/compiler stream is unusable.
+ kInstOptionShortForm = 0x01,
+ //! Emit long form of the instruction.
+ //!
+ //! X86/X64:
+ //!
+ //! Long form is mosrlt related to jmp and jcc instructions, but like the
+ //! `kInstOptionShortForm` option it can be used by other instructions
+ //! supporting both 8-bit and 32-bit immediates.
+ kInstOptionLongForm = 0x02,
+
+ //! Condition is likely to be taken.
+ kInstOptionTaken = 0x04,
+ //! Condition is unlikely to be taken.
+ kInstOptionNotTaken = 0x08
+};
+
+// ============================================================================
+// [asmjit::LabelLink]
+// ============================================================================
+
+//! \internal
+//!
+//! Data structure used to link linked-labels.
+struct LabelLink {
+ //! Previous link.
+ LabelLink* prev;
+ //! Offset.
+ intptr_t offset;
+ //! Inlined displacement.
+ intptr_t displacement;
+ //! RelocId if link must be absolute when relocated.
+ intptr_t relocId;
+};
+
+// ============================================================================
+// [asmjit::LabelData]
+// ============================================================================
+
+//! \internal
+//!
+//! Label data.
+struct LabelData {
+ //! Label offset.
+ intptr_t offset;
+ //! Label links chain.
+ LabelLink* links;
+};
+
+// ============================================================================
+// [asmjit::RelocData]
+// ============================================================================
+
+//! \internal
+//!
+//! Code relocation data (relative vs absolute addresses).
+//!
+//! X86/X64:
+//!
+//! X86 architecture uses 32-bit absolute addressing model by memory operands,
+//! but 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.
+struct RelocData {
+ //! Type of relocation.
+ uint32_t type;
+ //! Size of relocation (4 or 8 bytes).
+ uint32_t size;
+
+ //! Offset from code begin address.
+ Ptr from;
+
+ //! Relative displacement from code begin address (not to `offset`) or
+ //! absolute address.
+ Ptr data;
+};
+
+// ============================================================================
+// [asmjit::Assembler]
+// ============================================================================
+
+//! Base assembler.
+//!
+//! This class implements the base interface to an assembler. The architecture
+//! specific API is implemented by backends.
+//!
+//! \sa Compiler.
+struct ASMJIT_VCLASS Assembler : public CodeGen {
+ ASMJIT_NO_COPY(Assembler)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `Assembler` instance.
+ ASMJIT_API Assembler(Runtime* runtime);
+ //! Destroy the `Assembler` instance.
+ ASMJIT_API virtual ~Assembler();
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ //! Reset the assembler.
+ //!
+ //! If `releaseMemory` is true all buffers will be released to the system.
+ ASMJIT_API void reset(bool releaseMemory = false);
+
+ // --------------------------------------------------------------------------
+ // [Buffer]
+ // --------------------------------------------------------------------------
+
+ //! Get capacity of the code buffer.
+ ASMJIT_INLINE size_t getCapacity() const {
+ return static_cast<size_t>(_end - _buffer);
+ }
+
+ //! Get the number of remaining bytes (space between cursor and the end of
+ //! the buffer).
+ ASMJIT_INLINE size_t getRemainingSpace() const {
+ return static_cast<size_t>(_end - _cursor);
+ }
+
+ //! Get buffer.
+ ASMJIT_INLINE uint8_t* getBuffer() const {
+ return _buffer;
+ }
+
+ //! Get the end of the buffer (points to the first byte that is outside).
+ ASMJIT_INLINE uint8_t* getEnd() const {
+ return _end;
+ }
+
+ //! Get the current position in the buffer.
+ ASMJIT_INLINE uint8_t* getCursor() const {
+ return _cursor;
+ }
+
+ //! Set the current position in the buffer.
+ ASMJIT_INLINE void setCursor(uint8_t* cursor) {
+ ASMJIT_ASSERT(cursor >= _buffer && cursor <= _end);
+ _cursor = cursor;
+ }
+
+ //! Get the current offset in the buffer.
+ ASMJIT_INLINE size_t getOffset() const {
+ return static_cast<size_t>(_cursor - _buffer);
+ }
+
+ //! Set the current offset in the buffer to `offset` and get the previous
+ //! offset value.
+ ASMJIT_INLINE size_t setOffset(size_t offset) {
+ ASMJIT_ASSERT(offset < getCapacity());
+
+ size_t oldOffset = static_cast<size_t>(_cursor - _buffer);
+ _cursor = _buffer + offset;
+ return oldOffset;
+ }
+
+ //! Grow the internal buffer.
+ //!
+ //! The internal buffer will grow at least by `n` bytes so `n` bytes can be
+ //! added to it. If `n` is zero or `getOffset() + n` is not greater than the
+ //! current capacity of the buffer this function does nothing.
+ ASMJIT_API Error _grow(size_t n);
+
+ //! Reserve the internal buffer to at least `n` bytes.
+ ASMJIT_API Error _reserve(size_t n);
+
+ //! Get BYTE at position `pos`.
+ ASMJIT_INLINE uint8_t getByteAt(size_t pos) const {
+ ASMJIT_ASSERT(pos + 1 <= static_cast<size_t>(_end - _buffer));
+ return *reinterpret_cast<const uint8_t*>(_buffer + pos);
+ }
+
+ //! Get WORD at position `pos`.
+ ASMJIT_INLINE uint16_t getWordAt(size_t pos) const {
+ ASMJIT_ASSERT(pos + 2 <= static_cast<size_t>(_end - _buffer));
+ return *reinterpret_cast<const uint16_t*>(_buffer + pos);
+ }
+
+ //! Get DWORD at position `pos`.
+ ASMJIT_INLINE uint32_t getDWordAt(size_t pos) const {
+ ASMJIT_ASSERT(pos + 4 <= static_cast<size_t>(_end - _buffer));
+ return *reinterpret_cast<const uint32_t*>(_buffer + pos);
+ }
+
+ //! Get QWORD at position `pos`.
+ ASMJIT_INLINE uint64_t getQWordAt(size_t pos) const {
+ ASMJIT_ASSERT(pos + 8 <= static_cast<size_t>(_end - _buffer));
+ return *reinterpret_cast<const uint64_t*>(_buffer + pos);
+ }
+
+ //! Get int32_t at position `pos`.
+ ASMJIT_INLINE int32_t getInt32At(size_t pos) const {
+ ASMJIT_ASSERT(pos + 4 <= static_cast<size_t>(_end - _buffer));
+ return *reinterpret_cast<const int32_t*>(_buffer + pos);
+ }
+
+ //! Get uint32_t at position `pos`.
+ ASMJIT_INLINE uint32_t getUInt32At(size_t pos) const {
+ ASMJIT_ASSERT(pos + 4 <= static_cast<size_t>(_end - _buffer));
+ return *reinterpret_cast<const uint32_t*>(_buffer + pos);
+ }
+
+ //! Set BYTE at position `pos`.
+ ASMJIT_INLINE void setByteAt(size_t pos, uint8_t x) {
+ ASMJIT_ASSERT(pos + 1 <= static_cast<size_t>(_end - _buffer));
+ *reinterpret_cast<uint8_t*>(_buffer + pos) = x;
+ }
+
+ //! Set WORD at position `pos`.
+ ASMJIT_INLINE void setWordAt(size_t pos, uint16_t x) {
+ ASMJIT_ASSERT(pos + 2 <= static_cast<size_t>(_end - _buffer));
+ *reinterpret_cast<uint16_t*>(_buffer + pos) = x;
+ }
+
+ //! Set DWORD at position `pos`.
+ ASMJIT_INLINE void setDWordAt(size_t pos, uint32_t x) {
+ ASMJIT_ASSERT(pos + 4 <= static_cast<size_t>(_end - _buffer));
+ *reinterpret_cast<uint32_t*>(_buffer + pos) = x;
+ }
+
+ //! Set QWORD at position `pos`.
+ ASMJIT_INLINE void setQWordAt(size_t pos, uint64_t x) {
+ ASMJIT_ASSERT(pos + 8 <= static_cast<size_t>(_end - _buffer));
+ *reinterpret_cast<uint64_t*>(_buffer + pos) = x;
+ }
+
+ //! Set int32_t at position `pos`.
+ ASMJIT_INLINE void setInt32At(size_t pos, int32_t x) {
+ ASMJIT_ASSERT(pos + 4 <= static_cast<size_t>(_end - _buffer));
+ *reinterpret_cast<int32_t*>(_buffer + pos) = x;
+ }
+
+ //! Set uint32_t at position `pos`.
+ ASMJIT_INLINE void setUInt32At(size_t pos, uint32_t x) {
+ ASMJIT_ASSERT(pos + 4 <= static_cast<size_t>(_end - _buffer));
+ *reinterpret_cast<uint32_t*>(_buffer + pos) = x;
+ }
+
+ // --------------------------------------------------------------------------
+ // [GetCodeSize]
+ // --------------------------------------------------------------------------
+
+ //! Get current offset in buffer, same as `getOffset() + getTramplineSize()`.
+ ASMJIT_INLINE size_t getCodeSize() const {
+ return getOffset() + getTrampolineSize();
+ }
+
+ // --------------------------------------------------------------------------
+ // [GetTrampolineSize]
+ // --------------------------------------------------------------------------
+
+ //! Get size of all possible trampolines.
+ //!
+ //! Trampolines are 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 jumping or calling an absolute
+ //! address directly).
+ ASMJIT_INLINE size_t getTrampolineSize() const {
+ return _trampolineSize;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Label]
+ // --------------------------------------------------------------------------
+
+ //! Get number of labels created.
+ ASMJIT_INLINE size_t getLabelsCount() const {
+ return _labelList.getLength();
+ }
+
+ //! Get whether the `label` is valid (created by the assembler).
+ ASMJIT_INLINE bool isLabelValid(const Label& label) const {
+ return isLabelValid(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE bool isLabelValid(uint32_t id) const {
+ return static_cast<size_t>(id) < _labelList.getLength();
+ }
+
+ //! Get whether the `label` is bound.
+ //!
+ //! \note It's an error to pass label that is not valid. Check the validity
+ //! of the label by using `isLabelValid()` method before the bound check if
+ //! you are not sure about its validity, otherwise you may hit an assertion
+ //! failure in debug mode, and undefined behavior in release mode.
+ ASMJIT_INLINE bool isLabelBound(const Label& label) const {
+ return isLabelBound(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE bool isLabelBound(uint32_t id) const {
+ ASMJIT_ASSERT(isLabelValid(id));
+
+ return _labelList[id].offset != -1;
+ }
+
+ //! Get `label` offset or -1 if the label is not yet bound.
+ ASMJIT_INLINE intptr_t getLabelOffset(const Label& label) const {
+ return getLabelOffset(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE intptr_t getLabelOffset(uint32_t id) const {
+ ASMJIT_ASSERT(isLabelValid(id));
+ return _labelList[id].offset;
+ }
+
+ //! Get `LabelData` by `label`.
+ ASMJIT_INLINE LabelData* getLabelData(const Label& label) const {
+ return getLabelData(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE LabelData* getLabelData(uint32_t id) const {
+ ASMJIT_ASSERT(isLabelValid(id));
+ return const_cast<LabelData*>(&_labelList[id]);
+ }
+
+ //! \internal
+ //!
+ //! Register labels for other code generator, i.e. `Compiler`.
+ ASMJIT_API Error _registerIndexedLabels(size_t index);
+
+ //! \internal
+ //!
+ //! Create and initialize a new `Label`.
+ ASMJIT_API Error _newLabel(Label* dst);
+
+ //! \internal
+ //!
+ //! New LabelLink instance.
+ ASMJIT_API LabelLink* _newLabelLink();
+
+ //! Create and return a new `Label`.
+ ASMJIT_INLINE Label newLabel() {
+ Label result(NoInit);
+ _newLabel(&result);
+ return result;
+ }
+
+ //! Bind label to the current offset.
+ //!
+ //! \note Label can be bound only once!
+ ASMJIT_API virtual Error bind(const Label& label);
+
+ // --------------------------------------------------------------------------
+ // [Embed]
+ // --------------------------------------------------------------------------
+
+ //! Embed data into the code buffer.
+ ASMJIT_API virtual Error embed(const void* data, uint32_t size);
+
+ // --------------------------------------------------------------------------
+ // [Align]
+ // --------------------------------------------------------------------------
+
+ //! Align target buffer to `m` bytes.
+ //!
+ //! Typical usage of this is to align labels at start of the inner loops.
+ //!
+ //! Inserts `nop()` instructions or CPU optimized NOPs.
+ virtual Error align(uint32_t mode, uint32_t offset) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Reloc]
+ // --------------------------------------------------------------------------
+
+ //! Relocate the code to `baseAddress` and copy to `dst`.
+ //!
+ //! \param dst Contains the location where the relocated code should be
+ //! copied. The pointer can be address returned by virtual memory allocator
+ //! or any other address that has sufficient space.
+ //!
+ //! \param base Base address used for relocation. The `JitRuntime` always
+ //! sets the `base` address to be the same as `dst`, but other runtimes, for
+ //! example `StaticRuntime`, do not have to follow this rule.
+ //!
+ //! \retval The number bytes actually used. If the code generator reserved
+ //! space for possible trampolines, but didn't use it, the number of bytes
+ //! used can actually be less than the expected worst case. Virtual memory
+ //! allocator can shrink the memory allocated first time.
+ //!
+ //! A given buffer will be overwritten, to get the number of bytes required,
+ //! use `getCodeSize()`.
+ ASMJIT_API size_t relocCode(void* dst, Ptr baseAddress = kNoBaseAddress) const;
+
+ //! \internal
+ //!
+ //! Reloc code.
+ virtual size_t _relocCode(void* dst, Ptr baseAddress) const = 0;
+
+ // --------------------------------------------------------------------------
+ // [Make]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual void* make();
+
+ // --------------------------------------------------------------------------
+ // [Emit]
+ // --------------------------------------------------------------------------
+
+ //! Emit an instruction.
+ ASMJIT_API Error emit(uint32_t code);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2);
+ //! \overload
+ ASMJIT_INLINE Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) {
+ return _emit(code, o0, o1, o2, o3);
+ }
+
+ //! Emit an instruction with integer immediate operand.
+ ASMJIT_API Error emit(uint32_t code, int o0);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, uint64_t o0);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, int o1);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, uint64_t o1);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, int o2);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3);
+
+ //! Emit an instruction (virtual).
+ virtual Error _emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Buffer where the code is emitted (either live or temporary).
+ //!
+ //! This is actually the base pointer of the buffer, to get the current
+ //! position (cursor) look at the `_cursor` member.
+ uint8_t* _buffer;
+ //! The end of the buffer (points to the first invalid byte).
+ //!
+ //! The end of the buffer is calculated as <code>_buffer + size</code>.
+ uint8_t* _end;
+ //! The current position in code `_buffer`.
+ uint8_t* _cursor;
+
+ //! Size of possible trampolines.
+ uint32_t _trampolineSize;
+
+ //! Inline comment that will be logged by the next instruction and set to NULL.
+ const char* _comment;
+ //! Unused `LabelLink` structures pool.
+ LabelLink* _unusedLinks;
+
+ //! LabelData list.
+ PodVector<LabelData> _labelList;
+ //! RelocData list.
+ PodVector<RelocData> _relocList;
+};
+
+//! \}
+
+// ============================================================================
+// [Defined-Later]
+// ============================================================================
+
+ASMJIT_INLINE Label::Label(Assembler& a) : Operand(NoInit) {
+ a._newLabel(this);
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/codegen.cpp
@@ -1,1 +1,112 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Dependencies - AsmJit]
+#include "../base/codegen.h"
+#include "../base/intutil.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [asmjit::CodeGen - Construction / Destruction]
+// ============================================================================
+
+CodeGen::CodeGen(Runtime* runtime) :
+ _runtime(runtime),
+ _logger(nullptr),
+ _errorHandler(nullptr),
+ _baseAddress(runtime->getBaseAddress()),
+ _arch(kArchNone),
+ _regSize(0),
+ _reserved(0),
+ _features(IntUtil::mask(kCodeGenOptimizedAlign)),
+ _instOptions(0),
+ _error(kErrorOk),
+ _baseZone(16384 - kZoneOverhead) {}
+
+CodeGen::~CodeGen() {
+ if (_errorHandler)
+ _errorHandler->release();
+}
+
+// ============================================================================
+// [asmjit::CodeGen - Logging]
+// ============================================================================
+
+#ifndef ASMJIT_DISABLE_LOGGER
+Error CodeGen::setLogger(Logger* logger) {
+ _logger = logger;
+ return kErrorOk;
+}
+#endif // !ASMJIT_DISABLE_LOGGER
+
+// ============================================================================
+// [asmjit::CodeGen - Error]
+// ============================================================================
+
+Error CodeGen::setError(Error error, const char* message) {
+ if (error == kErrorOk) {
+ _error = kErrorOk;
+ return kErrorOk;
+ }
+
+ if (!message) {
+#ifndef ASMJIT_DISABLE_NAMES
+ message = ErrorUtil::asString(error);
+#else
+ static const char noMessage[] = "";
+ message = noMessage;
+#endif // ASMJIT_DISABLE_NAMES
+ }
+
+ // Error handler is called before logger so logging can be skipped if error
+ // has been handled.
+ ErrorHandler* handler = _errorHandler;
+ ASMJIT_TLOG("[ERROR] %s %s\n", message, !handler ? "(Possibly unhandled?)" : "");
+
+ if (handler && handler->handleError(error, message))
+ return error;
+
+#ifndef ASMJIT_DISABLE_LOGGER
+ Logger* logger = _logger;
+ if (logger) {
+ logger->logFormat(kLoggerStyleComment,
+ "*** ERROR: %s (%u).\n", message, static_cast<unsigned int>(error));
+ }
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ // The handler->handleError() function may throw an exception or longjmp()
+ // to terminate the execution of setError(). This is the reason why we have
+ // delayed changing the _error member until now.
+ _error = error;
+
+ return error;
+}
+
+Error CodeGen::setErrorHandler(ErrorHandler* handler) {
+ ErrorHandler* oldHandler = _errorHandler;
+
+ if (oldHandler)
+ oldHandler->release();
+
+ if (handler)
+ handler = handler->addRef();
+
+ _errorHandler = handler;
+ return kErrorOk;
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/codegen.h
@@ -1,1 +1,333 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../base/error.h"
+#include "../base/logger.h"
+#include "../base/runtime.h"
+#include "../base/zone.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::kCodeGen]
+// ============================================================================
+
+//! Features of \ref CodeGen.
+ASMJIT_ENUM(kCodeGen) {
+ //! Emit optimized code-alignment sequences (`Assembler` and `Compiler`).
+ //!
+ //! Default `true`.
+ //!
+ //! X86/X64
+ //! -------
+ //!
+ //! Default align sequence used by X86/X64 architecture is one-byte 0x90
+ //! opcode that is mostly shown by disassemblers as nop. However there are
+ //! more optimized align sequences for 2-11 bytes that may execute faster.
+ //! If this feature is enabled asmjit will generate specialized sequences
+ //! for alignment between 1 to 11 bytes. Also when `X86Compiler` is used,
+ //! it can add REX prefixes into the code to make some instructions greater
+ //! so no alignment sequence is needed.
+ kCodeGenOptimizedAlign = 0,
+
+ //! Emit jump-prediction hints (`Assembler` and `Compiler`).
+ //!
+ //! Default `false`.
+ //!
+ //! X86/X64
+ //! -------
+ //!
+ //! Jump prediction is usually based on the direction of the jump. If the
+ //! jump is backward it is usually predicted as taken; and if the jump is
+ //! forward it is usually predicted as not-taken. The reason is that loops
+ //! generally use backward jumps and conditions usually use forward jumps.
+ //! However this behavior can be overridden by using instruction prefixes.
+ //! If this option is enabled these hints will be emitted.
+ //!
+ //! This feature is disabled by default, because the only processor that
+ //! used to take into consideration prediction hints was P4. Newer processors
+ //! implement heuristics for branch prediction that ignores any static hints.
+ kCodeGenPredictedJumps = 1,
+
+ //! Schedule instructions so they can be executed faster (`Compiler` only).
+ //!
+ //! Default `false` - has to be explicitly enabled as the scheduler needs
+ //! some time to run.
+ //!
+ //! X86/X64
+ //! -------
+ //!
+ //! If scheduling is enabled AsmJit will try to reorder instructions to
+ //! minimize dependency chain. Scheduler always runs after the registers are
+ //! allocated so it doesn't change count of register allocs/spills.
+ //!
+ //! This feature is highly experimental and untested.
+ kCodeGenEnableScheduler = 2
+};
+
+// ============================================================================
+// [asmjit::kAlignMode]
+// ============================================================================
+
+//! Code aligning mode.
+ASMJIT_ENUM(kAlignMode) {
+ //! Align by emitting a sequence that can be executed (code).
+ kAlignCode = 0,
+ //! Align by emitting sequence that shouldn't be executed (data).
+ kAlignData = 1
+};
+
+// ============================================================================
+// [asmjit::kRelocMode]
+// ============================================================================
+
+//! Relocation mode.
+ASMJIT_ENUM(kRelocMode) {
+ //! Relocate an absolute address to an absolute address.
+ kRelocAbsToAbs = 0,
+ //! Relocate a relative address to an absolute address.
+ kRelocRelToAbs = 1,
+ //! Relocate an absolute address to a relative address.
+ kRelocAbsToRel = 2,
+ //! Relocate an absolute address to a relative address or use trampoline.
+ kRelocTrampoline = 3
+};
+
+// ============================================================================
+// [asmjit::CodeGen]
+// ============================================================================
+
+//! Abstract class defining basics of \ref Assembler and \ref Compiler.
+struct ASMJIT_VCLASS CodeGen {
+ ASMJIT_NO_COPY(CodeGen)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `CodeGen` instance.
+ ASMJIT_API CodeGen(Runtime* runtime);
+ //! Destroy the `CodeGen` instance.
+ ASMJIT_API virtual ~CodeGen();
+
+ // --------------------------------------------------------------------------
+ // [Runtime]
+ // --------------------------------------------------------------------------
+
+ //! Get runtime.
+ ASMJIT_INLINE Runtime* getRuntime() const {
+ return _runtime;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Logger]
+ // --------------------------------------------------------------------------
+
+#ifndef ASMJIT_DISABLE_LOGGER
+ //! Get whether the code generator has a logger.
+ ASMJIT_INLINE bool hasLogger() const {
+ return !!_logger;
+ }
+
+ //! Get logger.
+ ASMJIT_INLINE Logger* getLogger() const {
+ return _logger;
+ }
+
+ //! Set logger to `logger`.
+ ASMJIT_API Error setLogger(Logger* logger);
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ // --------------------------------------------------------------------------
+ // [Arch]
+ // --------------------------------------------------------------------------
+
+ //! Get target architecture.
+ ASMJIT_INLINE uint32_t getArch() const {
+ return _arch;
+ }
+
+ //! Get default register size (4 or 8 bytes).
+ ASMJIT_INLINE uint32_t getRegSize() const {
+ return _regSize;
+ }
+
+ // --------------------------------------------------------------------------
+ // [BaseAddress]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the code-generator has a base address.
+ //!
+ //! \sa \ref getBaseAddress()
+ ASMJIT_INLINE bool hasBaseAddress() const {
+ return _baseAddress != kNoBaseAddress;
+ }
+
+ //! Get the base address.
+ ASMJIT_INLINE Ptr getBaseAddress() const {
+ return _baseAddress;
+ }
+
+ //! Set the base address to `baseAddress`.
+ ASMJIT_INLINE void setBaseAddress(Ptr baseAddress) {
+ _baseAddress = baseAddress;
+ }
+
+ //! Reset the base address.
+ ASMJIT_INLINE void resetBaseAddress() {
+ setBaseAddress(kNoBaseAddress);
+ }
+
+ // --------------------------------------------------------------------------
+ // [LastError / ErrorHandler]
+ // --------------------------------------------------------------------------
+
+ //! Get last error code.
+ ASMJIT_INLINE Error getError() const {
+ return _error;
+ }
+
+ //! Set last error code and propagate it through the error handler.
+ ASMJIT_API Error setError(Error error, const char* message = nullptr);
+
+ //! Clear the last error code.
+ ASMJIT_INLINE void resetError() {
+ _error = kErrorOk;
+ }
+
+ //! Get error handler.
+ ASMJIT_INLINE ErrorHandler* getErrorHandler() const {
+ return _errorHandler;
+ }
+
+ //! Set error handler.
+ ASMJIT_API Error setErrorHandler(ErrorHandler* handler);
+
+ //! Clear error handler.
+ ASMJIT_INLINE Error resetErrorHandler() {
+ return setErrorHandler(nullptr);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Code-Generation Features]
+ // --------------------------------------------------------------------------
+
+ //! Get code-generator `feature`.
+ ASMJIT_INLINE bool hasFeature(uint32_t feature) const {
+ ASMJIT_ASSERT(feature < 32);
+
+ return (_features & (1 << feature)) != 0;
+ }
+
+ //! Set code-generator `feature` to `value`.
+ ASMJIT_INLINE void setFeature(uint32_t feature, bool value) {
+ ASMJIT_ASSERT(feature < 32);
+
+ feature = static_cast<uint32_t>(value) << feature;
+ _features = (_features & ~feature) | feature;
+ }
+
+ //! Get code-generator features.
+ ASMJIT_INLINE uint32_t getFeatures() const {
+ return _features;
+ }
+
+ //! Set code-generator features.
+ ASMJIT_INLINE void setFeatures(uint32_t features) {
+ _features = features;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Instruction Options]
+ // --------------------------------------------------------------------------
+
+ //! Get options of the next instruction.
+ ASMJIT_INLINE uint32_t getInstOptions() const {
+ return _instOptions;
+ }
+
+ //! Get options of the next instruction and reset them.
+ ASMJIT_INLINE uint32_t getInstOptionsAndReset() {
+ uint32_t instOptions = _instOptions;
+ _instOptions = 0;
+ return instOptions;
+ };
+
+ //! Set options of the next instruction.
+ ASMJIT_INLINE void setInstOptions(uint32_t instOptions) {
+ _instOptions = instOptions;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Make]
+ // --------------------------------------------------------------------------
+
+ //! Make is a convenience method to make and relocate the current code and
+ //! add it to the associated `Runtime`.
+ //!
+ //! What is needed is only to cast the returned pointer to your function type
+ //! and then use it. If there was an error during `make()` `NULL` is returned
+ //! and the last error code can be obtained by calling `getError()`.
+ virtual void* make() = 0;
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Target runtime.
+ Runtime* _runtime;
+
+#ifndef ASMJIT_DISABLE_LOGGER
+ //! Logger.
+ Logger* _logger;
+#else
+ //! \internal
+ //!
+ //! Makes libraries built with or without logging support binary compatible.
+ void* _logger;
+#endif // ASMJIT_DISABLE_LOGGER
+
+ //! Error handler, called by \ref setError().
+ ErrorHandler* _errorHandler;
+
+ //! Base address (-1 if unknown/not used).
+ Ptr _baseAddress;
+
+ //! Target architecture ID.
+ uint8_t _arch;
+ //! Target architecture GP register size in bytes (4 or 8).
+ uint8_t _regSize;
+ //! \internal
+ uint16_t _reserved;
+
+ //! Code-Generation features, used by \ref hasFeature() and \ref setFeature().
+ uint32_t _features;
+ //! Options affecting the next instruction.
+ uint32_t _instOptions;
+
+ //! Last error code.
+ uint32_t _error;
+
+ //! Base zone.
+ Zone _baseZone;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/compiler.cpp
@@ -1,1 +1,622 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Guard]
+#include "../build.h"
+#ifndef ASMJIT_DISABLE_COMPILER
+
+// [Dependencies - AsmJit]
+#include "../base/assembler.h"
+#include "../base/compiler.h"
+#include "../base/context_p.h"
+#include "../base/cpuinfo.h"
+#include "../base/intutil.h"
+#include "../base/logger.h"
+
+// [Dependencies - C]
+#include <cstdarg>
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [Constants]
+// ============================================================================
+
+static const char noName[1] = { '\0' };
+enum { kBaseCompilerDefaultLookAhead = 64 };
+
+// ============================================================================
+// [asmjit::Compiler - Construction / Destruction]
+// ============================================================================
+
+Compiler::Compiler(Runtime* runtime) :
+ CodeGen(runtime),
+ _assembler(nullptr),
+ _nodeFlowId(0),
+ _nodeFlags(0),
+ _maxLookAhead(kBaseCompilerDefaultLookAhead),
+ _targetVarMapping(nullptr),
+ _firstNode(nullptr),
+ _lastNode(nullptr),
+ _cursor(nullptr),
+ _func(nullptr),
+ _varZone(4096 - kZoneOverhead),
+ _stringZone(4096 - kZoneOverhead),
+ _localConstZone(4096 - kZoneOverhead),
+ _localConstPool(&_localConstZone),
+ _globalConstPool(&_baseZone) {}
+
+Compiler::~Compiler() {
+ reset(true);
+
+ if (_assembler)
+ delete _assembler;
+}
+
+// ============================================================================
+// [asmjit::Compiler - Clear / Reset]
+// ============================================================================
+
+void Compiler::reset(bool releaseMemory) {
+ // CodeGen members.
+ _baseAddress = kNoBaseAddress;
+ _instOptions = 0;
+ _error = kErrorOk;
+
+ _baseZone.reset(releaseMemory);
+
+ // Compiler members.
+ _nodeFlowId = 0;
+ _nodeFlags = 0;
+
+ if (_assembler)
+ _assembler->reset(releaseMemory);
+
+ _firstNode = nullptr;
+ _lastNode = nullptr;
+
+ _cursor = nullptr;
+ _func = nullptr;
+
+ _localConstPool.reset();
+ _globalConstPool.reset();
+
+ _localConstPoolLabel.reset();
+ _globalConstPoolLabel.reset();
+
+ _varZone.reset(releaseMemory);
+ _stringZone.reset(releaseMemory);
+ _localConstZone.reset(releaseMemory);
+
+ _targetList.reset(releaseMemory);
+ _varList.reset(releaseMemory);
+}
+
+// ============================================================================
+// [asmjit::Compiler - Node Management]
+// ============================================================================
+
+Node* Compiler::setCursor(Node* node) {
+ Node* old = _cursor;
+ _cursor = node;
+ return old;
+}
+
+Node* Compiler::addNode(Node* node) {
+ ASMJIT_ASSERT(node);
+ ASMJIT_ASSERT(!node->_prev);
+ ASMJIT_ASSERT(!node->_next);
+
+ if (!_cursor) {
+ if (!_firstNode) {
+ _firstNode = node;
+ _lastNode = node;
+ }
+ else {
+ node->_next = _firstNode;
+ _firstNode->_prev = node;
+ _firstNode = node;
+ }
+ }
+ else {
+ Node* prev = _cursor;
+ Node* next = _cursor->_next;
+
+ node->_prev = prev;
+ node->_next = next;
+
+ prev->_next = node;
+ if (next)
+ next->_prev = node;
+ else
+ _lastNode = node;
+ }
+
+ _cursor = node;
+ return node;
+}
+
+Node* Compiler::addNodeBefore(Node* node, Node* ref) {
+ ASMJIT_ASSERT(node);
+ ASMJIT_ASSERT(!node->_prev);
+ ASMJIT_ASSERT(!node->_next);
+ ASMJIT_ASSERT(ref);
+
+ Node* prev = ref->_prev;
+ Node* next = ref;
+
+ node->_prev = prev;
+ node->_next = next;
+
+ next->_prev = node;
+ if (prev)
+ prev->_next = node;
+ else
+ _firstNode = node;
+
+ return node;
+}
+
+Node* Compiler::addNodeAfter(Node* node, Node* ref) {
+ ASMJIT_ASSERT(node);
+ ASMJIT_ASSERT(!node->_prev);
+ ASMJIT_ASSERT(!node->_next);
+ ASMJIT_ASSERT(ref);
+
+ Node* prev = ref;
+ Node* next = ref->_next;
+
+ node->_prev = prev;
+ node->_next = next;
+
+ prev->_next = node;
+ if (next)
+ next->_prev = node;
+ else
+ _lastNode = node;
+
+ return node;
+}
+
+static ASMJIT_INLINE void BaseCompiler_nodeRemoved(Compiler*, Node* node_) {
+ if (node_->isJmpOrJcc()) {
+ JumpNode* node = static_cast<JumpNode*>(node_);
+ TargetNode* target = node->getTarget();
+
+ // Disconnect.
+ JumpNode** pPrev = &target->_from;
+ for (;;) {
+ ASMJIT_ASSERT(*pPrev);
+ JumpNode* current = *pPrev;
+
+ if (!current)
+ break;
+
+ if (current == node) {
+ *pPrev = node->_jumpNext;
+ break;
+ }
+
+ pPrev = ¤t->_jumpNext;
+ }
+
+ target->subNumRefs();
+ }
+}
+
+Node* Compiler::removeNode(Node* node) {
+ Node* prev = node->_prev;
+ Node* next = node->_next;
+
+ if (_firstNode == node)
+ _firstNode = next;
+ else
+ prev->_next = next;
+
+ if (_lastNode == node)
+ _lastNode = prev;
+ else
+ next->_prev = prev;
+
+ node->_prev = nullptr;
+ node->_next = nullptr;
+
+ if (_cursor == node)
+ _cursor = prev;
+ BaseCompiler_nodeRemoved(this, node);
+
+ return node;
+}
+
+void Compiler::removeNodes(Node* first, Node* last) {
+ if (first == last) {
+ removeNode(first);
+ return;
+ }
+
+ Node* prev = first->_prev;
+ Node* next = last->_next;
+
+ if (_firstNode == first)
+ _firstNode = next;
+ else
+ prev->_next = next;
+
+ if (_lastNode == last)
+ _lastNode = prev;
+ else
+ next->_prev = prev;
+
+ Node* node = first;
+ for (;;) {
+ next = node->getNext();
+ ASMJIT_ASSERT(next);
+
+ node->_prev = nullptr;
+ node->_next = nullptr;
+
+ if (_cursor == node)
+ _cursor = prev;
+ BaseCompiler_nodeRemoved(this, node);
+
+ if (node == last)
+ break;
+ node = next;
+ }
+}
+
+// ============================================================================
+// [asmjit::Compiler - Align]
+// ============================================================================
+
+AlignNode* Compiler::newAlign(uint32_t mode, uint32_t offset) {
+ AlignNode* node = newNode<AlignNode>(mode, offset);
+ if (!node)
+ goto _NoMemory;
+ return node;
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+AlignNode* Compiler::addAlign(uint32_t mode, uint32_t offset) {
+ AlignNode* node = newAlign(mode, offset);
+ if (!node)
+ return nullptr;
+ return static_cast<AlignNode*>(addNode(node));
+}
+
+// ============================================================================
+// [asmjit::Compiler - Target]
+// ============================================================================
+
+TargetNode* Compiler::newTarget() {
+ TargetNode* node = newNode<TargetNode>(
+ OperandUtil::makeLabelId(static_cast<uint32_t>(_targetList.getLength())));
+
+ if (!node || _targetList.append(node) != kErrorOk)
+ goto _NoMemory;
+ return node;
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+TargetNode* Compiler::addTarget() {
+ TargetNode* node = newTarget();
+ if (!node)
+ return nullptr;
+ return static_cast<TargetNode*>(addNode(node));
+}
+
+// ============================================================================
+// [asmjit::Compiler - Label]
+// ============================================================================
+
+Error Compiler::_newLabel(Label* dst) {
+ dst->_init_packed_op_sz_b0_b1_id(kOperandTypeLabel, 0, 0, 0, kInvalidValue);
+ dst->_init_packed_d2_d3(0, 0);
+
+ TargetNode* node = newTarget();
+ if (!node)
+ goto _NoMemory;
+
+ dst->_label.id = node->getLabelId();
+ return kErrorOk;
+
+_NoMemory:
+ return setError(kErrorNoHeapMemory);
+}
+
+Error Compiler::bind(const Label& label) {
+ uint32_t index = label.getId();
+ ASMJIT_ASSERT(index < _targetList.getLength());
+
+ addNode(_targetList[index]);
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::Compiler - Embed]
+// ============================================================================
+
+EmbedNode* Compiler::newEmbed(const void* data, uint32_t size) {
+ EmbedNode* node;
+
+ if (size > EmbedNode::kInlineBufferSize) {
+ void* clonedData = _stringZone.alloc(size);
+ if (!clonedData)
+ goto _NoMemory;
+
+ if (data)
+ ::memcpy(clonedData, data, size);
+ data = clonedData;
+ }
+
+ node = newNode<EmbedNode>(const_cast<void*>(data), size);
+ if (!node)
+ goto _NoMemory;
+ return node;
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+EmbedNode* Compiler::addEmbed(const void* data, uint32_t size) {
+ EmbedNode* node = newEmbed(data, size);
+ if (!node)
+ return node;
+ return static_cast<EmbedNode*>(addNode(node));
+}
+
+// ============================================================================
+// [asmjit::Compiler - Comment]
+// ============================================================================
+
+CommentNode* Compiler::newComment(const char* str) {
+ CommentNode* node;
+
+ if (str && str[0]) {
+ str = _stringZone.sdup(str);
+ if (!str)
+ goto _NoMemory;
+ }
+
+ node = newNode<CommentNode>(str);
+ if (!node)
+ goto _NoMemory;
+ return node;
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+CommentNode* Compiler::addComment(const char* str) {
+ CommentNode* node = newComment(str);
+ if (!node)
+ return nullptr;
+ return static_cast<CommentNode*>(addNode(node));
+}
+
+CommentNode* Compiler::comment(const char* fmt, ...) {
+ char buf[256];
+ char* p = buf;
+
+ if (fmt) {
+ *p++ = ';';
+ *p++ = ' ';
+
+ va_list ap;
+ va_start(ap, fmt);
+ p += vsnprintf(p, 254, fmt, ap);
+ va_end(ap);
+ }
+
+ p[0] = '\n';
+ p[1] = '\0';
+
+ return addComment(fmt);
+}
+
+// ============================================================================
+// [asmjit::Compiler - Hint]
+// ============================================================================
+
+HintNode* Compiler::newHint(Var& var, uint32_t hint, uint32_t value) {
+ if (var.getId() == kInvalidValue)
+ return nullptr;
+ VarData* vd = getVd(var);
+
+ HintNode* node = newNode<HintNode>(vd, hint, value);
+ if (!node)
+ goto _NoMemory;
+ return node;
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+HintNode* Compiler::addHint(Var& var, uint32_t hint, uint32_t value) {
+ if (var.getId() == kInvalidValue)
+ return nullptr;
+
+ HintNode* node = newHint(var, hint, value);
+ if (!node)
+ return nullptr;
+ return static_cast<HintNode*>(addNode(node));
+}
+
+// ============================================================================
+// [asmjit::Compiler - Vars]
+// ============================================================================
+
+VarData* Compiler::_newVd(uint32_t type, uint32_t size, uint32_t c, const char* name) {
+ VarData* vd = reinterpret_cast<VarData*>(_varZone.alloc(sizeof(VarData)));
+ if (!vd)
+ goto _NoMemory;
+
+ vd->_name = noName;
+ vd->_id = OperandUtil::makeVarId(static_cast<uint32_t>(_varList.getLength()));
+ vd->_contextId = kInvalidValue;
+
+ if (name && name[0] != '\0') {
+ vd->_name = _stringZone.sdup(name);
+ }
+
+ vd->_type = static_cast<uint8_t>(type);
+ vd->_class = static_cast<uint8_t>(c);
+ vd->_flags = 0;
+ vd->_priority = 10;
+
+ vd->_state = kVarStateUnused;
+ vd->_regIndex = kInvalidReg;
+ vd->_isStack = false;
+ vd->_isMemArg = false;
+ vd->_isCalculated = false;
+ vd->_saveOnUnuse = false;
+ vd->_modified = false;
+ vd->_reserved0 = 0;
+ vd->_alignment = static_cast<uint8_t>(IntUtil::iMin<uint32_t>(size, 64));
+
+ vd->_size = size;
+ vd->_homeMask = 0;
+
+ vd->_memOffset = 0;
+ vd->_memCell = nullptr;
+
+ vd->rReadCount = 0;
+ vd->rWriteCount = 0;
+ vd->mReadCount = 0;
+ vd->mWriteCount = 0;
+
+ vd->_va = nullptr;
+
+ if (_varList.append(vd) != kErrorOk)
+ goto _NoMemory;
+ return vd;
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+void Compiler::alloc(Var& var) {
+ addHint(var, kVarHintAlloc, kInvalidValue);
+}
+
+void Compiler::alloc(Var& var, uint32_t regIndex) {
+ addHint(var, kVarHintAlloc, regIndex);
+}
+
+void Compiler::alloc(Var& var, const Reg& reg) {
+ addHint(var, kVarHintAlloc, reg.getRegIndex());
+}
+
+void Compiler::save(Var& var) {
+ addHint(var, kVarHintSave, kInvalidValue);
+}
+
+void Compiler::spill(Var& var) {
+ addHint(var, kVarHintSpill, kInvalidValue);
+}
+
+void Compiler::unuse(Var& var) {
+ addHint(var, kVarHintUnuse, kInvalidValue);
+}
+
+uint32_t Compiler::getPriority(Var& var) const {
+ if (var.getId() == kInvalidValue)
+ return kInvalidValue;
+
+ VarData* vd = getVdById(var.getId());
+ return vd->getPriority();
+}
+
+void Compiler::setPriority(Var& var, uint32_t priority) {
+ if (var.getId() == kInvalidValue)
+ return;
+
+ if (priority > 255)
+ priority = 255;
+
+ VarData* vd = getVdById(var.getId());
+ vd->_priority = static_cast<uint8_t>(priority);
+}
+
+bool Compiler::getSaveOnUnuse(Var& var) const {
+ if (var.getId() == kInvalidValue)
+ return false;
+
+ VarData* vd = getVdById(var.getId());
+ return static_cast<bool>(vd->_saveOnUnuse);
+}
+
+void Compiler::setSaveOnUnuse(Var& var, bool value) {
+ if (var.getId() == kInvalidValue)
+ return;
+
+ VarData* vd = getVdById(var.getId());
+ vd->_saveOnUnuse = value;
+}
+
+void Compiler::rename(Var& var, const char* name) {
+ if (var.getId() == kInvalidValue)
+ return;
+
+ VarData* vd = getVdById(var.getId());
+ vd->_name = noName;
+
+ if (name && name[0] != '\0') {
+ vd->_name = _stringZone.sdup(name);
+ }
+}
+
+// ============================================================================
+// [asmjit::Compiler - Assembler]
+// ============================================================================
+
+Assembler* Compiler::getAssembler() {
+ Assembler* a = _assembler;
+
+ if (a) {
+ a->reset(false);
+ }
+ else {
+ a = _newAssembler();
+ _assembler = a;
+ }
+
+#ifndef ASMJIT_DISABLE_LOGGER
+ Logger* logger = _logger;
+ if (logger)
+ a->setLogger(logger);
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ a->setBaseAddress(_baseAddress);
+ a->setFeatures(_features);
+
+ return a;
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // !ASMJIT_DISABLE_COMPILER
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/compiler.h
@@ -1,1 +1,3144 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+#include "../build.h"
+#ifndef ASMJIT_DISABLE_COMPILER
+
+// [Dependencies - AsmJit]
+#include "../base/assembler.h"
+#include "../base/codegen.h"
+#include "../base/constpool.h"
+#include "../base/containers.h"
+#include "../base/error.h"
+#include "../base/intutil.h"
+#include "../base/operand.h"
+#include "../base/zone.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [Forward Declarations]
+// ============================================================================
+
+struct Compiler;
+
+struct VarAttr;
+struct VarData;
+struct VarMap;
+struct VarState;
+
+struct Node;
+struct EndNode;
+struct InstNode;
+struct JumpNode;
+
+// ============================================================================
+// [asmjit::kConstScope]
+// ============================================================================
+
+//! \addtogroup asmjit_base_compiler
+//! \{
+
+//! Scope of the constant.
+ASMJIT_ENUM(kConstScope) {
+ //! Local constant, always embedded right after the current function.
+ kConstScopeLocal = 0,
+ //! Global constant, embedded at the end of the currently compiled code.
+ kConstScopeGlobal = 1
+};
+
+// ============================================================================
+// [asmjit::kVarType]
+// ============================================================================
+
+ASMJIT_ENUM(kVarType) {
+ //! Variable is 8-bit signed integer.
+ kVarTypeInt8 = 0,
+ //! Variable is 8-bit unsigned integer.
+ kVarTypeUInt8 = 1,
+ //! Variable is 16-bit signed integer.
+ kVarTypeInt16 = 2,
+ //! Variable is 16-bit unsigned integer.
+ kVarTypeUInt16 = 3,
+ //! Variable is 32-bit signed integer.
+ kVarTypeInt32 = 4,
+ //! Variable is 32-bit unsigned integer.
+ kVarTypeUInt32 = 5,
+ //! Variable is 64-bit signed integer.
+ kVarTypeInt64 = 6,
+ //! Variable is 64-bit unsigned integer.
+ kVarTypeUInt64 = 7,
+
+ //! Variable is target `intptr_t`, not compatible with host `intptr_t`.
+ kVarTypeIntPtr = 8,
+ //! Variable is target `uintptr_t`, not compatible with host `uintptr_t`.
+ kVarTypeUIntPtr = 9,
+
+ //! Variable is 32-bit floating point (single precision).
+ kVarTypeFp32 = 10,
+ //! Variable is 64-bit floating point (double precision).
+ kVarTypeFp64 = 11,
+
+ //! \internal
+ _kVarTypeIntStart = kVarTypeInt8,
+ //! \internal
+ _kVarTypeIntEnd = kVarTypeUIntPtr,
+
+ //! \internal
+ _kVarTypeFpStart = kVarTypeFp32,
+ //! \internal
+ _kVarTypeFpEnd = kVarTypeFp64
+};
+
+// ============================================================================
+// [asmjit::kVarFlags]
+// ============================================================================
+
+//! \internal
+//!
+//! X86/X64 variable flags.
+ASMJIT_ENUM(kVarFlags) {
+ //! Variable contains single-precision floating-point(s).
+ kVarFlagSp = 0x10,
+ //! Variable contains double-precision floating-point(s).
+ kVarFlagDp = 0x20,
+ //! Variable is packed, i.e. packed floats, doubles, ...
+ kVarFlagPacked = 0x40
+};
+
+// ============================================================================
+// [asmjit::kVarAttrFlags]
+// ============================================================================
+
+//! Variable attribute flags.
+ASMJIT_ENUM(kVarAttrFlags) {
+ //! Variable is accessed through register on input.
+ kVarAttrInReg = 0x00000001,
+ //! Variable is accessed through register on output.
+ kVarAttrOutReg = 0x00000002,
+ //! Variable is accessed through register on input & output.
+ kVarAttrInOutReg = 0x00000003,
+
+ //! Variable is accessed through memory on input.
+ kVarAttrInMem = 0x00000004,
+ //! Variable is accessed through memory on output.
+ kVarAttrOutMem = 0x00000008,
+ //! Variable is accessed through memory on input & output.
+ kVarAttrInOutMem = 0x0000000C,
+
+ //! Register allocator can decide if input will be in register or memory.
+ kVarAttrInDecide = 0x00000010,
+ //! Register allocator can decide if output will be in register or memory.
+ kVarAttrOutDecide = 0x00000020,
+ //! Register allocator can decide if in/out will be in register or memory.
+ kVarAttrInOutDecide = 0x00000030,
+
+ //! Variable is converted to other type/class on the input.
+ kVarAttrInConv = 0x00000040,
+ //! Variable is converted from other type/class on the output.
+ kVarAttrOutConv = 0x00000080,
+ //! Combination of `kVarAttrInConv` and `kVarAttrOutConv`.
+ kVarAttrInOutConv = 0x000000C0,
+
+ //! Variable is a function call operand.
+ kVarAttrInCall = 0x00000100,
+ //! Variable is a function argument passed in register.
+ kVarAttrInArg = 0x00000200,
+
+ //! Variable is a function return value passed in register.
+ kVarAttrOutRet = 0x00000400,
+ //! Variable should be spilled.
+ kVarAttrSpill = 0x00000800,
+ //! Variable should be unused at the end of the instruction/node.
+ kVarAttrUnuse = 0x00001000,
+
+ //! \internal
+ //!
+ //! All in-flags.
+ kVarAttrInAll =
+ kVarAttrInReg |
+ kVarAttrInMem |
+ kVarAttrInDecide |
+ kVarAttrInCall |
+ kVarAttrInArg,
+
+ //! \internal
+ //!
+ //! All out-flags.
+ kVarAttrOutAll =
+ kVarAttrOutReg |
+ kVarAttrOutMem |
+ kVarAttrOutDecide |
+ kVarAttrOutRet,
+
+ //! Variable is already allocated on the input.
+ kVarAttrAllocInDone = 0x00400000,
+ //! Variable is already allocated on the output.
+ kVarAttrAllocOutDone = 0x00800000
+};
+
+// ============================================================================
+// [asmjit::kVarHint]
+// ============================================================================
+
+//! Variable hint (used by `Compiler)`.
+//!
+//! \sa Compiler.
+ASMJIT_ENUM(kVarHint) {
+ //! Alloc variable.
+ kVarHintAlloc = 0,
+ //! Spill variable.
+ kVarHintSpill = 1,
+ //! Save variable if modified.
+ kVarHintSave = 2,
+ //! Save variable if modified and mark it as unused.
+ kVarHintSaveAndUnuse = 3,
+ //! Mark variable as unused.
+ kVarHintUnuse = 4
+};
+
+// ============================================================================
+// [asmjit::kVarState]
+// ============================================================================
+
+//! State of variable.
+//!
+//! \note State of variable is used only during make process and it's not
+//! visible to the developer.
+ASMJIT_ENUM(kVarState) {
+ //! Variable is currently not used.
+ kVarStateUnused = 0,
+
+ //! Variable is in register.
+ //!
+ //! Variable is currently allocated in register.
+ kVarStateReg = 1,
+
+ //! Variable is in memory location or spilled.
+ //!
+ //! Variable was spilled from register to memory or variable is used for
+ //! memory only storage.
+ kVarStateMem = 2
+};
+
+// ============================================================================
+// [asmjit::kFuncConv]
+// ============================================================================
+
+//! Function calling convention.
+//!
+//! For a platform specific calling conventions, see:
+//! - `kX86FuncConv` - X86/X64 calling conventions.
+ASMJIT_ENUM(kFuncConv) {
+ //! Calling convention is invalid (can't be used).
+ kFuncConvNone = 0,
+
+#ifdef ASMJIT_DOCGEN
+ //! Default calling convention for current platform / operating system.
+ kFuncConvHost = DependsOnHost,
+
+ //! Default C calling convention based on current compiler's settings.
+ kFuncConvHostCDecl = DependsOnHost,
+
+ //! Compatibility for `__stdcall` calling convention.
+ //!
+ //! \note This enumeration is always set to a value which is compatible with
+ //! current compilers __stdcall calling convention. In 64-bit mode the value
+ //! is compatible with `kX86FuncConvW64` or `kX86FuncConvU64`.
+ kFuncConvHostStdCall = DependsOnHost,
+
+ //! Compatibility for `__fastcall` calling convention.
+ //!
+ //! \note This enumeration is always set to a value which is compatible with
+ //! current compilers `__fastcall` calling convention. In 64-bit mode the value
+ //! is compatible with `kX86FuncConvW64` or `kX86FuncConvU64`.
+ kFuncConvHostFastCall = DependsOnHost
+#endif // ASMJIT_DOCGEN
+};
+
+// ============================================================================
+// [asmjit::kFuncHint]
+// ============================================================================
+
+//! Function hints.
+//!
+//! For a platform specific calling conventions, see:
+//! - `kX86FuncHint` - X86/X64 function hints.
+ASMJIT_ENUM(kFuncHint) {
+ //! Make a naked function (default true).
+ //!
+ //! Naked function is function without using standard prolog/epilog sequence).
+ //!
+ //! X86/X64 Specific
+ //! ----------------
+ //!
+ //! Standard prolog sequence is:
+ //!
+ //! ~~~
+ //! push zbp
+ //! mov zsp, zbp
+ //! sub zsp, StackAdjustment
+ //! ~~~
+ //!
+ //! which is an equivalent to:
+ //!
+ //! ~~~
+ //! enter StackAdjustment, 0
+ //! ~~~
+ //!
+ //! Standard epilog sequence is:
+ //!
+ //! ~~~
+ //! mov zsp, zbp
+ //! pop zbp
+ //! ~~~
+ //!
+ //! which is an equavalent to:
+ //!
+ //! ~~~
+ //! leave
+ //! ~~~
+ //!
+ //! Naked functions can omit the prolog/epilog sequence. The advantage of
+ //! doing such modification is that EBP/RBP register can be used by the
+ //! register allocator which can result in less spills/allocs.
+ kFuncHintNaked = 0,
+
+ //! Generate compact function prolog/epilog if possible.
+ //!
+ //! X86/X64 Specific
+ //! ----------------
+ //!
+ //! Use shorter, but possible slower prolog/epilog sequence to save/restore
+ //! registers.
+ kFuncHintCompact = 1
+};
+
+// ============================================================================
+// [asmjit::kFuncFlags]
+// ============================================================================
+
+//! Function flags.
+//!
+//! For a platform specific calling conventions, see:
+//! - `kX86FuncFlags` - X86/X64 function flags.
+ASMJIT_ENUM(kFuncFlags) {
+ //! Whether the function is using naked (minimal) prolog / epilog.
+ kFuncFlagIsNaked = 0x00000001,
+
+ //! Whether an another function is called from this function.
+ kFuncFlagIsCaller = 0x00000002,
+
+ //! Whether the stack is not aligned to the required stack alignment,
+ //! thus it has to be aligned manually.
+ kFuncFlagIsStackMisaligned = 0x00000004,
+
+ //! Whether the stack pointer is adjusted by the stack size needed
+ //! to save registers and function variables.
+ //!
+ //! X86/X64 Specific
+ //! ----------------
+ //!
+ //! Stack pointer (ESP/RSP) is adjusted by 'sub' instruction in prolog and by
+ //! 'add' instruction in epilog (only if function is not naked). If function
+ //! needs to perform manual stack alignment more instructions are used to
+ //! adjust the stack (like "and zsp, -Alignment").
+ kFuncFlagIsStackAdjusted = 0x00000008,
+
+ //! Whether the function is finished using `Compiler::endFunc()`.
+ kFuncFlagIsFinished = 0x80000000
+};
+
+// ============================================================================
+// [asmjit::kFuncDir]
+// ============================================================================
+
+//! Function arguments direction.
+ASMJIT_ENUM(kFuncDir) {
+ //! Arguments are passed left to right.
+ //!
+ //! This arguments direction is unusual in C, however it's used in Pascal.
+ kFuncDirLtr = 0,
+
+ //! Arguments are passed right ro left
+ //!
+ //! This is the default argument direction in C.
+ kFuncDirRtl = 1
+};
+
+// ============================================================================
+// [asmjit::kFuncArg]
+// ============================================================================
+
+//! Function argument (lo/hi) specification.
+ASMJIT_ENUM(kFuncArg) {
+ //! Maxumum number of function arguments supported by AsmJit.
+ kFuncArgCount = 16,
+ //! Extended maximum number of arguments (used internally).
+ kFuncArgCountLoHi = kFuncArgCount * 2,
+
+ //! Index to the LO part of function argument (default).
+ //!
+ //! This value is typically omitted and added only if there is HI argument
+ //! accessed.
+ kFuncArgLo = 0,
+ //! Index to the HI part of function argument.
+ //!
+ //! HI part of function argument depends on target architecture. On x86 it's
+ //! typically used to transfer 64-bit integers (they form a pair of 32-bit
+ //! integers).
+ kFuncArgHi = kFuncArgCount
+};
+
+// ============================================================================
+// [asmjit::kFuncRet]
+// ============================================================================
+
+//! Function return value (lo/hi) specification.
+ASMJIT_ENUM(kFuncRet) {
+ //! Index to the LO part of function return value.
+ kFuncRetLo = 0,
+ //! Index to the HI part of function return value.
+ kFuncRetHi = 1
+};
+
+// ============================================================================
+// [asmjit::kFuncStackInvalid]
+// ============================================================================
+
+enum kFuncMisc {
+ //! Invalid stack offset in function or function parameter.
+ kFuncStackInvalid = -1
+};
+
+// ============================================================================
+// [asmjit::kNodeType]
+// ============================================================================
+
+//! Type of node, see \ref Node.
+ASMJIT_ENUM(kNodeType) {
+ //! Invalid node (internal, can't be used).
+ kNodeTypeNone = 0,
+ //! Node is an .align directive, see \ref AlignNode.
+ kNodeTypeAlign,
+ //! Node is an embedded data, see \ref EmbedNode.
+ kNodeTypeEmbed,
+ //! Node is a comment, see \ref CommentNode.
+ kNodeTypeComment,
+ //! Node is a variable hint (alloc, spill, use, unuse), see \ref HintNode.
+ kNodeTypeHint,
+ //! Node is a label, see \ref TargetNode.
+ kNodeTypeTarget,
+ //! Node is an instruction, see \ref InstNode.
+ kNodeTypeInst,
+ //! Node is a function declaration, see \ref FuncNode.
+ kNodeTypeFunc,
+ //! Node is an end of the function, see \ref EndNode.
+ kNodeTypeEnd,
+ //! Node is a return, see \ref RetNode.
+ kNodeTypeRet,
+ //! Node is a function call, see \ref CallNode.
+ kNodeTypeCall,
+ //! Node is a function call argument moved on stack, see \ref SArgNode.
+ kNodeTypeSArg
+};
+
+// ============================================================================
+// [asmjit::kNodeFlags]
+// ============================================================================
+
+ASMJIT_ENUM(kNodeFlags) {
+ //! Whether the node has been translated, thus contains only registers.
+ kNodeFlagIsTranslated = 0x0001,
+
+ //! Whether the node was scheduled - possibly reordered, but basically this
+ //! is a mark that is set by scheduler after the node has been visited.
+ kNodeFlagIsScheduled = 0x0002,
+
+ //! Whether the node is informative only and can be safely removed.
+ kNodeFlagIsInformative = 0x0004,
+
+ //! Whether the `InstNode` is a jump.
+ kNodeFlagIsJmp = 0x0008,
+ //! Whether the `InstNode` is a conditional jump.
+ kNodeFlagIsJcc = 0x0010,
+
+ //! Whether the `InstNode` is an unconditinal jump or conditional
+ //! jump that is likely to be taken.
+ kNodeFlagIsTaken = 0x0020,
+
+ //! Whether the `Node` will return from a function.
+ //!
+ //! This flag is used by both `EndNode` and `RetNode`.
+ kNodeFlagIsRet = 0x0040,
+
+ //! Whether the instruction is special.
+ kNodeFlagIsSpecial = 0x0080,
+
+ //! Whether the instruction is an FPU instruction.
+ kNodeFlagIsFp = 0x0100
+};
+
+// ============================================================================
+// [asmjit::MemCell]
+// ============================================================================
+
+struct MemCell {
+ ASMJIT_NO_COPY(MemCell)
+ MemCell() { }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get cell offset.
+ ASMJIT_INLINE int32_t getOffset() const { return _offset; }
+ //! Set cell offset.
+ ASMJIT_INLINE void setOffset(int32_t offset) { _offset = offset; }
+
+ //! Get cell size.
+ ASMJIT_INLINE uint32_t getSize() const { return _size; }
+ //! Set cell size.
+ ASMJIT_INLINE void setSize(uint32_t size) { _size = size; }
+
+ //! Get cell alignment.
+ ASMJIT_INLINE uint32_t getAlignment() const { return _alignment; }
+ //! Set cell alignment.
+ ASMJIT_INLINE void setAlignment(uint32_t alignment) { _alignment = alignment; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Next active cell.
+ MemCell* _next;
+
+ //! Offset, relative to base-offset.
+ int32_t _offset;
+ //! Size.
+ uint32_t _size;
+ //! Alignment.
+ uint32_t _alignment;
+};
+
+// ============================================================================
+// [asmjit::Var]
+// ============================================================================
+
+//! Base class for all variables.
+struct Var : public Operand {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Var() : Operand(NoInit) {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeVar, 0, 0, 0, kInvalidValue);
+ _init_packed_d2_d3(kInvalidValue, kInvalidValue);
+ }
+
+ ASMJIT_INLINE Var(const Var& other) : Operand(other) {}
+
+ explicit ASMJIT_INLINE Var(const _NoInit&) : Operand(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [Var Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone `Var` operand.
+ ASMJIT_INLINE Var clone() const {
+ return Var(*this);
+ }
+
+ //! Reset Var operand.
+ ASMJIT_INLINE void reset() {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeVar, 0, kInvalidReg, kInvalidReg, kInvalidValue);
+ _init_packed_d2_d3(kInvalidValue, kInvalidValue);
+ }
+
+ //! Get whether the variable has been initialized by `Compiler`.
+ ASMJIT_INLINE bool isInitialized() const {
+ return _vreg.id != kInvalidValue;
+ }
+
+ //! Get variable type.
+ ASMJIT_INLINE uint32_t getVarType() const {
+ return _vreg.vType;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Var& operator=(const Var& other) { _copy(other); return *this; }
+
+ ASMJIT_INLINE bool operator==(const Var& other) const { return _packed[0] == other._packed[0]; }
+ ASMJIT_INLINE bool operator!=(const Var& other) const { return !operator==(other); }
+};
+
+// ============================================================================
+// [asmjit::VarBits]
+// ============================================================================
+
+//! Bit-array used by variable-liveness analysis.
+struct VarBits {
+ // --------------------------------------------------------------------------
+ // [Enums]
+ // --------------------------------------------------------------------------
+
+ enum {
+ kEntitySize = static_cast<int>(sizeof(uintptr_t)),
+ kEntityBits = kEntitySize * 8
+ };
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE uintptr_t getBit(uint32_t index) const {
+ return (data[index / kEntityBits] >> (index % kEntityBits)) & 1;
+ }
+
+ ASMJIT_INLINE void setBit(uint32_t index) {
+ data[index / kEntityBits] |= static_cast<uintptr_t>(1) << (index % kEntityBits);
+ }
+
+ ASMJIT_INLINE void delBit(uint32_t index) {
+ data[index / kEntityBits] &= ~(static_cast<uintptr_t>(1) << (index % kEntityBits));
+ }
+
+ // --------------------------------------------------------------------------
+ // [Ops]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE bool copyBits(const VarBits* s0, uint32_t len) {
+ uintptr_t r = 0;
+ for (uint32_t i = 0; i < len; i++) {
+ uintptr_t t = s0->data[i];
+ data[i] = t;
+ r |= t;
+ }
+ return r != 0;
+ }
+
+ ASMJIT_INLINE bool addBits(const VarBits* s0, uint32_t len) {
+ return addBits(this, s0, len);
+ }
+
+ ASMJIT_INLINE bool addBits(const VarBits* s0, const VarBits* s1, uint32_t len) {
+ uintptr_t r = 0;
+ for (uint32_t i = 0; i < len; i++) {
+ uintptr_t t = s0->data[i] | s1->data[i];
+ data[i] = t;
+ r |= t;
+ }
+ return r != 0;
+ }
+
+ ASMJIT_INLINE bool andBits(const VarBits* s1, uint32_t len) {
+ return andBits(this, s1, len);
+ }
+
+ ASMJIT_INLINE bool andBits(const VarBits* s0, const VarBits* s1, uint32_t len) {
+ uintptr_t r = 0;
+ for (uint32_t i = 0; i < len; i++) {
+ uintptr_t t = s0->data[i] & s1->data[i];
+ data[i] = t;
+ r |= t;
+ }
+ return r != 0;
+ }
+
+ ASMJIT_INLINE bool delBits(const VarBits* s1, uint32_t len) {
+ return delBits(this, s1, len);
+ }
+
+ ASMJIT_INLINE bool delBits(const VarBits* s0, const VarBits* s1, uint32_t len) {
+ uintptr_t r = 0;
+ for (uint32_t i = 0; i < len; i++) {
+ uintptr_t t = s0->data[i] & ~s1->data[i];
+ data[i] = t;
+ r |= t;
+ }
+ return r != 0;
+ }
+
+ ASMJIT_INLINE bool _addBitsDelSource(VarBits* s1, uint32_t len) {
+ return _addBitsDelSource(this, s1, len);
+ }
+
+ ASMJIT_INLINE bool _addBitsDelSource(const VarBits* s0, VarBits* s1, uint32_t len) {
+ uintptr_t r = 0;
+ for (uint32_t i = 0; i < len; i++) {
+ uintptr_t a = s0->data[i];
+ uintptr_t b = s1->data[i];
+
+ this->data[i] = a | b;
+ b &= ~a;
+
+ s1->data[i] = b;
+ r |= b;
+ }
+ return r != 0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ uintptr_t data[1];
+};
+
+// ============================================================================
+// [asmjit::VarData]
+// ============================================================================
+
+//! Base variable data.
+struct VarData {
+ // --------------------------------------------------------------------------
+ // [Accessors - Base]
+ // --------------------------------------------------------------------------
+
+ //! Get variable name.
+ ASMJIT_INLINE const char* getName() const {
+ return _name;
+ }
+
+ //! Get variable id.
+ ASMJIT_INLINE uint32_t getId() const {
+ return _id;
+ }
+
+ //! Get variable type.
+ ASMJIT_INLINE uint32_t getType() const {
+ return _type;
+ }
+
+ //! Get variable class.
+ ASMJIT_INLINE uint32_t getClass() const {
+ return _class;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - ContextId]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the variable has context id.
+ ASMJIT_INLINE bool hasContextId() const {
+ return _contextId != kInvalidValue;
+ }
+
+ //! Get context variable id (used only by `Context)`.
+ ASMJIT_INLINE uint32_t getContextId() const {
+ return _contextId;
+ }
+
+ //! Set context variable id (used only by `Context)`.
+ ASMJIT_INLINE void setContextId(uint32_t contextId) {
+ _contextId = contextId;
+ }
+
+ //! Reset context variable id (used only by `Context)`.
+ ASMJIT_INLINE void resetContextId() {
+ _contextId = kInvalidValue;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Priority]
+ // --------------------------------------------------------------------------
+
+ //! Get variable priority, used by compiler to decide which variable to spill.
+ ASMJIT_INLINE uint32_t getPriority() const {
+ return _priority;
+ }
+
+ //! Set variable priority.
+ ASMJIT_INLINE void setPriority(uint32_t priority) {
+ ASMJIT_ASSERT(priority <= 0xFF);
+ _priority = static_cast<uint8_t>(priority);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - State]
+ // --------------------------------------------------------------------------
+
+ //! Get variable state, only used by `Context`.
+ ASMJIT_INLINE uint32_t getState() const {
+ return _state;
+ }
+
+ //! Set variable state, only used by `Context`.
+ ASMJIT_INLINE void setState(uint32_t state) {
+ ASMJIT_ASSERT(state <= 0xFF);
+ _state = static_cast<uint8_t>(state);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - RegIndex]
+ // --------------------------------------------------------------------------
+
+ //! Get register index.
+ ASMJIT_INLINE uint32_t getRegIndex() const {
+ return _regIndex;
+ }
+
+ //! Set register index.
+ ASMJIT_INLINE void setRegIndex(uint32_t regIndex) {
+ ASMJIT_ASSERT(regIndex <= 0xFF);
+ _regIndex = static_cast<uint8_t>(regIndex);
+ }
+
+ //! Reset register index.
+ ASMJIT_INLINE void resetRegIndex() {
+ _regIndex = static_cast<uint8_t>(kInvalidReg);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - HomeIndex/Mask]
+ // --------------------------------------------------------------------------
+
+ //! Get home registers mask.
+ ASMJIT_INLINE uint32_t getHomeMask() const {
+ return _homeMask;
+ }
+
+ //! Add a home register index to the home registers mask.
+ ASMJIT_INLINE void addHomeIndex(uint32_t regIndex) {
+ _homeMask |= IntUtil::mask(regIndex);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Flags]
+ // --------------------------------------------------------------------------
+
+ //! Get variable flags.
+ ASMJIT_INLINE uint32_t getFlags() const {
+ return _flags;
+ }
+
+ //! Get whether the VarData is only memory allocated on the stack.
+ ASMJIT_INLINE bool isStack() const { return static_cast<bool>(_isStack); }
+
+ //! Get whether the variable is a function argument passed through memory.
+ ASMJIT_INLINE bool isMemArg() const { return static_cast<bool>(_isMemArg); }
+
+ //! Get variable content can be calculated by a simple instruction.
+ ASMJIT_INLINE bool isCalculated() const { return static_cast<bool>(_isCalculated); }
+ //! Get whether to save variable when it's unused (spill).
+ ASMJIT_INLINE bool saveOnUnuse() const { return static_cast<bool>(_saveOnUnuse); }
+
+ //! Get whether the variable was changed.
+ ASMJIT_INLINE bool isModified() const { return static_cast<bool>(_modified); }
+ //! Set whether the variable was changed.
+ ASMJIT_INLINE void setModified(bool modified) { _modified = modified; }
+
+ //! Get variable alignment.
+ ASMJIT_INLINE uint32_t getAlignment() const { return _alignment; }
+ //! Get variable size.
+ ASMJIT_INLINE uint32_t getSize() const { return _size; }
+
+ //! Get home memory offset.
+ ASMJIT_INLINE int32_t getMemOffset() const { return _memOffset; }
+ //! Set home memory offset.
+ ASMJIT_INLINE void setMemOffset(int32_t offset) { _memOffset = offset; }
+
+ //! Get home memory cell.
+ ASMJIT_INLINE MemCell* getMemCell() const { return _memCell; }
+ //! Set home memory cell.
+ ASMJIT_INLINE void setMemCell(MemCell* cell) { _memCell = cell; }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Temporary Usage]
+ // --------------------------------------------------------------------------
+
+ //! Get temporary VarAttr.
+ ASMJIT_INLINE VarAttr* getVa() const { return _va; }
+ //! Set temporary VarAttr.
+ ASMJIT_INLINE void setVa(VarAttr* va) { _va = va; }
+ //! Reset temporary VarAttr.
+ ASMJIT_INLINE void resetVa() { _va = nullptr; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Variable name.
+ const char* _name;
+
+ //! Variable id.
+ uint32_t _id;
+ //! Context variable id, used by `Context` only, initially `kInvalidValue`.
+ uint32_t _contextId;
+
+ //! Variable type.
+ uint8_t _type;
+ //! Variable class.
+ uint8_t _class;
+ //! Variable flags.
+ uint8_t _flags;
+ //! Variable priority.
+ uint8_t _priority;
+
+ //! Variable state (connected with actual `VarState)`.
+ uint8_t _state;
+ //! Actual register index (only used by `Context)`, during translate.
+ uint8_t _regIndex;
+
+ //! Whether the variable is only used as memory allocated on the stack.
+ uint8_t _isStack : 1;
+ //! Whether the variable is a function argument passed through memory.
+ uint8_t _isMemArg : 1;
+ //! Whether variable content can be calculated by a simple instruction.
+ //!
+ //! This is used mainly by MMX and SSE2 code. This flag indicates that
+ //! register allocator should never reserve memory for this variable, because
+ //! the content can be generated by a single instruction (for example PXOR).
+ uint8_t _isCalculated : 1;
+ //! Save on unuse (at end of the variable scope).
+ uint8_t _saveOnUnuse : 1;
+ //! Whether variable was changed (connected with actual `VarState)`.
+ uint8_t _modified : 1;
+ //! \internal
+ uint8_t _reserved0 : 3;
+ //! Variable natural alignment.
+ uint8_t _alignment;
+
+ //! Variable size.
+ uint32_t _size;
+
+ //! Mask of all registers variable has been allocated to.
+ uint32_t _homeMask;
+
+ //! Home memory offset.
+ int32_t _memOffset;
+ //! Home memory cell, used by `Context` (initially NULL).
+ MemCell* _memCell;
+
+ //! Register read access statistics.
+ uint32_t rReadCount;
+ //! Register write access statistics.
+ uint32_t rWriteCount;
+
+ //! Memory read statistics.
+ uint32_t mReadCount;
+ //! Memory write statistics.
+ uint32_t mWriteCount;
+
+ // --------------------------------------------------------------------------
+ // [Members - Temporary Usage]
+ // --------------------------------------------------------------------------
+
+ // These variables are only used during register allocation. They are
+ // initialized by init() phase and reset by cleanup() phase.
+
+ union {
+ //! Temporary link to VarAttr* used by the `Context` used in
+ //! various phases, but always set back to NULL when finished.
+ //!
+ //! This temporary data is designed to be used by algorithms that need to
+ //! store some data into variables themselves during compilation. But it's
+ //! expected that after variable is compiled & translated the data is set
+ //! back to zero/null. Initial value is NULL.
+ VarAttr* _va;
+
+ //! \internal
+ //!
+ //! Same as `_va` just provided as `uintptr_t`.
+ uintptr_t _vaUInt;
+ };
+};
+
+// ============================================================================
+// [asmjit::VarAttr]
+// ============================================================================
+
+struct VarAttr {
+ // --------------------------------------------------------------------------
+ // [Setup]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void setup(VarData* vd, uint32_t flags = 0, uint32_t inRegs = 0, uint32_t allocableRegs = 0) {
+ _vd = vd;
+ _flags = flags;
+ _varCount = 0;
+ _inRegIndex = kInvalidReg;
+ _outRegIndex = kInvalidReg;
+ _reserved = 0;
+ _inRegs = inRegs;
+ _allocableRegs = allocableRegs;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get VarData.
+ ASMJIT_INLINE VarData* getVd() const { return _vd; }
+ //! Set VarData.
+ ASMJIT_INLINE void setVd(VarData* vd) { _vd = vd; }
+
+ //! Get flags.
+ ASMJIT_INLINE uint32_t getFlags() const { return _flags; }
+ //! Set flags.
+ ASMJIT_INLINE void setFlags(uint32_t flags) { _flags = flags; }
+
+ //! Get whether `flag` is on.
+ ASMJIT_INLINE bool hasFlag(uint32_t flag) { return (_flags & flag) != 0; }
+ //! Add `flags`.
+ ASMJIT_INLINE void addFlags(uint32_t flags) { _flags |= flags; }
+ //! Mask `flags`.
+ ASMJIT_INLINE void andFlags(uint32_t flags) { _flags &= flags; }
+ //! Clear `flags`.
+ ASMJIT_INLINE void delFlags(uint32_t flags) { _flags &= ~flags; }
+
+ //! Get how many times the variable is used by the instruction/node.
+ ASMJIT_INLINE uint32_t getVarCount() const { return _varCount; }
+ //! Set how many times the variable is used by the instruction/node.
+ ASMJIT_INLINE void setVarCount(uint32_t count) { _varCount = static_cast<uint8_t>(count); }
+ //! Add how many times the variable is used by the instruction/node.
+ ASMJIT_INLINE void addVarCount(uint32_t count = 1) { _varCount += static_cast<uint8_t>(count); }
+
+ //! Get whether the variable has to be allocated in a specific input register.
+ ASMJIT_INLINE uint32_t hasInRegIndex() const { return _inRegIndex != kInvalidReg; }
+ //! Get the input register index or `kInvalidReg`.
+ ASMJIT_INLINE uint32_t getInRegIndex() const { return _inRegIndex; }
+ //! Set the input register index.
+ ASMJIT_INLINE void setInRegIndex(uint32_t index) { _inRegIndex = static_cast<uint8_t>(index); }
+ //! Reset the input register index.
+ ASMJIT_INLINE void resetInRegIndex() { _inRegIndex = kInvalidReg; }
+
+ //! Get whether the variable has to be allocated in a specific output register.
+ ASMJIT_INLINE uint32_t hasOutRegIndex() const { return _outRegIndex != kInvalidReg; }
+ //! Get the output register index or `kInvalidReg`.
+ ASMJIT_INLINE uint32_t getOutRegIndex() const { return _outRegIndex; }
+ //! Set the output register index.
+ ASMJIT_INLINE void setOutRegIndex(uint32_t index) { _outRegIndex = static_cast<uint8_t>(index); }
+ //! Reset the output register index.
+ ASMJIT_INLINE void resetOutRegIndex() { _outRegIndex = kInvalidReg; }
+
+ //! Get whether the mandatory input registers are in used.
+ ASMJIT_INLINE bool hasInRegs() const { return _inRegs != 0; }
+ //! Get mandatory input registers (mask).
+ ASMJIT_INLINE uint32_t getInRegs() const { return _inRegs; }
+ //! Set mandatory input registers (mask).
+ ASMJIT_INLINE void setInRegs(uint32_t mask) { _inRegs = mask; }
+ //! Add mandatory input registers (mask).
+ ASMJIT_INLINE void addInRegs(uint32_t mask) { _inRegs |= mask; }
+ //! And mandatory input registers (mask).
+ ASMJIT_INLINE void andInRegs(uint32_t mask) { _inRegs &= mask; }
+ //! Clear mandatory input registers (mask).
+ ASMJIT_INLINE void delInRegs(uint32_t mask) { _inRegs &= ~mask; }
+
+ //! Get allocable input registers (mask).
+ ASMJIT_INLINE uint32_t getAllocableRegs() const { return _allocableRegs; }
+ //! Set allocable input registers (mask).
+ ASMJIT_INLINE void setAllocableRegs(uint32_t mask) { _allocableRegs = mask; }
+ //! Add allocable input registers (mask).
+ ASMJIT_INLINE void addAllocableRegs(uint32_t mask) { _allocableRegs |= mask; }
+ //! And allocable input registers (mask).
+ ASMJIT_INLINE void andAllocableRegs(uint32_t mask) { _allocableRegs &= mask; }
+ //! Clear allocable input registers (mask).
+ ASMJIT_INLINE void delAllocableRegs(uint32_t mask) { _allocableRegs &= ~mask; }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE VarAttr& operator=(const VarAttr& other) {
+ ::memcpy(this, &other, sizeof(VarAttr));
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ VarData* _vd;
+ //! Flags.
+ uint32_t _flags;
+
+ union {
+ struct {
+ //! How many times the variable is used by the instruction/node.
+ uint8_t _varCount;
+ //! Input register index or `kInvalidReg` if it's not given.
+ //!
+ //! Even if the input register index is not given (i.e. it may by any
+ //! register), register allocator should assign an index that will be
+ //! used to persist a variable into this specific index. It's helpful
+ //! in situations where one variable has to be allocated in multiple
+ //! registers to determine the register which will be persistent.
+ uint8_t _inRegIndex;
+ //! Output register index or `kInvalidReg` if it's not given.
+ //!
+ //! Typically `kInvalidReg` if variable is only used on input.
+ uint8_t _outRegIndex;
+ //! \internal
+ uint8_t _reserved;
+ };
+
+ //! \internal
+ //!
+ //! Packed data #0.
+ uint32_t _packed;
+ };
+
+ //! Mandatory input registers.
+ //!
+ //! Mandatory input registers are required by the instruction even if
+ //! there are duplicates. This schema allows us to allocate one variable
+ //! in one or more register when needed. Required mostly by instructions
+ //! that have implicit register operands (imul, cpuid, ...) and function
+ //! call.
+ uint32_t _inRegs;
+
+ //! Allocable input registers.
+ //!
+ //! Optional input registers is a mask of all allocable registers for a given
+ //! variable where we have to pick one of them. This mask is usually not used
+ //! when _inRegs is set. If both masks are used then the register
+ //! allocator tries first to find an intersection between these and allocates
+ //! an extra slot if not found.
+ uint32_t _allocableRegs;
+};
+
+// ============================================================================
+// [asmjit::VarMap]
+// ============================================================================
+
+//! Variables' map related to a single node (instruction / other node).
+struct VarMap {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get count of variables (all).
+ ASMJIT_INLINE uint32_t getVaCount() const {
+ return _vaCount;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Variables count.
+ uint32_t _vaCount;
+};
+
+// ============================================================================
+// [asmjit::VarState]
+// ============================================================================
+
+//! Variables' state.
+struct VarState {};
+
+// ============================================================================
+// [asmjit::TypeId / VarMapping]
+// ============================================================================
+
+//! Function builder 'void' type.
+struct Void {};
+
+//! Function builder 'int8_t' type.
+struct Int8Type {};
+//! Function builder 'uint8_t' type.
+struct UInt8Type {};
+
+//! Function builder 'int16_t' type.
+struct Int16Type {};
+//! Function builder 'uint16_t' type.
+struct UInt16Type {};
+
+//! Function builder 'int32_t' type.
+struct Int32Type {};
+//! Function builder 'uint32_t' type.
+struct UInt32Type {};
+
+//! Function builder 'int64_t' type.
+struct Int64Type {};
+//! Function builder 'uint64_t' type.
+struct UInt64Type {};
+
+//! Function builder 'intptr_t' type.
+struct IntPtrType {};
+//! Function builder 'uintptr_t' type.
+struct UIntPtrType {};
+
+//! Function builder 'float' type.
+struct FloatType {};
+//! Function builder 'double' type.
+struct DoubleType {};
+
+#ifndef ASMJIT_DOCGEN
+template<typename T>
+struct TypeId {
+ enum { kId = static_cast<int>(::asmjit::kInvalidVar) };
+};
+
+template<typename T>
+struct TypeId<T*> {
+ enum { kId = kVarTypeIntPtr };
+};
+
+#define ASMJIT_TYPE_ID(_T_, _Id_) \
+ template<> \
+ struct TypeId<_T_> { enum { kId = _Id_ }; }
+
+ASMJIT_TYPE_ID(void, kInvalidVar);
+ASMJIT_TYPE_ID(Void, kInvalidVar);
+
+ASMJIT_TYPE_ID(int8_t, kVarTypeInt8);
+ASMJIT_TYPE_ID(Int8Type, kVarTypeInt8);
+
+ASMJIT_TYPE_ID(uint8_t, kVarTypeUInt8);
+ASMJIT_TYPE_ID(UInt8Type, kVarTypeUInt8);
+
+ASMJIT_TYPE_ID(int16_t, kVarTypeInt16);
+ASMJIT_TYPE_ID(Int16Type, kVarTypeInt16);
+
+ASMJIT_TYPE_ID(uint16_t, kVarTypeUInt8);
+ASMJIT_TYPE_ID(UInt16Type, kVarTypeUInt8);
+
+ASMJIT_TYPE_ID(int32_t, kVarTypeInt32);
+ASMJIT_TYPE_ID(Int32Type, kVarTypeUInt8);
+
+ASMJIT_TYPE_ID(uint32_t, kVarTypeUInt32);
+ASMJIT_TYPE_ID(UInt32Type, kVarTypeUInt8);
+
+ASMJIT_TYPE_ID(int64_t, kVarTypeInt64);
+ASMJIT_TYPE_ID(Int64Type, kVarTypeUInt8);
+
+ASMJIT_TYPE_ID(uint64_t, kVarTypeUInt64);
+ASMJIT_TYPE_ID(UInt64Type, kVarTypeUInt8);
+
+ASMJIT_TYPE_ID(float, kVarTypeFp32);
+ASMJIT_TYPE_ID(FloatType, kVarTypeFp32);
+
+ASMJIT_TYPE_ID(double, kVarTypeFp64);
+ASMJIT_TYPE_ID(DoubleType, kVarTypeFp64);
+#endif // !ASMJIT_DOCGEN
+
+// ============================================================================
+// [asmjit::FuncInOut]
+// ============================================================================
+
+//! Function in/out - argument or return value translated from `FuncPrototype`.
+struct FuncInOut {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE uint32_t getVarType() const { return _varType; }
+
+ ASMJIT_INLINE bool hasRegIndex() const { return _regIndex != kInvalidReg; }
+ ASMJIT_INLINE uint32_t getRegIndex() const { return _regIndex; }
+
+ ASMJIT_INLINE bool hasStackOffset() const { return _stackOffset != kFuncStackInvalid; }
+ ASMJIT_INLINE int32_t getStackOffset() const { return static_cast<int32_t>(_stackOffset); }
+
+ //! Get whether the argument / return value is assigned.
+ ASMJIT_INLINE bool isSet() const {
+ return (_regIndex != kInvalidReg) | (_stackOffset != kFuncStackInvalid);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ //! Reset the function argument to "unassigned state".
+ ASMJIT_INLINE void reset() { _packed = 0xFFFFFFFF; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ union {
+ struct {
+ //! Variable type, see `kVarType`.
+ uint8_t _varType;
+ //! Register index if argument / return value is a register.
+ uint8_t _regIndex;
+ //! Stack offset if argument / return value is on the stack.
+ int16_t _stackOffset;
+ };
+
+ //! All members packed into single 32-bit integer.
+ uint32_t _packed;
+ };
+};
+
+// ============================================================================
+// [asmjit::FuncPrototype]
+// ============================================================================
+
+//! Function prototype.
+//!
+//! Function prototype contains information about function return type, count
+//! of arguments and their types. Function prototype is a low level structure
+//! which doesn't contain platform specific or calling convention specific
+//! information. Function prototype is used to create a `FuncDecl`.
+struct FuncPrototype {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get function return value.
+ ASMJIT_INLINE uint32_t getRet() const { return _ret; }
+
+ //! Get function arguments' IDs.
+ ASMJIT_INLINE const uint32_t* getArgList() const { return _argList; }
+ //! Get count of function arguments.
+ ASMJIT_INLINE uint32_t getArgCount() const { return _argCount; }
+
+ //! Get argument at index `id`.
+ ASMJIT_INLINE uint32_t getArg(uint32_t id) const {
+ ASMJIT_ASSERT(id < _argCount);
+ return _argList[id];
+ }
+
+ //! Set function definition - return type and arguments.
+ ASMJIT_INLINE void _setPrototype(uint32_t ret, const uint32_t* argList, uint32_t argCount) {
+ _ret = ret;
+ _argList = argList;
+ _argCount = argCount;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ uint32_t _ret;
+ uint32_t _argCount;
+ const uint32_t* _argList;
+};
+
+// ============================================================================
+// [asmjit::FuncBuilderX]
+// ============================================================================
+
+//! Custom function builder for up to 32 function arguments.
+struct FuncBuilderX : public FuncPrototype {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE FuncBuilderX() {
+ _setPrototype(kInvalidVar, _builderArgList, 0);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Set return type to `retType`.
+ ASMJIT_INLINE void setRet(uint32_t retType) {
+ _ret = retType;
+ }
+
+ ASMJIT_INLINE void setArg(uint32_t id, uint32_t type) {
+ ASMJIT_ASSERT(id < _argCount);
+ _builderArgList[id] = type;
+ }
+
+ ASMJIT_INLINE void addArg(uint32_t type) {
+ ASMJIT_ASSERT(_argCount < kFuncArgCount);
+ _builderArgList[_argCount++] = type;
+ }
+
+ template<typename T>
+ ASMJIT_INLINE void setRetT() {
+ setRet(TypeId<T>::kId);
+ }
+
+ template<typename T>
+ ASMJIT_INLINE void setArgT(uint32_t id) {
+ setArg(id, TypeId<T>::kId);
+ }
+
+ template<typename T>
+ ASMJIT_INLINE void addArgT() {
+ addArg(TypeId<T>::kId);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ uint32_t _builderArgList[kFuncArgCount];
+};
+
+//! \internal
+#define T(_Type_) TypeId<_Type_>::kId
+
+//! Function prototype (no args).
+template<typename RET>
+struct FuncBuilder0 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder0() {
+ _setPrototype(T(RET), nullptr, 0);
+ }
+};
+
+//! Function prototype (1 argument).
+template<typename RET, typename P0>
+struct FuncBuilder1 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder1() {
+ static const uint32_t args[] = { T(P0) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (2 arguments).
+template<typename RET, typename P0, typename P1>
+struct FuncBuilder2 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder2() {
+ static const uint32_t args[] = { T(P0), T(P1) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (3 arguments).
+template<typename RET, typename P0, typename P1, typename P2>
+struct FuncBuilder3 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder3() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (4 arguments).
+template<typename RET, typename P0, typename P1, typename P2, typename P3>
+struct FuncBuilder4 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder4() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (5 arguments).
+template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4>
+struct FuncBuilder5 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder5() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (6 arguments).
+template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
+struct FuncBuilder6 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder6() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (7 arguments).
+template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
+struct FuncBuilder7 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder7() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (8 arguments).
+template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
+struct FuncBuilder8 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder8() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6), T(P7) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (9 arguments).
+template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
+struct FuncBuilder9 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder9() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6), T(P7), T(P8) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (10 arguments).
+template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
+struct FuncBuilder10 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder10() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6), T(P7), T(P8), T(P9) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+#undef T
+
+// ============================================================================
+// [asmjit::FuncDecl]
+// ============================================================================
+
+//! Function declaration.
+struct FuncDecl {
+ // --------------------------------------------------------------------------
+ // [Accessors - Calling Convention]
+ // --------------------------------------------------------------------------
+
+ //! Get function calling convention, see `kFuncConv`.
+ ASMJIT_INLINE uint32_t getConvention() const { return _convention; }
+
+ //! Get whether the callee pops the stack.
+ ASMJIT_INLINE uint32_t getCalleePopsStack() const { return _calleePopsStack; }
+
+ //! Get direction of arguments passed on the stack.
+ //!
+ //! Direction should be always `kFuncDirRtl`.
+ //!
+ //! \note This is related to used calling convention, it's not affected by
+ //! number of function arguments or their types.
+ ASMJIT_INLINE uint32_t getDirection() const { return _direction; }
+
+ //! Get stack size needed for function arguments passed on the stack.
+ ASMJIT_INLINE uint32_t getArgStackSize() const { return _argStackSize; }
+ //! Get size of "Red Zone".
+ ASMJIT_INLINE uint32_t getRedZoneSize() const { return _redZoneSize; }
+ //! Get size of "Spill Zone".
+ ASMJIT_INLINE uint32_t getSpillZoneSize() const { return _spillZoneSize; }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Arguments and Return]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the function has a return value.
+ ASMJIT_INLINE bool hasRet() const { return _retCount != 0; }
+ //! Get count of function return values.
+ ASMJIT_INLINE uint32_t getRetCount() const { return _retCount; }
+
+ //! Get function return value.
+ ASMJIT_INLINE FuncInOut& getRet(uint32_t index = kFuncRetLo) { return _retList[index]; }
+ //! Get function return value.
+ ASMJIT_INLINE const FuncInOut& getRet(uint32_t index = kFuncRetLo) const { return _retList[index]; }
+
+ //! Get count of function arguments.
+ ASMJIT_INLINE uint32_t getArgCount() const { return _argCount; }
+
+ //! Get function arguments array.
+ ASMJIT_INLINE FuncInOut* getArgList() { return _argList; }
+ //! Get function arguments array (const).
+ ASMJIT_INLINE const FuncInOut* getArgList() const { return _argList; }
+
+ //! Get function argument at index `index`.
+ ASMJIT_INLINE FuncInOut& getArg(size_t index) {
+ ASMJIT_ASSERT(index < kFuncArgCountLoHi);
+ return _argList[index];
+ }
+
+ //! Get function argument at index `index`.
+ ASMJIT_INLINE const FuncInOut& getArg(size_t index) const {
+ ASMJIT_ASSERT(index < kFuncArgCountLoHi);
+ return _argList[index];
+ }
+
+ ASMJIT_INLINE void resetArg(size_t index) {
+ ASMJIT_ASSERT(index < kFuncArgCountLoHi);
+ _argList[index].reset();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Calling convention.
+ uint8_t _convention;
+ //! Whether a callee pops stack.
+ uint8_t _calleePopsStack : 1;
+ //! Direction for arguments passed on the stack, see `kFuncDir`.
+ uint8_t _direction : 1;
+ //! Reserved #0 (alignment).
+ uint8_t _reserved0 : 6;
+
+ //! Count of arguments in `_argList`.
+ uint8_t _argCount;
+ //! Count of return value(s).
+ uint8_t _retCount;
+
+ //! Count of bytes consumed by arguments on the stack (aligned).
+ uint32_t _argStackSize;
+
+ //! Size of "Red Zone".
+ //!
+ //! \note Used by AMD64-ABI (128 bytes).
+ uint16_t _redZoneSize;
+
+ //! Size of "Spill Zone".
+ //!
+ //! \note Used by WIN64-ABI (32 bytes).
+ uint16_t _spillZoneSize;
+
+ //! Function arguments (including HI arguments) mapped to physical
+ //! registers and stack offset.
+ FuncInOut _argList[kFuncArgCountLoHi];
+
+ //! Function return value(s).
+ FuncInOut _retList[2];
+};
+
+// ============================================================================
+// [asmjit::Node]
+// ============================================================================
+
+//! Base node.
+//!
+//! `Every` node represents an abstract instruction, directive, label, or
+//! macro-instruction generated by compiler.
+struct Node {
+ ASMJIT_NO_COPY(Node)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create new `Node`.
+ //!
+ //! \note Always use compiler to create nodes.
+ ASMJIT_INLINE Node(Compiler* compiler, uint32_t type); // Defined-Later.
+
+ //! Destroy `Node`.
+ ASMJIT_INLINE ~Node() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors - List]
+ // --------------------------------------------------------------------------
+
+ //! Get previous node in the compiler stream.
+ ASMJIT_INLINE Node* getPrev() const {
+ return _prev;
+ }
+
+ //! Get next node in the compiler stream.
+ ASMJIT_INLINE Node* getNext() const {
+ return _next;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Comment]
+ // --------------------------------------------------------------------------
+
+ //! Get comment string.
+ ASMJIT_INLINE const char* getComment() const {
+ return _comment;
+ }
+
+ //! Set comment string to `str`.
+ ASMJIT_INLINE void setComment(const char* comment) {
+ _comment = comment;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Type and Flags]
+ // --------------------------------------------------------------------------
+
+ //! Get type of node, see `kNodeType`.
+ ASMJIT_INLINE uint32_t getType() const {
+ return _type;
+ }
+
+ //! Get node flags.
+ ASMJIT_INLINE uint32_t getFlags() const {
+ return _flags;
+ }
+
+ //! Set node flags to `flags`.
+ ASMJIT_INLINE void setFlags(uint32_t flags) {
+ _flags = static_cast<uint16_t>(flags);
+ }
+
+ //! Get whether the instruction has flag `flag`.
+ ASMJIT_INLINE bool hasFlag(uint32_t flag) const {
+ return (static_cast<uint32_t>(_flags) & flag) != 0;
+ }
+
+ //! Add instruction `flags`.
+ ASMJIT_INLINE void addFlags(uint32_t flags) {
+ _flags |= static_cast<uint16_t>(flags);
+ }
+
+ //! Clear instruction `flags`.
+ ASMJIT_INLINE void delFlags(uint32_t flags) {
+ _flags &= static_cast<uint16_t>(~flags);
+ }
+
+ //! Get whether the node has beed fetched.
+ ASMJIT_INLINE bool isFetched() const {
+ return _flowId != 0;
+ }
+
+ //! Get whether the node has been translated.
+ ASMJIT_INLINE bool isTranslated() const {
+ return hasFlag(kNodeFlagIsTranslated);
+ }
+
+ //! Get whether the node has been translated.
+ ASMJIT_INLINE bool isScheduled() const {
+ return hasFlag(kNodeFlagIsScheduled);
+ }
+
+ //! Get whether the node is informative only and can be safely removed after
+ //! translation.
+ //!
+ //! Informative nodes are comments and hints.
+ ASMJIT_INLINE bool isInformative() const {
+ return hasFlag(kNodeFlagIsInformative);
+ }
+
+ //! Whether the instruction is an unconditional jump.
+ ASMJIT_INLINE bool isJmp() const { return hasFlag(kNodeFlagIsJmp); }
+ //! Whether the instruction is a conditional jump.
+ ASMJIT_INLINE bool isJcc() const { return hasFlag(kNodeFlagIsJcc); }
+ //! Whether the instruction is an unconditional or conditional jump.
+ ASMJIT_INLINE bool isJmpOrJcc() const { return hasFlag(kNodeFlagIsJmp | kNodeFlagIsJcc); }
+ //! Whether the instruction is a return.
+ ASMJIT_INLINE bool isRet() const { return hasFlag(kNodeFlagIsRet); }
+
+ //! Get whether the instruction is special.
+ ASMJIT_INLINE bool isSpecial() const { return hasFlag(kNodeFlagIsSpecial); }
+ //! Get whether the instruction accesses FPU.
+ ASMJIT_INLINE bool isFp() const { return hasFlag(kNodeFlagIsFp); }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - FlowId]
+ // --------------------------------------------------------------------------
+
+ //! Get flow index.
+ ASMJIT_INLINE uint32_t getFlowId() const { return _flowId; }
+ //! Set flow index.
+ ASMJIT_INLINE void setFlowId(uint32_t flowId) { _flowId = flowId; }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - VarMap]
+ // --------------------------------------------------------------------------
+
+ //! Get whether node contains variable allocation instructions.
+ ASMJIT_INLINE bool hasMap() const {
+ return !!_map;
+ }
+
+ //! Get variable allocation instructions.
+ ASMJIT_INLINE VarMap* getMap() const {
+ return _map;
+ }
+
+ //! Get variable allocation instructions casted to `T*`.
+ template<typename T>
+ ASMJIT_INLINE T* getMap() const {
+ return static_cast<T*>(_map);
+ }
+
+ //! Set variable allocation instructions.
+ ASMJIT_INLINE void setMap(VarMap* map) {
+ _map = map;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - VarState]
+ // --------------------------------------------------------------------------
+
+ //! Get node state.
+ ASMJIT_INLINE VarState* getState() const {
+ return _state;
+ }
+
+ //! Get node state casted to `T*`.
+ template<typename T>
+ ASMJIT_INLINE T* getState() const {
+ return static_cast<VarState*>(_state);
+ }
+
+ //! Set node state.
+ ASMJIT_INLINE void setState(VarState* state) {
+ _state = state;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Liveness]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the node has variable liveness bits.
+ ASMJIT_INLINE bool hasLiveness() const {
+ return !!_liveness;
+ }
+
+ //! Get variable liveness bits.
+ ASMJIT_INLINE VarBits* getLiveness() const {
+ return _liveness;
+ }
+
+ //! Set variable liveness bits.
+ ASMJIT_INLINE void setLiveness(VarBits* liveness) {
+ _liveness = liveness;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Previous node.
+ Node* _prev;
+ //! Next node.
+ Node* _next;
+
+ //! Node type, see `kNodeType`.
+ uint8_t _type;
+ //! Operands count (if the node has operands, otherwise zero).
+ uint8_t _opCount;
+ //! Node flags, different meaning for every node type.
+ uint16_t _flags;
+
+ //! Flow index.
+ uint32_t _flowId;
+
+ //! Inline comment string, initially set to NULL.
+ const char* _comment;
+
+ //! Variable mapping (VarAttr to VarData), initially NULL, filled during
+ //! fetch phase.
+ VarMap* _map;
+
+ //! Variable liveness bits (initially NULL, filled by analysis phase).
+ VarBits* _liveness;
+
+ //! Saved state.
+ //!
+ //! Initially NULL, not all nodes have saved state, only branch/flow control
+ //! nodes.
+ VarState* _state;
+};
+
+// ============================================================================
+// [asmjit::AlignNode]
+// ============================================================================
+
+//! Align node.
+struct AlignNode : public Node {
+ ASMJIT_NO_COPY(AlignNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `AlignNode` instance.
+ ASMJIT_INLINE AlignNode(Compiler* compiler, uint32_t mode, uint32_t offset) :
+ Node(compiler, kNodeTypeAlign) {
+
+ _mode = mode;
+ _offset = offset;
+ }
+
+ //! Destroy the `AlignNode` instance.
+ ASMJIT_INLINE ~AlignNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get alignment mode.
+ ASMJIT_INLINE uint32_t getMode() const {
+ return _mode;
+ }
+
+ //! Set alignment mode.
+ ASMJIT_INLINE void setMode(uint32_t mode) {
+ _mode = mode;
+ }
+
+ //! Get align offset in bytes.
+ ASMJIT_INLINE uint32_t getOffset() const {
+ return _offset;
+ }
+
+ //! Set align offset in bytes to `offset`.
+ ASMJIT_INLINE void setOffset(uint32_t offset) {
+ _offset = offset;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Alignment mode, see \ref kAlignMode.
+ uint32_t _mode;
+ //! Alignment offset in bytes.
+ uint32_t _offset;
+};
+
+// ============================================================================
+// [asmjit::EmbedNode]
+// ============================================================================
+
+//! Embed node.
+//!
+//! Embed node is used to embed data into final assembler stream. The data is
+//! considered to be RAW; No analysis is performed on RAW data.
+struct EmbedNode : public Node {
+ ASMJIT_NO_COPY(EmbedNode)
+
+ // --------------------------------------------------------------------------
+ // [Enums]
+ // --------------------------------------------------------------------------
+
+ enum { kInlineBufferSize = 8 };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `EmbedNode` instance.
+ ASMJIT_INLINE EmbedNode(Compiler* compiler, void* data, uint32_t size) : Node(compiler, kNodeTypeEmbed) {
+ _size = size;
+ if (size <= kInlineBufferSize) {
+ if (data)
+ ::memcpy(_data.buf, data, size);
+ }
+ else {
+ _data.ptr = static_cast<uint8_t*>(data);
+ }
+ }
+
+ //! Destroy the `EmbedNode` instance.
+ ASMJIT_INLINE ~EmbedNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get pointer to data.
+ uint8_t* getData() { return getSize() <= kInlineBufferSize ? const_cast<uint8_t*>(_data.buf) : _data.ptr; }
+ //! Get size of data.
+ uint32_t getSize() const { return _size; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Size of the embedded data.
+ uint32_t _size;
+
+ union {
+ //! data buffer.
+ uint8_t buf[kInlineBufferSize];
+ //! Data buffer.
+ uint8_t* ptr;
+ } _data;
+};
+
+// ============================================================================
+// [asmjit::CommentNode]
+// ============================================================================
+
+//! Comment node.
+//!
+//! Comments allows to comment your assembler stream for better debugging
+//! and visualization. Comments are usually ignored in release builds unless
+//! the logger is present.
+struct CommentNode : public Node {
+ ASMJIT_NO_COPY(CommentNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `CommentNode` instance.
+ ASMJIT_INLINE CommentNode(Compiler* compiler, const char* comment) : Node(compiler, kNodeTypeComment) {
+ addFlags(kNodeFlagIsInformative);
+ _comment = comment;
+ }
+
+ //! Destroy the `CommentNode` instance.
+ ASMJIT_INLINE ~CommentNode() {}
+};
+
+// ============================================================================
+// [asmjit::HintNode]
+// ============================================================================
+
+//! Hint node.
+struct HintNode : public Node {
+ ASMJIT_NO_COPY(HintNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `HintNode` instance.
+ ASMJIT_INLINE HintNode(Compiler* compiler, VarData* vd, uint32_t hint, uint32_t value) : Node(compiler, kNodeTypeHint) {
+ addFlags(kNodeFlagIsInformative);
+ _vd = vd;
+ _hint = hint;
+ _value = value;
+ }
+
+ //! Destroy the `HintNode` instance.
+ ASMJIT_INLINE ~HintNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get variable.
+ ASMJIT_INLINE VarData* getVd() const { return _vd; }
+
+ //! Get hint it (see `kVarHint)`.
+ ASMJIT_INLINE uint32_t getHint() const{ return _hint; }
+ //! Set hint it (see `kVarHint)`.
+ ASMJIT_INLINE void setHint(uint32_t hint) { _hint = hint; }
+
+ //! Get hint value.
+ ASMJIT_INLINE uint32_t getValue() const { return _value; }
+ //! Set hint value.
+ ASMJIT_INLINE void setValue(uint32_t value) { _value = value; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Variable.
+ VarData* _vd;
+ //! Hint id.
+ uint32_t _hint;
+ //! Value.
+ uint32_t _value;
+};
+
+// ============================================================================
+// [asmjit::TargetNode]
+// ============================================================================
+
+//! label node.
+struct TargetNode : public Node {
+ ASMJIT_NO_COPY(TargetNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `TargetNode` instance.
+ ASMJIT_INLINE TargetNode(Compiler* compiler, uint32_t labelId) : Node(compiler, kNodeTypeTarget) {
+ _id = labelId;
+ _numRefs = 0;
+ _offset = -1;
+ _from = nullptr;
+ }
+
+ //! Destroy the `TargetNode` instance.
+ ASMJIT_INLINE ~TargetNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get target label.
+ ASMJIT_INLINE Label getLabel() const { return Label(_id); }
+ //! Get target label id.
+ ASMJIT_INLINE uint32_t getLabelId() const { return _id; }
+
+ //! Get first jmp instruction.
+ ASMJIT_INLINE JumpNode* getFrom() const { return _from; }
+
+ //! Get whether the node has assigned state.
+ ASMJIT_INLINE bool hasState() const { return !!_state; }
+ //! Get state for this target.
+ ASMJIT_INLINE VarState* getState() const { return _state; }
+ //! Set state for this target.
+ ASMJIT_INLINE void setState(VarState* state) { _state = state; }
+
+ //! Get number of jumps to this target.
+ ASMJIT_INLINE uint32_t getNumRefs() const { return _numRefs; }
+ //! Set number of jumps to this target.
+ ASMJIT_INLINE void setNumRefs(uint32_t i) { _numRefs = i; }
+
+ //! Add number of jumps to this target.
+ ASMJIT_INLINE void addNumRefs(uint32_t i = 1) { _numRefs += i; }
+ //! Subtract number of jumps to this target.
+ ASMJIT_INLINE void subNumRefs(uint32_t i = 1) { _numRefs -= i; }
+
+ //! Get the label offset.
+ //!
+ //! \note Only valid after the content has been serialized to the `Assembler`.
+ ASMJIT_INLINE intptr_t getOffset() const { return _offset; }
+
+ //! Set the label offset.
+ ASMJIT_INLINE void setOffset(intptr_t offset) { _offset = offset; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Label id.
+ uint32_t _id;
+ //! Count of jumps here.
+ uint32_t _numRefs;
+
+ //! Label offset, after serialization.
+ intptr_t _offset;
+ //! First jump instruction that points to this target (label).
+ JumpNode* _from;
+};
+
+// ============================================================================
+// [asmjit::InstNode]
+// ============================================================================
+
+//! Instruction node.
+struct InstNode : public Node {
+ ASMJIT_NO_COPY(InstNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `InstNode` instance.
+ ASMJIT_INLINE InstNode(Compiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) : Node(compiler, kNodeTypeInst) {
+ _code = static_cast<uint16_t>(code);
+ _options = static_cast<uint8_t>(options);
+
+ _opCount = static_cast<uint8_t>(opCount);
+ _opList = opList;
+
+ _updateMemOp();
+ }
+
+ //! Destroy the `InstNode` instance.
+ ASMJIT_INLINE ~InstNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get instruction code, see `kX86InstId`.
+ ASMJIT_INLINE uint32_t getCode() const {
+ return _code;
+ }
+
+ //! Set instruction code to `code`.
+ //!
+ //! Please do not modify instruction code if you are not know what you are
+ //! doing. Incorrect instruction code or operands can raise assertion() at
+ //! runtime.
+ ASMJIT_INLINE void setCode(uint32_t code) {
+ _code = static_cast<uint16_t>(code);
+ }
+
+ //! Whether the instruction is an unconditional jump or whether the
+ //! instruction is a conditional jump which is likely to be taken.
+ ASMJIT_INLINE bool isTaken() const {
+ return hasFlag(kNodeFlagIsTaken);
+ }
+
+ //! Get emit options.
+ ASMJIT_INLINE uint32_t getOptions() const {
+ return _options;
+ }
+ //! Set emit options.
+ ASMJIT_INLINE void setOptions(uint32_t options) {
+ _options = static_cast<uint8_t>(options);
+ }
+ //! Add emit options.
+ ASMJIT_INLINE void addOptions(uint32_t options) {
+ _options |= static_cast<uint8_t>(options);
+ }
+ //! Mask emit options.
+ ASMJIT_INLINE void andOptions(uint32_t options) {
+ _options &= static_cast<uint8_t>(options);
+ }
+ //! Clear emit options.
+ ASMJIT_INLINE void delOptions(uint32_t options) {
+ _options &= static_cast<uint8_t>(~options);
+ }
+
+ //! Get operands list.
+ ASMJIT_INLINE Operand* getOpList() {
+ return _opList;
+ }
+ //! \overload
+ ASMJIT_INLINE const Operand* getOpList() const {
+ return _opList;
+ }
+
+ //! Get operands count.
+ ASMJIT_INLINE uint32_t getOpCount() const {
+ return _opCount;
+ }
+
+ //! Get whether the instruction contains a memory operand.
+ ASMJIT_INLINE bool hasMemOp() const {
+ return _memOpIndex != 0xFF;
+ }
+
+ //! Set memory operand index (in opList), 0xFF means that instruction
+ //! doesn't have a memory operand.
+ ASMJIT_INLINE void setMemOpIndex(uint32_t index) {
+ _memOpIndex = static_cast<uint8_t>(index);
+ }
+ //! Reset memory operand index, setting it to 0xFF.
+ ASMJIT_INLINE void resetMemOpIndex() {
+ _memOpIndex = 0xFF;
+ }
+
+ //! Get memory operand.
+ //!
+ //! Can only be called if the instruction has such operand, see `hasMemOp()`.
+ ASMJIT_INLINE BaseMem* getMemOp() const {
+ ASMJIT_ASSERT(hasMemOp());
+ return static_cast<BaseMem*>(&_opList[_memOpIndex]);
+ }
+
+ //! \overload
+ template<typename T>
+ ASMJIT_INLINE T* getMemOp() const {
+ ASMJIT_ASSERT(hasMemOp());
+ return static_cast<T*>(&_opList[_memOpIndex]);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Utils]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void _updateMemOp() {
+ Operand* opList = getOpList();
+ uint32_t opCount = getOpCount();
+
+ uint32_t i;
+ for (i = 0; i < opCount; i++)
+ if (opList[i].isMem())
+ goto _Update;
+ i = 0xFF;
+
+_Update:
+ setMemOpIndex(i);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Instruction code, see `kInstId`.
+ uint16_t _code;
+ //! Instruction options, see `kInstOptions`.
+ uint8_t _options;
+ //! \internal
+ uint8_t _memOpIndex;
+
+ //! Operands list.
+ Operand* _opList;
+};
+
+// ============================================================================
+// [asmjit::JumpNode]
+// ============================================================================
+
+//! Jump node.
+struct JumpNode : public InstNode {
+ ASMJIT_NO_COPY(JumpNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE JumpNode(Compiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) :
+ InstNode(compiler, code, options, opList, opCount) {}
+ ASMJIT_INLINE ~JumpNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE TargetNode* getTarget() const { return _target; }
+ ASMJIT_INLINE JumpNode* getJumpNext() const { return _jumpNext; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Target node.
+ TargetNode* _target;
+ //! Next jump to the same target in a single linked-list.
+ JumpNode *_jumpNext;
+};
+
+// ============================================================================
+// [asmjit::FuncNode]
+// ============================================================================
+
+//! Function declaration node.
+//!
+//! Functions are base blocks for generating assembler output. Each generated
+//! assembler stream needs standard entry and leave sequences which are compatible
+//! with the operating system ABI.
+//!
+//! `FuncNode` can be used to generate function prolog and epilog which are
+//! compatible with a given function calling convention and to allocate and
+//! manage variables that can be allocated/spilled during compilation phase.
+struct FuncNode : public Node {
+ ASMJIT_NO_COPY(FuncNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `FuncNode` instance.
+ //!
+ //! Always use `Compiler::addFunc()` to create a `FuncNode` instance.
+ ASMJIT_INLINE FuncNode(Compiler* compiler) :
+ Node(compiler, kNodeTypeFunc),
+ _entryNode(nullptr),
+ _exitNode(nullptr),
+ _decl(nullptr),
+ _end(nullptr),
+ _argList(nullptr),
+ _funcHints(IntUtil::mask(kFuncHintNaked)),
+ _funcFlags(0),
+ _expectedStackAlignment(0),
+ _requiredStackAlignment(0),
+ _redZoneSize(0),
+ _spillZoneSize(0),
+ _argStackSize(0),
+ _memStackSize(0),
+ _callStackSize(0) {}
+
+ //! Destroy the `FuncNode` instance.
+ ASMJIT_INLINE ~FuncNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get function entry `TargetNode`.
+ ASMJIT_INLINE TargetNode* getEntryNode() const { return _entryNode; }
+ //! Get function exit `TargetNode`.
+ ASMJIT_INLINE TargetNode* getExitNode() const { return _exitNode; }
+
+ //! Get function entry label.
+ ASMJIT_INLINE Label getEntryLabel() const { return _entryNode->getLabel(); }
+ //! Get function exit label.
+ ASMJIT_INLINE Label getExitLabel() const { return _exitNode->getLabel(); }
+
+ //! Get function `EndNode`.
+ ASMJIT_INLINE EndNode* getEnd() const { return _end; }
+ //! Get function declaration.
+ ASMJIT_INLINE FuncDecl* getDecl() const { return _decl; }
+
+ //! Get arguments list.
+ ASMJIT_INLINE VarData** getArgList() const { return _argList; }
+ //! Get arguments count.
+ ASMJIT_INLINE uint32_t getArgCount() const { return _decl->getArgCount(); }
+
+ //! Get argument at `i`.
+ ASMJIT_INLINE VarData* getArg(uint32_t i) const {
+ ASMJIT_ASSERT(i < getArgCount());
+ return _argList[i];
+ }
+
+ //! Set argument at `i`.
+ ASMJIT_INLINE void setArg(uint32_t i, VarData* vd) {
+ ASMJIT_ASSERT(i < getArgCount());
+ _argList[i] = vd;
+ }
+
+ //! Reset argument at `i`.
+ ASMJIT_INLINE void resetArg(uint32_t i) {
+ ASMJIT_ASSERT(i < getArgCount());
+ _argList[i] = nullptr;
+ }
+
+ //! Get function hints.
+ ASMJIT_INLINE uint32_t getFuncHints() const { return _funcHints; }
+ //! Get function flags.
+ ASMJIT_INLINE uint32_t getFuncFlags() const { return _funcFlags; }
+
+ //! Get whether the _funcFlags has `flag`
+ ASMJIT_INLINE bool hasFuncFlag(uint32_t flag) const { return (_funcFlags & flag) != 0; }
+ //! Set function `flag`.
+ ASMJIT_INLINE void addFuncFlags(uint32_t flags) { _funcFlags |= flags; }
+ //! Clear function `flag`.
+ ASMJIT_INLINE void clearFuncFlags(uint32_t flags) { _funcFlags &= ~flags; }
+
+ //! Get whether the function is naked.
+ ASMJIT_INLINE bool isNaked() const { return hasFuncFlag(kFuncFlagIsNaked); }
+ //! Get whether the function is also a caller.
+ ASMJIT_INLINE bool isCaller() const { return hasFuncFlag(kFuncFlagIsCaller); }
+ //! Get whether the required stack alignment is lower than expected one,
+ //! thus it has to be aligned manually.
+ ASMJIT_INLINE bool isStackMisaligned() const { return hasFuncFlag(kFuncFlagIsStackMisaligned); }
+ //! Get whether the stack pointer is adjusted inside function prolog/epilog.
+ ASMJIT_INLINE bool isStackAdjusted() const { return hasFuncFlag(kFuncFlagIsStackAdjusted); }
+
+ //! Get whether the function is finished.
+ ASMJIT_INLINE bool isFinished() const { return hasFuncFlag(kFuncFlagIsFinished); }
+
+ //! Get expected stack alignment.
+ ASMJIT_INLINE uint32_t getExpectedStackAlignment() const { return _expectedStackAlignment; }
+ //! Set expected stack alignment.
+ ASMJIT_INLINE void setExpectedStackAlignment(uint32_t alignment) { _expectedStackAlignment = alignment; }
+
+ //! Get required stack alignment.
+ ASMJIT_INLINE uint32_t getRequiredStackAlignment() const { return _requiredStackAlignment; }
+ //! Set required stack alignment.
+ ASMJIT_INLINE void setRequiredStackAlignment(uint32_t alignment) { _requiredStackAlignment = alignment; }
+
+ //! Update required stack alignment so it's not lower than expected
+ //! stack alignment.
+ ASMJIT_INLINE void updateRequiredStackAlignment() {
+ if (_requiredStackAlignment <= _expectedStackAlignment) {
+ _requiredStackAlignment = _expectedStackAlignment;
+ clearFuncFlags(kFuncFlagIsStackMisaligned);
+ }
+ else {
+ addFuncFlags(kFuncFlagIsStackMisaligned);
+ }
+ }
+
+ //! Set stack "Red Zone" size.
+ ASMJIT_INLINE uint32_t getRedZoneSize() const { return _redZoneSize; }
+ //! Get stack "Red Zone" size.
+ ASMJIT_INLINE void setRedZoneSize(uint32_t s) { _redZoneSize = static_cast<uint16_t>(s); }
+
+ //! Set stack "Spill Zone" size.
+ ASMJIT_INLINE uint32_t getSpillZoneSize() const { return _spillZoneSize; }
+ //! Get stack "Spill Zone" size.
+ ASMJIT_INLINE void setSpillZoneSize(uint32_t s) { _spillZoneSize = static_cast<uint16_t>(s); }
+
+ //! Get stack size used by function arguments.
+ ASMJIT_INLINE uint32_t getArgStackSize() const { return _argStackSize; }
+
+ //! Get stack size used by variables and memory allocated on the stack.
+ ASMJIT_INLINE uint32_t getMemStackSize() const { return _memStackSize; }
+
+ //! Get stack size used by function calls.
+ ASMJIT_INLINE uint32_t getCallStackSize() const { return _callStackSize; }
+ //! Merge stack size used by function call with `s`.
+ ASMJIT_INLINE void mergeCallStackSize(uint32_t s) { if (_callStackSize < s) _callStackSize = s; }
+
+ // --------------------------------------------------------------------------
+ // [Hints]
+ // --------------------------------------------------------------------------
+
+ //! Set function hint.
+ ASMJIT_INLINE void setHint(uint32_t hint, uint32_t value) {
+ ASMJIT_ASSERT(hint <= 31);
+ ASMJIT_ASSERT(value <= 1);
+
+ _funcHints &= ~(1 << hint);
+ _funcHints |= (value << hint);
+ }
+
+ //! Get function hint.
+ ASMJIT_INLINE uint32_t getHint(uint32_t hint) const {
+ ASMJIT_ASSERT(hint <= 31);
+ return (_funcHints >> hint) & 0x1;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Function entry.
+ TargetNode* _entryNode;
+ //! Function exit.
+ TargetNode* _exitNode;
+
+ //! Function declaration.
+ FuncDecl* _decl;
+ //! Function end.
+ EndNode* _end;
+
+ //! Arguments list as `VarData`.
+ VarData** _argList;
+
+ //! Function hints;
+ uint32_t _funcHints;
+ //! Function flags.
+ uint32_t _funcFlags;
+
+ //! Expected stack alignment (we depend on this value).
+ //!
+ //! \note It can be global alignment given by the OS or described by an
+ //! target platform ABI.
+ uint32_t _expectedStackAlignment;
+ //! Required stack alignment (usually for multimedia instructions).
+ uint32_t _requiredStackAlignment;
+
+ //! The "Red Zone" size - count of bytes which might be accessed without
+ //! adjusting the stack pointer.
+ uint16_t _redZoneSize;
+ //! Spill zone size (zone used by WIN64ABI).
+ uint16_t _spillZoneSize;
+
+ //! Stack size needed for function arguments.
+ uint32_t _argStackSize;
+ //! Stack size needed for all variables and memory allocated on the stack.
+ uint32_t _memStackSize;
+ //! Stack size needed to call other functions.
+ uint32_t _callStackSize;
+};
+
+// ============================================================================
+// [asmjit::EndNode]
+// ============================================================================
+
+//! End of function/block node.
+struct EndNode : public Node {
+ ASMJIT_NO_COPY(EndNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `EndNode` instance.
+ ASMJIT_INLINE EndNode(Compiler* compiler) : Node(compiler, kNodeTypeEnd) {
+ _flags |= kNodeFlagIsRet;
+ }
+
+ //! Destroy the `EndNode` instance.
+ ASMJIT_INLINE ~EndNode() {}
+};
+
+// ============================================================================
+// [asmjit::RetNode]
+// ============================================================================
+
+//! Function return node.
+struct RetNode : public Node {
+ ASMJIT_NO_COPY(RetNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `RetNode` instance.
+ ASMJIT_INLINE RetNode(Compiler* compiler, const Operand& o0, const Operand& o1) : Node(compiler, kNodeTypeRet) {
+ _flags |= kNodeFlagIsRet;
+ _ret[0] = o0;
+ _ret[1] = o1;
+ }
+
+ //! Destroy the `RetNode` instance.
+ ASMJIT_INLINE ~RetNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get the first return operand.
+ ASMJIT_INLINE Operand& getFirst() { return _ret[0]; }
+ //! \overload
+ ASMJIT_INLINE const Operand& getFirst() const { return _ret[0]; }
+
+ //! Get the second return operand.
+ ASMJIT_INLINE Operand& getSecond() { return _ret[1]; }
+ //! \overload
+ ASMJIT_INLINE const Operand& getSecond() const { return _ret[1]; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Ret operand(s).
+ Operand _ret[2];
+};
+
+// ============================================================================
+// [asmjit::CallNode]
+// ============================================================================
+
+//! Function-call node.
+struct CallNode : public Node {
+ ASMJIT_NO_COPY(CallNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `CallNode` instance.
+ ASMJIT_INLINE CallNode(Compiler* compiler, const Operand& target) :
+ Node(compiler, kNodeTypeCall),
+ _decl(nullptr),
+ _target(target),
+ _args(nullptr) {}
+
+ //! Destroy the `CallNode` instance.
+ ASMJIT_INLINE ~CallNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get function declaration.
+ ASMJIT_INLINE FuncDecl* getDecl() const { return _decl; }
+
+ //! Get target operand.
+ ASMJIT_INLINE Operand& getTarget() { return _target; }
+ //! \overload
+ ASMJIT_INLINE const Operand& getTarget() const { return _target; }
+
+ //! Get return at `i`.
+ ASMJIT_INLINE Operand& getRet(uint32_t i = 0) {
+ ASMJIT_ASSERT(i < 2);
+ return _ret[i];
+ }
+ //! \overload
+ ASMJIT_INLINE const Operand& getRet(uint32_t i = 0) const {
+ ASMJIT_ASSERT(i < 2);
+ return _ret[i];
+ }
+
+ //! Get argument at `i`.
+ ASMJIT_INLINE Operand& getArg(uint32_t i) {
+ ASMJIT_ASSERT(i < kFuncArgCountLoHi);
+ return _args[i];
+ }
+ //! \overload
+ ASMJIT_INLINE const Operand& getArg(uint32_t i) const {
+ ASMJIT_ASSERT(i < kFuncArgCountLoHi);
+ return _args[i];
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Function declaration.
+ FuncDecl* _decl;
+
+ //! Target (address of function, register, label, ...).
+ Operand _target;
+ //! Return.
+ Operand _ret[2];
+ //! Arguments.
+ Operand* _args;
+};
+
+// ============================================================================
+// [asmjit::SArgNode]
+// ============================================================================
+
+//! Function-call 'argument on the stack' node.
+struct SArgNode : public Node {
+ ASMJIT_NO_COPY(SArgNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `SArgNode` instance.
+ ASMJIT_INLINE SArgNode(Compiler* compiler, CallNode* call, VarData* sVd, VarData* cVd) :
+ Node(compiler, kNodeTypeSArg),
+ _call(call),
+ _sVd(sVd),
+ _cVd(cVd),
+ _args(0) {}
+
+ //! Destroy the `SArgNode` instance.
+ ASMJIT_INLINE ~SArgNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get the associated function-call.
+ ASMJIT_INLINE CallNode* getCall() const { return _call; }
+ //! Get source variable.
+ ASMJIT_INLINE VarData* getSVd() const { return _sVd; }
+ //! Get conversion variable.
+ ASMJIT_INLINE VarData* getCVd() const { return _cVd; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Associated `CallNode`.
+ CallNode* _call;
+ //! Source variable.
+ VarData* _sVd;
+ //! Temporary variable used for conversion (or NULL).
+ VarData* _cVd;
+
+ //! Affected arguments bit-array.
+ uint32_t _args;
+};
+
+//! \}
+
+// ============================================================================
+// [asmjit::Compiler]
+// ============================================================================
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+//! Base compiler.
+//!
+//! \sa Assembler.
+struct ASMJIT_VCLASS Compiler : public CodeGen {
+ ASMJIT_NO_COPY(Compiler)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `Compiler` instance.
+ ASMJIT_API Compiler(Runtime* runtime);
+ //! Destroy the `Compiler` instance.
+ ASMJIT_API virtual ~Compiler();
+
+ // --------------------------------------------------------------------------
+ // [LookAhead]
+ // --------------------------------------------------------------------------
+
+ //! Get maximum look ahead.
+ ASMJIT_INLINE uint32_t getMaxLookAhead() const {
+ return _maxLookAhead;
+ }
+
+ //! Set maximum look ahead to `val`.
+ ASMJIT_INLINE void setMaxLookAhead(uint32_t val) {
+ _maxLookAhead = val;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Clear / Reset]
+ // --------------------------------------------------------------------------
+
+ //! Reset the compiler.
+ //!
+ //! If `releaseMemory` is true all buffers will be released to the system.
+ ASMJIT_API void reset(bool releaseMemory = false);
+
+ // --------------------------------------------------------------------------
+ // [Nodes]
+ // --------------------------------------------------------------------------
+
+ template<typename T>
+ ASMJIT_INLINE T* newNode() {
+ void* p = _baseZone.alloc(sizeof(T));
+ return new(p) T(this);
+ }
+
+ template<typename T, typename P0>
+ ASMJIT_INLINE T* newNode(P0 p0) {
+ void* p = _baseZone.alloc(sizeof(T));
+ return new(p) T(this, p0);
+ }
+
+ template<typename T, typename P0, typename P1>
+ ASMJIT_INLINE T* newNode(P0 p0, P1 p1) {
+ void* p = _baseZone.alloc(sizeof(T));
+ return new(p) T(this, p0, p1);
+ }
+
+ template<typename T, typename P0, typename P1, typename P2>
+ ASMJIT_INLINE T* newNode(P0 p0, P1 p1, P2 p2) {
+ void* p = _baseZone.alloc(sizeof(T));
+ return new(p) T(this, p0, p1, p2);
+ }
+
+ //! Get first node.
+ ASMJIT_INLINE Node* getFirstNode() const { return _firstNode; }
+ //! Get last node.
+ ASMJIT_INLINE Node* getLastNode() const { return _lastNode; }
+
+ //! Get current node.
+ //!
+ //! \note If this method returns `NULL` it means that nothing has been emitted
+ //! yet.
+ ASMJIT_INLINE Node* getCursor() const { return _cursor; }
+ //! Set the current node without returning the previous node (private).
+ ASMJIT_INLINE void _setCursor(Node* node) { _cursor = node; }
+ //! Set the current node to `node` and return the previous one.
+ ASMJIT_API Node* setCursor(Node* node);
+
+ //! Add node `node` after current and set current to `node`.
+ ASMJIT_API Node* addNode(Node* node);
+ //! Add node before `ref`.
+ ASMJIT_API Node* addNodeBefore(Node* node, Node* ref);
+ //! Add node after `ref`.
+ ASMJIT_API Node* addNodeAfter(Node* node, Node* ref);
+ //! Remove node `node`.
+ ASMJIT_API Node* removeNode(Node* node);
+ //! Remove multiple nodes.
+ ASMJIT_API void removeNodes(Node* first, Node* last);
+
+ // --------------------------------------------------------------------------
+ // [Func]
+ // --------------------------------------------------------------------------
+
+ //! Get current function.
+ ASMJIT_INLINE FuncNode* getFunc() const { return _func; }
+
+ // --------------------------------------------------------------------------
+ // [Align]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `AlignNode`.
+ ASMJIT_API AlignNode* newAlign(uint32_t mode, uint32_t offset);
+ //! Add a new `AlignNode`.
+ ASMJIT_API AlignNode* addAlign(uint32_t mode, uint32_t offset);
+
+ //! Align target buffer to `m` bytes.
+ //!
+ //! Typical usage of this is to align labels at start of the inner loops.
+ //!
+ //! Inserts `nop()` instructions or CPU optimized NOPs.
+ ASMJIT_INLINE AlignNode* align(uint32_t mode, uint32_t offset) {
+ return addAlign(mode, offset);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Target]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `TargetNode`.
+ ASMJIT_API TargetNode* newTarget();
+ //! Add a new `TargetNode`.
+ ASMJIT_API TargetNode* addTarget();
+
+ //! Get `TargetNode` by `id`.
+ ASMJIT_INLINE TargetNode* getTargetById(uint32_t id) {
+ ASMJIT_ASSERT(OperandUtil::isLabelId(id));
+ ASMJIT_ASSERT(id < _targetList.getLength());
+
+ return _targetList[id];
+ }
+
+ //! Get `TargetNode` by `label`.
+ ASMJIT_INLINE TargetNode* getTarget(const Label& label) {
+ return getTargetById(label.getId());
+ }
+
+ // --------------------------------------------------------------------------
+ // [Label]
+ // --------------------------------------------------------------------------
+
+ //! Get count of created labels.
+ ASMJIT_INLINE size_t getLabelsCount() const {
+ return _targetList.getLength();
+ }
+
+ //! Get whether `label` is created.
+ ASMJIT_INLINE bool isLabelValid(const Label& label) const {
+ return isLabelValid(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE bool isLabelValid(uint32_t id) const {
+ return static_cast<size_t>(id) < _targetList.getLength();
+ }
+
+ //! Get `TargetNode` by `label`.
+ ASMJIT_INLINE TargetNode* getTargetByLabel(const Label& label) {
+ return getTargetByLabel(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE TargetNode* getTargetByLabel(uint32_t id) {
+ ASMJIT_ASSERT(isLabelValid(id));
+ return _targetList[id];
+ }
+
+ //! Get `label` offset or -1 if the label is not bound.
+ //!
+ //! This method can be only called after the code has been serialized to the
+ //! `Assembler`, otherwise the offset returned will be -1 (even if the label
+ //! has been bound).
+ ASMJIT_INLINE intptr_t getLabelOffset(const Label& label) const {
+ return getLabelOffset(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE intptr_t getLabelOffset(uint32_t id) const {
+ ASMJIT_ASSERT(isLabelValid(id));
+ return _targetList[id]->getOffset();
+ }
+
+ //! \internal
+ //!
+ //! Create and initialize a new `Label`.
+ ASMJIT_API Error _newLabel(Label* dst);
+
+ //! Create and return a new `Label`.
+ ASMJIT_INLINE Label newLabel() {
+ Label result(NoInit);
+ _newLabel(&result);
+ return result;
+ }
+
+ //! Bind label to the current offset.
+ //!
+ //! \note Label can be bound only once!
+ ASMJIT_API Error bind(const Label& label);
+
+ // --------------------------------------------------------------------------
+ // [Embed]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `EmbedNode`.
+ ASMJIT_API EmbedNode* newEmbed(const void* data, uint32_t size);
+ //! Add a new `EmbedNode`.
+ ASMJIT_API EmbedNode* addEmbed(const void* data, uint32_t size);
+
+ //! Embed data.
+ ASMJIT_INLINE EmbedNode* embed(const void* data, uint32_t size) {
+ return addEmbed(data, size);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Comment]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `CommentNode`.
+ ASMJIT_API CommentNode* newComment(const char* str);
+ //! Add a new `CommentNode`.
+ ASMJIT_API CommentNode* addComment(const char* str);
+
+ //! Emit a single comment line.
+ ASMJIT_API CommentNode* comment(const char* fmt, ...);
+
+ // --------------------------------------------------------------------------
+ // [Hint]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `HintNode`.
+ ASMJIT_API HintNode* newHint(Var& var, uint32_t hint, uint32_t value);
+ //! Add a new `HintNode`.
+ ASMJIT_API HintNode* addHint(Var& var, uint32_t hint, uint32_t value);
+
+ // --------------------------------------------------------------------------
+ // [Vars]
+ // --------------------------------------------------------------------------
+
+ //! Get whether variable `var` is created.
+ ASMJIT_INLINE bool isVarValid(const Var& var) const {
+ return static_cast<size_t>(var.getId() & kOperandIdNum) < _varList.getLength();
+ }
+
+ //! \internal
+ //!
+ //! Get `VarData` by `var`.
+ ASMJIT_INLINE VarData* getVd(const Var& var) const {
+ return getVdById(var.getId());
+ }
+
+ //! \internal
+ //!
+ //! Get `VarData` by `id`.
+ ASMJIT_INLINE VarData* getVdById(uint32_t id) const {
+ ASMJIT_ASSERT(id != kInvalidValue);
+ ASMJIT_ASSERT(static_cast<size_t>(id & kOperandIdNum) < _varList.getLength());
+
+ return _varList[id & kOperandIdNum];
+ }
+
+ //! \internal
+ //!
+ //! Get an array of 'VarData*'.
+ ASMJIT_INLINE VarData** _getVdArray() const {
+ return const_cast<VarData**>(_varList.getData());
+ }
+
+ //! \internal
+ //!
+ //! Create a new `VarData`.
+ ASMJIT_API VarData* _newVd(uint32_t type, uint32_t size, uint32_t c, const char* name);
+
+ //! Create a new `Var`.
+ virtual Error _newVar(Var* var, uint32_t type, const char* name) = 0;
+
+ //! Alloc variable `var`.
+ ASMJIT_API void alloc(Var& var);
+ //! Alloc variable `var` using `regIndex` as a register index.
+ ASMJIT_API void alloc(Var& var, uint32_t regIndex);
+ //! Alloc variable `var` using `reg` as a register operand.
+ ASMJIT_API void alloc(Var& var, const Reg& reg);
+ //! Spill variable `var`.
+ ASMJIT_API void spill(Var& var);
+ //! Save variable `var` if the status is `modified` at this point.
+ ASMJIT_API void save(Var& var);
+ //! Unuse variable `var`.
+ ASMJIT_API void unuse(Var& var);
+
+ //! Alloc variable `var` (if initialized), but only if it's initialized.
+ ASMJIT_INLINE void allocUnsafe(Var& var) {
+ if (var.isInitialized())
+ alloc(var);
+ }
+
+ //! Alloc variable `var` (if initialized) using `regIndex` as a register index
+ ASMJIT_INLINE void allocUnsafe(Var& var, uint32_t regIndex) {
+ if (var.isInitialized())
+ alloc(var, regIndex);
+ }
+
+ //! Alloc variable `var` (if initialized) using `reg` as a register operand.
+ ASMJIT_INLINE void allocUnsafe(Var& var, const Reg& reg) {
+ if (var.isInitialized())
+ alloc(var, reg);
+ }
+
+ //! Spill variable `var` (if initialized).
+ ASMJIT_INLINE void spillUnsafe(Var& var) {
+ if (var.isInitialized())
+ spill(var);
+ }
+
+ //! Save variable `var` (if initialized) if the status is `modified` at this point.
+ ASMJIT_INLINE void saveUnsafe(Var& var) {
+ if (var.isInitialized())
+ save(var);
+ }
+
+ //! Unuse variable `var` (if initialized).
+ ASMJIT_INLINE void unuseUnsafe(Var& var) {
+ if (var.isInitialized())
+ unuse(var);
+ }
+
+ //! Get priority of variable `var`.
+ ASMJIT_API uint32_t getPriority(Var& var) const;
+ //! Set priority of variable `var` to `priority`.
+ ASMJIT_API void setPriority(Var& var, uint32_t priority);
+
+ //! Get save-on-unuse `var` property.
+ ASMJIT_API bool getSaveOnUnuse(Var& var) const;
+ //! Set save-on-unuse `var` property to `value`.
+ ASMJIT_API void setSaveOnUnuse(Var& var, bool value);
+
+ //! Rename variable `var` to `name`.
+ //!
+ //! \note Only new name will appear in the logger.
+ ASMJIT_API void rename(Var& var, const char* name);
+
+ // --------------------------------------------------------------------------
+ // [Stack]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ //!
+ //! Create a new memory chunk allocated on the current function's stack.
+ virtual Error _newStack(BaseMem* mem, uint32_t size, uint32_t alignment, const char* name) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Const]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ //!
+ //! Put data to a constant-pool and get a memory reference to it.
+ virtual Error _newConst(BaseMem* mem, uint32_t scope, const void* data, size_t size) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Assembler]
+ // --------------------------------------------------------------------------
+
+ //! Get an assembler instance that is associated with the compiler.
+ //!
+ //! \note One instance of `Assembler` is shared and has lifetime same as the
+ //! compiler, however, each call to `getAssembler()` resets the assembler so
+ //! new code can be serialized into it.
+ ASMJIT_API Assembler* getAssembler();
+
+ //! \internal
+ //!
+ //! Create a new `Assembler` instance associated with the compiler.
+ virtual Assembler* _newAssembler() = 0;
+
+ // --------------------------------------------------------------------------
+ // [Serialize]
+ // --------------------------------------------------------------------------
+
+ //! Serialize a compiled code to `assembler`.
+ virtual Error serialize(Assembler* assembler) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Internal assembler.
+ Assembler* _assembler;
+
+ //! Flow id added to each node created (used only by `Context)`.
+ uint32_t _nodeFlowId;
+ //! Flags added to each node created (used only by `Context)`.
+ uint32_t _nodeFlags;
+
+ //! Maximum count of nodes to look ahead when allocating/spilling
+ //! registers.
+ uint32_t _maxLookAhead;
+
+ //! Variable mapping (translates incoming kVarType into target).
+ const uint8_t* _targetVarMapping;
+
+ //! First node.
+ Node* _firstNode;
+ //! Last node.
+ Node* _lastNode;
+
+ //! Current node.
+ Node* _cursor;
+ //! Current function.
+ FuncNode* _func;
+
+ //! Variable zone.
+ Zone _varZone;
+ //! String/data zone.
+ Zone _stringZone;
+ //! Local constant pool zone.
+ Zone _localConstZone;
+
+ //! TargetNode list.
+ PodVector<TargetNode*> _targetList;
+ //! VarData list.
+ PodVector<VarData*> _varList;
+
+ //! Local constant pool, flushed at the end of each function.
+ ConstPool _localConstPool;
+ //! Global constant pool, flushed at the end of the compilation.
+ ConstPool _globalConstPool;
+
+ //! Label to start of the local constant pool.
+ Label _localConstPoolLabel;
+ //! Label to start of the global constant pool.
+ Label _globalConstPoolLabel;
+};
+
+//! \}
+
+// ============================================================================
+// [Defined-Later]
+// ============================================================================
+
+ASMJIT_INLINE Label::Label(Compiler& c) : Operand(NoInit) {
+ c._newLabel(this);
+}
+
+ASMJIT_INLINE Node::Node(Compiler* compiler, uint32_t type) {
+ _prev = nullptr;
+ _next = nullptr;
+ _type = static_cast<uint8_t>(type);
+ _opCount = 0;
+ _flags = static_cast<uint16_t>(compiler->_nodeFlags);
+ _flowId = compiler->_nodeFlowId;
+ _comment = nullptr;
+ _map = nullptr;
+ _liveness = nullptr;
+ _state = nullptr;
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+#endif // !ASMJIT_DISABLE_COMPILER
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/constpool.cpp
@@ -1,1 +1,373 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Dependencies - AsmJit]
+#include "../base/constpool.h"
+#include "../base/intutil.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// Binary tree code is based on Julienne Walker's "Andersson Binary Trees"
+// article and implementation. However, only three operations are implemented -
+// get, insert and traverse.
+
+// ============================================================================
+// [asmjit::ConstPoolTree - Ops]
+// ============================================================================
+
+//! \internal
+//!
+//! Remove left horizontal links.
+static ASMJIT_INLINE ConstPoolNode* ConstPoolTree_skewNode(ConstPoolNode* node) {
+ ConstPoolNode* link = node->_link[0];
+ uint32_t level = node->_level;
+
+ if (level != 0 && link && link->_level == level) {
+ node->_link[0] = link->_link[1];
+ link->_link[1] = node;
+
+ node = link;
+ }
+
+ return node;
+}
+
+//! \internal
+//!
+//! Remove consecutive horizontal links.
+static ASMJIT_INLINE ConstPoolNode* ConstPoolTree_splitNode(ConstPoolNode* node) {
+ ConstPoolNode* link = node->_link[1];
+ uint32_t level = node->_level;
+
+ if (level != 0 && link && link->_link[1] && link->_link[1]->_level == level) {
+ node->_link[1] = link->_link[0];
+ link->_link[0] = node;
+
+ node = link;
+ node->_level++;
+ }
+
+ return node;
+}
+
+ConstPoolNode* ConstPoolTree::get(const void* data) {
+ ConstPoolNode* node = _root;
+ size_t dataSize = _dataSize;
+
+ while (node) {
+ int c = ::memcmp(node->getData(), data, dataSize);
+ if (c == 0)
+ return node;
+ node = node->_link[c < 0];
+ }
+
+ return nullptr;
+}
+
+void ConstPoolTree::put(ConstPoolNode* newNode) {
+ size_t dataSize = _dataSize;
+
+ _length++;
+ if (!_root) {
+ _root = newNode;
+ return;
+ }
+
+ ConstPoolNode* node = _root;
+ ConstPoolNode* stack[kHeightLimit];
+
+ unsigned int top = 0;
+ unsigned int dir;
+
+ // Find a spot and save the stack.
+ for (;;) {
+ stack[top++] = node;
+ dir = ::memcmp(node->getData(), newNode->getData(), dataSize) < 0;
+
+ ConstPoolNode* link = node->_link[dir];
+ if (!link)
+ break;
+
+ node = link;
+ }
+
+ // Link and rebalance.
+ node->_link[dir] = newNode;
+
+ while (top > 0) {
+ // Which child?
+ node = stack[--top];
+
+ if (top != 0) {
+ dir = stack[top - 1]->_link[1] == node;
+ }
+
+ node = ConstPoolTree_skewNode(node);
+ node = ConstPoolTree_splitNode(node);
+
+ // Fix the parent.
+ if (top != 0)
+ stack[top - 1]->_link[dir] = node;
+ else
+ _root = node;
+ }
+}
+
+// ============================================================================
+// [asmjit::ConstPool - Construction / Destruction]
+// ============================================================================
+
+ConstPool::ConstPool(Zone* zone) {
+ _zone = zone;
+
+ size_t dataSize = 1;
+ for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_tree); i++) {
+ _tree[i].setDataSize(dataSize);
+ _gaps[i] = nullptr;
+ dataSize <<= 1;
+ }
+
+ _gapPool = nullptr;
+ _size = 0;
+ _alignment = 0;
+}
+
+ConstPool::~ConstPool() {}
+
+// ============================================================================
+// [asmjit::ConstPool - Reset]
+// ============================================================================
+
+void ConstPool::reset() {
+ for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_tree); i++) {
+ _tree[i].reset();
+ _gaps[i] = nullptr;
+ }
+
+ _gapPool = nullptr;
+ _size = 0;
+ _alignment = 0;
+}
+
+// ============================================================================
+// [asmjit::ConstPool - Ops]
+// ============================================================================
+
+/*static ASMJIT_INLINE size_t ConstPool_getGapIndex(size_t size) {
+ if (size <= 1)
+ return ConstPool::kIndex1;
+ else if (size <= 3)
+ return ConstPool::kIndex2;
+ else if (size <= 7)
+ return ConstPool::kIndex4;
+ else if (size <= 15)
+ return ConstPool::kIndex8;
+ else
+ return ConstPool::kIndex16;
+}*/
+
+static ASMJIT_INLINE ConstPoolGap* ConstPool_allocGap(ConstPool* self) {
+ ConstPoolGap* gap = self->_gapPool;
+ if (!gap)
+ return self->_zone->allocT<ConstPoolGap>();
+
+ self->_gapPool = gap->_next;
+ return gap;
+}
+
+static ASMJIT_INLINE void ConstPool_freeGap(ConstPool* self, ConstPoolGap* gap) {
+ gap->_next = self->_gapPool;
+ self->_gapPool = gap;
+}
+
+static void ConstPool_addGap(ConstPool* self, size_t offset, size_t length) {
+ ASMJIT_ASSERT(length > 0);
+
+ while (length > 0) {
+ size_t gapIndex;
+ size_t gapLength;
+
+ if (length >= 16 && IntUtil::isAligned<size_t>(offset, 16)) {
+ gapIndex = ConstPool::kIndex16;
+ gapLength = 16;
+ }
+ else if (length >= 8 && IntUtil::isAligned<size_t>(offset, 8)) {
+ gapIndex = ConstPool::kIndex8;
+ gapLength = 8;
+ }
+ else if (length >= 4 && IntUtil::isAligned<size_t>(offset, 4)) {
+ gapIndex = ConstPool::kIndex4;
+ gapLength = 4;
+ }
+ else if (length >= 2 && IntUtil::isAligned<size_t>(offset, 2)) {
+ gapIndex = ConstPool::kIndex2;
+ gapLength = 2;
+ }
+ else {
+ gapIndex = ConstPool::kIndex1;
+ gapLength = 1;
+ }
+
+ // We don't have to check for errors here, if this failed nothing really
+ // happened (just the gap won't be visible) and it will fail again at
+ // place where checking will cause kErrorNoHeapMemory.
+ ConstPoolGap* gap = ConstPool_allocGap(self);
+ if (!gap)
+ return;
+
+ gap->_next = self->_gaps[gapIndex];
+ self->_gaps[gapIndex] = gap;
+
+ gap->_offset = offset;
+ gap->_length = gapLength;
+
+ offset += gapLength;
+ length -= gapLength;
+ }
+}
+
+Error ConstPool::add(const void* data, size_t size, size_t& dstOffset) {
+ size_t treeIndex;
+
+ if (size == 32)
+ treeIndex = kIndex32;
+ else if (size == 16)
+ treeIndex = kIndex16;
+ else if (size == 8)
+ treeIndex = kIndex8;
+ else if (size == 4)
+ treeIndex = kIndex4;
+ else if (size == 2)
+ treeIndex = kIndex2;
+ else if (size == 1)
+ treeIndex = kIndex1;
+ else
+ return kErrorInvalidArgument;
+
+ ConstPoolNode* node = _tree[treeIndex].get(data);
+ if (node) {
+ dstOffset = node->_offset;
+ return kErrorOk;
+ }
+
+ // Before incrementing the current offset try if there is a gap that can
+ // be used for the requested data.
+ size_t offset = ~static_cast<size_t>(0);
+ size_t gapIndex = treeIndex;
+
+ while (gapIndex != kIndexCount - 1) {
+ ConstPoolGap* gap = _gaps[treeIndex];
+
+ // Check if there is a gap.
+ if (gap) {
+ size_t gapOffset = gap->_offset;
+ size_t gapLength = gap->_length;
+
+ // Destroy the gap for now.
+ _gaps[treeIndex] = gap->_next;
+ ConstPool_freeGap(this, gap);
+
+ offset = gapOffset;
+ ASMJIT_ASSERT(IntUtil::isAligned<size_t>(offset, size));
+
+ gapLength -= size;
+ if (gapLength > 0)
+ ConstPool_addGap(this, gapOffset, gapLength);
+ }
+
+ gapIndex++;
+ }
+
+ if (offset == ~static_cast<size_t>(0)) {
+ // Get how many bytes have to be skipped so the address is aligned accordingly
+ // to the 'size'.
+ size_t deltaTo = IntUtil::deltaTo<size_t>(_size, size);
+
+ if (deltaTo != 0) {
+ ConstPool_addGap(this, _size, deltaTo);
+ _size += deltaTo;
+ }
+
+ offset = _size;
+ _size += size;
+ }
+
+ // Add the initial node to the right index.
+ node = ConstPoolTree::_newNode(_zone, data, size, offset, false);
+ if (!node)
+ return kErrorNoHeapMemory;
+
+ _tree[treeIndex].put(node);
+ _alignment = IntUtil::iMax<size_t>(_alignment, size);
+
+ dstOffset = offset;
+
+ // Now create a bunch of shared constants that are based on the data pattern.
+ // We stop at size 4, it probably doesn't make sense to split constants down
+ // to 1 byte.
+ size_t pCount = 1;
+ while (size > 4) {
+ size >>= 1;
+ pCount <<= 1;
+
+ ASMJIT_ASSERT(treeIndex != 0);
+ treeIndex--;
+
+ const uint8_t* pData = static_cast<const uint8_t*>(data);
+ for (size_t i = 0; i < pCount; i++, pData += size) {
+ node = _tree[treeIndex].get(pData);
+
+ if (node)
+ continue;
+
+ node = ConstPoolTree::_newNode(_zone, pData, size, offset + (i * size), true);
+ _tree[treeIndex].put(node);
+ }
+ }
+
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::ConstPool - Reset]
+// ============================================================================
+
+struct ConstPoolFill {
+ ASMJIT_INLINE ConstPoolFill(uint8_t* dst, size_t dataSize) :
+ _dst(dst),
+ _dataSize(dataSize) {}
+
+ ASMJIT_INLINE void visit(const ConstPoolNode* node) {
+ if (!node->_shared)
+ ::memcpy(_dst + node->_offset, node->getData(), _dataSize);
+ }
+
+ uint8_t* _dst;
+ size_t _dataSize;
+};
+
+void ConstPool::fill(void* dst) {
+ // Clears possible gaps, asmjit should never emit garbage to the output.
+ ::memset(dst, 0, _size);
+
+ ConstPoolFill filler(static_cast<uint8_t*>(dst), 1);
+ for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_tree); i++) {
+ _tree[i].iterate(filler);
+ filler._dataSize <<= 1;
+ }
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/constpool.h
@@ -1,1 +1,295 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../base/error.h"
+#include "../base/zone.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::ConstPoolNode]
+// ============================================================================
+
+//! \internal
+//!
+//! Zone-allocated constant-pool node.
+struct ConstPoolNode {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void* getData() const {
+ return static_cast<void*>(const_cast<ConstPoolNode*>(this) + 1);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Left/Right nodes.
+ ConstPoolNode* _link[2];
+ //! Horizontal level for balance.
+ uint32_t _level : 31;
+ //! Whether this constant is shared with another.
+ uint32_t _shared : 1;
+ //! Data offset from the beginning of the pool.
+ uint32_t _offset;
+};
+
+// ============================================================================
+// [asmjit::ConstPoolTree]
+// ============================================================================
+
+//! \internal
+//!
+//! Zone-allocated constant-pool tree.
+struct ConstPoolTree {
+ enum {
+ //! Maximum tree height == log2(1 << 64).
+ kHeightLimit = 64
+ };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE ConstPoolTree(size_t dataSize = 0) :
+ _root(nullptr),
+ _length(0),
+ _dataSize(dataSize) {}
+ ASMJIT_INLINE ~ConstPoolTree() {}
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void reset() {
+ _root = nullptr;
+ _length = 0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE bool isEmpty() const {
+ return _length == 0;
+ }
+
+ ASMJIT_INLINE size_t getLength() const {
+ return _length;
+ }
+
+ ASMJIT_INLINE void setDataSize(size_t dataSize) {
+ ASMJIT_ASSERT(isEmpty());
+ _dataSize = dataSize;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Ops]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API ConstPoolNode* get(const void* data);
+ ASMJIT_API void put(ConstPoolNode* node);
+
+ // --------------------------------------------------------------------------
+ // [Iterate]
+ // --------------------------------------------------------------------------
+
+ template<typename Visitor>
+ ASMJIT_INLINE void iterate(Visitor& visitor) const {
+ ConstPoolNode* node = const_cast<ConstPoolNode*>(_root);
+ ConstPoolNode* link;
+
+ ConstPoolNode* stack[kHeightLimit];
+
+ if (!node)
+ return;
+
+ size_t top = 0;
+
+ for (;;) {
+ link = node->_link[0];
+
+ if (link) {
+ ASMJIT_ASSERT(top != kHeightLimit);
+ stack[top++] = node;
+ continue;
+ }
+
+ visitor.visit(node);
+ link = node->_link[1];
+
+ if (link) {
+ node = link;
+ continue;
+ }
+
+ if (top == 0)
+ break;
+
+ node = stack[--top];
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // [Helpers]
+ // --------------------------------------------------------------------------
+
+ static ASMJIT_INLINE ConstPoolNode* _newNode(Zone* zone, const void* data, size_t size, size_t offset, bool shared) {
+ ConstPoolNode* node = zone->allocT<ConstPoolNode>(sizeof(ConstPoolNode) + size);
+ if (!node)
+ return nullptr;
+
+ node->_link[0] = nullptr;
+ node->_link[1] = nullptr;
+ node->_level = 1;
+ node->_shared = shared;
+ node->_offset = static_cast<uint32_t>(offset);
+
+ ::memcpy(node->getData(), data, size);
+ return node;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Root of the tree
+ ConstPoolNode* _root;
+ //! Length of the tree (count of nodes).
+ size_t _length;
+ //! Size of the data.
+ size_t _dataSize;
+};
+
+// ============================================================================
+// [asmjit::ConstPoolGap]
+// ============================================================================
+
+//! \internal
+//!
+//! Zone-allocated constant-pool gap.
+struct ConstPoolGap {
+ //! Link to the next gap
+ ConstPoolGap* _next;
+ //! Offset of the gap.
+ size_t _offset;
+ //! Remaining bytes of the gap (basically a gap size).
+ size_t _length;
+};
+
+// ============================================================================
+// [asmjit::ConstPool]
+// ============================================================================
+
+//! Constant pool.
+struct ConstPool {
+ ASMJIT_NO_COPY(ConstPool)
+
+ enum {
+ kIndex1 = 0,
+ kIndex2 = 1,
+ kIndex4 = 2,
+ kIndex8 = 3,
+ kIndex16 = 4,
+ kIndex32 = 5,
+ kIndexCount = 6
+ };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API ConstPool(Zone* zone);
+ ASMJIT_API ~ConstPool();
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API void reset();
+
+ // --------------------------------------------------------------------------
+ // [Ops]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the constant-pool is empty.
+ ASMJIT_INLINE bool isEmpty() const {
+ return _size == 0;
+ }
+
+ //! Get the size of the constant-pool in bytes.
+ ASMJIT_INLINE size_t getSize() const {
+ return _size;
+ }
+
+ //! Get minimum alignment.
+ ASMJIT_INLINE size_t getAlignment() const {
+ return _alignment;
+ }
+
+ //! Add a constant to the constant pool.
+ //!
+ //! The constant must have known size, which is 1, 2, 4, 8, 16 or 32 bytes.
+ //! The constant is added to the pool only if it doesn't not exist, otherwise
+ //! cached value is returned.
+ //!
+ //! AsmJit is able to subdivide added constants, so for example if you add
+ //! 8-byte constant 0x1122334455667788 it will create the following slots:
+ //!
+ //! 8-byte: 0x1122334455667788
+ //! 4-byte: 0x11223344, 0x55667788
+ //!
+ //! The reason is that when combining MMX/SSE/AVX code some patterns are used
+ //! frequently. However, AsmJit is not able to reallocate a constant that has
+ //! been already added. For example if you try to add 4-byte constant and then
+ //! 8-byte constant having the same 4-byte pattern as the previous one, two
+ //! independent slots will be generated by the pool.
+ ASMJIT_API Error add(const void* data, size_t size, size_t& dstOffset);
+
+ // --------------------------------------------------------------------------
+ // [Fill]
+ // --------------------------------------------------------------------------
+
+ //! Fill the destination with the constants from the pool.
+ ASMJIT_API void fill(void* dst);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Zone allocator.
+ Zone* _zone;
+ //! Tree per size.
+ ConstPoolTree _tree[kIndexCount];
+ //! Gaps per size.
+ ConstPoolGap* _gaps[kIndexCount];
+ //! Gaps pool
+ ConstPoolGap* _gapPool;
+
+ //! Size of the pool (in bytes).
+ size_t _size;
+ //! Alignemnt.
+ size_t _alignment;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/containers.cpp
@@ -1,1 +1,117 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Dependencies - AsmJit]
+#include "../base/containers.h"
+#include "../base/intutil.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [asmjit::PodVectorBase - NullData]
+// ============================================================================
+
+const PodVectorData PodVectorBase::_nullData = { 0, 0 };
+
+// ============================================================================
+// [asmjit::PodVectorBase - Reset]
+// ============================================================================
+
+//! Clear vector data and free internal buffer.
+void PodVectorBase::reset(bool releaseMemory) {
+ PodVectorData* d = _d;
+
+ if (d == &_nullData)
+ return;
+
+ if (releaseMemory) {
+ ASMJIT_FREE(d);
+ _d = const_cast<PodVectorData*>(&_nullData);
+ return;
+ }
+
+ d->length = 0;
+}
+
+// ============================================================================
+// [asmjit::PodVectorBase - Helpers]
+// ============================================================================
+
+Error PodVectorBase::_grow(size_t n, size_t sizeOfT) {
+ PodVectorData* d = _d;
+
+ size_t threshold = kMemAllocGrowMax / sizeOfT;
+ size_t capacity = d->capacity;
+ size_t after = d->length;
+
+ if (IntUtil::maxUInt<size_t>() - n < after)
+ return kErrorNoHeapMemory;
+
+ after += n;
+
+ if (capacity >= after)
+ return kErrorOk;
+
+ // PodVector is used as a linear array for some data structures used by
+ // AsmJit code generation. The purpose of this agressive growing schema
+ // is to minimize memory reallocations, because AsmJit code generation
+ // classes live short life and will be freed or reused soon.
+ if (capacity < 32)
+ capacity = 32;
+ else if (capacity < 128)
+ capacity = 128;
+ else if (capacity < 512)
+ capacity = 512;
+
+ while (capacity < after) {
+ if (capacity < threshold)
+ capacity *= 2;
+ else
+ capacity += threshold;
+ }
+
+ return _reserve(capacity, sizeOfT);
+}
+
+Error PodVectorBase::_reserve(size_t n, size_t sizeOfT) {
+ PodVectorData* d = _d;
+
+ if (d->capacity >= n)
+ return kErrorOk;
+
+ size_t nBytes = sizeof(PodVectorData) + n * sizeOfT;
+ if (nBytes < n)
+ return kErrorNoHeapMemory;
+
+ if (d == &_nullData) {
+ d = static_cast<PodVectorData*>(ASMJIT_ALLOC(nBytes));
+ if (!d)
+ return kErrorNoHeapMemory;
+ d->length = 0;
+ }
+ else {
+ d = static_cast<PodVectorData*>(ASMJIT_REALLOC(d, nBytes));
+ if (!d)
+ return kErrorNoHeapMemory;
+ }
+
+ d->capacity = n;
+ _d = d;
+
+ return kErrorOk;
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/containers.h
@@ -1,1 +1,346 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../base/error.h"
+#include "../base/globals.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::PodVectorData]
+// ============================================================================
+
+//! \internal
+struct PodVectorData {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get data.
+ ASMJIT_INLINE void* getData() const {
+ return const_cast<void *>(reinterpret_cast<const void *>(this + 1));
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Capacity of the vector.
+ size_t capacity;
+ //! Length of the vector.
+ size_t length;
+};
+
+// ============================================================================
+// [asmjit::PodVectorBase]
+// ============================================================================
+
+//! \internal
+struct PodVectorBase {
+ static ASMJIT_API const PodVectorData _nullData;
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new instance of `PodVectorBase`.
+ ASMJIT_INLINE PodVectorBase() :
+ _d(const_cast<PodVectorData*>(&_nullData)) {}
+
+ //! Destroy the `PodVectorBase` and data.
+ ASMJIT_INLINE ~PodVectorBase() {
+ reset(true);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ //! Reset the vector data and set its `length` to zero.
+ //!
+ //! If `releaseMemory` is true the vector buffer will be released to the
+ //! system.
+ ASMJIT_API void reset(bool releaseMemory = false);
+
+ // --------------------------------------------------------------------------
+ // [Grow / Reserve]
+ // --------------------------------------------------------------------------
+
+protected:
+ ASMJIT_API Error _grow(size_t n, size_t sizeOfT);
+ ASMJIT_API Error _reserve(size_t n, size_t sizeOfT);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+public:
+ PodVectorData* _d;
+};
+
+// ============================================================================
+// [asmjit::PodVector<T>]
+// ============================================================================
+
+//! 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 <typename T>
+struct PodVector : PodVectorBase {
+ ASMJIT_NO_COPY(PodVector<T>)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new instance of `PodVector<T>`.
+ ASMJIT_INLINE PodVector() {}
+ //! Destroy the `PodVector<>` and data.
+ ASMJIT_INLINE ~PodVector() {}
+
+ // --------------------------------------------------------------------------
+ // [Data]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the vector is empty.
+ ASMJIT_INLINE bool isEmpty() const {
+ return _d->length == 0;
+ }
+
+ //! Get length.
+ ASMJIT_INLINE size_t getLength() const {
+ return _d->length;
+ }
+
+ //! Get capacity.
+ ASMJIT_INLINE size_t getCapacity() const {
+ return _d->capacity;
+ }
+
+ //! Get data.
+ ASMJIT_INLINE T* getData() {
+ return static_cast<T*>(_d->getData());
+ }
+
+ //! \overload
+ ASMJIT_INLINE const T* getData() const {
+ return static_cast<const T*>(_d->getData());
+ }
+
+ // --------------------------------------------------------------------------
+ // [Grow / Reserve]
+ // --------------------------------------------------------------------------
+
+ //! Called to grow the buffer to fit at least `n` elements more.
+ ASMJIT_INLINE Error _grow(size_t n) {
+ return PodVectorBase::_grow(n, sizeof(T));
+ }
+
+ //! Realloc internal array to fit at least `n` items.
+ ASMJIT_INLINE Error _reserve(size_t n) {
+ return PodVectorBase::_reserve(n, sizeof(T));
+ }
+
+ // --------------------------------------------------------------------------
+ // [Ops]
+ // --------------------------------------------------------------------------
+
+ //! Prepend `item` to vector.
+ Error prepend(const T& item) {
+ PodVectorData* d = _d;
+
+ if (d->length == d->capacity) {
+ ASMJIT_PROPAGATE_ERROR(_grow(1));
+ _d = d;
+ }
+
+ ::memmove(static_cast<T*>(d->getData()) + 1, d->getData(), d->length * sizeof(T));
+ ::memcpy(d->getData(), &item, sizeof(T));
+
+ d->length++;
+ return kErrorOk;
+ }
+
+ //! Insert an `item` at the `index`.
+ Error insert(size_t index, const T& item) {
+ PodVectorData* d = _d;
+ ASMJIT_ASSERT(index <= d->length);
+
+ if (d->length == d->capacity) {
+ ASMJIT_PROPAGATE_ERROR(_grow(1));
+ d = _d;
+ }
+
+ T* dst = static_cast<T*>(d->getData()) + index;
+ ::memmove(dst + 1, dst, d->length - index);
+ ::memcpy(dst, &item, sizeof(T));
+
+ d->length++;
+ return kErrorOk;
+ }
+
+ //! Append `item` to vector.
+ Error append(const T& item) {
+ PodVectorData* d = _d;
+
+ if (d->length == d->capacity) {
+ ASMJIT_PROPAGATE_ERROR(_grow(1));
+ d = _d;
+ }
+
+ ::memcpy(static_cast<T*>(d->getData()) + d->length, &item, sizeof(T));
+
+ d->length++;
+ return kErrorOk;
+ }
+
+ //! Get index of `val` or `kInvalidIndex` if not found.
+ size_t indexOf(const T& val) const {
+ PodVectorData* d = _d;
+
+ const T* data = static_cast<const T*>(d->getData());
+ size_t len = d->length;
+
+ for (size_t i = 0; i < len; i++)
+ if (data[i] == val)
+ return i;
+
+ return kInvalidIndex;
+ }
+
+ //! Remove item at index `i`.
+ void removeAt(size_t i) {
+ PodVectorData* d = _d;
+ ASMJIT_ASSERT(i < d->length);
+
+ T* data = static_cast<T*>(d->getData()) + i;
+ d->length--;
+ ::memmove(data, data + 1, d->length - i);
+ }
+
+ //! Swap this pod-vector with `other`.
+ void swap(PodVector<T>& other) {
+ T* otherData = other._d;
+ other._d = _d;
+ _d = otherData;
+ }
+
+ //! Get item at index `i`.
+ ASMJIT_INLINE T& operator[](size_t i) {
+ ASMJIT_ASSERT(i < getLength());
+ return getData()[i];
+ }
+
+ //! Get item at index `i`.
+ ASMJIT_INLINE const T& operator[](size_t i) const {
+ ASMJIT_ASSERT(i < getLength());
+ return getData()[i];
+ }
+};
+
+// ============================================================================
+// [asmjit::PodList<T>]
+// ============================================================================
+
+//! \internal
+template <typename T>
+struct PodList {
+ ASMJIT_NO_COPY(PodList<T>)
+
+ // --------------------------------------------------------------------------
+ // [Link]
+ // --------------------------------------------------------------------------
+
+ struct Link {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get next node.
+ ASMJIT_INLINE Link* getNext() const { return _next; }
+
+ //! Get value.
+ ASMJIT_INLINE T getValue() const { return _value; }
+ //! Set value to `value`.
+ ASMJIT_INLINE void setValue(const T& value) { _value = value; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ Link* _next;
+ T _value;
+ };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE PodList() : _first(nullptr), _last(nullptr) {}
+ ASMJIT_INLINE ~PodList() {}
+
+ // --------------------------------------------------------------------------
+ // [Data]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE bool isEmpty() const { return !!_first; }
+
+ ASMJIT_INLINE Link* getFirst() const { return _first; }
+ ASMJIT_INLINE Link* getLast() const { return _last; }
+
+ // --------------------------------------------------------------------------
+ // [Ops]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void reset() {
+ _first = nullptr;
+ _last = nullptr;
+ }
+
+ ASMJIT_INLINE void prepend(Link* link) {
+ link->_next = _first;
+ if (!_first)
+ _last = link;
+ _first = link;
+ }
+
+ ASMJIT_INLINE void append(Link* link) {
+ link->_next = nullptr;
+ if (!_first)
+ _first = link;
+ else
+ _last->_next = link;
+ _last = link;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ Link* _first;
+ Link* _last;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/context.cpp
@@ -1,1 +1,562 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Guard]
+#include "../build.h"
+#ifndef ASMJIT_DISABLE_COMPILER
+
+// [Dependencies - AsmJit]
+#include "../base/context_p.h"
+#include "../base/intutil.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [asmjit::Context - Construction / Destruction]
+// ============================================================================
+
+Context::Context(Compiler* compiler) :
+ _compiler(compiler),
+ _baseZone(8192 - kZoneOverhead),
+ _varMapToVaListOffset(0) {
+
+ Context::reset();
+}
+
+Context::~Context() {}
+
+// ============================================================================
+// [asmjit::Context - Reset]
+// ============================================================================
+
+void Context::reset(bool releaseMemory) {
+ _baseZone.reset(releaseMemory);
+
+ _func = nullptr;
+ _start = nullptr;
+ _end = nullptr;
+ _extraBlock = nullptr;
+ _stop = nullptr;
+
+ _unreachableList.reset();
+ _jccList.reset();
+ _contextVd.reset(releaseMemory);
+
+ _memVarCells = nullptr;
+ _memStackCells = nullptr;
+
+ _mem1ByteVarsUsed = 0;
+ _mem2ByteVarsUsed = 0;
+ _mem4ByteVarsUsed = 0;
+ _mem8ByteVarsUsed = 0;
+ _mem16ByteVarsUsed = 0;
+ _mem32ByteVarsUsed = 0;
+ _mem64ByteVarsUsed = 0;
+ _memStackCellsUsed = 0;
+
+ _memMaxAlign = 0;
+ _memVarTotal = 0;
+ _memStackTotal = 0;
+ _memAllTotal = 0;
+ _annotationLength = 12;
+
+ _state = nullptr;
+}
+
+// ============================================================================
+// [asmjit::Context - Mem]
+// ============================================================================
+
+static ASMJIT_INLINE uint32_t BaseContext_getDefaultAlignment(uint32_t size) {
+ if (size > 32)
+ return 64;
+ else if (size > 16)
+ return 32;
+ else if (size > 8)
+ return 16;
+ else if (size > 4)
+ return 8;
+ else if (size > 2)
+ return 4;
+ else if (size > 1)
+ return 2;
+ else
+ return 1;
+}
+
+MemCell* Context::_newVarCell(VarData* vd) {
+ ASMJIT_ASSERT(!vd->_memCell);
+
+ MemCell* cell;
+ uint32_t size = vd->getSize();
+
+ if (vd->isStack()) {
+ cell = _newStackCell(size, vd->getAlignment());
+
+ if (!cell)
+ return nullptr;
+ }
+ else {
+ cell = static_cast<MemCell*>(_baseZone.alloc(sizeof(MemCell)));
+ if (!cell)
+ goto _NoMemory;
+
+ cell->_next = _memVarCells;
+ _memVarCells = cell;
+
+ cell->_offset = 0;
+ cell->_size = size;
+ cell->_alignment = size;
+
+ _memMaxAlign = IntUtil::iMax<uint32_t>(_memMaxAlign, size);
+ _memVarTotal += size;
+
+ switch (size) {
+ case 1: _mem1ByteVarsUsed++ ; break;
+ case 2: _mem2ByteVarsUsed++ ; break;
+ case 4: _mem4ByteVarsUsed++ ; break;
+ case 8: _mem8ByteVarsUsed++ ; break;
+ case 16: _mem16ByteVarsUsed++; break;
+ case 32: _mem32ByteVarsUsed++; break;
+ case 64: _mem64ByteVarsUsed++; break;
+ default: ASMJIT_ASSERT(!"Reached");
+ }
+ }
+
+ vd->_memCell = cell;
+ return cell;
+
+_NoMemory:
+ _compiler->setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+MemCell* Context::_newStackCell(uint32_t size, uint32_t alignment) {
+ MemCell* cell = static_cast<MemCell*>(_baseZone.alloc(sizeof(MemCell)));
+ if (!cell)
+ goto _NoMemory;
+
+ if (alignment == 0)
+ alignment = BaseContext_getDefaultAlignment(size);
+
+ if (alignment > 64)
+ alignment = 64;
+
+ ASMJIT_ASSERT(IntUtil::isPowerOf2(alignment));
+ size = IntUtil::alignTo<uint32_t>(size, alignment);
+
+ // Insert it sorted according to the alignment and size.
+ {
+ MemCell** pPrev = &_memStackCells;
+ MemCell* cur = *pPrev;
+
+ for (cur = *pPrev; cur; cur = cur->_next) {
+ if (cur->getAlignment() > alignment)
+ continue;
+ if (cur->getAlignment() == alignment && cur->getSize() > size)
+ continue;
+ break;
+ }
+
+ cell->_next = cur;
+ cell->_offset = 0;
+ cell->_size = size;
+ cell->_alignment = alignment;
+
+ *pPrev = cell;
+ _memStackCellsUsed++;
+
+ _memMaxAlign = IntUtil::iMax<uint32_t>(_memMaxAlign, alignment);
+ _memStackTotal += size;
+ }
+
+ return cell;
+
+_NoMemory:
+ _compiler->setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+Error Context::resolveCellOffsets() {
+ MemCell* varCell = _memVarCells;
+ MemCell* stackCell = _memStackCells;
+
+ uint32_t stackAlignment = 0;
+ if (stackCell)
+ stackAlignment = stackCell->getAlignment();
+
+ uint32_t pos64 = 0;
+ uint32_t pos32 = pos64 + _mem64ByteVarsUsed * 64;
+ uint32_t pos16 = pos32 + _mem32ByteVarsUsed * 32;
+ uint32_t pos8 = pos16 + _mem16ByteVarsUsed * 16;
+ uint32_t pos4 = pos8 + _mem8ByteVarsUsed * 8 ;
+ uint32_t pos2 = pos4 + _mem4ByteVarsUsed * 4 ;
+ uint32_t pos1 = pos2 + _mem2ByteVarsUsed * 2 ;
+
+ uint32_t stackPos = pos1 + _mem1ByteVarsUsed;
+
+ uint32_t gapAlignment = stackAlignment;
+ uint32_t gapSize = 0;
+
+ if (gapAlignment)
+ IntUtil::deltaTo(stackPos, gapAlignment);
+ stackPos += gapSize;
+
+ uint32_t gapPos = stackPos;
+ uint32_t allTotal = stackPos;
+
+ // Vars - Allocated according to alignment/width.
+ while (varCell) {
+ uint32_t size = varCell->getSize();
+ uint32_t offset = 0;
+
+ switch (size) {
+ case 1: offset = pos1 ; pos1 += 1 ; break;
+ case 2: offset = pos2 ; pos2 += 2 ; break;
+ case 4: offset = pos4 ; pos4 += 4 ; break;
+ case 8: offset = pos8 ; pos8 += 8 ; break;
+ case 16: offset = pos16; pos16 += 16; break;
+ case 32: offset = pos32; pos32 += 32; break;
+ case 64: offset = pos64; pos64 += 64; break;
+ default: ASMJIT_ASSERT(!"Reached");
+ }
+
+ varCell->setOffset(static_cast<int32_t>(offset));
+ varCell = varCell->_next;
+ }
+
+ // Stack - Allocated according to alignment and width.
+ while (stackCell) {
+ uint32_t size = stackCell->getSize();
+ uint32_t alignment = stackCell->getAlignment();
+ uint32_t offset;
+
+ // Try to fill the gap between variables / stack first.
+ if (size <= gapSize && alignment <= gapAlignment) {
+ offset = gapPos;
+
+ gapSize -= size;
+ gapPos -= size;
+
+ if (alignment < gapAlignment)
+ gapAlignment = alignment;
+ }
+ else {
+ offset = stackPos;
+
+ stackPos += size;
+ allTotal += size;
+ }
+
+ stackCell->setOffset(offset);
+ stackCell = stackCell->_next;
+ }
+
+ _memAllTotal = allTotal;
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::Context - RemoveUnreachableCode]
+// ============================================================================
+
+Error Context::removeUnreachableCode() {
+ PodList<Node*>::Link* link = _unreachableList.getFirst();
+ Node* stop = getStop();
+
+ while (link) {
+ Node* node = link->getValue();
+ if (node && node->getPrev()) {
+ // Locate all unreachable nodes.
+ Node* first = node;
+ do {
+ if (node->isFetched())
+ break;
+ node = node->getNext();
+ } while (node != stop);
+
+ // Remove.
+ if (node != first) {
+ Node* last = node ? node->getPrev() : getCompiler()->getLastNode();
+ getCompiler()->removeNodes(first, last);
+ }
+ }
+
+ link = link->getNext();
+ }
+
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::Context - Liveness Analysis]
+// ============================================================================
+
+//! \internal
+struct LivenessTarget {
+ //! Previous target.
+ LivenessTarget* prev;
+
+ //! Target node.
+ TargetNode* node;
+ //! Jumped from.
+ JumpNode* from;
+};
+
+Error Context::livenessAnalysis() {
+ FuncNode* func = getFunc();
+ JumpNode* from = nullptr;
+
+ Node* node = func->getEnd();
+ uint32_t bLen = static_cast<uint32_t>(
+ ((_contextVd.getLength() + VarBits::kEntityBits - 1) / VarBits::kEntityBits));
+
+ LivenessTarget* ltCur = nullptr;
+ LivenessTarget* ltUnused = nullptr;
+
+ size_t varMapToVaListOffset = _varMapToVaListOffset;
+
+ // No variables.
+ if (bLen == 0)
+ return kErrorOk;
+
+ VarBits* bCur = newBits(bLen);
+ if (!bCur)
+ goto _NoMemory;
+
+ // Allocate bits for code visited first time.
+_OnVisit:
+ for (;;) {
+ if (node->hasLiveness()) {
+ if (bCur->_addBitsDelSource(node->getLiveness(), bCur, bLen))
+ goto _OnPatch;
+ else
+ goto _OnDone;
+ }
+
+ VarBits* bTmp = copyBits(bCur, bLen);
+ if (!bTmp)
+ goto _NoMemory;
+
+ node->setLiveness(bTmp);
+ VarMap* map = node->getMap();
+
+ if (map) {
+ uint32_t vaCount = map->getVaCount();
+ VarAttr* vaList = reinterpret_cast<VarAttr*>(reinterpret_cast<uint8_t*>(map) + varMapToVaListOffset);
+
+ for (uint32_t i = 0; i < vaCount; i++) {
+ VarAttr* va = &vaList[i];
+ VarData* vd = va->getVd();
+
+ uint32_t flags = va->getFlags();
+ uint32_t ctxId = vd->getContextId();
+
+ if ((flags & kVarAttrOutAll) && !(flags & kVarAttrInAll)) {
+ // Write-Only.
+ bTmp->setBit(ctxId);
+ bCur->delBit(ctxId);
+ }
+ else {
+ // Read-Only or Read/Write.
+ bTmp->setBit(ctxId);
+ bCur->setBit(ctxId);
+ }
+ }
+ }
+
+ if (node->getType() == kNodeTypeTarget)
+ goto _OnTarget;
+
+ if (node == func)
+ goto _OnDone;
+
+ ASMJIT_ASSERT(node->getPrev());
+ node = node->getPrev();
+ }
+
+ // Patch already generated liveness bits.
+_OnPatch:
+ for (;;) {
+ ASMJIT_ASSERT(node->hasLiveness());
+ VarBits* bNode = node->getLiveness();
+
+ if (!bNode->_addBitsDelSource(bCur, bLen))
+ goto _OnDone;
+
+ if (node->getType() == kNodeTypeTarget)
+ goto _OnTarget;
+
+ if (node == func)
+ goto _OnDone;
+
+ node = node->getPrev();
+ }
+
+_OnTarget:
+ if (static_cast<TargetNode*>(node)->getNumRefs() != 0) {
+ // Push a new LivenessTarget onto the stack if needed.
+ if (!ltCur || ltCur->node != node) {
+ // Allocate a new LivenessTarget object (from pool or zone).
+ LivenessTarget* ltTmp = ltUnused;
+
+ if (ltTmp) {
+ ltUnused = ltUnused->prev;
+ }
+ else {
+ ltTmp = _baseZone.allocT<LivenessTarget>(
+ sizeof(LivenessTarget) - sizeof(VarBits) + bLen * sizeof(uintptr_t));
+
+ if (!ltTmp)
+ goto _NoMemory;
+ }
+
+ // Initialize and make current - ltTmp->from will be set later on.
+ ltTmp->prev = ltCur;
+ ltTmp->node = static_cast<TargetNode*>(node);
+ ltCur = ltTmp;
+
+ from = static_cast<TargetNode*>(node)->getFrom();
+ ASMJIT_ASSERT(from);
+ }
+ else {
+ from = ltCur->from;
+ goto _OnJumpNext;
+ }
+
+ // Visit/Patch.
+ do {
+ ltCur->from = from;
+ bCur->copyBits(node->getLiveness(), bLen);
+
+ if (!from->hasLiveness()) {
+ node = from;
+ goto _OnVisit;
+ }
+
+ // Issue #25: Moved '_OnJumpNext' here since it's important to patch
+ // code again if there are more live variables than before.
+_OnJumpNext:
+ if (bCur->delBits(from->getLiveness(), bLen)) {
+ node = from;
+ goto _OnPatch;
+ }
+
+ from = from->getJumpNext();
+ } while (from);
+
+ // Pop the current LivenessTarget from the stack.
+ {
+ LivenessTarget* ltTmp = ltCur;
+
+ ltCur = ltCur->prev;
+ ltTmp->prev = ltUnused;
+ ltUnused = ltTmp;
+ }
+ }
+
+ bCur->copyBits(node->getLiveness(), bLen);
+ node = node->getPrev();
+
+ if (node->isJmp() || !node->isFetched())
+ goto _OnDone;
+
+ if (!node->hasLiveness())
+ goto _OnVisit;
+
+ if (bCur->delBits(node->getLiveness(), bLen))
+ goto _OnPatch;
+
+_OnDone:
+ if (ltCur) {
+ node = ltCur->node;
+ from = ltCur->from;
+
+ goto _OnJumpNext;
+ }
+ return kErrorOk;
+
+_NoMemory:
+ return setError(kErrorNoHeapMemory);
+}
+
+// ============================================================================
+// [asmjit::Context - Schedule]
+// ============================================================================
+
+Error Context::schedule() {
+ // By default there is no instruction scheduler implemented.
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::Context - Cleanup]
+// ============================================================================
+
+void Context::cleanup() {
+ VarData** array = _contextVd.getData();
+ size_t length = _contextVd.getLength();
+
+ for (size_t i = 0; i < length; i++) {
+ VarData* vd = array[i];
+ vd->resetContextId();
+ vd->resetRegIndex();
+ }
+
+ _contextVd.reset(false);
+ _extraBlock = nullptr;
+}
+
+// ============================================================================
+// [asmjit::Context - CompileFunc]
+// ============================================================================
+
+Error Context::compile(FuncNode* func) {
+ Node* end = func->getEnd();
+ Node* stop = end->getNext();
+
+ _func = func;
+ _stop = stop;
+ _extraBlock = end;
+
+ ASMJIT_PROPAGATE_ERROR(fetch());
+ ASMJIT_PROPAGATE_ERROR(removeUnreachableCode());
+ ASMJIT_PROPAGATE_ERROR(livenessAnalysis());
+
+ Compiler* compiler = getCompiler();
+
+#ifndef ASMJIT_DISABLE_LOGGER
+ if (compiler->hasLogger())
+ ASMJIT_PROPAGATE_ERROR(annotate());
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ ASMJIT_PROPAGATE_ERROR(translate());
+
+ if (compiler->hasFeature(kCodeGenEnableScheduler))
+ ASMJIT_PROPAGATE_ERROR(schedule());
+
+ // We alter the compiler cursor, because it doesn't make sense to reference
+ // it after compilation - some nodes may disappear and it's forbidden to add
+ // new code after the compilation is done.
+ compiler->_setCursor(nullptr);
+
+ return kErrorOk;
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // !ASMJIT_DISABLE_COMPILER
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/context_p.h
@@ -1,1 +1,304 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+#include "../build.h"
+#ifndef ASMJIT_DISABLE_COMPILER
+
+// [Dependencies - AsmJit]
+#include "../base/compiler.h"
+#include "../base/zone.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_compiler
+//! \{
+
+// ============================================================================
+// [asmjit::Context]
+// ============================================================================
+
+//! \internal
+//!
+//! Code generation context is the logic behind `Compiler`. The context is
+//! used to compile the code stored in `Compiler`.
+struct Context {
+ ASMJIT_NO_COPY(Context)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ Context(Compiler* compiler);
+ virtual ~Context();
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ //! Reset the whole context.
+ virtual void reset(bool releaseMemory = false);
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get compiler.
+ ASMJIT_INLINE Compiler* getCompiler() const { return _compiler; }
+
+ //! Get function.
+ ASMJIT_INLINE FuncNode* getFunc() const { return _func; }
+ //! Get stop node.
+ ASMJIT_INLINE Node* getStop() const { return _stop; }
+
+ //! Get start of the current scope.
+ ASMJIT_INLINE Node* getStart() const { return _start; }
+ //! Get end of the current scope.
+ ASMJIT_INLINE Node* getEnd() const { return _end; }
+
+ //! Get extra block.
+ ASMJIT_INLINE Node* getExtraBlock() const { return _extraBlock; }
+ //! Set extra block.
+ ASMJIT_INLINE void setExtraBlock(Node* node) { _extraBlock = node; }
+
+ // --------------------------------------------------------------------------
+ // [Error]
+ // --------------------------------------------------------------------------
+
+ //! Get the last error code.
+ ASMJIT_INLINE Error getError() const {
+ return getCompiler()->getError();
+ }
+
+ //! Set the last error code and propagate it through the error handler.
+ ASMJIT_INLINE Error setError(Error error, const char* message = nullptr) {
+ return getCompiler()->setError(error, message);
+ }
+
+ // --------------------------------------------------------------------------
+ // [State]
+ // --------------------------------------------------------------------------
+
+ //! Get current state.
+ ASMJIT_INLINE VarState* getState() const {
+ return _state;
+ }
+
+ //! Load current state from `target` state.
+ virtual void loadState(VarState* src) = 0;
+
+ //! Save current state, returning new `VarState` instance.
+ virtual VarState* saveState() = 0;
+
+ //! Change the current state to `target` state.
+ virtual void switchState(VarState* src) = 0;
+
+ //! Change the current state to the intersection of two states `a` and `b`.
+ virtual void intersectStates(VarState* a, VarState* b) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Context]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Error _registerContextVar(VarData* vd) {
+ if (vd->hasContextId())
+ return kErrorOk;
+
+ uint32_t cid = static_cast<uint32_t>(_contextVd.getLength());
+ ASMJIT_PROPAGATE_ERROR(_contextVd.append(vd));
+
+ vd->setContextId(cid);
+ return kErrorOk;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Mem]
+ // --------------------------------------------------------------------------
+
+ MemCell* _newVarCell(VarData* vd);
+ MemCell* _newStackCell(uint32_t size, uint32_t alignment);
+
+ ASMJIT_INLINE MemCell* getVarCell(VarData* vd) {
+ MemCell* cell = vd->getMemCell();
+ return cell ? cell : _newVarCell(vd);
+ }
+
+ virtual Error resolveCellOffsets();
+
+ // --------------------------------------------------------------------------
+ // [Bits]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE VarBits* newBits(uint32_t len) {
+ return static_cast<VarBits*>(
+ _baseZone.allocZeroed(static_cast<size_t>(len) * VarBits::kEntitySize));
+ }
+
+ ASMJIT_INLINE VarBits* copyBits(const VarBits* src, uint32_t len) {
+ return static_cast<VarBits*>(
+ _baseZone.dup(src, static_cast<size_t>(len) * VarBits::kEntitySize));
+ }
+
+ // --------------------------------------------------------------------------
+ // [Fetch]
+ // --------------------------------------------------------------------------
+
+ //! Fetch.
+ //!
+ //! Fetch iterates over all nodes and gathers information about all variables
+ //! used. The process generates information required by register allocator,
+ //! variable liveness analysis and translator.
+ virtual Error fetch() = 0;
+
+ // --------------------------------------------------------------------------
+ // [RemoveUnreachableCode]
+ // --------------------------------------------------------------------------
+
+ //! Remove unreachable code.
+ virtual Error removeUnreachableCode();
+
+ // --------------------------------------------------------------------------
+ // [Analyze]
+ // --------------------------------------------------------------------------
+
+ //! Perform variable liveness analysis.
+ //!
+ //! Analysis phase iterates over nodes in reverse order and generates a bit
+ //! array describing variables that are alive at every node in the function.
+ //! When the analysis start all variables are assumed dead. When a read or
+ //! read/write operations of a variable is detected the variable becomes
+ //! alive; when only write operation is detected the variable becomes dead.
+ //!
+ //! When a label is found all jumps to that label are followed and analysis
+ //! repeats until all variables are resolved.
+ virtual Error livenessAnalysis();
+
+ // --------------------------------------------------------------------------
+ // [Annotate]
+ // --------------------------------------------------------------------------
+
+ virtual Error annotate() = 0;
+
+ // --------------------------------------------------------------------------
+ // [Translate]
+ // --------------------------------------------------------------------------
+
+ //! Translate code by allocating registers and handling state changes.
+ virtual Error translate() = 0;
+
+ // --------------------------------------------------------------------------
+ // [Schedule]
+ // --------------------------------------------------------------------------
+
+ virtual Error schedule();
+
+ // --------------------------------------------------------------------------
+ // [Cleanup]
+ // --------------------------------------------------------------------------
+
+ virtual void cleanup();
+
+ // --------------------------------------------------------------------------
+ // [Compile]
+ // --------------------------------------------------------------------------
+
+ virtual Error compile(FuncNode* func);
+
+ // --------------------------------------------------------------------------
+ // [Serialize]
+ // --------------------------------------------------------------------------
+
+ virtual Error serialize(Assembler* assembler, Node* start, Node* stop) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Compiler.
+ Compiler* _compiler;
+ //! Function.
+ FuncNode* _func;
+
+ //! Zone allocator.
+ Zone _baseZone;
+
+ //! \internal
+ //!
+ //! Offset (how many bytes to add) to `VarMap` to get `VarAttr` array. Used
+ //! by liveness analysis shared across all backends. This is needed because
+ //! `VarMap` is a base class for a specialized version that liveness analysis
+ //! doesn't use, it just needs `VarAttr` array.
+ uint32_t _varMapToVaListOffset;
+
+ //! Start of the current active scope.
+ Node* _start;
+ //! End of the current active scope.
+ Node* _end;
+
+ //! Node that is used to insert extra code after the function body.
+ Node* _extraBlock;
+ //! Stop node.
+ Node* _stop;
+
+ //! Unreachable nodes.
+ PodList<Node*> _unreachableList;
+ //! Jump nodes.
+ PodList<Node*> _jccList;
+
+ //! All variables used by the current function.
+ PodVector<VarData*> _contextVd;
+
+ //! Memory used to spill variables.
+ MemCell* _memVarCells;
+ //! Memory used to alloc memory on the stack.
+ MemCell* _memStackCells;
+
+ //! Count of 1-byte cells.
+ uint32_t _mem1ByteVarsUsed;
+ //! Count of 2-byte cells.
+ uint32_t _mem2ByteVarsUsed;
+ //! Count of 4-byte cells.
+ uint32_t _mem4ByteVarsUsed;
+ //! Count of 8-byte cells.
+ uint32_t _mem8ByteVarsUsed;
+ //! Count of 16-byte cells.
+ uint32_t _mem16ByteVarsUsed;
+ //! Count of 32-byte cells.
+ uint32_t _mem32ByteVarsUsed;
+ //! Count of 64-byte cells.
+ uint32_t _mem64ByteVarsUsed;
+ //! Count of stack memory cells.
+ uint32_t _memStackCellsUsed;
+
+ //! Maximum memory alignment used by the function.
+ uint32_t _memMaxAlign;
+ //! Count of bytes used by variables.
+ uint32_t _memVarTotal;
+ //! Count of bytes used by stack.
+ uint32_t _memStackTotal;
+ //! Count of bytes used by variables and stack after alignment.
+ uint32_t _memAllTotal;
+
+ //! Default lenght of annotated instruction.
+ uint32_t _annotationLength;
+
+ //! Current state (used by register allocator).
+ VarState* _state;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+#endif // !ASMJIT_DISABLE_COMPILER
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/cpuinfo.cpp
@@ -1,1 +1,80 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Dependencies - AsmJit]
+#include "../base/cpuinfo.h"
+
+#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
+# include "../x86/x86cpuinfo.h"
+#else
+// ?
+#endif // ASMJIT_HOST || ASMJIT_HOST_X64
+
+// [Dependencies - Posix]
+#ifdef ASMJIT_OS_POSIX
+# include <cerrno>
+# include <sys/statvfs.h>
+# include <sys/utsname.h>
+# include <unistd.h>
+#endif // ASMJIT_OS_POSIX
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [asmjit::CpuInfo - DetectHwThreadsCount]
+// ============================================================================
+
+uint32_t CpuInfo::detectHwThreadsCount() {
+#ifdef ASMJIT_OS_WINDOWS
+ SYSTEM_INFO info;
+ ::GetSystemInfo(&info);
+ return info.dwNumberOfProcessors;
+#elif defined(ASMJIT_OS_POSIX) && defined(_SC_NPROCESSORS_ONLN)
+ // It seems that sysconf returns the number of "logical" processors on both
+ // mac and linux. So we get the number of "online logical" processors.
+ long res = ::sysconf(_SC_NPROCESSORS_ONLN);
+ if (res == -1) return 1;
+
+ return static_cast<uint32_t>(res);
+#else
+ return 1;
+#endif
+}
+
+// ============================================================================
+// [asmjit::CpuInfo - GetHost]
+// ============================================================================
+
+#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
+struct AutoX86CpuInfo : public X86CpuInfo {
+ ASMJIT_INLINE AutoX86CpuInfo() : X86CpuInfo() {
+ X86CpuUtil::detect(this);
+ }
+};
+#else
+# error "AsmJit - Unsupported CPU."
+#endif // ASMJIT_HOST || ASMJIT_HOST_X64
+
+const CpuInfo* CpuInfo::getHost() {
+#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
+ static AutoX86CpuInfo cpuInfo;
+#else
+# error "AsmJit - Unsupported CPU."
+#endif // ASMJIT_HOST || ASMJIT_HOST_X64
+ return &cpuInfo;
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/cpuinfo.h
@@ -1,1 +1,143 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::kCpuVendor]
+// ============================================================================
+
+//! Cpu vendor ID.
+//!
+//! Vendor IDs are specific to AsmJit library. During the library initialization
+//! AsmJit checks host CPU and tries to identify the vendor based on the CPUID
+//! calls. Some manufacturers changed their vendor strings and AsmJit is aware
+//! of that - it checks multiple combinations and decides which vendor ID should
+//! be used.
+ASMJIT_ENUM(kCpuVendor) {
+ //! No/Unknown vendor.
+ kCpuVendorNone = 0,
+
+ //! Intel vendor.
+ kCpuVendorIntel = 1,
+ //! AMD vendor.
+ kCpuVendorAmd = 2,
+ //! VIA vendor.
+ kCpuVendorVia = 3
+};
+
+// ============================================================================
+// [asmjit::CpuInfo]
+// ============================================================================
+
+//! Base cpu information.
+struct CpuInfo {
+ ASMJIT_NO_COPY(CpuInfo)
+
+ //! \internal
+ enum {
+ kFeaturesPerUInt32 = static_cast<int>(sizeof(uint32_t)) * 8
+ };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE CpuInfo(uint32_t size = sizeof(CpuInfo)) : _size(size) {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get CPU vendor string.
+ ASMJIT_INLINE const char* getVendorString() const { return _vendorString; }
+ //! Get CPU brand string.
+ ASMJIT_INLINE const char* getBrandString() const { return _brandString; }
+
+ //! Get CPU vendor ID.
+ ASMJIT_INLINE uint32_t getVendorId() const { return _vendorId; }
+ //! Get CPU family ID.
+ ASMJIT_INLINE uint32_t getFamily() const { return _family; }
+ //! Get CPU model ID.
+ ASMJIT_INLINE uint32_t getModel() const { return _model; }
+ //! Get CPU stepping.
+ ASMJIT_INLINE uint32_t getStepping() const { return _stepping; }
+
+ //! Get number of hardware threads available.
+ ASMJIT_INLINE uint32_t getHwThreadsCount() const { return _hwThreadsCount; }
+
+ //! Get whether CPU has a `feature`.
+ ASMJIT_INLINE bool hasFeature(uint32_t feature) const {
+ ASMJIT_ASSERT(feature < sizeof(_features) * 8);
+
+ return static_cast<bool>(
+ (_features[feature / kFeaturesPerUInt32] >> (feature % kFeaturesPerUInt32)) & 0x1);
+ }
+
+ //! Add a CPU `feature`.
+ ASMJIT_INLINE CpuInfo& addFeature(uint32_t feature) {
+ ASMJIT_ASSERT(feature < sizeof(_features) * 8);
+
+ _features[feature / kFeaturesPerUInt32] |= (1U << (feature % kFeaturesPerUInt32));
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Statics]
+ // --------------------------------------------------------------------------
+
+ //! Detect the number of hardware threads.
+ static ASMJIT_API uint32_t detectHwThreadsCount();
+
+ //! Get host cpu.
+ static ASMJIT_API const CpuInfo* getHost();
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Size of the structure in bytes.
+ uint32_t _size;
+
+ //! Cpu short vendor string.
+ char _vendorString[16];
+ //! Cpu long vendor string (brand).
+ char _brandString[64];
+
+ //! Cpu vendor id, see `asmjit::kCpuVendor`.
+ uint32_t _vendorId;
+ //! Cpu family ID.
+ uint32_t _family;
+ //! Cpu model ID.
+ uint32_t _model;
+ //! Cpu stepping.
+ uint32_t _stepping;
+
+ //! Number of hardware threads.
+ uint32_t _hwThreadsCount;
+
+ //! Cpu features bitfield.
+ uint32_t _features[4];
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/cputicks.cpp
@@ -1,1 +1,132 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Dependencies - AsmJit]
+#include "../base/cputicks.h"
+
+// [Dependencies - Posix]
+#ifdef ASMJIT_OS_POSIX
+# include <ctime>
+# include <unistd.h>
+#endif // ASMJIT_OS_POSIX
+
+// [Dependencies - Mac]
+#ifdef ASMJIT_OS_MAC
+# include <mach/mach_time.h>
+#endif // ASMJIT_OS_MAC
+
+// [Dependencies - Windows]
+#ifdef ASMJIT_OS_WINDOWS
+// `_InterlockedCompareExchange` is only available as intrinsic (MS Compiler).
+# ifdef _MSC_VER
+# include <intrin.h>
+# pragma intrinsic(_InterlockedCompareExchange)
+# else
+# define _InterlockedCompareExchange InterlockedCompareExchange
+# endif // _MSC_VER
+#endif // ASMJIT_OS_WINDOWS
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [asmjit::CpuTicks - Windows]
+// ============================================================================
+
+#ifdef ASMJIT_OS_WINDOWS
+static volatile uint32_t CpuTicks_hiResOk;
+static volatile double CpuTicks_hiResFreq;
+
+uint32_t CpuTicks::now() {
+ do {
+ uint32_t hiResOk = CpuTicks_hiResOk;
+
+ if (hiResOk == 1) {
+ LARGE_INTEGER now;
+ if (!::QueryPerformanceCounter(&now))
+ break;
+ return static_cast<int64_t>(now.QuadPart / CpuTicks_hiResFreq);
+ }
+
+ if (hiResOk == 0) {
+ LARGE_INTEGER qpf;
+ if (!::QueryPerformanceFrequency(&qpf)) {
+ _InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(&CpuTicks_hiResOk), 0xFFFFFFFF, 0);
+ break;
+ }
+
+ LARGE_INTEGER now;
+ if (!::QueryPerformanceCounter(&now)) {
+ _InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(&CpuTicks_hiResOk), 0xFFFFFFFF, 0);
+ break;
+ }
+
+ double freqDouble = double(qpf.QuadPart) / 1000.0;
+
+ CpuTicks_hiResFreq = freqDouble;
+ _InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(&CpuTicks_hiResOk), 1, 0);
+
+ return static_cast<uint32_t>(
+ static_cast<int64_t>(now.QuadPart / freqDouble) & 0xFFFFFFFF);
+ }
+ } while (0);
+
+ // Bail to a less precise GetTickCount().
+ return ::GetTickCount();
+}
+
+// ============================================================================
+// [asmjit::CpuTicks - Mac]
+// ============================================================================
+
+#elif defined(ASMJIT_OS_MAC)
+static mach_timebase_info_data_t CpuTicks_machTime;
+
+uint32_t CpuTicks::now() {
+ // Initialize the first time CpuTicks::now() is called (See Apple's QA1398).
+ if (CpuTicks_machTime.denom == 0) {
+ if (mach_timebase_info(&CpuTicks_machTime) != KERN_SUCCESS);
+ return 0;
+ }
+
+ // mach_absolute_time() returns nanoseconds, we need just milliseconds.
+ uint64_t t = mach_absolute_time() / 1000000;
+
+ t = t * CpuTicks_machTime.numer / CpuTicks_machTime.denom;
+ return static_cast<uint32_t>(t & 0xFFFFFFFFU);
+}
+
+// ============================================================================
+// [asmjit::CpuTicks - Posix]
+// ============================================================================
+
+#else
+uint32_t CpuTicks::now() {
+# if defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
+ struct timespec ts;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
+ return 0;
+
+ uint64_t t = (uint64_t(ts.tv_sec ) * 1000) + (uint64_t(ts.tv_nsec) / 1000000);
+ return static_cast<uint32_t>(t & 0xFFFFFFFFU);
+# else // _POSIX_MONOTONIC_CLOCK
+# error "AsmJit - Unsupported OS."
+ return 0;
+# endif // _POSIX_MONOTONIC_CLOCK
+}
+#endif // ASMJIT_OS
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/cputicks.h
@@ -1,1 +1,36 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::CpuTicks]
+// ============================================================================
+
+//! CPU ticks utilities.
+struct CpuTicks {
+ //! Get the current CPU ticks for benchmarking (1ms resolution).
+ static ASMJIT_API uint32_t now();
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/error.cpp
@@ -1,1 +1,82 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Dependencies - AsmJit]
+#include "../base/error.h"
+#include "../base/intutil.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [asmjit::ErrorHandler - Construction / Destruction]
+// ============================================================================
+
+ErrorHandler::ErrorHandler() {}
+ErrorHandler::~ErrorHandler() {}
+
+// ============================================================================
+// [asmjit::ErrorHandler - Interface]
+// ============================================================================
+
+ErrorHandler* ErrorHandler::addRef() const {
+ return const_cast<ErrorHandler*>(this);
+}
+
+void ErrorHandler::release() {}
+
+// ============================================================================
+// [asmjit::ErrorUtil - AsString]
+// ============================================================================
+
+#ifndef ASMJIT_DISABLE_NAMES
+static const char errorMessages[] = {
+ "Ok\0"
+ "No heap memory\0"
+ "No virtual memory\0"
+ "Invalid argument\0"
+ "Invalid state\0"
+ "No code generated\0"
+ "Code too large\0"
+ "Label already bound\0"
+ "Unknown instruction\0"
+ "Illegal instruction\0"
+ "Illegal addressing\0"
+ "Illegal displacement\0"
+ "Overlapped arguments\0"
+ "Unknown error\0"
+};
+
+static const char* findPackedString(const char* p, uint32_t id, uint32_t maxId) {
+ uint32_t i = 0;
+
+ if (id > maxId)
+ id = maxId;
+
+ while (i < id) {
+ while (p[0])
+ p++;
+ p++;
+ }
+
+ return p;
+}
+
+const char* ErrorUtil::asString(Error e) {
+ return findPackedString(errorMessages, e, kErrorCount);
+}
+#endif // ASMJIT_DISABLE_NAMES
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/error.h
@@ -1,1 +1,214 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::kError]
+// ============================================================================
+
+//! AsmJit error codes.
+ASMJIT_ENUM(kError) {
+ //! No error (success).
+ //!
+ //! This is default state and state you want.
+ kErrorOk = 0,
+
+ //! Heap memory allocation failed.
+ kErrorNoHeapMemory = 1,
+
+ //! Virtual memory allocation failed.
+ kErrorNoVirtualMemory = 2,
+
+ //! Invalid argument.
+ kErrorInvalidArgument = 3,
+
+ //! Invalid state.
+ kErrorInvalidState = 4,
+
+ //! No code generated.
+ //!
+ //! Returned by runtime if the code-generator contains no code.
+ kErrorNoCodeGenerated = 5,
+
+ //! Code generated is too large to fit in memory reserved.
+ //!
+ //! Returned by `StaticRuntime` in case that the code generated is too large
+ //! to fit in the memory already reserved for it.
+ kErrorCodeTooLarge = 6,
+
+ //! Label is already bound.
+ kErrorLabelAlreadyBound = 7,
+
+ //! Unknown instruction (an instruction ID is out of bounds or instruction
+ //! name is invalid).
+ kErrorUnknownInst = 8,
+
+ //! Illegal instruction.
+ //!
+ //! This status code can also be returned in X64 mode if AH, BH, CH or DH
+ //! registers have been used together with a REX prefix. The instruction
+ //! is not encodable in such case.
+ //!
+ //! Example of raising `kErrorIllegalInst` error.
+ //!
+ //! ~~~
+ //! // Invalid address size.
+ //! a.mov(dword_ptr(eax), al);
+ //!
+ //! // Undecodable instruction - AH used with R10, however R10 can only be
+ //! // encoded by using REX prefix, which conflicts with AH.
+ //! a.mov(byte_ptr(r10), ah);
+ //! ~~~
+ //!
+ //! \note In debug mode assertion is raised instead of returning an error.
+ kErrorIllegalInst = 9,
+
+ //! Illegal (unencodable) addressing used.
+ kErrorIllegalAddresing = 10,
+
+ //! Illegal (unencodable) displacement used.
+ //!
+ //! X86/X64
+ //! -------
+ //!
+ //! Short form of jump instruction has been used, but the displacement is out
+ //! of bounds.
+ kErrorIllegalDisplacement = 11,
+
+ //! A variable has been assigned more than once to a function argument (Compiler).
+ kErrorOverlappedArgs = 12,
+
+ //! Count of AsmJit error codes.
+ kErrorCount = 13
+};
+
+// ============================================================================
+// [asmjit::Error]
+// ============================================================================
+
+//! AsmJit error type (unsigned integer).
+typedef uint32_t Error;
+
+// ============================================================================
+// [asmjit::ErrorHandler]
+// ============================================================================
+
+//! Error handler.
+//!
+//! Error handler can be used to override the default behavior of `CodeGen`
+//! error handling and propagation. See `handleError` on how to override it.
+//!
+//! Please note that `addRef` and `release` functions are used, but there is
+//! no reference counting implemented by default, reimplement to change the
+//! default behavior.
+struct ASMJIT_VCLASS ErrorHandler {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `ErrorHandler` instance.
+ ASMJIT_API ErrorHandler();
+ //! Destroy the `ErrorHandler` instance.
+ ASMJIT_API virtual ~ErrorHandler();
+
+ // --------------------------------------------------------------------------
+ // [Interface]
+ // --------------------------------------------------------------------------
+
+ //! Reference this error handler.
+ //!
+ //! \note This member function is provided for convenience. The default
+ //! implementation does nothing. If you are working in environment where
+ //! multiple `ErrorHandler` instances are used by a different code generators
+ //! you may provide your own functionality for reference counting. In that
+ //! case `addRef()` and `release()` functions should be overridden.
+ ASMJIT_API virtual ErrorHandler* addRef() const;
+
+ //! Release this error handler.
+ //!
+ //! \note This member function is provided for convenience. See `addRef()`
+ //! for more detailed information related to reference counting.
+ ASMJIT_API virtual void release();
+
+ //! Error handler (pure).
+ //!
+ //! Error handler is called when an error happened. An error can happen in
+ //! many places, but error handler is mostly used by `Assembler` and
+ //! `Compiler` classes to report anything that may cause incorrect code
+ //! generation. There are multiple ways how the error handler can be used
+ //! and each has it's pros/cons.
+ //!
+ //! AsmJit library doesn't use exceptions and can be compiled with or without
+ //! exception handling support. Even if the AsmJit library is compiled without
+ //! exceptions it is exception-safe and handleError() can report an incoming
+ //! error by throwing an exception of any type. It's guaranteed that the
+ //! exception won't be catched by AsmJit and will be propagated to the code
+ //! calling AsmJit `Assembler` or `Compiler` methods. Alternative to
+ //! throwing an exception is using `setjmp()` and `longjmp()` pair available
+ //! in the standard C library.
+ //!
+ //! If the exception or setjmp() / longjmp() mechanism is used, the state of
+ //! the `BaseAssember` or `Compiler` is unchanged and if it's possible the
+ //! execution (instruction serialization) can continue. However if the error
+ //! happened during any phase that translates or modifies the stored code
+ //! (for example relocation done by `Assembler` or analysis/translation
+ //! done by `Compiler`) the execution can't continue and the error will
+ //! be also stored in `Assembler` or `Compiler`.
+ //!
+ //! Finally, if no exceptions nor setjmp() / longjmp() mechanisms were used,
+ //! you can still implement a compatible handling by returning from your
+ //! error handler. Returning `true` means that error was reported and AsmJit
+ //! should continue execution, but `false` sets the rror immediately to the
+ //! `Assembler` or `Compiler` and execution shouldn't continue (this
+ //! is the default behavior in case no error handler is used).
+ virtual bool handleError(Error code, const char* message) = 0;
+};
+
+// ============================================================================
+// [asmjit::ErrorUtil]
+// ============================================================================
+
+//! Error utilities.
+struct ErrorUtil {
+#ifndef ASMJIT_DISABLE_NAMES
+ //! Get printable version of AsmJit `kError` code.
+ static ASMJIT_API const char* asString(Error code);
+#endif // ASMJIT_DISABLE_NAMES
+};
+
+//! \}
+
+// ============================================================================
+// [ASMJIT_PROPAGATE_ERROR]
+// ============================================================================
+
+//! \internal
+//!
+//! Used by AsmJit to return the `_Exp_` result if it's an error.
+#define ASMJIT_PROPAGATE_ERROR(_Exp_) \
+ do { \
+ ::asmjit::Error errval_ = (_Exp_); \
+ if (errval_ != ::asmjit::kErrorOk) \
+ return errval_; \
+ } while (0)
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/globals.cpp
@@ -1,1 +1,31 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [asmjit::Assert]
+// ============================================================================
+
+void assertionFailed(const char* exp, const char* file, int line) {
+ ::fprintf(stderr, "Assertion failed: %s\n, file %s, line %d\n", exp, file, line);
+ ::abort();
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/globals.h
@@ -1,1 +1,173 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../build.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::Ptr / SignedPtr]
+// ============================================================================
+
+//! 64-bit unsigned pointer, compatible with JIT and non-JIT generators.
+//!
+//! This is the preferred pointer type to use with AsmJit library. It has a
+//! capability to hold any pointer for any architecture making it an ideal
+//! candidate for cross-platform code generation.
+typedef uint64_t Ptr;
+
+//! 64-bit signed pointer, like \ref Ptr, but made signed.
+typedef int64_t SignedPtr;
+
+// ============================================================================
+// [asmjit::kGlobals]
+// ============================================================================
+
+//! Invalid index
+//!
+//! Invalid index is the last possible index that is never used in practice. In
+//! AsmJit it is used exclusively with strings to indicate the the length of the
+//! string is not known and has to be determined.
+static const size_t kInvalidIndex = ~static_cast<size_t>(0);
+
+//! Invalid base address.
+static const Ptr kNoBaseAddress = static_cast<Ptr>(static_cast<SignedPtr>(-1));
+
+//! Global constants.
+ASMJIT_ENUM(kGlobals) {
+ //! Invalid value or operand id.
+ kInvalidValue = 0xFFFFFFFF,
+
+ //! Invalid register index.
+ kInvalidReg = 0xFF,
+ //! Invalid variable type.
+ kInvalidVar = 0xFF,
+
+ //! Host memory allocator overhead.
+ //!
+ //! The overhead is decremented from all zone allocators so the operating
+ //! system doesn't have allocate extra virtual page to keep tract of the
+ //! requested memory block.
+ //!
+ //! The number is actually a guess.
+ kMemAllocOverhead = sizeof(intptr_t) * 4,
+
+ //! Memory grow threshold.
+ //!
+ //! After the grow threshold is reached the capacity won't be doubled
+ //! anymore.
+ kMemAllocGrowMax = 8192 * 1024
+};
+
+// ============================================================================
+// [asmjit::kArch]
+// ============================================================================
+
+//! Architecture.
+ASMJIT_ENUM(kArch) {
+ //! No/Unknown architecture.
+ kArchNone = 0,
+
+ //! X86 architecture.
+ kArchX86 = 1,
+ //! X64 architecture, also called AMD64.
+ kArchX64 = 2,
+
+ //! Arm architecture.
+ kArchArm = 4,
+
+#ifdef ASMJIT_HOST_X86
+ kArchHost = kArchX86,
+#endif // ASMJIT_HOST_X86
+
+#ifdef ASMJIT_HOST_X64
+ kArchHost = kArchX64,
+#endif // ASMJIT_HOST_X64
+
+#ifdef ASMJIT_HOST_ARM
+ kArchHost = kArchArm,
+#endif // ASMJIT_HOST_ARM
+
+ //! Whether the host is 64-bit.
+ kArchHost64Bit = sizeof(intptr_t) >= 8
+};
+
+//! \}
+
+// ============================================================================
+// [asmjit::Init / NoInit]
+// ============================================================================
+
+#ifndef ASMJIT_DOCGEN
+struct _Init {};
+static const _Init Init = {};
+
+struct _NoInit {};
+static const _NoInit NoInit = {};
+#endif // !ASMJIT_DOCGEN
+
+// ============================================================================
+// [asmjit::Assert]
+// ============================================================================
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+//! Called in debug build on assertion failure.
+//!
+//! \param exp Expression that failed.
+//! \param file Source file name where it happened.
+//! \param line Line in the source file.
+//!
+//! If you have problems with assertions put a breakpoint at assertionFailed()
+//! function (asmjit/base/globals.cpp) and check the call stack to locate the
+//! failing code.
+ASMJIT_API void assertionFailed(const char* exp, const char* file, int line);
+
+#ifdef ASMJIT_DEBUG
+# define ASMJIT_ASSERT(_Exp_) \
+ do { \
+ if (!(_Exp_)) ::asmjit::assertionFailed(#_Exp_, __FILE__, __LINE__); \
+ } while (0)
+#else
+# define ASMJIT_ASSERT(_Exp_) ASMJIT_NOP()
+#endif // DEBUG
+
+//! \}
+
+} // asmjit namespace
+
+// ============================================================================
+// [asmjit_cast<>]
+// ============================================================================
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+//! 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 `reinterpret_cast<>` works for you,
+//! there is no reason to use `asmjit_cast<>`. If you are writing
+//! cross-platform software with various compiler support, consider using
+//! `asmjit_cast<>` instead of `reinterpret_cast<>`.
+/*template<typename T, typename Z>
+static ASMJIT_INLINE T asmjit_cast(Z* p) { return (T)p; }*/
+
+//! \}
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/intutil.h
@@ -1,1 +1,709 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+#ifdef _MSC_VER
+# pragma intrinsic(_BitScanForward)
+#endif // ASMJIT_OS_WINDOWS
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::IntTraits]
+// ============================================================================
+
+//! \internal
+template<typename T>
+struct IntTraits {
+ enum {
+ kIsSigned = static_cast<T>(~static_cast<T>(0)) < static_cast<T>(0),
+ kIsUnsigned = !kIsSigned,
+
+ kIs8Bit = sizeof(T) == 1,
+ kIs16Bit = sizeof(T) == 2,
+ kIs32Bit = sizeof(T) == 4,
+ kIs64Bit = sizeof(T) == 8,
+
+ kIsIntPtr = sizeof(T) == sizeof(intptr_t)
+ };
+};
+
+// ============================================================================
+// [asmjit::IntUtil]
+// ============================================================================
+
+//! Integer utilities.
+struct IntUtil {
+ // --------------------------------------------------------------------------
+ // [Float <-> Int]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ union Float {
+ int32_t i;
+ float f;
+ };
+
+ //! \internal
+ union Double {
+ int64_t i;
+ double d;
+ };
+
+ //! Bit-cast `float` to 32-bit integer.
+ static ASMJIT_INLINE int32_t floatAsInt(float f) { Float m; m.f = f; return m.i; }
+ //! Bit-cast 32-bit integer to `float`.
+ static ASMJIT_INLINE float intAsFloat(int32_t i) { Float m; m.i = i; return m.f; }
+
+ //! Bit-cast `double` to 64-bit integer.
+ static ASMJIT_INLINE int64_t doubleAsInt(double d) { Double m; m.d = d; return m.i; }
+ //! Bit-cast 64-bit integer to `double`.
+ static ASMJIT_INLINE double intAsDouble(int64_t i) { Double m; m.i = i; return m.d; }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - Pack / Unpack]
+ // --------------------------------------------------------------------------
+
+ //! Pack two 8-bit integer and one 16-bit integer into a 32-bit integer as it
+ //! is an array of `{u0,u1,w2}`.
+ static ASMJIT_INLINE uint32_t pack32_2x8_1x16(uint32_t u0, uint32_t u1, uint32_t w2) {
+#ifdef ASMJIT_HOST_LE
+ return u0 + (u1 << 8) + (w2 << 16);
+#else
+ return (u0 << 24) + (u1 << 16) + (w2);
+#endif // ASMJIT_HOST
+ }
+
+ //! Pack four 8-bit integer into a 32-bit integer as it is an array of `{u0,u1,u2,u3}`.
+ static ASMJIT_INLINE uint32_t pack32_4x8(uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) {
+#ifdef ASMJIT_HOST_LE
+ return u0 + (u1 << 8) + (u2 << 16) + (u3 << 24);
+#else
+ return (u0 << 24) + (u1 << 16) + (u2 << 8) + u3;
+#endif // ASMJIT_HOST
+ }
+
+ //! Pack two 32-bit integer into a 64-bit integer as it is an array of `{u0,u1}`.
+ static ASMJIT_INLINE uint64_t pack64_2x32(uint32_t u0, uint32_t u1) {
+#ifdef ASMJIT_HOST_LE
+ return (static_cast<uint64_t>(u1) << 32) + u0;
+#else
+ return (static_cast<uint64_t>(u0) << 32) + u1;
+#endif // ASMJIT_HOST
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - Min/Max]
+ // --------------------------------------------------------------------------
+
+ // NOTE: Because some environments declare min() and max() as macros, it has
+ // been decided to use different name so we never collide with them.
+
+ //! Get minimum value of `a` and `b`.
+ template<typename T>
+ static ASMJIT_INLINE T iMin(const T& a, const T& b) { return a < b ? a : b; }
+
+ //! Get maximum value of `a` and `b`.
+ template<typename T>
+ static ASMJIT_INLINE T iMax(const T& a, const T& b) { return a > b ? a : b; }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - MaxUInt]
+ // --------------------------------------------------------------------------
+
+ //! Get maximum unsigned value of `T`.
+ template<typename T>
+ static ASMJIT_INLINE T maxUInt() { return ~T(0); }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - InInterval]
+ // --------------------------------------------------------------------------
+
+ //! Get whether `x` is greater or equal than `start` and less or equal than `end`.
+ template<typename T>
+ static ASMJIT_INLINE bool inInterval(const T& x, const T& start, const T& end) {
+ return x >= start && x <= end;
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - IsInt/IsUInt]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the given integer `x` can be casted to 8-bit signed integer.
+ template<typename T>
+ static ASMJIT_INLINE bool isInt8(T x) {
+ if (IntTraits<T>::kIsSigned)
+ return sizeof(T) <= sizeof(int8_t) ? true : x >= T(-128) && x <= T(127);
+ else
+ return x <= T(127);
+ }
+
+ //! Get whether the given integer `x` can be casted to 8-bit unsigned integer.
+ template<typename T>
+ static ASMJIT_INLINE bool isUInt8(T x) {
+ if (IntTraits<T>::kIsSigned)
+ return x >= T(0) && (sizeof(T) <= sizeof(uint8_t) ? true : x <= T(255));
+ else
+ return sizeof(T) <= sizeof(uint8_t) ? true : x <= T(255);
+ }
+
+ //! Get whether the given integer `x` can be casted to 16-bit signed integer.
+ template<typename T>
+ static ASMJIT_INLINE bool isInt16(T x) {
+ if (IntTraits<T>::kIsSigned)
+ return sizeof(T) <= sizeof(int16_t) ? true : x >= T(-32768) && x <= T(32767);
+ else
+ return x >= T(0) && (sizeof(T) <= sizeof(int16_t) ? true : x <= T(32767));
+ }
+
+ //! Get whether the given integer `x` can be casted to 16-bit unsigned integer.
+ template<typename T>
+ static ASMJIT_INLINE bool isUInt16(T x) {
+ if (IntTraits<T>::kIsSigned)
+ return x >= T(0) && (sizeof(T) <= sizeof(uint16_t) ? true : x <= T(65535));
+ else
+ return sizeof(T) <= sizeof(uint16_t) ? true : x <= T(65535);
+ }
+
+ //! Get whether the given integer `x` can be casted to 32-bit signed integer.
+ template<typename T>
+ static ASMJIT_INLINE bool isInt32(T x) {
+ if (IntTraits<T>::kIsSigned)
+ return sizeof(T) <= sizeof(int32_t) ? true : x >= T(-2147483647) - 1 && x <= T(2147483647);
+ else
+ return x >= T(0) && (sizeof(T) <= sizeof(int32_t) ? true : x <= T(2147483647));
+ }
+
+ //! Get whether the given integer `x` can be casted to 32-bit unsigned integer.
+ template<typename T>
+ static ASMJIT_INLINE bool isUInt32(T x) {
+ if (IntTraits<T>::kIsSigned)
+ return x >= T(0) && (sizeof(T) <= sizeof(uint32_t) ? true : x <= T(4294967295U));
+ else
+ return sizeof(T) <= sizeof(uint32_t) ? true : x <= T(4294967295U);
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - IsPowerOf2]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the `n` value is a power of two (only one bit is set).
+ template<typename T>
+ static ASMJIT_INLINE bool isPowerOf2(T n) {
+ return n != 0 && (n & (n - 1)) == 0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - Mask]
+ // --------------------------------------------------------------------------
+
+ //! Generate a bit-mask that has `x` bit set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x) {
+ ASMJIT_ASSERT(x < 32);
+ return (1U << x);
+ }
+
+ //! Generate a bit-mask that has `x0` and `x1` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1) {
+ return mask(x0) | mask(x1);
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1` and `x2` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2) {
+ return mask(x0) | mask(x1) | mask(x2);
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2` and `x3` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3);
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3` and `x4` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3) |
+ mask(x4) ;
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4` and `x5` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3) |
+ mask(x4) | mask(x5) ;
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5` and `x6` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3) |
+ mask(x4) | mask(x5) | mask(x6) ;
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6` and `x7` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3) |
+ mask(x4) | mask(x5) | mask(x6) | mask(x7) ;
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6`, `x7` and `x8` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7, uint32_t x8) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3) |
+ mask(x4) | mask(x5) | mask(x6) | mask(x7) |
+ mask(x8) ;
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6`, `x7`, `x8` and `x9` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7, uint32_t x8, uint32_t x9) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3) |
+ mask(x4) | mask(x5) | mask(x6) | mask(x7) |
+ mask(x8) | mask(x9) ;
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - Bits]
+ // --------------------------------------------------------------------------
+
+ //! Generate a bit-mask that has `x` most significant bits set.
+ static ASMJIT_INLINE uint32_t bits(uint32_t x) {
+ // Shifting more bits that the type has has undefined behavior. Everything
+ // we need is that application shouldn't crash because of that, but the
+ // content of register after shift is not defined. So in case that the
+ // requested shift is too large for the type we correct this undefined
+ // behavior by setting all bits to ones (this is why we generate an overflow
+ // mask).
+ uint32_t overflow = static_cast<uint32_t>(
+ -static_cast<int32_t>(x >= sizeof(uint32_t) * 8));
+
+ return ((static_cast<uint32_t>(1) << x) - 1U) | overflow;
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - HasBit]
+ // --------------------------------------------------------------------------
+
+ //! Get whether `x` has bit `n` set.
+ static ASMJIT_INLINE bool hasBit(uint32_t x, uint32_t n) {
+ return static_cast<bool>((x >> n) & 0x1);
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - BitCount]
+ // --------------------------------------------------------------------------
+
+ //! Get count of bits in `x`.
+ //!
+ //! Taken from http://graphics.stanford.edu/~seander/bithacks.html .
+ static ASMJIT_INLINE uint32_t bitCount(uint32_t x) {
+ x = x - ((x >> 1) & 0x55555555U);
+ x = (x & 0x33333333U) + ((x >> 2) & 0x33333333U);
+ return (((x + (x >> 4)) & 0x0F0F0F0FU) * 0x01010101U) >> 24;
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - FindFirstBit]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ static ASMJIT_INLINE uint32_t findFirstBitSlow(uint32_t mask) {
+ // This is a reference (slow) implementation of findFirstBit(), used when
+ // we don't have compiler support for this task. The implementation speed
+ // has been improved to check for 2 bits per iteration.
+ uint32_t i = 1;
+
+ while (mask != 0) {
+ uint32_t two = mask & 0x3;
+ if (two != 0x0)
+ return i - (two & 0x1);
+
+ i += 2;
+ mask >>= 2;
+ }
+
+ return 0xFFFFFFFFU;
+ }
+
+ //! Find a first bit in `mask`.
+ static ASMJIT_INLINE uint32_t findFirstBit(uint32_t mask) {
+#ifdef _MSC_VER
+ DWORD i;
+ if (_BitScanForward(&i, mask)) {
+ ASMJIT_ASSERT(findFirstBitSlow(mask) == i);
+ return static_cast<uint32_t>(i);
+ }
+ return 0xFFFFFFFFU;
+#else
+ return findFirstBitSlow(mask);
+#endif
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - Misc]
+ // --------------------------------------------------------------------------
+
+ static ASMJIT_INLINE uint32_t keepNOnesFromRight(uint32_t mask, uint32_t nBits) {
+ uint32_t m = 0x1;
+
+ do {
+ nBits -= (mask & m) == 0;
+ m <<= 1;
+ if (nBits == 0) {
+ m -= 1;
+ mask &= m;
+ break;
+ }
+ } while (m);
+
+ return mask;
+ }
+
+ static ASMJIT_INLINE uint32_t indexNOnesFromRight(uint8_t* dst, uint32_t mask, uint32_t nBits) {
+ uint32_t totalBits = nBits;
+ uint8_t i = 0;
+ uint32_t m = 0x1;
+
+ do {
+ if (mask & m) {
+ *dst++ = i;
+ if (--nBits == 0)
+ break;
+ }
+
+ m <<= 1;
+ i++;
+ } while (m);
+
+ return totalBits - nBits;
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - Alignment]
+ // --------------------------------------------------------------------------
+
+ template<typename T>
+ static ASMJIT_INLINE bool isAligned(T base, T alignment) {
+ return (base % alignment) == 0;
+ }
+
+ //! Align `base` to `alignment`.
+ template<typename T>
+ static ASMJIT_INLINE T alignTo(T base, T alignment) {
+ return (base + (alignment - 1)) & ~(alignment - 1);
+ }
+
+ template<typename T>
+ static ASMJIT_INLINE T alignToPowerOf2(T base) {
+ // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.
+ base -= 1;
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4293)
+#endif // _MSC_VER
+
+ base = base | (base >> 1);
+ base = base | (base >> 2);
+ base = base | (base >> 4);
+
+ // 8/16/32 constants are multiplied by the condition to prevent a compiler
+ // complaining about the 'shift count >= type width' (GCC).
+ if (sizeof(T) >= 2) base = base | (base >> ( 8 * (sizeof(T) >= 2))); // Base >> 8.
+ if (sizeof(T) >= 4) base = base | (base >> (16 * (sizeof(T) >= 4))); // Base >> 16.
+ if (sizeof(T) >= 8) base = base | (base >> (32 * (sizeof(T) >= 8))); // Base >> 32.
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif // _MSC_VER
+
+ return base + 1;
+ }
+
+ //! Get delta required to align `base` to `alignment`.
+ template<typename T>
+ static ASMJIT_INLINE T deltaTo(T base, T alignment) {
+ return alignTo(base, alignment) - base;
+ }
+};
+
+// ============================================================================
+// [asmjit::UInt64]
+// ============================================================================
+
+union UInt64 {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64 fromUInt64(uint64_t val) {
+ UInt64 data;
+ data.setUInt64(val);
+ return data;
+ }
+
+ ASMJIT_INLINE UInt64 fromUInt64(const UInt64& val) {
+ UInt64 data;
+ data.setUInt64(val);
+ return data;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void reset() {
+ if (kArchHost64Bit) {
+ u64 = 0;
+ }
+ else {
+ u32[0] = 0;
+ u32[1] = 0;
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE uint64_t getUInt64() const {
+ return u64;
+ }
+
+ ASMJIT_INLINE UInt64& setUInt64(uint64_t val) {
+ u64 = val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& setUInt64(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 = val.u64;
+ }
+ else {
+ u32[0] = val.u32[0];
+ u32[1] = val.u32[1];
+ }
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& setPacked_2x32(uint32_t u0, uint32_t u1) {
+ if (kArchHost64Bit) {
+ u64 = IntUtil::pack64_2x32(u0, u1);
+ }
+ else {
+ u32[0] = u0;
+ u32[1] = u1;
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Add]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& add(uint64_t val) {
+ u64 += val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& add(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 += val.u64;
+ }
+ else {
+ u32[0] += val.u32[0];
+ u32[1] += val.u32[1];
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Sub]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& sub(uint64_t val) {
+ u64 -= val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& sub(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 -= val.u64;
+ }
+ else {
+ u32[0] -= val.u32[0];
+ u32[1] -= val.u32[1];
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [And]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& and_(uint64_t val) {
+ u64 &= val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& and_(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 &= val.u64;
+ }
+ else {
+ u32[0] &= val.u32[0];
+ u32[1] &= val.u32[1];
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Or]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& or_(uint64_t val) {
+ u64 |= val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& or_(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 |= val.u64;
+ }
+ else {
+ u32[0] |= val.u32[0];
+ u32[1] |= val.u32[1];
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Xor]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& xor_(uint64_t val) {
+ u64 ^= val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& xor_(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 ^= val.u64;
+ }
+ else {
+ u32[0] ^= val.u32[0];
+ u32[1] ^= val.u32[1];
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Del]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& del(uint64_t val) {
+ u64 &= ~val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& del(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 &= ~val.u64;
+ }
+ else {
+ u32[0] &= ~val.u32[0];
+ u32[1] &= ~val.u32[1];
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Eq]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE bool isZero() const {
+ return kArchHost64Bit ? u64 == 0 : (u32[0] | u32[1]) == 0;
+ }
+
+ ASMJIT_INLINE bool isNonZero() const {
+ return kArchHost64Bit ? u64 != 0 : (u32[0] | u32[1]) != 0;
+ }
+
+ ASMJIT_INLINE bool eq(uint64_t val) const {
+ return u64 == val;
+ }
+
+ ASMJIT_INLINE bool eq(const UInt64& val) const {
+ return kArchHost64Bit ? u64 == val.u64 : (u32[0] == val.u32[0]) & (u32[1] == val.u32[1]);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& operator+=(uint64_t val) { return add(val); }
+ ASMJIT_INLINE UInt64& operator+=(const UInt64& val) { return add(val); }
+
+ ASMJIT_INLINE UInt64& operator-=(uint64_t val) { return sub(val); }
+ ASMJIT_INLINE UInt64& operator-=(const UInt64& val) { return sub(val); }
+
+ ASMJIT_INLINE UInt64& operator&=(uint64_t val) { return and_(val); }
+ ASMJIT_INLINE UInt64& operator&=(const UInt64& val) { return and_(val); }
+
+ ASMJIT_INLINE UInt64& operator|=(uint64_t val) { return or_(val); }
+ ASMJIT_INLINE UInt64& operator|=(const UInt64& val) { return or_(val); }
+
+ ASMJIT_INLINE UInt64& operator^=(uint64_t val) { return xor_(val); }
+ ASMJIT_INLINE UInt64& operator^=(const UInt64& val) { return xor_(val); }
+
+ ASMJIT_INLINE bool operator==(uint64_t val) const { return eq(val); }
+ ASMJIT_INLINE bool operator==(const UInt64& val) const { return eq(val); }
+
+ ASMJIT_INLINE bool operator!=(uint64_t val) const { return !eq(val); }
+ ASMJIT_INLINE bool operator!=(const UInt64& val) const { return !eq(val); }
+
+ ASMJIT_INLINE bool operator<(uint64_t val) const { return u64 < val; }
+ ASMJIT_INLINE bool operator<(const UInt64& val) const { return u64 < val.u64; }
+
+ ASMJIT_INLINE bool operator<=(uint64_t val) const { return u64 <= val; }
+ ASMJIT_INLINE bool operator<=(const UInt64& val) const { return u64 <= val.u64; }
+
+ ASMJIT_INLINE bool operator>(uint64_t val) const { return u64 > val; }
+ ASMJIT_INLINE bool operator>(const UInt64& val) const { return u64 > val.u64; }
+
+ ASMJIT_INLINE bool operator>=(uint64_t val) const { return u64 >= val; }
+ ASMJIT_INLINE bool operator>=(const UInt64& val) const { return u64 >= val.u64; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ uint64_t u64;
+
+ uint32_t u32[2];
+ uint16_t u16[4];
+ uint8_t u8[8];
+
+ struct {
+#ifdef ASMJIT_HOST_LE
+ uint32_t lo, hi;
+#else
+ uint32_t hi, lo;
+#endif // ASMJIT_HOST_LE
+ };
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/lock.h
@@ -1,1 +1,127 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../build.h"
+
+// [Dependencies - Posix]
+#ifdef ASMJIT_OS_POSIX
+# include <pthread.h>
+#endif // ASMJIT_OS_POSIX
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::Lock]
+// ============================================================================
+
+//! Lock - used in thread-safe code for locking.
+struct Lock {
+ ASMJIT_NO_COPY(Lock)
+
+ // --------------------------------------------------------------------------
+ // [Windows]
+ // --------------------------------------------------------------------------
+
+#ifdef ASMJIT_OS_WINDOWS
+ typedef CRITICAL_SECTION Handle;
+
+ //! Create a new `Lock` instance.
+ ASMJIT_INLINE Lock() { InitializeCriticalSection(&_handle); }
+ //! Destroy the `Lock` instance.
+ ASMJIT_INLINE ~Lock() { DeleteCriticalSection(&_handle); }
+
+ //! Lock.
+ ASMJIT_INLINE void lock() { EnterCriticalSection(&_handle); }
+ //! Unlock.
+ ASMJIT_INLINE void unlock() { LeaveCriticalSection(&_handle); }
+
+#endif // ASMJIT_OS_WINDOWS
+
+ // --------------------------------------------------------------------------
+ // [Posix]
+ // --------------------------------------------------------------------------
+
+#ifdef ASMJIT_OS_POSIX
+ typedef pthread_mutex_t Handle;
+
+ //! Create a new `Lock` instance.
+ ASMJIT_INLINE Lock() { pthread_mutex_init(&_handle, nullptr); }
+ //! Destroy the `Lock` instance.
+ ASMJIT_INLINE ~Lock() { pthread_mutex_destroy(&_handle); }
+
+ //! Lock.
+ ASMJIT_INLINE void lock() { pthread_mutex_lock(&_handle); }
+ //! Unlock.
+ ASMJIT_INLINE void unlock() { pthread_mutex_unlock(&_handle); }
+#endif // ASMJIT_OS_POSIX
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get handle.
+ ASMJIT_INLINE Handle& getHandle() {
+ return _handle;
+ }
+ //! \overload
+ ASMJIT_INLINE const Handle& getHandle() const {
+ return _handle;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Handle.
+ Handle _handle;
+};
+
+// ============================================================================
+// [asmjit::AutoLock]
+// ============================================================================
+
+//! Scoped lock.
+struct AutoLock {
+ ASMJIT_NO_COPY(AutoLock)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Autolock `target`, scoped.
+ ASMJIT_INLINE AutoLock(Lock& target) : _target(target) {
+ _target.lock();
+ }
+
+ //! Autounlock `target`.
+ ASMJIT_INLINE ~AutoLock() {
+ _target.unlock();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Pointer to target (lock).
+ Lock& _target;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/logger.cpp
@@ -1,1 +1,168 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Guard]
+#include "../build.h"
+#ifndef ASMJIT_DISABLE_LOGGER
+
+// [Dependencies - AsmJit]
+#include "../base/intutil.h"
+#include "../base/logger.h"
+#include "../base/string.h"
+
+// [Dependencies - C]
+#include <cstdarg>
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [asmjit::Logger - Construction / Destruction]
+// ============================================================================
+
+Logger::Logger() {
+ _options = 0;
+ ::memset(_indentation, 0, ASMJIT_ARRAY_SIZE(_indentation));
+}
+
+Logger::~Logger() {}
+
+// ============================================================================
+// [asmjit::Logger - Logging]
+// ============================================================================
+
+void Logger::logFormat(uint32_t style, const char* fmt, ...) {
+ char buf[1024];
+ size_t len;
+
+ va_list ap;
+ va_start(ap, fmt);
+ len = vsnprintf(buf, 1023, fmt, ap);
+ va_end(ap);
+
+ logString(style, buf, len);
+}
+
+void Logger::logBinary(uint32_t style, const void* data, size_t size) {
+ static const char prefix[] = ".data ";
+ static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ const uint8_t* s = static_cast<const uint8_t*>(data);
+ size_t i = size;
+
+ char buffer[128];
+ ::memcpy(buffer, prefix, ASMJIT_ARRAY_SIZE(prefix) - 1);
+
+ while (i) {
+ uint32_t n = static_cast<uint32_t>(IntUtil::iMin<size_t>(i, 16));
+ char* p = buffer + ASMJIT_ARRAY_SIZE(prefix) - 1;
+
+ i -= n;
+ do {
+ uint32_t c = s[0];
+
+ p[0] = hex[c >> 4];
+ p[1] = hex[c & 15];
+
+ p += 2;
+ s += 1;
+ } while (--n);
+
+ *p++ = '\n';
+ logString(style, buffer, static_cast<size_t>(p - buffer));
+ }
+}
+
+// ============================================================================
+// [asmjit::Logger - LogBinary]
+// ============================================================================
+
+void Logger::setOption(uint32_t id, bool value) {
+ if (id >= kLoggerOptionCount)
+ return;
+
+ uint32_t mask = 1 << id;
+
+ if (value)
+ _options |= mask;
+ else
+ _options &= ~mask;
+}
+
+// ============================================================================
+// [asmjit::Logger - Indentation]
+// ============================================================================
+
+void Logger::setIndentation(const char* indentation) {
+ ::memset(_indentation, 0, ASMJIT_ARRAY_SIZE(_indentation));
+ if (!indentation)
+ return;
+
+ size_t length = StringUtil::nlen(indentation, ASMJIT_ARRAY_SIZE(_indentation) - 1);
+ ::memcpy(_indentation, indentation, length);
+}
+
+// ============================================================================
+// [asmjit::FileLogger - Construction / Destruction]
+// ============================================================================
+
+FileLogger::FileLogger(FILE* stream) : _stream(nullptr) {
+ setStream(stream);
+}
+
+FileLogger::~FileLogger() {}
+
+// ============================================================================
+// [asmjit::FileLogger - Accessors]
+// ============================================================================
+
+//! Set file stream.
+void FileLogger::setStream(FILE* stream) {
+ _stream = stream;
+}
+
+// ============================================================================
+// [asmjit::FileLogger - Logging]
+// ============================================================================
+
+void FileLogger::logString(uint32_t, const char* buf, size_t len) {
+ if (!_stream)
+ return;
+
+ if (len == kInvalidIndex)
+ len = strlen(buf);
+
+ fwrite(buf, 1, len, _stream);
+}
+
+// ============================================================================
+// [asmjit::StringLogger - Construction / Destruction]
+// ============================================================================
+
+StringLogger::StringLogger() {}
+StringLogger::~StringLogger() {}
+
+// ============================================================================
+// [asmjit::StringLogger - Logging]
+// ============================================================================
+
+void StringLogger::logString(uint32_t, const char* buf, size_t len) {
+ _stringBuilder.appendString(buf, len);
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // !ASMJIT_DISABLE_LOGGER
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/logger.h
@@ -1,1 +1,243 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+#include "../build.h"
+#ifndef ASMJIT_DISABLE_LOGGER
+
+// [Dependencies - AsmJit]
+#include "../base/string.h"
+
+// [Dependencies - C]
+#include <cstdarg>
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::kLoggerOption]
+// ============================================================================
+
+//! Logger options.
+ASMJIT_ENUM(kLoggerOption) {
+ //! Whether to output instructions also in binary form.
+ kLoggerOptionBinaryForm = 0,
+
+ //! Whether to output immediates as hexadecimal numbers.
+ kLoggerOptionHexImmediate = 1,
+ //! Whether to output displacements as hexadecimal numbers.
+ kLoggerOptionHexDisplacement = 2,
+
+ //! Count of logger options.
+ kLoggerOptionCount = 3
+};
+
+// ============================================================================
+// [asmjit::kLoggerStyle]
+// ============================================================================
+
+//! Logger style.
+ASMJIT_ENUM(kLoggerStyle) {
+ kLoggerStyleDefault = 0,
+ kLoggerStyleDirective = 1,
+ kLoggerStyleLabel = 2,
+ kLoggerStyleData = 3,
+ kLoggerStyleComment = 4,
+
+ kLoggerStyleCount = 5
+};
+
+// ============================================================================
+// [asmjit::Logger]
+// ============================================================================
+
+//! Abstract logging class.
+//!
+//! This class can be inherited and reimplemented to fit into your logging
+//! subsystem. When reimplementing use `Logger::log()` method to log into
+//! a custom stream.
+//!
+//! This class also contain `_enabled` member that can be used to enable
+//! or disable logging.
+struct ASMJIT_VCLASS Logger {
+ ASMJIT_NO_COPY(Logger)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a `Logger` instance.
+ ASMJIT_API Logger();
+ //! Destroy the `Logger` instance.
+ ASMJIT_API virtual ~Logger();
+
+ // --------------------------------------------------------------------------
+ // [Logging]
+ // --------------------------------------------------------------------------
+
+ //! Log output.
+ virtual void logString(uint32_t style, const char* buf, size_t len = kInvalidIndex) = 0;
+
+ //! Log formatter message (like sprintf) sending output to `logString()` method.
+ ASMJIT_API void logFormat(uint32_t style, const char* fmt, ...);
+ //! Log binary data.
+ ASMJIT_API void logBinary(uint32_t style, const void* data, size_t size);
+
+ // --------------------------------------------------------------------------
+ // [Options]
+ // --------------------------------------------------------------------------
+
+ //! Get all logger options as a single integer.
+ ASMJIT_INLINE uint32_t getOptions() const {
+ return _options;
+ }
+
+ //! Get the given logger option.
+ ASMJIT_INLINE bool getOption(uint32_t id) const {
+ ASMJIT_ASSERT(id < kLoggerOptionCount);
+ return static_cast<bool>((_options >> id) & 0x1);
+ }
+
+ //! Set the given logger option.
+ ASMJIT_API void setOption(uint32_t id, bool value);
+
+ // --------------------------------------------------------------------------
+ // [Indentation]
+ // --------------------------------------------------------------------------
+
+ //! Get indentation.
+ ASMJIT_INLINE const char* getIndentation() const {
+ return _indentation;
+ }
+
+ //! Set indentation.
+ ASMJIT_API void setIndentation(const char* indentation);
+
+ //! Reset indentation.
+ ASMJIT_INLINE void resetIndentation() {
+ setIndentation(nullptr);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Options, see `kLoggerOption`.
+ uint32_t _options;
+
+ //! Indentation.
+ char _indentation[12];
+};
+
+// ============================================================================
+// [asmjit::FileLogger]
+// ============================================================================
+
+//! Logger that can log to standard C `FILE*` stream.
+struct ASMJIT_VCLASS FileLogger : public Logger {
+ ASMJIT_NO_COPY(FileLogger)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `FileLogger` that logs to a `FILE` stream.
+ ASMJIT_API FileLogger(FILE* stream = nullptr);
+
+ //! Destroy the `FileLogger`.
+ ASMJIT_API virtual ~FileLogger();
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get `FILE*` stream.
+ //!
+ //! \note Return value can be `NULL`.
+ ASMJIT_INLINE FILE* getStream() const { return _stream; }
+
+ //! Set `FILE*` stream, can be set to `NULL` to disable logging, although
+ //! the `CodeGen` will still call `logString` even if there is no stream.
+ ASMJIT_API void setStream(FILE* stream);
+
+ // --------------------------------------------------------------------------
+ // [Logging]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual void logString(uint32_t style, const char* buf, size_t len = kInvalidIndex);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! C file stream.
+ FILE* _stream;
+};
+
+// ============================================================================
+// [asmjit::StringLogger]
+// ============================================================================
+
+//! String logger.
+struct ASMJIT_VCLASS StringLogger : public Logger {
+ ASMJIT_NO_COPY(StringLogger)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create new `StringLogger`.
+ ASMJIT_API StringLogger();
+
+ //! Destroy the `StringLogger`.
+ ASMJIT_API virtual ~StringLogger();
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get <code>char*</code> pointer which represents the resulting
+ //! string.
+ //!
+ //! The pointer is owned by `StringLogger`, it can't be modified or freed.
+ ASMJIT_INLINE const char* getString() const {
+ return _stringBuilder.getData();
+ }
+
+ //! Clear the resulting string.
+ ASMJIT_INLINE void clearString() {
+ _stringBuilder.clear();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Logging]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual void logString(uint32_t style, const char* buf, size_t len = kInvalidIndex);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Output.
+ StringBuilder _stringBuilder;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+#endif // !ASMJIT_DISABLE_LOGGER
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/operand.cpp
@@ -1,1 +1,39 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [asmjit::Operand]
+// ============================================================================
+
+// Prevent static initialization.
+struct Operand {
+ uint8_t op;
+ uint8_t size;
+ uint8_t reserved_2_1;
+ uint8_t reserved_3_1;
+ uint32_t id;
+ uint64_t reserved_8_8;
+};
+
+ASMJIT_VAR const Operand noOperand;
+const Operand noOperand = { 0, 0, 0, 0, kInvalidValue, 0 };
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/operand.h
@@ -1,1 +1,1086 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../base/intutil.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [Forward Declarations]
+// ============================================================================
+
+struct Assembler;
+struct Compiler;
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::kOperandType]
+// ============================================================================
+
+//! Operand types that can be encoded in `Operand`.
+ASMJIT_ENUM(kOperandType) {
+ //! Invalid operand, used only internally (not initialized Operand).
+ kOperandTypeNone = 0,
+ //! Operand is a register.
+ kOperandTypeReg = 1,
+ //! Operand is a variable.
+ kOperandTypeVar = 2,
+ //! Operand is a memory.
+ kOperandTypeMem = 3,
+ //! Operand is an immediate value.
+ kOperandTypeImm = 4,
+ //! Operand is a label.
+ kOperandTypeLabel = 5
+};
+
+// ============================================================================
+// [asmjit::kOperandId]
+// ============================================================================
+
+//! Operand id masks used to determine the operand type.
+ASMJIT_ENUM(kOperandId) {
+ //! Operand id refers to `Var`.
+ kOperandIdVar = 0x80000000U,
+ //! Operand id to real index mask.
+ kOperandIdNum = 0x7FFFFFFFU
+};
+
+// ============================================================================
+// [asmjit::kRegClass]
+// ============================================================================
+
+//! Register class.
+ASMJIT_ENUM(kRegClass) {
+ //! Gp register class, compatible with all architectures.
+ kRegClassGp = 0
+};
+
+// ============================================================================
+// [asmjit::kSize]
+// ============================================================================
+
+//! Common size of registers and pointers.
+ASMJIT_ENUM(kSize) {
+ //! 1 byte size (BYTE).
+ kSizeByte = 1,
+ //! 2 bytes size (WORD).
+ kSizeWord = 2,
+ //! 4 bytes size (DWORD).
+ kSizeDWord = 4,
+ //! 8 bytes size (QWORD).
+ kSizeQWord = 8,
+ //! 10 bytes size (TWORD).
+ kSizeTWord = 10,
+ //! 16 bytes size (OWORD / DQWORD).
+ kSizeOWord = 16,
+ //! 32 bytes size (YWORD / QQWORD).
+ kSizeYWord = 32
+};
+
+// ============================================================================
+// [asmjit::kMemType]
+// ============================================================================
+
+//! Type of memory operand.
+ASMJIT_ENUM(kMemType) {
+ //! Memory operand is a combination of base register and optional index register
+ //! and displacement.
+ //!
+ //! The `Assembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex`
+ //! types the same way, but `Compiler` interprets `kMemTypeBaseIndex` as
+ //! `[base + index]` and `kMemTypeStackIndex` as `[stack(base) + index]`.
+ kMemTypeBaseIndex = 0,
+
+ //! Memory operand is a combination of variable's memory location,
+ //! optional index register and displacement.
+ //!
+ //! The `Assembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex`
+ //! types in the same way, but `Compiler` interprets `kMemTypeBaseIndex` as
+ //! `[base + index]` and `kMemTypeStackIndex` as `[stack(base) + index]`.
+ kMemTypeStackIndex = 1,
+
+ //! Memory operand refers to the memory location specified by a label.
+ kMemTypeLabel = 2,
+ //! Memory operand is an absolute memory location.
+ //!
+ //! Supported mostly by x86, truncated to a 32-bit value when running in
+ //! 64-bit mode (x64).
+ kMemTypeAbsolute = 3
+};
+
+// ============================================================================
+// [asmjit::Operand]
+// ============================================================================
+
+//! Operand can contain register, memory location, immediate, or label.
+struct Operand {
+ // --------------------------------------------------------------------------
+ // [Structs]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ //!
+ //! Base operand data.
+ struct BaseOp {
+ //! Type of operand, see `kOperandType`.
+ uint8_t op;
+ //! Size of operand (register, address, immediate, or variable).
+ uint8_t size;
+ //! \internal
+ uint8_t reserved_2_1;
+ //! \internal
+ uint8_t reserved_3_1;
+
+ //! Operand id, identifier used by `Assembler` and `Compiler`.
+ //!
+ //! \note Uninitialized operand has always set id to `kInvalidValue`.
+ uint32_t id;
+
+ //! \internal
+ uint32_t reserved_8_4;
+ //! \internal
+ uint32_t reserved_12_4;
+ };
+
+ //! \internal
+ //!
+ //! Register or Variable operand data.
+ struct VRegOp {
+ //! Type of operand, `kOperandTypeReg`.
+ uint8_t op;
+ //! Size of register or variable.
+ uint8_t size;
+
+ union {
+ //! Register code = (type << 8) | index.
+ uint16_t code;
+
+ //! Register type and index access.
+ struct {
+#ifdef ASMJIT_HOST_LE
+ //! Register index.
+ uint8_t index;
+ //! Register type.
+ uint8_t type;
+#else
+ //! Register type.
+ uint8_t type;
+ //! Register index.
+ uint8_t index;
+#endif // ASMJIT_HOST
+ };
+ };
+
+ //! Variable id, used by `Compiler` to identify variables.
+ uint32_t id;
+
+ union {
+ struct {
+ //! Variable type.
+ uint32_t vType;
+ //! \internal
+ uint32_t reserved_12_4;
+ };
+
+ //! \internal
+ //!
+ //! This is not needed or used, it's just to force compiler to always
+ //! align this struct to 8-bytes (so the struct is compatible to others
+ //! when it comes to alignment). It should fix VS linker warning as well.
+ uint64_t reserved8_8;
+ };
+ };
+
+ //! \internal
+ //!
+ //! Memory or Variable operand data.
+ struct VMemOp {
+ //! Type of operand, `kOperandTypeMem`.
+ uint8_t op;
+ //! Size of the pointer in bytes.
+ uint8_t size;
+ //! Type of the memory operand, see `kMemType`.
+ uint8_t type;
+ //! X86/X64 layout:
+ //! - segment [3 bits], see `kX86Seg`.
+ //! - shift [2 bits], index register shift (0 to 3).
+ uint8_t flags;
+
+ //! Base register, variable or label id.
+ uint32_t base;
+ //! Index register or variable.
+ uint32_t index;
+ //! 32-bit displacement or absolute address.
+ int32_t displacement;
+ };
+
+ //! \internal
+ //!
+ //! Immediate operand data.
+ struct ImmOp {
+ //! Type of operand, `kOperandTypeImm`.
+ uint8_t op;
+ //! Size of immediate (or 0 to autodetect).
+ uint8_t size;
+ //! \internal
+ uint8_t reserved_2_1;
+ //! \internal
+ uint8_t reserved_3_1;
+
+ //! Operand id, always set to `kInvalidValue` (immediates don't have IDs).
+ uint32_t id;
+
+ union {
+ //! 8x8-bit signed immediate values.
+ int8_t _i8[8];
+ //! 8x8-bit unsigned immediate values.
+ uint8_t _u8[8];
+
+ //! 4x16-bit signed immediate values.
+ int16_t _i16[4];
+ //! 4x16-bit unsigned immediate values.
+ uint16_t _u16[4];
+
+ //! 2x32-bit signed immediate values.
+ int32_t _i32[2];
+ //! 2x32-bit unsigned immediate values.
+ uint32_t _u32[2];
+
+ //! 1x64-bit signed immediate value.
+ int64_t _i64[1];
+ //! 1x64-bit unsigned immediate value.
+ uint64_t _u64[1];
+
+ //! 2x SP-FP values.
+ float _f32[2];
+ //! 1x DP-FP value.
+ double _f64[1];
+ } value;
+ };
+
+ //! \internal
+ //!
+ //! Label operand data.
+ struct LabelOp {
+ //! Type of operand, `kOperandTypeLabel`.
+ uint8_t op;
+ //! Always zero, labels don't have size.
+ uint8_t size;
+ //! \internal
+ uint8_t reserved_2_1;
+ //! \internal
+ uint8_t reserved_3_1;
+
+ //! Operand id (`kInvalidValue` if the label is not initialized by code
+ //! generator).
+ uint32_t id;
+
+ //! \internal
+ uint32_t reserved_8_4;
+ //! \internal
+ uint32_t reserved_12_4;
+ };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create an uninitialized operand.
+ ASMJIT_INLINE Operand() {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeNone, 0, 0, 0, kInvalidValue);
+ _init_packed_d2_d3(0, 0);
+ }
+
+ //! Create a reference to `other` operand.
+ ASMJIT_INLINE Operand(const Operand& other) {
+ _init(other);
+ }
+
+ explicit ASMJIT_INLINE Operand(const _NoInit&) {}
+
+ // --------------------------------------------------------------------------
+ // [Operand]
+ // --------------------------------------------------------------------------
+
+ //! Clone `Operand`.
+ ASMJIT_INLINE Operand clone() const {
+ return Operand(*this);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Init & Copy]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ //!
+ //! Initialize operand to `other` (used by constructors).
+ ASMJIT_INLINE void _init(const Operand& other) {
+ ::memcpy(this, &other, sizeof(Operand));
+ }
+
+ ASMJIT_INLINE void _init_packed_op_sz_b0_b1_id(uint32_t op, uint32_t sz, uint32_t r0, uint32_t r1, uint32_t id) {
+ // This hack is not for performance, but to decrease the size of the binary
+ // generated when constructing AsmJit operands (mostly for third parties).
+ // Some compilers are not able to join four BYTE writes to a single DWORD
+ // write. Because the 'a', 'b', 'c' and 'd' variables are usually compile
+ // time constants the compiler can do a really nice job if they are joined
+ // by using bitwise operations.
+ _packed[0].setPacked_2x32(IntUtil::pack32_4x8(op, sz, r0, r1), id);
+ }
+
+ ASMJIT_INLINE void _init_packed_op_sz_w0_id(uint32_t op, uint32_t sz, uint32_t w0, uint32_t id) {
+ _packed[0].setPacked_2x32(IntUtil::pack32_2x8_1x16(op, sz, w0), id);
+ }
+
+ ASMJIT_INLINE void _init_packed_d0_d1(uint32_t u0, uint32_t u1) {
+ _packed[0].setPacked_2x32(u0, u1);
+ }
+
+ ASMJIT_INLINE void _init_packed_d2_d3(uint32_t u2, uint32_t u3) {
+ _packed[1].setPacked_2x32(u2, u3);
+ }
+
+ //! \internal
+ //!
+ //! Initialize operand to `other` (used by assign operators).
+ ASMJIT_INLINE void _copy(const Operand& other) {
+ ::memcpy(this, &other, sizeof(Operand));
+ }
+
+ // --------------------------------------------------------------------------
+ // [Data]
+ // --------------------------------------------------------------------------
+
+ template<typename T>
+ ASMJIT_INLINE T& getData() {
+ return reinterpret_cast<T&>(_base);
+ }
+
+ template<typename T>
+ ASMJIT_INLINE const T& getData() const {
+ return reinterpret_cast<const T&>(_base);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Type]
+ // --------------------------------------------------------------------------
+
+ //! Get type of the operand, see `kOperandType`.
+ ASMJIT_INLINE uint32_t getOp() const { return _base.op; }
+
+ //! Get whether the operand is none - `kOperandTypeNone`.
+ ASMJIT_INLINE bool isNone() const { return (_base.op == kOperandTypeNone); }
+ //! Get whether the operand is a register - `kOperandTypeReg`.
+ ASMJIT_INLINE bool isReg() const { return (_base.op == kOperandTypeReg); }
+ //! Get whether the operand is a variable - `kOperandTypeVar`.
+ ASMJIT_INLINE bool isVar() const { return (_base.op == kOperandTypeVar); }
+ //! Get whether the operand is a memory address - `kOperandTypeMem`.
+ ASMJIT_INLINE bool isMem() const { return (_base.op == kOperandTypeMem); }
+ //! Get whether the operand is an immediate value - `kOperandTypeImm`.
+ ASMJIT_INLINE bool isImm() const { return (_base.op == kOperandTypeImm); }
+ //! Get whether the operand is a label - `kOperandTypeLabel`.
+ ASMJIT_INLINE bool isLabel() const { return (_base.op == kOperandTypeLabel); }
+
+ // --------------------------------------------------------------------------
+ // [Type - Combined]
+ // --------------------------------------------------------------------------
+
+ //! Get register type.
+ ASMJIT_INLINE uint32_t getRegType() const {
+ return _vreg.type;
+ }
+
+ //! Get register index.
+ ASMJIT_INLINE uint32_t getRegIndex() const {
+ return _vreg.index;
+ }
+
+ //! Get whether the operand is register of `type`.
+ ASMJIT_INLINE bool isRegType(uint32_t type) const {
+ return (_packed[0].u32[0] & IntUtil::pack32_2x8_1x16(0xFF, 0, 0xFF00)) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 0, (type << 8));
+ }
+
+ //! Get whether the operand is register and of `type` and `index`.
+ ASMJIT_INLINE bool isRegCode(uint32_t type, uint32_t index) const {
+ return (_packed[0].u32[0] & IntUtil::pack32_2x8_1x16(0xFF, 0, 0xFFFF)) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 0, (type << 8) + index);
+ }
+
+ //! Get whether the operand is a register or memory.
+ ASMJIT_INLINE bool isRegOrMem() const {
+ ASMJIT_ASSERT(kOperandTypeReg == 1);
+ ASMJIT_ASSERT(kOperandTypeMem == 3);
+ return (static_cast<uint32_t>(_base.op) | 0x2U) == 0x3U;
+ }
+
+ //! Get whether the operand is variable or memory.
+ ASMJIT_INLINE bool isVarOrMem() const {
+ ASMJIT_ASSERT(kOperandTypeVar == 2);
+ ASMJIT_ASSERT(kOperandTypeMem == 3);
+ return (static_cast<uint32_t>(_base.op) - 2U) <= 1;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Size]
+ // --------------------------------------------------------------------------
+
+ //! Get size of the operand in bytes.
+ ASMJIT_INLINE uint32_t getSize() const {
+ return _base.size;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Id]
+ // --------------------------------------------------------------------------
+
+ //! Get operand id.
+ //!
+ //! Operand id's are used internally by `Assembler` and `Compiler`.
+ //!
+ //! There is no way to change or remove operand id. Unneeded operands can be
+ //! simply reassigned by `operator=`.
+ ASMJIT_INLINE uint32_t getId() const {
+ return _base.id;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ union {
+ //! Base data.
+ BaseOp _base;
+ //! Register or variable data.
+ VRegOp _vreg;
+ //! Memory data.
+ VMemOp _vmem;
+ //! Immediate data.
+ ImmOp _imm;
+ //! Label data.
+ LabelOp _label;
+
+ //! Packed operand as two 64-bit integers.
+ UInt64 _packed[2];
+ };
+};
+
+// ============================================================================
+// [asmjit::OperandUtil]
+// ============================================================================
+
+//! Operand utilities.
+struct OperandUtil {
+ //! Make variable id.
+ static ASMJIT_INLINE uint32_t makeVarId(uint32_t id) {
+ return id | kOperandIdVar;
+ }
+
+ //! Make label id.
+ static ASMJIT_INLINE uint32_t makeLabelId(uint32_t id) {
+ return id;
+ }
+
+ //! Strip variable id bit so it becomes a pure index to `VarData[]` array.
+ static ASMJIT_INLINE uint32_t stripVarId(uint32_t id) {
+ return id & 0x7FFFFFFFU;
+ }
+
+ //! Get whether the id refers to `Var`.
+ //!
+ //! \note The function will never return `true` if the id is `kInvalidValue`.
+ //! The trick is to compare a given id to -1 (kInvalidValue) so we check both
+ //! using only one comparison.
+ static ASMJIT_INLINE bool isVarId(uint32_t id) {
+ return static_cast<int32_t>(id) < -1;
+ }
+
+ //! Get whether the id refers to `Label`.
+ //!
+ //! \note The function will never return `true` if the id is `kInvalidValue`.
+ static ASMJIT_INLINE bool isLabelId(uint32_t id) {
+ return static_cast<int32_t>(id) >= 0;
+ }
+};
+
+// ============================================================================
+// [asmjit::Reg]
+// ============================================================================
+
+//! Base class for all register operands.
+struct Reg : public Operand {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a dummy base register.
+ ASMJIT_INLINE Reg() : Operand(NoInit) {
+ _init_packed_op_sz_w0_id(kOperandTypeReg, 0, (kInvalidReg << 8) + kInvalidReg, kInvalidValue);
+ _init_packed_d2_d3(kInvalidVar, 0);
+ }
+
+ //! Create a new base register.
+ ASMJIT_INLINE Reg(uint32_t type, uint32_t index, uint32_t size) : Operand(NoInit) {
+ _init_packed_op_sz_w0_id(kOperandTypeReg, size, (type << 8) + index, kInvalidValue);
+ _init_packed_d2_d3(kInvalidVar, 0);
+ }
+
+ //! Create a new reference to `other`.
+ ASMJIT_INLINE Reg(const Reg& other) : Operand(other) {}
+
+ //! Create a new reference to `other` and change the index to `index`.
+ ASMJIT_INLINE Reg(const Reg& other, uint32_t index) : Operand(other) {
+ _vreg.index = static_cast<uint8_t>(index);
+ }
+
+ explicit ASMJIT_INLINE Reg(const _NoInit&) : Operand(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [Reg Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone `Reg` operand.
+ ASMJIT_INLINE Reg clone() const {
+ return Reg(*this);
+ }
+
+ //! Get whether register code is equal to `type`.
+ ASMJIT_INLINE bool isRegType(uint32_t type) const {
+ return _vreg.type == type;
+ }
+
+ //! Get whether register code is equal to `type`.
+ ASMJIT_INLINE bool isRegCode(uint32_t code) const {
+ return _vreg.code == code;
+ }
+
+ //! Get whether register code is equal to `type`.
+ ASMJIT_INLINE bool isRegCode(uint32_t type, uint32_t index) const {
+ return _vreg.code == (type << 8) + index;
+ }
+
+ //! Get register code that equals to '(type << 8) + index'.
+ ASMJIT_INLINE uint32_t getRegCode() const {
+ return _vreg.code;
+ }
+
+ //! Get register type.
+ ASMJIT_INLINE uint32_t getRegType() const {
+ return _vreg.type;
+ }
+
+ //! Get register index.
+ ASMJIT_INLINE uint32_t getRegIndex() const {
+ return _vreg.index;
+ }
+
+#define ASMJIT_REG_OP(_Type_) \
+ ASMJIT_INLINE _Type_ clone() const { \
+ return _Type_(*this); \
+ } \
+ \
+ /*! Set register `size`. */ \
+ ASMJIT_INLINE _Type_& setSize(uint32_t size) { \
+ _vreg.size = static_cast<uint8_t>(size); \
+ return *this; \
+ } \
+ \
+ /*! Set register `code`. */ \
+ ASMJIT_INLINE _Type_& setCode(uint32_t code) { \
+ _vreg.code = static_cast<uint16_t>(code); \
+ return *this; \
+ } \
+ \
+ /*! Set register `type` and `index`. */ \
+ ASMJIT_INLINE _Type_& setCode(uint32_t type, uint32_t index) { \
+ _vreg.type = static_cast<uint8_t>(type); \
+ _vreg.index = static_cast<uint8_t>(index); \
+ return *this; \
+ } \
+ \
+ /*! Set register `type`. */ \
+ ASMJIT_INLINE _Type_& setType(uint32_t type) { \
+ _vreg.type = static_cast<uint8_t>(type); \
+ return *this; \
+ } \
+ \
+ /*! Set register `index`. */ \
+ ASMJIT_INLINE _Type_& setIndex(uint32_t index) { \
+ _vreg.index = static_cast<uint8_t>(index); \
+ return *this; \
+ } \
+ \
+ ASMJIT_INLINE _Type_& operator=(const _Type_& other) { _copy(other); return *this; } \
+ \
+ ASMJIT_INLINE bool operator==(const _Type_& other) const { return _packed[0].u32[0] == other._packed[0].u32[0]; } \
+ ASMJIT_INLINE bool operator!=(const _Type_& other) const { return !operator==(other); }
+};
+
+// ============================================================================
+// [asmjit::BaseMem]
+// ============================================================================
+
+//! Base class for all memory operands.
+struct BaseMem : public Operand {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE BaseMem() : Operand(NoInit) {
+ reset();
+ }
+
+ ASMJIT_INLINE BaseMem(const BaseMem& other) : Operand(other) {}
+ explicit ASMJIT_INLINE BaseMem(const _NoInit&) : Operand(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [BaseMem Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone `BaseMem` operand.
+ ASMJIT_INLINE BaseMem clone() const {
+ return BaseMem(*this);
+ }
+
+ //! Reset `BaseMem` operand.
+ ASMJIT_INLINE void reset() {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, 0, kMemTypeBaseIndex, 0, kInvalidValue);
+ _init_packed_d2_d3(kInvalidValue, 0);
+ }
+
+ //! Get the type of the memory operand, see `kMemType`.
+ ASMJIT_INLINE uint32_t getMemType() const {
+ return _vmem.type;
+ }
+
+ //! Get whether the type of the memory operand is either `kMemTypeBaseIndex`
+ //! or `kMemTypeStackIndex`.
+ ASMJIT_INLINE bool isBaseIndexType() const {
+ return _vmem.type <= kMemTypeStackIndex;
+ }
+
+ //! Get whether the memory operand has base register.
+ ASMJIT_INLINE bool hasBase() const {
+ return _vmem.base != kInvalidValue;
+ }
+
+ //! Get memory operand base id, or `kInvalidValue`.
+ ASMJIT_INLINE uint32_t getBase() const {
+ return _vmem.base;
+ }
+
+ //! Set memory operand size.
+ ASMJIT_INLINE BaseMem& setSize(uint32_t size) {
+ _vmem.size = static_cast<uint8_t>(size);
+ return *this;
+ }
+
+ //! Get memory operand relative displacement.
+ ASMJIT_INLINE int32_t getDisplacement() const {
+ return _vmem.displacement;
+ }
+
+ //! Set memory operand relative displacement.
+ ASMJIT_INLINE BaseMem& setDisplacement(int32_t disp) {
+ _vmem.displacement = disp;
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE BaseMem& operator=(const BaseMem& other) {
+ _copy(other);
+ return *this;
+ }
+
+ ASMJIT_INLINE bool operator==(const BaseMem& other) const {
+ return (_packed[0] == other._packed[0]) & (_packed[1] == other._packed[1]);
+ }
+
+ ASMJIT_INLINE bool operator!=(const BaseMem& other) const {
+ return !(*this == other);
+ }
+};
+
+// ============================================================================
+// [asmjit::Imm]
+// ============================================================================
+
+//! Immediate operand.
+//!
+//! Immediate operand is usually part of instruction itself. It's inlined after
+//! or before the instruction opcode. Immediates can be only signed or unsigned
+//! integers.
+//!
+//! To create immediate operand use `imm()` or `imm_u()` non-members or `Imm`
+//! constructors.
+struct Imm : public Operand {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new immediate value (initial value is 0).
+ Imm() : Operand(NoInit) {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeImm, 0, 0, 0, kInvalidValue);
+ _imm.value._i64[0] = 0;
+ }
+
+ //! Create a new signed immediate value, assigning the value to `val`.
+ explicit Imm(int64_t val) : Operand(NoInit) {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeImm, 0, 0, 0, kInvalidValue);
+ _imm.value._i64[0] = val;
+ }
+
+ //! Create a new immediate value from `other`.
+ ASMJIT_INLINE Imm(const Imm& other) : Operand(other) {}
+
+ explicit ASMJIT_INLINE Imm(const _NoInit&) : Operand(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [Immediate Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone `Imm` operand.
+ ASMJIT_INLINE Imm clone() const {
+ return Imm(*this);
+ }
+
+ //! Get whether the immediate can be casted to 8-bit signed integer.
+ ASMJIT_INLINE bool isInt8() const { return IntUtil::isInt8(_imm.value._i64[0]); }
+ //! Get whether the immediate can be casted to 8-bit unsigned integer.
+ ASMJIT_INLINE bool isUInt8() const { return IntUtil::isUInt8(_imm.value._i64[0]); }
+
+ //! Get whether the immediate can be casted to 16-bit signed integer.
+ ASMJIT_INLINE bool isInt16() const { return IntUtil::isInt16(_imm.value._i64[0]); }
+ //! Get whether the immediate can be casted to 16-bit unsigned integer.
+ ASMJIT_INLINE bool isUInt16() const { return IntUtil::isUInt16(_imm.value._i64[0]); }
+
+ //! Get whether the immediate can be casted to 32-bit signed integer.
+ ASMJIT_INLINE bool isInt32() const { return IntUtil::isInt32(_imm.value._i64[0]); }
+ //! Get whether the immediate can be casted to 32-bit unsigned integer.
+ ASMJIT_INLINE bool isUInt32() const { return IntUtil::isUInt32(_imm.value._i64[0]); }
+
+ //! Get immediate value as 8-bit signed integer.
+ ASMJIT_INLINE int8_t getInt8() const { return _imm.value._i8[_ASMJIT_HOST_INDEX(8, 0)]; }
+ //! Get immediate value as 8-bit unsigned integer.
+ ASMJIT_INLINE uint8_t getUInt8() const { return _imm.value._u8[_ASMJIT_HOST_INDEX(8, 0)]; }
+ //! Get immediate value as 16-bit signed integer.
+ ASMJIT_INLINE int16_t getInt16() const { return _imm.value._i16[_ASMJIT_HOST_INDEX(4, 0)]; }
+ //! Get immediate value as 16-bit unsigned integer.
+ ASMJIT_INLINE uint16_t getUInt16() const { return _imm.value._u16[_ASMJIT_HOST_INDEX(4, 0)]; }
+ //! Get immediate value as 32-bit signed integer.
+ ASMJIT_INLINE int32_t getInt32() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)]; }
+ //! Get immediate value as 32-bit unsigned integer.
+ ASMJIT_INLINE uint32_t getUInt32() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)]; }
+ //! Get immediate value as 64-bit signed integer.
+ ASMJIT_INLINE int64_t getInt64() const { return _imm.value._i64[0]; }
+ //! Get immediate value as 64-bit unsigned integer.
+ ASMJIT_INLINE uint64_t getUInt64() const { return _imm.value._u64[0]; }
+
+ //! Get immediate value as `intptr_t`.
+ ASMJIT_INLINE intptr_t getIntPtr() const {
+ if (sizeof(intptr_t) == sizeof(int64_t))
+ return static_cast<intptr_t>(getInt64());
+ else
+ return static_cast<intptr_t>(getInt32());
+ }
+
+ //! Get immediate value as `uintptr_t`.
+ ASMJIT_INLINE uintptr_t getUIntPtr() const {
+ if (sizeof(uintptr_t) == sizeof(uint64_t))
+ return static_cast<uintptr_t>(getUInt64());
+ else
+ return static_cast<uintptr_t>(getUInt32());
+ }
+
+ //! Get low 32-bit signed integer.
+ ASMJIT_INLINE int32_t getInt32Lo() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)]; }
+ //! Get low 32-bit signed integer.
+ ASMJIT_INLINE uint32_t getUInt32Lo() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)]; }
+ //! Get high 32-bit signed integer.
+ ASMJIT_INLINE int32_t getInt32Hi() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)]; }
+ //! Get high 32-bit signed integer.
+ ASMJIT_INLINE uint32_t getUInt32Hi() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)]; }
+
+ //! Set immediate value to 8-bit signed integer `val`.
+ ASMJIT_INLINE Imm& setInt8(int8_t val) {
+ if (kArchHost64Bit) {
+ _imm.value._i64[0] = static_cast<int64_t>(val);
+ }
+ else {
+ int32_t val32 = static_cast<int32_t>(val);
+ _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val32;
+ _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val32 >> 31;
+ }
+ return *this;
+ }
+
+ //! Set immediate value to 8-bit unsigned integer `val`.
+ ASMJIT_INLINE Imm& setUInt8(uint8_t val) {
+ if (kArchHost64Bit) {
+ _imm.value._u64[0] = static_cast<uint64_t>(val);
+ }
+ else {
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = static_cast<uint32_t>(val);
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ }
+ return *this;
+ }
+
+ //! Set immediate value to 16-bit signed integer `val`.
+ ASMJIT_INLINE Imm& setInt16(int16_t val) {
+ if (kArchHost64Bit) {
+ _imm.value._i64[0] = static_cast<int64_t>(val);
+ }
+ else {
+ int32_t val32 = static_cast<int32_t>(val);
+ _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val32;
+ _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val32 >> 31;
+ }
+ return *this;
+ }
+
+ //! Set immediate value to 16-bit unsigned integer `val`.
+ ASMJIT_INLINE Imm& setUInt16(uint16_t val) {
+ if (kArchHost64Bit) {
+ _imm.value._u64[0] = static_cast<uint64_t>(val);
+ }
+ else {
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = static_cast<uint32_t>(val);
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ }
+ return *this;
+ }
+
+ //! Set immediate value to 32-bit signed integer `val`.
+ ASMJIT_INLINE Imm& setInt32(int32_t val) {
+ if (kArchHost64Bit) {
+ _imm.value._i64[0] = static_cast<int64_t>(val);
+ }
+ else {
+ _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val;
+ _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val >> 31;
+ }
+ return *this;
+ }
+
+ //! Set immediate value to 32-bit unsigned integer `val`.
+ ASMJIT_INLINE Imm& setUInt32(uint32_t val) {
+ if (kArchHost64Bit) {
+ _imm.value._u64[0] = static_cast<uint64_t>(val);
+ }
+ else {
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = val;
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ }
+ return *this;
+ }
+
+ //! Set immediate value to 64-bit signed integer `val`.
+ ASMJIT_INLINE Imm& setInt64(int64_t val) {
+ _imm.value._i64[0] = val;
+ return *this;
+ }
+
+ //! Set immediate value to 64-bit unsigned integer `val`.
+ ASMJIT_INLINE Imm& setUInt64(uint64_t val) {
+ _imm.value._u64[0] = val;
+ return *this;
+ }
+
+ //! Set immediate value to intptr_t `val`.
+ ASMJIT_INLINE Imm& setIntPtr(intptr_t val) {
+ _imm.value._i64[0] = static_cast<int64_t>(val);
+ return *this;
+ }
+
+ //! Set immediate value to uintptr_t `val`.
+ ASMJIT_INLINE Imm& setUIntPtr(uintptr_t val) {
+ _imm.value._u64[0] = static_cast<uint64_t>(val);
+ return *this;
+ }
+
+ //! Set immediate value as unsigned type to `val`.
+ ASMJIT_INLINE Imm& setPtr(void* p) { return setIntPtr(reinterpret_cast<intptr_t>(p)); }
+
+ // --------------------------------------------------------------------------
+ // [Float]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Imm& setFloat(float f) {
+ _imm.value._f32[_ASMJIT_HOST_INDEX(2, 0)] = f;
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ return *this;
+ }
+
+ ASMJIT_INLINE Imm& setDouble(double d) {
+ _imm.value._f64[0] = d;
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Truncate]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Imm& truncateTo8Bits() {
+ if (kArchHost64Bit) {
+ _imm.value._u64[0] &= static_cast<uint64_t>(0x000000FFU);
+ }
+ else {
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] &= 0x000000FFU;
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ }
+ return *this;
+ }
+
+ ASMJIT_INLINE Imm& truncateTo16Bits() {
+ if (kArchHost64Bit) {
+ _imm.value._u64[0] &= static_cast<uint64_t>(0x0000FFFFU);
+ }
+ else {
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] &= 0x0000FFFFU;
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ }
+ return *this;
+ }
+
+ ASMJIT_INLINE Imm& truncateTo32Bits() {
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ //! Assign `other` to the immediate operand.
+ ASMJIT_INLINE Imm& operator=(const Imm& other) {
+ _copy(other);
+ return *this;
+ }
+};
+
+// ============================================================================
+// [asmjit::Label]
+// ============================================================================
+
+//! Label (jump target or data location).
+//!
+//! Label represents a location in code typically used as jump targets, but may
+//! be also reference data or static variables. Label has to be explicitly
+//! created by a code-generator by calling `CodeGen::newLabel()` where `CodeGen`
+//! is your code generator, which derives from `Assembler` or `Compiler`.
+//!
+//! Example of using labels:
+//!
+//! ~~~
+//! // Create Assembler/Compiler.
+//! host::Assembler a;
+//!
+//! // Create Label instance.
+//! Label L_1(a);
+//!
+//! // ... your code ...
+//!
+//! // Using label.
+//! a.jump(L_1);
+//!
+//! // ... your code ...
+//!
+//! // Bind label to the current position, see `CodeGen::bind()`.
+//! a.bind(L_1);
+//! ~~~
+struct Label : public Operand {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create new, unassociated label.
+ ASMJIT_INLINE Label() : Operand(NoInit) {
+ reset();
+ }
+
+ explicit ASMJIT_INLINE Label(uint32_t id) : Operand(NoInit) {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeLabel, 0, 0, 0, id);
+ _init_packed_d2_d3(0, 0);
+ }
+
+ //! Create new initialized label.
+ explicit ASMJIT_INLINE Label(Assembler& a);
+ //! Create new initialized label.
+ explicit ASMJIT_INLINE Label(Compiler& c);
+
+ //! Create reference to another label.
+ ASMJIT_INLINE Label(const Label& other) : Operand(other) {}
+
+ explicit ASMJIT_INLINE Label(const _NoInit&) : Operand(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void reset() {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeLabel, 0, 0, 0, kInvalidValue);
+ _init_packed_d2_d3(0, 0);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Label Specific]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the label has been initialized by `Assembler` or `Compiler`.
+ ASMJIT_INLINE bool isInitialized() const {
+ return _label.id != kInvalidValue;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Label& operator=(const Label& other) { _copy(other); return *this; }
+
+ ASMJIT_INLINE bool operator==(const Label& other) const { return _base.id == other._base.id; }
+ ASMJIT_INLINE bool operator!=(const Label& other) const { return _base.id != other._base.id; }
+};
+
+// ============================================================================
+// [asmjit::Operand - Globals]
+// ============================================================================
+
+//! No operand, can be used to reset an operand by assignment or to refer to an
+//! operand that doesn't exist.
+ASMJIT_VAR const Operand noOperand;
+
+//! Create signed immediate value operand.
+static ASMJIT_INLINE Imm imm(int64_t val) {
+ return Imm(val);
+}
+
+//! Create unsigned immediate value operand.
+static ASMJIT_INLINE Imm imm_u(uint64_t val) {
+ return Imm(static_cast<int64_t>(val));
+}
+
+//! Create void* pointer immediate value operand.
+static ASMJIT_INLINE Imm imm_ptr(void* p) {
+ return Imm(static_cast<int64_t>(reinterpret_cast<intptr_t>(p)));
+}
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/runtime.cpp
@@ -1,1 +1,192 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Dependencies - AsmJit]
+#include "../base/assembler.h"
+#include "../base/cpuinfo.h"
+#include "../base/error.h"
+#include "../base/runtime.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [asmjit::Runtime - Construction / Destruction]
+// ============================================================================
+
+Runtime::Runtime() {
+ _sizeLimit = 0;
+
+ _runtimeType = kRuntimeTypeNone;
+ _allocType = kVMemAllocFreeable;
+ ::memset(_reserved, 0, sizeof(_reserved));
+
+ _baseAddress = kNoBaseAddress;
+}
+
+Runtime::~Runtime() {}
+
+// ============================================================================
+// [asmjit::HostRuntime - Construction / Destruction]
+// ============================================================================
+
+HostRuntime::HostRuntime() {
+ _runtimeType = kRuntimeTypeJit;
+}
+
+HostRuntime::~HostRuntime() {}
+
+// ============================================================================
+// [asmjit::HostRuntime - Interface]
+// ============================================================================
+
+const CpuInfo* HostRuntime::getCpuInfo() {
+ return CpuInfo::getHost();
+}
+
+uint32_t HostRuntime::getStackAlignment() {
+ uint32_t alignment = sizeof(intptr_t);
+
+#ifdef ASMJIT_HOST_X86
+ // Modern Linux, APPLE and UNIX guarantees 16-byte stack alignment, but I'm
+ // not sure about all other UNIX operating systems, because 16-byte alignment
+ // is addition to an older specification.
+# if (defined(__linux__) || \
+ defined(__linux) || \
+ defined(__unix__) || \
+ defined(__FreeBSD__) || \
+ defined(__NetBSD__) || \
+ defined(__OpenBSD__) || \
+ defined(__DARWIN__) || \
+ defined(__APPLE__) )
+ alignment = 16;
+# endif
+#elif defined(ASMJIT_HOST_X64)
+ alignment = 16;
+#endif
+
+ return alignment;
+}
+
+void HostRuntime::flush(void* p, size_t size) {
+ // Only useful on non-x86 architectures.
+#if !defined(ASMJIT_HOST_X86) && !defined(ASMJIT_HOST_X64)
+
+ // Windows has built-in support in kernel32.dll.
+# ifdef ASMJIT_OS_WINDOWS
+ ::FlushInstructionCache(_memMgr.getProcessHandle(), p, size);
+# endif // ASMJIT_OS_WINDOWS
+
+#endif // !ASMJIT_HOST_X86 && !ASMJIT_HOST_X64
+}
+
+// ============================================================================
+// [asmjit::StaticRuntime - Construction / Destruction]
+// ============================================================================
+
+StaticRuntime::StaticRuntime(void* baseAddress, size_t sizeLimit) {
+ _sizeLimit = sizeLimit;
+ _baseAddress = static_cast<Ptr>(reinterpret_cast<uintptr_t>(baseAddress));
+}
+
+StaticRuntime::~StaticRuntime() {}
+
+// ============================================================================
+// [asmjit::StaticRuntime - Interface]
+// ============================================================================
+
+Error StaticRuntime::add(void** dst, Assembler* assembler) {
+ size_t codeSize = assembler->getCodeSize();
+ size_t sizeLimit = _sizeLimit;
+
+ if (codeSize == 0) {
+ *dst = nullptr;
+ return kErrorNoCodeGenerated;
+ }
+
+ if (sizeLimit != 0 && sizeLimit < codeSize) {
+ *dst = nullptr;
+ return kErrorCodeTooLarge;
+ }
+
+ Ptr baseAddress = _baseAddress;
+ uint8_t* p = static_cast<uint8_t*>(reinterpret_cast<void*>(static_cast<uintptr_t>(baseAddress)));
+
+ // Since the base address is known the `relocSize` returned should be equal
+ // to `codeSize`. It's better to fail if they don't match instead of passsing
+ // silently.
+ size_t relocSize = assembler->relocCode(p, baseAddress);
+ if (relocSize == 0 || codeSize != relocSize) {
+ *dst = nullptr;
+ return kErrorInvalidState;
+ }
+
+ _baseAddress += codeSize;
+ if (sizeLimit)
+ sizeLimit -= codeSize;
+
+ flush(p, codeSize);
+ *dst = p;
+
+ return kErrorOk;
+}
+
+Error StaticRuntime::release(void* p) {
+ // There is nothing to release as `StaticRuntime` doesn't manage any memory.
+ ASMJIT_UNUSED(p);
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::JitRuntime - Construction / Destruction]
+// ============================================================================
+
+JitRuntime::JitRuntime() {}
+JitRuntime::~JitRuntime() {}
+
+// ============================================================================
+// [asmjit::JitRuntime - Interface]
+// ============================================================================
+
+Error JitRuntime::add(void** dst, Assembler* assembler) {
+ size_t codeSize = assembler->getCodeSize();
+ if (codeSize == 0) {
+ *dst = nullptr;
+ return kErrorNoCodeGenerated;
+ }
+
+ void* p = _memMgr.alloc(codeSize, getAllocType());
+ if (!p) {
+ *dst = nullptr;
+ return kErrorNoVirtualMemory;
+ }
+
+ // Relocate the code and release the unused memory back to `VMemMgr`.
+ size_t relocSize = assembler->relocCode(p);
+ if (relocSize < codeSize) {
+ _memMgr.shrink(p, relocSize);
+ }
+
+ flush(p, relocSize);
+ *dst = p;
+
+ return kErrorOk;
+}
+
+Error JitRuntime::release(void* p) {
+ return _memMgr.release(p);
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/runtime.h
@@ -1,1 +1,258 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../base/error.h"
+#include "../base/vmem.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [Forward Declarations]
+// ============================================================================
+
+struct Assembler;
+struct CpuInfo;
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::kRuntimeType]
+// ============================================================================
+
+ASMJIT_ENUM(kRuntimeType) {
+ kRuntimeTypeNone = 0,
+
+ kRuntimeTypeJit = 1,
+ kRuntimeTypeRemote = 2
+};
+
+// ============================================================================
+// [asmjit::Runtime]
+// ============================================================================
+
+//! Base runtime.
+struct ASMJIT_VCLASS Runtime {
+ ASMJIT_NO_COPY(Runtime)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a `Runtime` instance.
+ ASMJIT_API Runtime();
+ //! Destroy the `Runtime` instance.
+ ASMJIT_API virtual ~Runtime();
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get runtime type.
+ ASMJIT_INLINE uint32_t getRuntimeType() const {
+ return _runtimeType;
+ }
+
+ //! Get whether the runtime has a base address.
+ //!
+ //! \sa \ref getBaseAddress()
+ ASMJIT_INLINE bool hasBaseAddress() const {
+ return _baseAddress == kNoBaseAddress;
+ }
+
+ //! Get the base address.
+ ASMJIT_INLINE Ptr getBaseAddress() const {
+ return _baseAddress;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Interface]
+ // --------------------------------------------------------------------------
+
+ //! Get CPU information.
+ virtual const CpuInfo* getCpuInfo() = 0;
+
+ //! Get stack alignment of target runtime.
+ virtual uint32_t getStackAlignment() = 0;
+
+ //! Allocate a memory needed for a code generated by `assembler` and
+ //! relocate it to the target location.
+ //!
+ //! The beginning of the memory allocated for the function is returned in
+ //! `dst`. Returns Status code as \ref kError, on failure `dst` is set to
+ //! `NULL`.
+ virtual Error add(void** dst, Assembler* assembler) = 0;
+
+ //! Release memory allocated by `add`.
+ virtual Error release(void* p) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Maximum size of the code that can be added to the runtime (0=unlimited).
+ size_t _sizeLimit;
+ //! Base address (-1 means no base address).
+ Ptr _baseAddress;
+
+ //! Type of the runtime.
+ uint8_t _runtimeType;
+ //! Type of the allocation.
+ uint8_t _allocType;
+ //! \internal
+ uint8_t _reserved[sizeof(intptr_t) - 2];
+};
+
+// ============================================================================
+// [asmjit::HostRuntime]
+// ============================================================================
+
+//! Base runtime for JIT code generation.
+struct ASMJIT_VCLASS HostRuntime : public Runtime {
+ ASMJIT_NO_COPY(HostRuntime)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a `HostRuntime` instance.
+ ASMJIT_API HostRuntime();
+ //! Destroy the `HostRuntime` instance.
+ ASMJIT_API virtual ~HostRuntime();
+
+ // --------------------------------------------------------------------------
+ // [Interface]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual const CpuInfo* getCpuInfo();
+ ASMJIT_API virtual uint32_t getStackAlignment();
+
+ //! Flush an instruction cache.
+ //!
+ //! This member function is called after the code has been copied to the
+ //! destination buffer. It is only useful for JIT code generation as it
+ //! causes a flush of the processor cache.
+ //!
+ //! Flushing is basically a NOP under X86/X64, but is needed by architectures
+ //! that do not have a transparent instruction cache.
+ //!
+ //! This function can also be overridden to improve compatibility with tools
+ //! such as Valgrind, however, it's not an official part of AsmJit.
+ ASMJIT_API virtual void flush(void* p, size_t size);
+};
+
+// ============================================================================
+// [asmjit::StaticRuntime]
+// ============================================================================
+
+//! JIT static runtime.
+//!
+//! JIT static runtime can be used to generate code to a memory location that
+//! is known.
+struct ASMJIT_VCLASS StaticRuntime : public HostRuntime {
+ ASMJIT_NO_COPY(StaticRuntime)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a `StaticRuntime` instance.
+ //!
+ //! The `address` specifies a fixed target address, which will be used as a
+ //! base address for relocation, and `sizeLimit` specified the maximum size
+ //! of a code that can be copied to it. If there is no limit `sizeLimit`
+ //! should be zero.
+ ASMJIT_API StaticRuntime(void* baseAddress, size_t sizeLimit = 0);
+ //! Destroy the `StaticRuntime` instance.
+ ASMJIT_API virtual ~StaticRuntime();
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get the base address.
+ ASMJIT_INLINE Ptr getBaseAddress() const {
+ return _baseAddress;
+ }
+
+ //! Get the maximum size of the code that can be relocated to the target
+ //! address or zero if unlimited.
+ ASMJIT_INLINE size_t getSizeLimit() const {
+ return _sizeLimit;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Interface]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual Error add(void** dst, Assembler* assembler);
+ ASMJIT_API virtual Error release(void* p);
+};
+
+// ============================================================================
+// [asmjit::JitRuntime]
+// ============================================================================
+
+//! JIT runtime.
+struct ASMJIT_VCLASS JitRuntime : public HostRuntime {
+ ASMJIT_NO_COPY(JitRuntime)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a `JitRuntime` instance.
+ ASMJIT_API JitRuntime();
+ //! Destroy the `JitRuntime` instance.
+ ASMJIT_API virtual ~JitRuntime();
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get the type of allocation.
+ ASMJIT_INLINE uint32_t getAllocType() const {
+ return _allocType;
+ }
+
+ //! Set the type of allocation.
+ ASMJIT_INLINE void setAllocType(uint32_t allocType) {
+ _allocType = allocType;
+ }
+
+ //! Get the virtual memory manager.
+ ASMJIT_INLINE VMemMgr* getMemMgr() const {
+ return const_cast<VMemMgr*>(&_memMgr);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Interface]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual Error add(void** dst, Assembler* assembler);
+ ASMJIT_API virtual Error release(void* p);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Virtual memory manager.
+ VMemMgr _memMgr;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/string.cpp
@@ -1,1 +1,375 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Dependencies - AsmJit]
+#include "../base/intutil.h"
+#include "../base/string.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// Should be placed in read-only memory.
+static const char StringBuilder_empty[4] = { 0 };
+
+// ============================================================================
+// [asmjit::StringBuilder - Construction / Destruction]
+// ============================================================================
+
+StringBuilder::StringBuilder() :
+ _data(const_cast<char*>(StringBuilder_empty)),
+ _length(0),
+ _capacity(0),
+ _canFree(false) {}
+
+StringBuilder::~StringBuilder() {
+ if (_canFree)
+ ASMJIT_FREE(_data);
+}
+
+// ============================================================================
+// [asmjit::StringBuilder - Prepare / Reserve]
+// ============================================================================
+
+char* StringBuilder::prepare(uint32_t op, size_t len) {
+ // --------------------------------------------------------------------------
+ // [Set]
+ // --------------------------------------------------------------------------
+
+ if (op == kStringOpSet) {
+ // We don't care here, but we can't return a NULL pointer since it indicates
+ // failure in memory allocation.
+ if (len == 0) {
+ if (_data != StringBuilder_empty)
+ _data[0] = 0;
+
+ _length = 0;
+ return _data;
+ }
+
+ if (_capacity < len) {
+ if (len >= IntUtil::maxUInt<size_t>() - sizeof(intptr_t) * 2)
+ return nullptr;
+
+ size_t to = IntUtil::alignTo<size_t>(len, sizeof(intptr_t));
+ if (to < 256 - sizeof(intptr_t))
+ to = 256 - sizeof(intptr_t);
+
+ char* newData = static_cast<char*>(ASMJIT_ALLOC(to + sizeof(intptr_t)));
+ if (!newData) {
+ clear();
+ return nullptr;
+ }
+
+ if (_canFree)
+ ASMJIT_FREE(_data);
+
+ _data = newData;
+ _capacity = to + sizeof(intptr_t) - 1;
+ _canFree = true;
+ }
+
+ _data[len] = 0;
+ _length = len;
+
+ ASMJIT_ASSERT(_length <= _capacity);
+ return _data;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Append]
+ // --------------------------------------------------------------------------
+
+ else {
+ // We don't care here, but we can't return a NULL pointer since it indicates
+ // failure in memory allocation.
+ if (len == 0)
+ return _data + _length;
+
+ // Overflow.
+ if (IntUtil::maxUInt<size_t>() - sizeof(intptr_t) * 2 - _length < len)
+ return nullptr;
+
+ size_t after = _length + len;
+ if (_capacity < after) {
+ size_t to = _capacity;
+
+ if (to < 256)
+ to = 256;
+
+ while (to < 1024 * 1024 && to < after)
+ to *= 2;
+
+ if (to < after) {
+ to = after;
+ if (to < (IntUtil::maxUInt<size_t>() - 1024 * 32))
+ to = IntUtil::alignTo<size_t>(to, 1024 * 32);
+ }
+
+ to = IntUtil::alignTo<size_t>(to, sizeof(intptr_t));
+ char* newData = static_cast<char*>(ASMJIT_ALLOC(to + sizeof(intptr_t)));
+
+ if (!newData)
+ return nullptr;
+
+ ::memcpy(newData, _data, _length);
+ if (_canFree)
+ ASMJIT_FREE(_data);
+
+ _data = newData;
+ _capacity = to + sizeof(intptr_t) - 1;
+ _canFree = true;
+ }
+
+ char* ret = _data + _length;
+ _data[after] = 0;
+ _length = after;
+
+ ASMJIT_ASSERT(_length <= _capacity);
+ return ret;
+ }
+}
+
+bool StringBuilder::reserve(size_t to) {
+ if (_capacity >= to)
+ return true;
+
+ if (to >= IntUtil::maxUInt<size_t>() - sizeof(intptr_t) * 2)
+ return false;
+
+ to = IntUtil::alignTo<size_t>(to, sizeof(intptr_t));
+
+ char* newData = static_cast<char*>(ASMJIT_ALLOC(to + sizeof(intptr_t)));
+ if (!newData)
+ return false;
+
+ ::memcpy(newData, _data, _length + 1);
+ if (_canFree)
+ ASMJIT_FREE(_data);
+
+ _data = newData;
+ _capacity = to + sizeof(intptr_t) - 1;
+ _canFree = true;
+ return true;
+}
+
+// ============================================================================
+// [asmjit::StringBuilder - Clear]
+// ============================================================================
+
+void StringBuilder::clear() {
+ if (_data != StringBuilder_empty)
+ _data[0] = 0;
+ _length = 0;
+}
+
+// ============================================================================
+// [asmjit::StringBuilder - Methods]
+// ============================================================================
+
+bool StringBuilder::_opString(uint32_t op, const char* str, size_t len) {
+ if (len == kInvalidIndex)
+ len = str ? ::strlen(str) : static_cast<size_t>(0);
+
+ char* p = prepare(op, len);
+ if (!p)
+ return false;
+
+ ::memcpy(p, str, len);
+ return true;
+}
+
+bool StringBuilder::_opChar(uint32_t op, char c) {
+ char* p = prepare(op, 1);
+ if (!p)
+ return false;
+
+ *p = c;
+ return true;
+}
+
+bool StringBuilder::_opChars(uint32_t op, char c, size_t len) {
+ char* p = prepare(op, len);
+ if (!p)
+ return false;
+
+ ::memset(p, c, len);
+ return true;
+}
+
+static const char StringBuilder_numbers[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+bool StringBuilder::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, uint32_t flags) {
+ if (base < 2 || base > 36)
+ base = 10;
+
+ char buf[128];
+ char* p = buf + ASMJIT_ARRAY_SIZE(buf);
+
+ uint64_t orig = i;
+ char sign = '\0';
+
+ // --------------------------------------------------------------------------
+ // [Sign]
+ // --------------------------------------------------------------------------
+
+ if ((flags & kStringFormatSigned) != 0 && static_cast<int64_t>(i) < 0) {
+ i = static_cast<uint64_t>(-static_cast<int64_t>(i));
+ sign = '-';
+ }
+ else if ((flags & kStringFormatShowSign) != 0) {
+ sign = '+';
+ }
+ else if ((flags & kStringFormatShowSpace) != 0) {
+ sign = ' ';
+ }
+
+ // --------------------------------------------------------------------------
+ // [Number]
+ // --------------------------------------------------------------------------
+
+ do {
+ uint64_t d = i / base;
+ uint64_t r = i % base;
+
+ *--p = StringBuilder_numbers[r];
+ i = d;
+ } while (i);
+
+ size_t numberLength = static_cast<size_t>(buf + ASMJIT_ARRAY_SIZE(buf) - p);
+
+ // --------------------------------------------------------------------------
+ // [Alternate Form]
+ // --------------------------------------------------------------------------
+
+ if ((flags & kStringFormatAlternate) != 0) {
+ if (base == 8) {
+ if (orig != 0)
+ *--p = '0';
+ }
+ if (base == 16) {
+ *--p = 'x';
+ *--p = '0';
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // [Width]
+ // --------------------------------------------------------------------------
+
+ if (sign != 0)
+ *--p = sign;
+
+ if (width > 256)
+ width = 256;
+
+ if (width <= numberLength)
+ width = 0;
+ else
+ width -= numberLength;
+
+ // --------------------------------------------------------------------------
+ // Write]
+ // --------------------------------------------------------------------------
+
+ size_t prefixLength = static_cast<size_t>(buf + ASMJIT_ARRAY_SIZE(buf) - p) - numberLength;
+ char* data = prepare(op, prefixLength + width + numberLength);
+
+ if (!data)
+ return false;
+
+ ::memcpy(data, p, prefixLength);
+ data += prefixLength;
+
+ ::memset(data, '0', width);
+ data += width;
+
+ ::memcpy(data, p + prefixLength, numberLength);
+ return true;
+}
+
+bool StringBuilder::_opHex(uint32_t op, const void* data, size_t len) {
+ if (len >= IntUtil::maxUInt<size_t>() / 2)
+ return false;
+
+ char* dst = prepare(op, len * 2);
+ if (!dst)
+ return false;
+
+ const char* src = static_cast<const char*>(data);
+ for (size_t i = 0; i < len; i++, dst += 2, src += 1)
+ {
+ dst[0] = StringBuilder_numbers[(src[0] >> 4) & 0xF];
+ dst[1] = StringBuilder_numbers[(src[0] ) & 0xF];
+ }
+
+ return true;
+}
+
+bool StringBuilder::_opVFormat(uint32_t op, const char* fmt, va_list ap) {
+ char buf[1024];
+
+ vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap);
+ buf[ASMJIT_ARRAY_SIZE(buf) - 1] = '\0';
+
+ return _opString(op, buf);
+}
+
+bool StringBuilder::setFormat(const char* fmt, ...) {
+ bool result;
+
+ va_list ap;
+ va_start(ap, fmt);
+ result = _opVFormat(kStringOpSet, fmt, ap);
+ va_end(ap);
+
+ return result;
+}
+
+bool StringBuilder::appendFormat(const char* fmt, ...) {
+ bool result;
+
+ va_list ap;
+ va_start(ap, fmt);
+ result = _opVFormat(kStringOpAppend, fmt, ap);
+ va_end(ap);
+
+ return result;
+}
+
+bool StringBuilder::eq(const char* str, size_t len) const {
+ const char* aData = _data;
+ const char* bData = str;
+
+ size_t aLength = _length;
+ size_t bLength = len;
+
+ if (bLength == kInvalidIndex) {
+ size_t i;
+ for (i = 0; i < aLength; i++) {
+ if (aData[i] != bData[i] || bData[i] == 0)
+ return false;
+ }
+
+ return bData[i] == 0;
+ }
+ else {
+ if (aLength != bLength)
+ return false;
+
+ return ::memcmp(aData, bData, aLength) == 0;
+ }
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/string.h
@@ -1,1 +1,368 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+// [Dependencies - C]
+#include <cstdarg>
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::kStringOp]
+// ============================================================================
+
+//! \internal
+//!
+//! String operation.
+ASMJIT_ENUM(kStringOp) {
+ //! Replace the current string by a given content.
+ kStringOpSet = 0,
+ //! Append a given content to the current string.
+ kStringOpAppend = 1
+};
+
+// ============================================================================
+// [asmjit::kStringFormat]
+// ============================================================================
+
+//! \internal
+//!
+//! String format flags.
+ASMJIT_ENUM(kStringFormat) {
+ kStringFormatShowSign = 0x00000001,
+ kStringFormatShowSpace = 0x00000002,
+ kStringFormatAlternate = 0x00000004,
+ kStringFormatSigned = 0x80000000
+};
+
+// ============================================================================
+// [asmjit::StringUtil]
+// ============================================================================
+
+//! String utilities.
+struct StringUtil {
+ static ASMJIT_INLINE size_t nlen(const char* s, size_t maxlen) {
+ size_t i;
+ for (i = 0; i < maxlen; i++)
+ if (!s[i])
+ break;
+ return i;
+ }
+};
+
+// ============================================================================
+// [asmjit::StringBuilder]
+// ============================================================================
+
+//! String builder.
+//!
+//! String builder was designed to be able to build a string using append like
+//! operation to append numbers, other strings, or signle characters. It can
+//! allocate it's own buffer or use a buffer created on the stack.
+//!
+//! String builder contains method specific to AsmJit functionality, used for
+//! logging or HTML output.
+struct StringBuilder {
+ ASMJIT_NO_COPY(StringBuilder)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API StringBuilder();
+ ASMJIT_API ~StringBuilder();
+
+ ASMJIT_INLINE StringBuilder(const _NoInit&) {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get string builder capacity.
+ ASMJIT_INLINE size_t getCapacity() const { return _capacity; }
+ //! Get length.
+ ASMJIT_INLINE size_t getLength() const { return _length; }
+
+ //! Get null-terminated string data.
+ ASMJIT_INLINE char* getData() { return _data; }
+ //! Get null-terminated string data (const).
+ ASMJIT_INLINE const char* getData() const { return _data; }
+
+ // --------------------------------------------------------------------------
+ // [Prepare / Reserve]
+ // --------------------------------------------------------------------------
+
+ //! Prepare to set/append.
+ ASMJIT_API char* prepare(uint32_t op, size_t len);
+
+ //! Reserve `to` bytes in string builder.
+ ASMJIT_API bool reserve(size_t to);
+
+ // --------------------------------------------------------------------------
+ // [Clear]
+ // --------------------------------------------------------------------------
+
+ //! Clear the content in String builder.
+ ASMJIT_API void clear();
+
+ // --------------------------------------------------------------------------
+ // [Op]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API bool _opString(uint32_t op, const char* str, size_t len = kInvalidIndex);
+ ASMJIT_API bool _opVFormat(uint32_t op, const char* fmt, va_list ap);
+ ASMJIT_API bool _opChar(uint32_t op, char c);
+ ASMJIT_API bool _opChars(uint32_t op, char c, size_t len);
+ ASMJIT_API bool _opNumber(uint32_t op, uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0);
+ ASMJIT_API bool _opHex(uint32_t op, const void* data, size_t len);
+
+ // --------------------------------------------------------------------------
+ // [Set]
+ // --------------------------------------------------------------------------
+
+ //! Replace the current content by `str` of `len`.
+ ASMJIT_INLINE bool setString(const char* str, size_t len = kInvalidIndex) {
+ return _opString(kStringOpSet, str, len);
+ }
+
+ //! Replace the current content by formatted string `fmt`.
+ ASMJIT_INLINE bool setVFormat(const char* fmt, va_list ap) {
+ return _opVFormat(kStringOpSet, fmt, ap);
+ }
+
+ //! Replace the current content by formatted string `fmt`.
+ ASMJIT_API bool setFormat(const char* fmt, ...);
+
+ //! Replace the current content by `c` character.
+ ASMJIT_INLINE bool setChar(char c) {
+ return _opChar(kStringOpSet, c);
+ }
+
+ //! Replace the current content by `c` of `len`.
+ ASMJIT_INLINE bool setChars(char c, size_t len) {
+ return _opChars(kStringOpSet, c, len);
+ }
+
+ //! Replace the current content by formatted integer `i`.
+ ASMJIT_INLINE bool setInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) {
+ return _opNumber(kStringOpSet, i, base, width, flags | kStringFormatSigned);
+ }
+
+ //! Replace the current content by formatted integer `i`.
+ ASMJIT_INLINE bool setUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) {
+ return _opNumber(kStringOpSet, i, base, width, flags);
+ }
+
+ //! Replace the current content by the given `data` converted to a HEX string.
+ ASMJIT_INLINE bool setHex(const void* data, size_t len) {
+ return _opHex(kStringOpSet, data, len);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Append]
+ // --------------------------------------------------------------------------
+
+ //! Append `str` of `len`.
+ ASMJIT_INLINE bool appendString(const char* str, size_t len = kInvalidIndex) {
+ return _opString(kStringOpAppend, str, len);
+ }
+
+ //! Append a formatted string `fmt` to the current content.
+ ASMJIT_INLINE bool appendVFormat(const char* fmt, va_list ap) {
+ return _opVFormat(kStringOpAppend, fmt, ap);
+ }
+
+ //! Append a formatted string `fmt` to the current content.
+ ASMJIT_API bool appendFormat(const char* fmt, ...);
+
+ //! Append `c` character.
+ ASMJIT_INLINE bool appendChar(char c) {
+ return _opChar(kStringOpAppend, c);
+ }
+
+ //! Append `c` of `len`.
+ ASMJIT_INLINE bool appendChars(char c, size_t len) {
+ return _opChars(kStringOpAppend, c, len);
+ }
+
+ //! Append `i`.
+ ASMJIT_INLINE bool appendInt(int64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) {
+ return _opNumber(kStringOpAppend, static_cast<uint64_t>(i), base, width, flags | kStringFormatSigned);
+ }
+
+ //! Append `i`.
+ ASMJIT_INLINE bool appendUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) {
+ return _opNumber(kStringOpAppend, i, base, width, flags);
+ }
+
+ //! Append the given `data` converted to a HEX string.
+ ASMJIT_INLINE bool appendHex(const void* data, size_t len) {
+ return _opHex(kStringOpAppend, data, len);
+ }
+
+ // --------------------------------------------------------------------------
+ // [_Append]
+ // --------------------------------------------------------------------------
+
+ //! Append `str` of `len`, inlined, without buffer overflow check.
+ ASMJIT_INLINE void _appendString(const char* str, size_t len = kInvalidIndex) {
+ // len should be a constant if we are inlining.
+ if (len == kInvalidIndex) {
+ char* p = &_data[_length];
+
+ while (*str) {
+ ASMJIT_ASSERT(p < _data + _capacity);
+ *p++ = *str++;
+ }
+
+ *p = '\0';
+ _length = static_cast<size_t>(p - _data);
+ }
+ else {
+ ASMJIT_ASSERT(_capacity - _length >= len);
+
+ char* p = &_data[_length];
+ char* pEnd = p + len;
+
+ while (p < pEnd)
+ *p++ = *str++;
+
+ *p = '\0';
+ _length += len;
+ }
+ }
+
+ //! Append `c` character, inlined, without buffer overflow check.
+ ASMJIT_INLINE void _appendChar(char c) {
+ ASMJIT_ASSERT(_capacity - _length >= 1);
+
+ _data[_length] = c;
+ _length++;
+ _data[_length] = '\0';
+ }
+
+ //! Append `c` of `len`, inlined, without buffer overflow check.
+ ASMJIT_INLINE void _appendChars(char c, size_t len) {
+ ASMJIT_ASSERT(_capacity - _length >= len);
+
+ char* p = &_data[_length];
+ char* pEnd = p + len;
+
+ while (p < pEnd)
+ *p++ = c;
+
+ *p = '\0';
+ _length += len;
+ }
+
+ ASMJIT_INLINE void _appendUInt32(uint32_t i) {
+ char buf_[32];
+
+ char* pEnd = buf_ + ASMJIT_ARRAY_SIZE(buf_);
+ char* pBuf = pEnd;
+
+ do {
+ uint32_t d = i / 10;
+ uint32_t r = i % 10;
+
+ *--pBuf = static_cast<uint8_t>(r + '0');
+ i = d;
+ } while (i);
+
+ ASMJIT_ASSERT(_capacity - _length >= static_cast<size_t>(pEnd - pBuf));
+ char* p = &_data[_length];
+
+ do {
+ *p++ = *pBuf;
+ } while (++pBuf != pEnd);
+
+ *p = '\0';
+ _length = static_cast<size_t>(p - _data);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Eq]
+ // --------------------------------------------------------------------------
+
+ //! Check for equality with other `str` of `len`.
+ ASMJIT_API bool eq(const char* str, size_t len = kInvalidIndex) const;
+ //! Check for equality with `other`.
+ ASMJIT_INLINE bool eq(const StringBuilder& other) const {
+ return eq(other._data);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE bool operator==(const StringBuilder& other) const { return eq(other); }
+ ASMJIT_INLINE bool operator!=(const StringBuilder& other) const { return !eq(other); }
+
+ ASMJIT_INLINE bool operator==(const char* str) const { return eq(str); }
+ ASMJIT_INLINE bool operator!=(const char* str) const { return !eq(str); }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! String data.
+ char* _data;
+ //! Length.
+ size_t _length;
+ //! Capacity.
+ size_t _capacity;
+ //! Whether the string can be freed.
+ size_t _canFree;
+};
+
+// ============================================================================
+// [asmjit::StringBuilderT]
+// ============================================================================
+
+//! \internal
+template<size_t N>
+struct StringBuilderT : public StringBuilder {
+ ASMJIT_NO_COPY(StringBuilderT<N>)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE StringBuilderT() : StringBuilder(NoInit) {
+ _data = _embeddedData;
+ _data[0] = 0;
+
+ _length = 0;
+ _capacity = N;
+ _canFree = false;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Embedded data.
+ char _embeddedData[static_cast<size_t>(
+ N + 1 + sizeof(intptr_t)) & ~static_cast<size_t>(sizeof(intptr_t) - 1)];
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/vectypes.h
@@ -1,1 +1,1247 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::Vec64]
+// ============================================================================
+
+//! 64-bit vector register data.
+union Vec64 {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Set all eight 8-bit signed integers.
+ static ASMJIT_INLINE Vec64 fromSb(
+ int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7)
+ {
+ Vec64 self;
+ self.setSb(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight 8-bit signed integers.
+ static ASMJIT_INLINE Vec64 fromSb(
+ int8_t x0)
+ {
+ Vec64 self;
+ self.setSb(x0);
+ return self;
+ }
+
+ //! Set all eight 8-bit unsigned integers.
+ static ASMJIT_INLINE Vec64 fromUb(
+ uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7)
+ {
+ Vec64 self;
+ self.setUb(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight 8-bit unsigned integers.
+ static ASMJIT_INLINE Vec64 fromUb(
+ uint8_t x0)
+ {
+ Vec64 self;
+ self.setUb(x0);
+ return self;
+ }
+
+ //! Set all four 16-bit signed integers.
+ static ASMJIT_INLINE Vec64 fromSw(
+ int16_t x0, int16_t x1, int16_t x2, int16_t x3)
+ {
+ Vec64 self;
+ self.setSw(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four 16-bit signed integers.
+ static ASMJIT_INLINE Vec64 fromSw(
+ int16_t x0)
+ {
+ Vec64 self;
+ self.setSw(x0);
+ return self;
+ }
+
+ //! Set all four 16-bit unsigned integers.
+ static ASMJIT_INLINE Vec64 fromUw(
+ uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3)
+ {
+ Vec64 self;
+ self.setUw(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four 16-bit unsigned integers.
+ static ASMJIT_INLINE Vec64 fromUw(
+ uint16_t x0)
+ {
+ Vec64 self;
+ self.setUw(x0);
+ return self;
+ }
+
+ //! Set all two 32-bit signed integers.
+ static ASMJIT_INLINE Vec64 fromSd(
+ int32_t x0, int32_t x1)
+ {
+ Vec64 self;
+ self.setSd(x0, x1);
+ return self;
+ }
+
+ //! Set all two 32-bit signed integers.
+ static ASMJIT_INLINE Vec64 fromSd(
+ int32_t x0)
+ {
+ Vec64 self;
+ self.setSd(x0);
+ return self;
+ }
+
+ //! Set all two 32-bit unsigned integers.
+ static ASMJIT_INLINE Vec64 fromUd(
+ uint32_t x0, uint32_t x1)
+ {
+ Vec64 self;
+ self.setUd(x0, x1);
+ return self;
+ }
+
+ //! Set all two 32-bit unsigned integers.
+ static ASMJIT_INLINE Vec64 fromUd(
+ uint32_t x0)
+ {
+ Vec64 self;
+ self.setUd(x0);
+ return self;
+ }
+
+ //! Set 64-bit signed integer.
+ static ASMJIT_INLINE Vec64 fromSq(
+ int64_t x0)
+ {
+ Vec64 self;
+ self.setSq(x0);
+ return self;
+ }
+
+ //! Set 64-bit unsigned integer.
+ static ASMJIT_INLINE Vec64 fromUq(
+ uint64_t x0)
+ {
+ Vec64 self;
+ self.setUq(x0);
+ return self;
+ }
+
+ //! Set all two SP-FP values.
+ static ASMJIT_INLINE Vec64 fromSf(
+ float x0, float x1)
+ {
+ Vec64 self;
+ self.setSf(x0, x1);
+ return self;
+ }
+
+ //! Set all two SP-FP values.
+ static ASMJIT_INLINE Vec64 fromSf(
+ float x0)
+ {
+ Vec64 self;
+ self.setSf(x0);
+ return self;
+ }
+
+ //! Set all two SP-FP values.
+ static ASMJIT_INLINE Vec64 fromDf(
+ double x0)
+ {
+ Vec64 self;
+ self.setDf(x0);
+ return self;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Set all eight 8-bit signed integers.
+ ASMJIT_INLINE void setSb(
+ int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7)
+ {
+ sb[0] = x0; sb[1] = x1; sb[2] = x2; sb[3] = x3;
+ sb[4] = x4; sb[5] = x5; sb[6] = x6; sb[7] = x7;
+ }
+
+ //! Set all eight 8-bit signed integers.
+ ASMJIT_INLINE void setSb(
+ int8_t x0)
+ {
+ setUb(static_cast<uint8_t>(x0));
+ }
+
+ //! Set all eight 8-bit unsigned integers.
+ ASMJIT_INLINE void setUb(
+ uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7)
+ {
+ ub[0] = x0; ub[1] = x1; ub[2] = x2; ub[3] = x3;
+ ub[4] = x4; ub[5] = x5; ub[6] = x6; ub[7] = x7;
+ }
+
+ //! Set all eight 8-bit unsigned integers.
+ ASMJIT_INLINE void setUb(
+ uint8_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = static_cast<uint64_t>(x0) * ASMJIT_UINT64_C(0x0101010101010101);
+ uq[0] = t;
+ }
+ else {
+ uint32_t t = static_cast<uint32_t>(x0) * static_cast<uint32_t>(0x01010101U);
+ ud[0] = t;
+ ud[1] = t;
+ }
+ }
+
+ //! Set all four 16-bit signed integers.
+ ASMJIT_INLINE void setSw(
+ int16_t x0, int16_t x1, int16_t x2, int16_t x3)
+ {
+ sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3;
+ }
+
+ //! Set all four 16-bit signed integers.
+ ASMJIT_INLINE void setSw(
+ int16_t x0)
+ {
+ setUw(static_cast<uint16_t>(x0));
+ }
+
+ //! Set all four 16-bit unsigned integers.
+ ASMJIT_INLINE void setUw(
+ uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3)
+ {
+ uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3;
+ }
+
+ //! Set all four 16-bit unsigned integers.
+ ASMJIT_INLINE void setUw(
+ uint16_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = static_cast<uint64_t>(x0) * ASMJIT_UINT64_C(0x0001000100010001);
+ uq[0] = t;
+ }
+ else {
+ uint32_t t = static_cast<uint32_t>(x0) * static_cast<uint32_t>(0x00010001U);
+ ud[0] = t;
+ ud[1] = t;
+ }
+ }
+
+ //! Set all two 32-bit signed integers.
+ ASMJIT_INLINE void setSd(
+ int32_t x0, int32_t x1)
+ {
+ sd[0] = x0; sd[1] = x1;
+ }
+
+ //! Set all two 32-bit signed integers.
+ ASMJIT_INLINE void setSd(
+ int32_t x0)
+ {
+ sd[0] = x0; sd[1] = x0;
+ }
+
+ //! Set all two 32-bit unsigned integers.
+ ASMJIT_INLINE void setUd(
+ uint32_t x0, uint32_t x1)
+ {
+ ud[0] = x0; ud[1] = x1;
+ }
+
+ //! Set all two 32-bit unsigned integers.
+ ASMJIT_INLINE void setUd(
+ uint32_t x0)
+ {
+ ud[0] = x0; ud[1] = x0;
+ }
+
+ //! Set 64-bit signed integer.
+ ASMJIT_INLINE void setSq(
+ int64_t x0)
+ {
+ sq[0] = x0;
+ }
+
+ //! Set 64-bit unsigned integer.
+ ASMJIT_INLINE void setUq(
+ uint64_t x0)
+ {
+ uq[0] = x0;
+ }
+
+ //! Set all two SP-FP values.
+ ASMJIT_INLINE void setSf(
+ float x0, float x1)
+ {
+ sf[0] = x0; sf[1] = x1;
+ }
+
+ //! Set all two SP-FP values.
+ ASMJIT_INLINE void setSf(
+ float x0)
+ {
+ sf[0] = x0; sf[1] = x0;
+ }
+
+ //! Set all two SP-FP values.
+ ASMJIT_INLINE void setDf(
+ double x0)
+ {
+ df[0] = x0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Array of eight 8-bit signed integers.
+ int8_t sb[8];
+ //! Array of eight 8-bit unsigned integers.
+ uint8_t ub[8];
+ //! Array of four 16-bit signed integers.
+ int16_t sw[4];
+ //! Array of four 16-bit unsigned integers.
+ uint16_t uw[4];
+ //! Array of two 32-bit signed integers.
+ int32_t sd[2];
+ //! Array of two 32-bit unsigned integers.
+ uint32_t ud[2];
+ //! Array of one 64-bit signed integer.
+ int64_t sq[1];
+ //! Array of one 64-bit unsigned integer.
+ uint64_t uq[1];
+
+ //! Array of two SP-FP values.
+ float sf[2];
+ //! Array of one DP-FP value.
+ double df[1];
+};
+
+// ============================================================================
+// [asmjit::Vec128]
+// ============================================================================
+
+//! 128-bit vector register data.
+union Vec128 {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Set all sixteen 8-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSb(
+ int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 ,
+ int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
+ int8_t x8 , int8_t x9 , int8_t x10, int8_t x11,
+ int8_t x12, int8_t x13, int8_t x14, int8_t x15)
+ {
+ Vec128 self;
+ self.setSb(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15);
+ return self;
+ }
+
+ //! Set all sixteen 8-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSb(
+ int8_t x0)
+ {
+ Vec128 self;
+ self.setSb(x0);
+ return self;
+ }
+
+ //! Set all sixteen 8-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUb(
+ uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 ,
+ uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
+ uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11,
+ uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15)
+ {
+ Vec128 self;
+ self.setUb(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15);
+ return self;
+ }
+
+ //! Set all sixteen 8-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUb(
+ uint8_t x0)
+ {
+ Vec128 self;
+ self.setUb(x0);
+ return self;
+ }
+
+ //! Set all eight 16-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSw(
+ int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7)
+ {
+ Vec128 self;
+ self.setSw(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight 16-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSw(
+ int16_t x0)
+ {
+ Vec128 self;
+ self.setSw(x0);
+ return self;
+ }
+
+ //! Set all eight 16-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUw(
+ uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7)
+ {
+ Vec128 self;
+ self.setUw(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight 16-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUw(
+ uint16_t x0)
+ {
+ Vec128 self;
+ self.setUw(x0);
+ return self;
+ }
+
+ //! Set all four 32-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSd(
+ int32_t x0, int32_t x1, int32_t x2, int32_t x3)
+ {
+ Vec128 self;
+ self.setSd(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four 32-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSd(
+ int32_t x0)
+ {
+ Vec128 self;
+ self.setSd(x0);
+ return self;
+ }
+
+ //! Set all four 32-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUd(
+ uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3)
+ {
+ Vec128 self;
+ self.setUd(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four 32-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUd(
+ uint32_t x0)
+ {
+ Vec128 self;
+ self.setUd(x0);
+ return self;
+ }
+
+ //! Set all two 64-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSq(
+ int64_t x0, int64_t x1)
+ {
+ Vec128 self;
+ self.setSq(x0, x1);
+ return self;
+ }
+
+ //! Set all two 64-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSq(
+ int64_t x0)
+ {
+ Vec128 self;
+ self.setSq(x0);
+ return self;
+ }
+
+ //! Set all two 64-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUq(
+ uint64_t x0, uint64_t x1)
+ {
+ Vec128 self;
+ self.setUq(x0, x1);
+ return self;
+ }
+
+ //! Set all two 64-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUq(
+ uint64_t x0)
+ {
+ Vec128 self;
+ self.setUq(x0);
+ return self;
+ }
+
+ //! Set all four SP-FP floats.
+ static ASMJIT_INLINE Vec128 fromSf(
+ float x0, float x1, float x2, float x3)
+ {
+ Vec128 self;
+ self.setSf(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four SP-FP floats.
+ static ASMJIT_INLINE Vec128 fromSf(
+ float x0)
+ {
+ Vec128 self;
+ self.setSf(x0);
+ return self;
+ }
+
+ //! Set all two DP-FP floats.
+ static ASMJIT_INLINE Vec128 fromDf(
+ double x0, double x1)
+ {
+ Vec128 self;
+ self.setDf(x0, x1);
+ return self;
+ }
+
+ //! Set all two DP-FP floats.
+ static ASMJIT_INLINE Vec128 fromDf(
+ double x0)
+ {
+ Vec128 self;
+ self.setDf(x0);
+ return self;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Set all sixteen 8-bit signed integers.
+ ASMJIT_INLINE void setSb(
+ int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 ,
+ int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
+ int8_t x8 , int8_t x9 , int8_t x10, int8_t x11,
+ int8_t x12, int8_t x13, int8_t x14, int8_t x15)
+ {
+ 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;
+ }
+
+ //! Set all sixteen 8-bit signed integers.
+ ASMJIT_INLINE void setSb(
+ int8_t x0)
+ {
+ setUb(static_cast<uint8_t>(x0));
+ }
+
+ //! Set all sixteen 8-bit unsigned integers.
+ ASMJIT_INLINE void setUb(
+ uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 ,
+ uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
+ uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11,
+ uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15)
+ {
+ 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;
+ }
+
+ //! Set all sixteen 8-bit unsigned integers.
+ ASMJIT_INLINE void setUb(
+ uint8_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = static_cast<uint64_t>(x0) * ASMJIT_UINT64_C(0x0101010101010101);
+ uq[0] = t;
+ uq[1] = t;
+ }
+ else {
+ uint32_t t = static_cast<uint32_t>(x0) * static_cast<uint32_t>(0x01010101U);
+ ud[0] = t;
+ ud[1] = t;
+ ud[2] = t;
+ ud[3] = t;
+ }
+ }
+
+ //! Set all eight 16-bit signed integers.
+ ASMJIT_INLINE void setSw(
+ int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7)
+ {
+ sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3;
+ sw[4] = x4; sw[5] = x5; sw[6] = x6; sw[7] = x7;
+ }
+
+ //! Set all eight 16-bit signed integers.
+ ASMJIT_INLINE void setSw(
+ int16_t x0)
+ {
+ setUw(static_cast<uint16_t>(x0));
+ }
+
+ //! Set all eight 16-bit unsigned integers.
+ ASMJIT_INLINE void setUw(
+ uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7)
+ {
+ uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3;
+ uw[4] = x4; uw[5] = x5; uw[6] = x6; uw[7] = x7;
+ }
+
+ //! Set all eight 16-bit unsigned integers.
+ ASMJIT_INLINE void setUw(
+ uint16_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = static_cast<uint64_t>(x0) * ASMJIT_UINT64_C(0x0001000100010001);
+ uq[0] = t;
+ uq[1] = t;
+ }
+ else {
+ uint32_t t = static_cast<uint32_t>(x0) * static_cast<uint32_t>(0x00010001U);
+ ud[0] = t;
+ ud[1] = t;
+ ud[2] = t;
+ ud[3] = t;
+ }
+ }
+
+ //! Set all four 32-bit signed integers.
+ ASMJIT_INLINE void setSd(
+ int32_t x0, int32_t x1, int32_t x2, int32_t x3)
+ {
+ sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3;
+ }
+
+ //! Set all four 32-bit signed integers.
+ ASMJIT_INLINE void setSd(
+ int32_t x0)
+ {
+ setUd(static_cast<uint32_t>(x0));
+ }
+
+ //! Set all four 32-bit unsigned integers.
+ ASMJIT_INLINE void setUd(
+ uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3)
+ {
+ ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3;
+ }
+
+ //! Set all four 32-bit unsigned integers.
+ ASMJIT_INLINE void setUd(
+ uint32_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = (static_cast<uint64_t>(x0) << 32) + x0;
+ uq[0] = t;
+ uq[1] = t;
+ }
+ else {
+ ud[0] = x0;
+ ud[1] = x0;
+ ud[2] = x0;
+ ud[3] = x0;
+ }
+ }
+
+ //! Set all two 64-bit signed integers.
+ ASMJIT_INLINE void setSq(
+ int64_t x0, int64_t x1)
+ {
+ sq[0] = x0; sq[1] = x1;
+ }
+
+ //! Set all two 64-bit signed integers.
+ ASMJIT_INLINE void setSq(
+ int64_t x0)
+ {
+ sq[0] = x0; sq[1] = x0;
+ }
+
+ //! Set all two 64-bit unsigned integers.
+ ASMJIT_INLINE void setUq(
+ uint64_t x0, uint64_t x1)
+ {
+ uq[0] = x0; uq[1] = x1;
+ }
+
+ //! Set all two 64-bit unsigned integers.
+ ASMJIT_INLINE void setUq(
+ uint64_t x0)
+ {
+ uq[0] = x0; uq[1] = x0;
+ }
+
+ //! Set all four SP-FP floats.
+ ASMJIT_INLINE void setSf(
+ float x0, float x1, float x2, float x3)
+ {
+ sf[0] = x0; sf[1] = x1; sf[2] = x2; sf[3] = x3;
+ }
+
+ //! Set all four SP-FP floats.
+ ASMJIT_INLINE void setSf(
+ float x0)
+ {
+ sf[0] = x0; sf[1] = x0; sf[2] = x0; sf[3] = x0;
+ }
+
+ //! Set all two DP-FP floats.
+ ASMJIT_INLINE void setDf(
+ double x0, double x1)
+ {
+ df[0] = x0; df[1] = x1;
+ }
+
+ //! Set all two DP-FP floats.
+ ASMJIT_INLINE void setDf(
+ double x0)
+ {
+ df[0] = x0; df[1] = x0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Array of sixteen 8-bit signed integers.
+ int8_t sb[16];
+ //! Array of sixteen 8-bit unsigned integers.
+ uint8_t ub[16];
+ //! Array of eight 16-bit signed integers.
+ int16_t sw[8];
+ //! Array of eight 16-bit unsigned integers.
+ uint16_t uw[8];
+ //! Array of four 32-bit signed integers.
+ int32_t sd[4];
+ //! Array of four 32-bit unsigned integers.
+ uint32_t ud[4];
+ //! Array of two 64-bit signed integers.
+ int64_t sq[2];
+ //! Array of two 64-bit unsigned integers.
+ uint64_t uq[2];
+
+ //! Array of four 32-bit single precision floating points.
+ float sf[4];
+ //! Array of two 64-bit double precision floating points.
+ double df[2];
+};
+
+// ============================================================================
+// [asmjit::Vec256]
+// ============================================================================
+
+//! 256-bit vector register data.
+union Vec256 {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Set all thirty two 8-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSb(
+ int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 ,
+ int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
+ int8_t x8 , int8_t x9 , int8_t x10, int8_t x11,
+ int8_t x12, int8_t x13, int8_t x14, int8_t x15,
+ int8_t x16, int8_t x17, int8_t x18, int8_t x19,
+ int8_t x20, int8_t x21, int8_t x22, int8_t x23,
+ int8_t x24, int8_t x25, int8_t x26, int8_t x27,
+ int8_t x28, int8_t x29, int8_t x30, int8_t x31)
+ {
+ Vec256 self;
+ self.setSb(
+ x0, x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , x9 , x10, x11, x12, x13, x14, x15,
+ x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31);
+ return self;
+ }
+
+ //! Set all thirty two 8-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSb(
+ int8_t x0)
+ {
+ Vec256 self;
+ self.setSb(x0);
+ return self;
+ }
+
+ //! Set all thirty two 8-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUb(
+ uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 ,
+ uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
+ uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11,
+ uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15,
+ uint8_t x16, uint8_t x17, uint8_t x18, uint8_t x19,
+ uint8_t x20, uint8_t x21, uint8_t x22, uint8_t x23,
+ uint8_t x24, uint8_t x25, uint8_t x26, uint8_t x27,
+ uint8_t x28, uint8_t x29, uint8_t x30, uint8_t x31)
+ {
+ Vec256 self;
+ self.setUb(
+ x0, x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , x9 , x10, x11, x12, x13, x14, x15,
+ x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31);
+ return self;
+ }
+
+ //! Set all thirty two 8-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUb(
+ uint8_t x0)
+ {
+ Vec256 self;
+ self.setUb(x0);
+ return self;
+ }
+
+ //! Set all sixteen 16-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSw(
+ int16_t x0, int16_t x1, int16_t x2 , int16_t x3 , int16_t x4 , int16_t x5 , int16_t x6 , int16_t x7 ,
+ int16_t x8, int16_t x9, int16_t x10, int16_t x11, int16_t x12, int16_t x13, int16_t x14, int16_t x15)
+ {
+ Vec256 self;
+ self.setSw(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15);
+ return self;
+ }
+
+ //! Set all sixteen 16-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSw(
+ int16_t x0)
+ {
+ Vec256 self;
+ self.setSw(x0);
+ return self;
+ }
+
+ //! Set all sixteen 16-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUw(
+ uint16_t x0, uint16_t x1, uint16_t x2 , uint16_t x3 , uint16_t x4 , uint16_t x5 , uint16_t x6 , uint16_t x7 ,
+ uint16_t x8, uint16_t x9, uint16_t x10, uint16_t x11, uint16_t x12, uint16_t x13, uint16_t x14, uint16_t x15)
+ {
+ Vec256 self;
+ self.setUw(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15);
+ return self;
+ }
+
+ //! Set all sixteen 16-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUw(
+ uint16_t x0)
+ {
+ Vec256 self;
+ self.setUw(x0);
+ return self;
+ }
+
+ //! Set all eight 32-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSd(
+ int32_t x0, int32_t x1, int32_t x2, int32_t x3,
+ int32_t x4, int32_t x5, int32_t x6, int32_t x7)
+ {
+ Vec256 self;
+ self.setSd(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight 32-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSd(
+ int32_t x0)
+ {
+ Vec256 self;
+ self.setSd(x0);
+ return self;
+ }
+
+ //! Set all eight 32-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUd(
+ uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3,
+ uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7)
+ {
+ Vec256 self;
+ self.setUd(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight 32-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUd(
+ uint32_t x0)
+ {
+ Vec256 self;
+ self.setUd(x0);
+ return self;
+ }
+
+ //! Set all four 64-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSq(
+ int64_t x0, int64_t x1, int64_t x2, int64_t x3)
+ {
+ Vec256 self;
+ self.setSq(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four 64-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSq(
+ int64_t x0)
+ {
+ Vec256 self;
+ self.setSq(x0);
+ return self;
+ }
+
+ //! Set all four 64-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUq(
+ uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
+ {
+ Vec256 self;
+ self.setUq(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four 64-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUq(
+ uint64_t x0)
+ {
+ Vec256 self;
+ self.setUq(x0);
+ return self;
+ }
+
+ //! Set all eight SP-FP floats.
+ static ASMJIT_INLINE Vec256 fromSf(
+ float x0, float x1, float x2, float x3,
+ float x4, float x5, float x6, float x7)
+ {
+ Vec256 self;
+ self.setSf(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight SP-FP floats.
+ static ASMJIT_INLINE Vec256 fromSf(
+ float x0)
+ {
+ Vec256 self;
+ self.setSf(x0);
+ return self;
+ }
+
+ //! Set all four DP-FP floats.
+ static ASMJIT_INLINE Vec256 fromDf(
+ double x0, double x1, double x2, double x3)
+ {
+ Vec256 self;
+ self.setDf(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four DP-FP floats.
+ static ASMJIT_INLINE Vec256 fromDf(
+ double x0)
+ {
+ Vec256 self;
+ self.setDf(x0);
+ return self;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Set all thirty two 8-bit signed integers.
+ ASMJIT_INLINE void setSb(
+ int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 ,
+ int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
+ int8_t x8 , int8_t x9 , int8_t x10, int8_t x11,
+ int8_t x12, int8_t x13, int8_t x14, int8_t x15,
+ int8_t x16, int8_t x17, int8_t x18, int8_t x19,
+ int8_t x20, int8_t x21, int8_t x22, int8_t x23,
+ int8_t x24, int8_t x25, int8_t x26, int8_t x27,
+ int8_t x28, int8_t x29, int8_t x30, int8_t x31)
+ {
+ 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;
+ sb[16] = x16; sb[17] = x17; sb[18] = x18; sb[19] = x19;
+ sb[20] = x20; sb[21] = x21; sb[22] = x22; sb[23] = x23;
+ sb[24] = x24; sb[25] = x25; sb[26] = x26; sb[27] = x27;
+ sb[28] = x28; sb[29] = x29; sb[30] = x30; sb[31] = x31;
+ }
+
+ //! Set all thirty two 8-bit signed integers.
+ ASMJIT_INLINE void setSb(
+ int8_t x0)
+ {
+ setUb(static_cast<uint8_t>(x0));
+ }
+
+ //! Set all thirty two 8-bit unsigned integers.
+ ASMJIT_INLINE void setUb(
+ uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 ,
+ uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
+ uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11,
+ uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15,
+ uint8_t x16, uint8_t x17, uint8_t x18, uint8_t x19,
+ uint8_t x20, uint8_t x21, uint8_t x22, uint8_t x23,
+ uint8_t x24, uint8_t x25, uint8_t x26, uint8_t x27,
+ uint8_t x28, uint8_t x29, uint8_t x30, uint8_t x31)
+ {
+ 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;
+ ub[16] = x16; ub[17] = x17; ub[18] = x18; ub[19] = x19;
+ ub[20] = x20; ub[21] = x21; ub[22] = x22; ub[23] = x23;
+ ub[24] = x24; ub[25] = x25; ub[26] = x26; ub[27] = x27;
+ ub[28] = x28; ub[29] = x29; ub[30] = x30; ub[31] = x31;
+ }
+
+ //! Set all thirty two 8-bit unsigned integers.
+ ASMJIT_INLINE void setUb(
+ uint8_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = static_cast<uint64_t>(x0)* ASMJIT_UINT64_C(0x0101010101010101);
+ uq[0] = t;
+ uq[1] = t;
+ uq[2] = t;
+ uq[3] = t;
+ }
+ else {
+ uint32_t t = static_cast<uint32_t>(x0)* static_cast<uint32_t>(0x01010101U);
+ ud[0] = t;
+ ud[1] = t;
+ ud[2] = t;
+ ud[3] = t;
+ ud[4] = t;
+ ud[5] = t;
+ ud[6] = t;
+ ud[7] = t;
+ }
+ }
+
+ //! Set all sixteen 16-bit signed integers.
+ ASMJIT_INLINE void setSw(
+ int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7,
+ int16_t x8, int16_t x9, int16_t x10, int16_t x11, int16_t x12, int16_t x13, int16_t x14, int16_t x15)
+ {
+ sw[0 ] = x0 ; sw[1 ] = x1 ; sw[2 ] = x2 ; sw[3 ] = x3 ;
+ sw[4 ] = x4 ; sw[5 ] = x5 ; sw[6 ] = x6 ; sw[7 ] = x7 ;
+ sw[8 ] = x8 ; sw[9 ] = x9 ; sw[10] = x10; sw[11] = x11;
+ sw[12] = x12; sw[13] = x13; sw[14] = x14; sw[15] = x15;
+ }
+
+ //! Set all sixteen 16-bit signed integers.
+ ASMJIT_INLINE void setSw(
+ int16_t x0)
+ {
+ setUw(static_cast<uint16_t>(x0));
+ }
+
+ //! Set all sixteen 16-bit unsigned integers.
+ ASMJIT_INLINE void setUw(
+ uint16_t x0, uint16_t x1, uint16_t x2 , uint16_t x3 , uint16_t x4 , uint16_t x5 , uint16_t x6 , uint16_t x7 ,
+ uint16_t x8, uint16_t x9, uint16_t x10, uint16_t x11, uint16_t x12, uint16_t x13, uint16_t x14, uint16_t x15)
+ {
+ uw[0 ] = x0 ; uw[1 ] = x1 ; uw[2 ] = x2 ; uw[3 ] = x3 ;
+ uw[4 ] = x4 ; uw[5 ] = x5 ; uw[6 ] = x6 ; uw[7 ] = x7 ;
+ uw[8 ] = x8 ; uw[9 ] = x9 ; uw[10] = x10; uw[11] = x11;
+ uw[12] = x12; uw[13] = x13; uw[14] = x14; uw[15] = x15;
+ }
+
+ //! Set all eight 16-bit unsigned integers.
+ ASMJIT_INLINE void setUw(
+ uint16_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = static_cast<uint64_t>(x0)* ASMJIT_UINT64_C(0x0001000100010001);
+ uq[0] = t;
+ uq[1] = t;
+ uq[2] = t;
+ uq[3] = t;
+ }
+ else {
+ uint32_t t = static_cast<uint32_t>(x0)* static_cast<uint32_t>(0x00010001U);
+ ud[0] = t;
+ ud[1] = t;
+ ud[2] = t;
+ ud[3] = t;
+ ud[4] = t;
+ ud[5] = t;
+ ud[6] = t;
+ ud[7] = t;
+ }
+ }
+
+ //! Set all eight 32-bit signed integers.
+ ASMJIT_INLINE void setSd(
+ int32_t x0, int32_t x1, int32_t x2, int32_t x3,
+ int32_t x4, int32_t x5, int32_t x6, int32_t x7)
+ {
+ sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3;
+ sd[4] = x4; sd[5] = x5; sd[6] = x6; sd[7] = x7;
+ }
+
+ //! Set all eight 32-bit signed integers.
+ ASMJIT_INLINE void setSd(
+ int32_t x0)
+ {
+ setUd(static_cast<uint32_t>(x0));
+ }
+
+ //! Set all eight 32-bit unsigned integers.
+ ASMJIT_INLINE void setUd(
+ uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3,
+ uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7)
+ {
+ ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3;
+ ud[4] = x4; ud[5] = x5; ud[6] = x6; ud[7] = x7;
+ }
+
+ //! Set all eight 32-bit unsigned integers.
+ ASMJIT_INLINE void setUd(
+ uint32_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = (static_cast<uint64_t>(x0) << 32) + x0;
+ uq[0] = t;
+ uq[1] = t;
+ uq[2] = t;
+ uq[3] = t;
+ }
+ else {
+ ud[0] = x0;
+ ud[1] = x0;
+ ud[2] = x0;
+ ud[3] = x0;
+ ud[4] = x0;
+ ud[5] = x0;
+ ud[6] = x0;
+ ud[7] = x0;
+ }
+ }
+
+ //! Set all four 64-bit signed integers.
+ ASMJIT_INLINE void setSq(
+ int64_t x0, int64_t x1, int64_t x2, int64_t x3)
+ {
+ sq[0] = x0; sq[1] = x1; sq[2] = x2; sq[3] = x3;
+ }
+
+ //! Set all four 64-bit signed integers.
+ ASMJIT_INLINE void setSq(
+ int64_t x0)
+ {
+ sq[0] = x0; sq[1] = x0; sq[2] = x0; sq[3] = x0;
+ }
+
+ //! Set all four 64-bit unsigned integers.
+ ASMJIT_INLINE void setUq(
+ uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
+ {
+ uq[0] = x0; uq[1] = x1; uq[2] = x2; uq[3] = x3;
+ }
+
+ //! Set all four 64-bit unsigned integers.
+ ASMJIT_INLINE void setUq(
+ uint64_t x0)
+ {
+ uq[0] = x0; uq[1] = x0; uq[2] = x0; uq[3] = x0;
+ }
+
+ //! Set all eight SP-FP floats.
+ ASMJIT_INLINE void setSf(
+ float x0, float x1, float x2, float x3,
+ float x4, float x5, float x6, float x7)
+ {
+ sf[0] = x0; sf[1] = x1; sf[2] = x2; sf[3] = x3;
+ sf[4] = x4; sf[5] = x5; sf[6] = x6; sf[7] = x7;
+ }
+
+ //! Set all eight SP-FP floats.
+ ASMJIT_INLINE void setSf(
+ float x0)
+ {
+ sf[0] = x0; sf[1] = x0; sf[2] = x0; sf[3] = x0;
+ sf[4] = x0; sf[5] = x0; sf[6] = x0; sf[7] = x0;
+ }
+
+ //! Set all four DP-FP floats.
+ ASMJIT_INLINE void setDf(
+ double x0, double x1, double x2, double x3)
+ {
+ df[0] = x0; df[1] = x1; df[2] = x2; df[3] = x3;
+ }
+
+ //! Set all four DP-FP floats.
+ ASMJIT_INLINE void setDf(
+ double x0)
+ {
+ df[0] = x0; df[1] = x0; df[2] = x0; df[3] = x0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Array of thirty two 8-bit signed integers.
+ int8_t sb[32];
+ //! Array of thirty two 8-bit unsigned integers.
+ uint8_t ub[32];
+ //! Array of sixteen 16-bit signed integers.
+ int16_t sw[16];
+ //! Array of sixteen 16-bit unsigned integers.
+ uint16_t uw[16];
+ //! Array of eight 32-bit signed integers.
+ int32_t sd[8];
+ //! Array of eight 32-bit unsigned integers.
+ uint32_t ud[8];
+ //! Array of four 64-bit signed integers.
+ int64_t sq[4];
+ //! Array of four 64-bit unsigned integers.
+ uint64_t uq[4];
+
+ //! Array of eight 32-bit single precision floating points.
+ float sf[8];
+ //! Array of four 64-bit double precision floating points.
+ double df[4];
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/vmem.cpp
@@ -1,1 +1,1150 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Dependencies - AsmJit]
+#include "../base/error.h"
+#include "../base/globals.h"
+#include "../base/intutil.h"
+#include "../base/lock.h"
+#include "../base/vmem.h"
+
+// [Dependencies - Posix]
+#ifdef ASMJIT_OS_POSIX
+# include <sys/types.h>
+# include <sys/mman.h>
+# include <unistd.h>
+#endif // ASMJIT_OS_POSIX
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+// This file contains implementation of virtual memory management for AsmJit
+// library. The initial concept is to keep this implementation simple but
+// efficient. There are several goals I decided to write implementation myself.
+//
+// Goals:
+//
+// - Granularity of allocated blocks is different than granularity for a typical
+// C malloc. It is at least 64-bytes so Assembler/Compiler can guarantee the
+// alignment required. Alignment requirements can grow in the future, but at
+// the moment 64 bytes is safe (we may jump to 128 bytes if necessary or make
+// it configurable).
+//
+// - Keep memory manager information outside of the allocated virtual memory
+// pages, because these pages allow executing of machine code and there should
+// not be data required to keep track of these blocks. Another reason is that
+// some environments (i.e. iOS) allow to generate and run JIT code, but this
+// code has to be set to [Executable, but not Writable].
+//
+// - Keep implementation simple and easy to follow.
+//
+// Implementation is based on bit arrays and binary trees. Bit arrays contain
+// information related to allocated and unused blocks of memory. The size of
+// a block is described by `MemNode::density`. Count of blocks is stored in
+// `MemNode::blocks`. For example if density is 64 and count of blocks is 20,
+// memory node contains 64*20 bytes of memory and smallest possible allocation
+// (and also alignment) is 64 bytes. So density is also related to memory
+// alignment. Binary trees (RB) are used to enable fast lookup into all addresses
+// allocated by memory manager instance. This is used mainly by `VMemPrivate::release()`.
+//
+// Bit array looks like this (empty = unused, X = used) - Size of block 64:
+//
+// -------------------------------------------------------------------------
+// | |X|X| | | | | |X|X|X|X|X|X| | | | | | | | | | | | |X| | | | |X|X|X| | |
+// -------------------------------------------------------------------------
+// (Maximum continuous block)
+//
+// These bits show that there are 12 allocated blocks (X) of 64 bytes, so total
+// size allocated is 768 bytes. Maximum count of continuous memory is 12 * 64.
+
+namespace asmjit {
+
+// ============================================================================
+// [asmjit::VMemUtil - Windows]
+// ============================================================================
+
+// Windows specific implementation using `VirtualAllocEx` and `VirtualFree`.
+#ifdef ASMJIT_OS_WINDOWS
+struct VMemLocal {
+ // AsmJit allows to pass a `NULL` handle to `VMemUtil`. This function is just
+ // a convenient way to convert such handle to the current process one.
+ ASMJIT_INLINE HANDLE getSafeProcessHandle(HANDLE hParam) const {
+ return hParam ? hParam : hProcess;
+ }
+
+ size_t pageSize;
+ size_t pageGranularity;
+ HANDLE hProcess;
+};
+static VMemLocal vMemLocal;
+
+static const VMemLocal& vMemGet() {
+ VMemLocal& vMem = vMemLocal;
+
+ if (!vMem.hProcess) {
+ SYSTEM_INFO info;
+ ::GetSystemInfo(&info);
+
+ vMem.pageSize = IntUtil::alignToPowerOf2<uint32_t>(info.dwPageSize);
+ vMem.pageGranularity = info.dwAllocationGranularity;
+
+ vMem.hProcess = ::GetCurrentProcess();
+ }
+
+ return vMem;
+};
+
+size_t VMemUtil::getPageSize() {
+ const VMemLocal& vMem = vMemGet();
+ return vMem.pageSize;
+}
+
+size_t VMemUtil::getPageGranularity() {
+ const VMemLocal& vMem = vMemGet();
+ return vMem.pageGranularity;
+}
+
+void* VMemUtil::alloc(size_t length, size_t* allocated, uint32_t flags) {
+ return allocProcessMemory(static_cast<HANDLE>(0), length, allocated, flags);
+}
+
+void* VMemUtil::allocProcessMemory(HANDLE hProcess, size_t length, size_t* allocated, uint32_t flags) {
+ if (length == 0)
+ return nullptr;
+
+ const VMemLocal& vMem = vMemGet();
+ hProcess = vMem.getSafeProcessHandle(hProcess);
+
+ // VirtualAlloc rounds allocated size to a page size automatically.
+ size_t mSize = IntUtil::alignTo(length, vMem.pageSize);
+
+ // Windows XP SP2 / Vista allow Data Excution Prevention (DEP).
+ DWORD protectFlags = 0;
+
+ if (flags & kVMemFlagExecutable)
+ protectFlags |= (flags & kVMemFlagWritable) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
+ else
+ protectFlags |= (flags & kVMemFlagWritable) ? PAGE_READWRITE : PAGE_READONLY;
+
+ LPVOID mBase = ::VirtualAllocEx(hProcess, nullptr, mSize, MEM_COMMIT | MEM_RESERVE, protectFlags);
+ if (!mBase)
+ return nullptr;
+
+ ASMJIT_ASSERT(IntUtil::isAligned<size_t>(
+ reinterpret_cast<size_t>(mBase), vMem.pageSize));
+
+ if (allocated)
+ *allocated = mSize;
+ return mBase;
+}
+
+Error VMemUtil::release(void* addr, size_t length) {
+ return releaseProcessMemory(static_cast<HANDLE>(0), addr, length);
+}
+
+Error VMemUtil::releaseProcessMemory(HANDLE hProcess, void* addr, size_t /* length */) {
+ hProcess = vMemGet().getSafeProcessHandle(hProcess);
+ if (!::VirtualFreeEx(hProcess, addr, 0, MEM_RELEASE))
+ return kErrorInvalidState;
+ return kErrorOk;
+}
+#endif // ASMJIT_OS_WINDOWS
+
+// ============================================================================
+// [asmjit::VMemUtil - Posix]
+// ============================================================================
+
+// Posix specific implementation using `mmap` and `munmap`.
+#ifdef ASMJIT_OS_POSIX
+
+// MacOS uses MAP_ANON instead of MAP_ANONYMOUS.
+#if !defined(MAP_ANONYMOUS)
+# define MAP_ANONYMOUS MAP_ANON
+#endif // MAP_ANONYMOUS
+
+struct VMemLocal {
+ size_t pageSize;
+ size_t pageGranularity;
+};
+static VMemLocal vMemLocal;
+
+static const VMemLocal& vMemGet() {
+ VMemLocal& vMem = vMemLocal;
+
+ if (!vMem.pageSize) {
+ size_t pageSize = ::getpagesize();
+ vMem.pageSize = pageSize;
+ vMem.pageGranularity = IntUtil::iMax<size_t>(pageSize, 65536);
+ }
+
+ return vMem;
+};
+
+size_t VMemUtil::getPageSize() {
+ const VMemLocal& vMem = vMemGet();
+ return vMem.pageSize;
+}
+
+size_t VMemUtil::getPageGranularity() {
+ const VMemLocal& vMem = vMemGet();
+ return vMem.pageGranularity;
+}
+
+void* VMemUtil::alloc(size_t length, size_t* allocated, uint32_t flags) {
+ const VMemLocal& vMem = vMemGet();
+ size_t msize = IntUtil::alignTo<size_t>(length, vMem.pageSize);
+ int protection = PROT_READ;
+
+ if (flags & kVMemFlagWritable ) protection |= PROT_WRITE;
+ if (flags & kVMemFlagExecutable) protection |= PROT_EXEC;
+
+ void* mbase = ::mmap(nullptr, msize, protection, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (mbase == MAP_FAILED)
+ return nullptr;
+
+ if (allocated)
+ *allocated = msize;
+ return mbase;
+}
+
+Error VMemUtil::release(void* addr, size_t length) {
+ if (::munmap(addr, length) != 0)
+ return kErrorInvalidState;
+
+ return kErrorOk;
+}
+#endif // ASMJIT_OS_POSIX
+
+// ============================================================================
+// [asmjit::VMemMgr - BitOps]
+// ============================================================================
+
+#define M_DIV(x, y) ((x) / (y))
+#define M_MOD(x, y) ((x) % (y))
+
+//! \internal
+enum {
+ kBitsPerEntity = (sizeof(size_t) * 8)
+};
+
+//! \internal
+//!
+//! Set `len` bits in `buf` starting at `index` bit index.
+static void _SetBits(size_t* buf, size_t index, size_t len) {
+ if (len == 0)
+ return;
+
+ size_t i = index / kBitsPerEntity; // size_t[]
+ size_t j = index % kBitsPerEntity; // size_t[][] bit index
+
+ // How many bytes process in the first group.
+ size_t c = kBitsPerEntity - j;
+ if (c > len)
+ c = len;
+
+ // Offset.
+ buf += i;
+
+ *buf++ |= (~static_cast<size_t>(0) >> (kBitsPerEntity - c)) << j;
+ len -= c;
+
+ while (len >= kBitsPerEntity) {
+ *buf++ = ~static_cast<size_t>(0);
+ len -= kBitsPerEntity;
+ }
+
+ if (len)
+ *buf |= (~static_cast<size_t>(0) >> (kBitsPerEntity - len));
+}
+
+// ============================================================================
+// [asmjit::VMemMgr::TypeDefs]
+// ============================================================================
+
+typedef VMemMgr::RbNode RbNode;
+typedef VMemMgr::MemNode MemNode;
+typedef VMemMgr::PermanentNode PermanentNode;
+
+// ============================================================================
+// [asmjit::VMemMgr::RbNode]
+// ============================================================================
+
+//! \internal
+//!
+//! Base red-black tree node.
+struct VMemMgr::RbNode {
+ // Implementation is based on article by Julienne Walker (Public Domain),
+ // including C code and original comments. Thanks for the excellent article.
+
+ // Left[0] and right[1] nodes.
+ RbNode* node[2];
+ // Virtual memory address.
+ uint8_t* mem;
+ // Whether the node is RED.
+ uint32_t red;
+};
+
+//! \internal
+//!
+//! Get whether the node is red (NULL or node with red flag).
+static ASMJIT_INLINE bool rbIsRed(RbNode* node) {
+ return node && node->red;
+}
+
+//! \internal
+//!
+//! Check whether the RB tree is valid.
+static int rbAssert(RbNode* root) {
+ if (!root)
+ return 1;
+
+ RbNode* ln = root->node[0];
+ RbNode* rn = root->node[1];
+
+ // Red violation.
+ ASMJIT_ASSERT( !(rbIsRed(root) && (rbIsRed(ln) || rbIsRed(rn))) );
+
+ int lh = rbAssert(ln);
+ int rh = rbAssert(rn);
+
+ // Invalid btree.
+ ASMJIT_ASSERT(!ln || ln->mem < root->mem);
+ ASMJIT_ASSERT(!rn || rn->mem > root->mem);
+
+ // Black violation.
+ ASMJIT_ASSERT( !(lh != 0 && rh != 0 && lh != rh) );
+
+ // Only count black links.
+ if (lh != 0 && rh != 0)
+ return rbIsRed(root) ? lh : lh + 1;
+ else
+ return 0;
+}
+
+//! \internal
+//!
+//! Single rotation.
+static ASMJIT_INLINE RbNode* rbRotateSingle(RbNode* root, int dir) {
+ RbNode* save = root->node[!dir];
+
+ root->node[!dir] = save->node[dir];
+ save->node[dir] = root;
+
+ root->red = 1;
+ save->red = 0;
+
+ return save;
+}
+
+//! \internal
+//!
+//! Double rotation.
+static ASMJIT_INLINE RbNode* rbRotateDouble(RbNode* root, int dir) {
+ root->node[!dir] = rbRotateSingle(root->node[!dir], !dir);
+ return rbRotateSingle(root, dir);
+}
+
+// ============================================================================
+// [asmjit::VMemMgr::MemNode]
+// ============================================================================
+
+struct VMemMgr::MemNode : public RbNode {
+ // --------------------------------------------------------------------------
+ // [Helpers]
+ // --------------------------------------------------------------------------
+
+ // Get available space.
+ ASMJIT_INLINE size_t getAvailable() const {
+ return size - used;
+ }
+
+ ASMJIT_INLINE void fillData(MemNode* other) {
+ mem = other->mem;
+
+ size = other->size;
+ used = other->used;
+ blocks = other->blocks;
+ density = other->density;
+ largestBlock = other->largestBlock;
+
+ baUsed = other->baUsed;
+ baCont = other->baCont;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ MemNode* prev; // Prev node in list.
+ MemNode* next; // Next node in list.
+
+ size_t size; // How many bytes contain this node.
+ size_t used; // How many bytes are used in this node.
+ size_t blocks; // How many blocks are here.
+ size_t density; // Minimum count of allocated bytes in this node (also alignment).
+ size_t largestBlock; // Contains largest block that can be allocated.
+
+ size_t* baUsed; // Contains bits about used blocks (0 = unused, 1 = used).
+ size_t* baCont; // Contains bits about continuous blocks (0 = stop , 1 = continue).
+};
+
+// ============================================================================
+// [asmjit::VMemMgr::PermanentNode]
+// ============================================================================
+
+//! \internal
+//!
+//! Permanent node.
+struct VMemMgr::PermanentNode {
+ // --------------------------------------------------------------------------
+ // [Helpers]
+ // --------------------------------------------------------------------------
+
+ //! Get available space.
+ ASMJIT_INLINE size_t getAvailable() const {
+ return size - used;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ PermanentNode* prev; // Pointer to prev chunk or NULL.
+ uint8_t* mem; // Base pointer (virtual memory address).
+ size_t size; // Count of bytes allocated.
+ size_t used; // Count of bytes used.
+};
+
+// ============================================================================
+// [asmjit::VMemMgr - Private]
+// ============================================================================
+
+//! \internal
+//!
+//! Helper to avoid `#ifdef`s in the code.
+ASMJIT_INLINE uint8_t* vMemMgrAllocVMem(VMemMgr* self, size_t size, size_t* vSize) {
+ uint32_t flags = kVMemFlagWritable | kVMemFlagExecutable;
+#ifndef ASMJIT_OS_WINDOWS
+ return static_cast<uint8_t*>(VMemUtil::alloc(size, vSize, flags));
+#else
+ return static_cast<uint8_t*>(VMemUtil::allocProcessMemory(self->_hProcess, size, vSize, flags));
+#endif
+}
+
+//! \internal
+//!
+//! Helper to avoid `#ifdef`s in the code.
+ASMJIT_INLINE Error vMemMgrReleaseVMem(VMemMgr* self, void* p, size_t vSize) {
+#ifndef ASMJIT_OS_WINDOWS
+ return VMemUtil::release(p, vSize);
+#else
+ return VMemUtil::releaseProcessMemory(self->_hProcess, p, vSize);
+#endif
+}
+
+//! \internal
+//!
+//! Check whether the Red-Black tree is valid.
+static bool vMemMgrCheckTree(VMemMgr* self) {
+ return rbAssert(self->_root) > 0;
+}
+
+//! \internal
+//!
+//! Alloc virtual memory including a heap memory needed for `MemNode` data.
+//!
+//! Returns set-up `MemNode*` or NULL if allocation failed.
+static MemNode* vMemMgrCreateNode(VMemMgr* self, size_t size, size_t density) {
+ size_t vSize;
+ uint8_t* vmem = vMemMgrAllocVMem(self, size, &vSize);
+
+ // Out of memory.
+ if (!vmem)
+ return nullptr;
+
+ size_t blocks = (vSize / density);
+ size_t bsize = (((blocks + 7) >> 3) + sizeof(size_t) - 1) & ~static_cast<size_t>(sizeof(size_t) - 1);
+
+ MemNode* node = static_cast<MemNode*>(ASMJIT_ALLOC(sizeof(MemNode)));
+ uint8_t* data = static_cast<uint8_t*>(ASMJIT_ALLOC(bsize * 2));
+
+ // Out of memory.
+ if (!node || !data) {
+ vMemMgrReleaseVMem(self, vmem, vSize);
+ if (node) ASMJIT_FREE(node);
+ if (data) ASMJIT_FREE(data);
+ return nullptr;
+ }
+
+ // Initialize RbNode data.
+ node->node[0] = nullptr;
+ node->node[1] = nullptr;
+ node->mem = vmem;
+ node->red = 1;
+
+ // Initialize MemNode data.
+ node->prev = nullptr;
+ node->next = nullptr;
+
+ node->size = vSize;
+ node->used = 0;
+ node->blocks = blocks;
+ node->density = density;
+ node->largestBlock = vSize;
+
+ ::memset(data, 0, bsize * 2);
+ node->baUsed = reinterpret_cast<size_t*>(data);
+ node->baCont = reinterpret_cast<size_t*>(data + bsize);
+
+ return node;
+}
+
+static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) {
+ if (!self->_root) {
+ // Empty tree case.
+ self->_root = node;
+ }
+ else {
+ // False tree root.
+ RbNode head = { 0 };
+
+ // Grandparent & parent.
+ RbNode* g = nullptr;
+ RbNode* t = &head;
+
+ // Iterator & parent.
+ RbNode* p = nullptr;
+ RbNode* q = t->node[1] = self->_root;
+
+ int dir = 0, last;
+
+ // Search down the tree.
+ for (;;) {
+ if (!q) {
+ // Insert new node at the bottom.
+ q = node;
+ p->node[dir] = node;
+ }
+ else if (rbIsRed(q->node[0]) && rbIsRed(q->node[1])) {
+ // Color flip.
+ q->red = 1;
+ q->node[0]->red = 0;
+ q->node[1]->red = 0;
+ }
+
+ // Fix red violation.
+ if (rbIsRed(q) && rbIsRed(p)) {
+ int dir2 = t->node[1] == g;
+ t->node[dir2] = q == p->node[last] ? rbRotateSingle(g, !last) : rbRotateDouble(g, !last);
+ }
+
+ // Stop if found.
+ if (q == node)
+ break;
+
+ last = dir;
+ dir = q->mem < node->mem;
+
+ // Update helpers.
+ if (g)
+ t = g;
+
+ g = p;
+ p = q;
+ q = q->node[dir];
+ }
+
+ // Update root.
+ self->_root = static_cast<MemNode*>(head.node[1]);
+ }
+
+ // Make root black.
+ self->_root->red = 0;
+
+ // Link with others.
+ node->prev = self->_last;
+
+ if (!self->_first) {
+ self->_first = node;
+ self->_last = node;
+ self->_optimal = node;
+ }
+ else {
+ node->prev = self->_last;
+ self->_last->next = node;
+ self->_last = node;
+ }
+}
+
+//! \internal
+//!
+//! Remove node from Red-Black tree.
+//!
+//! Returns node that should be freed, but it doesn't have to be necessarily
+//! the `node` passed.
+static MemNode* vMemMgrRemoveNode(VMemMgr* self, MemNode* node) {
+ // False tree root.
+ RbNode head = { 0 };
+
+ // Helpers.
+ RbNode* q = &head;
+ RbNode* p = nullptr;
+ RbNode* g = nullptr;
+
+ // Found item.
+ RbNode* f = nullptr;
+ int dir = 1;
+
+ // Set up.
+ q->node[1] = self->_root;
+
+ // Search and push a red down.
+ while (q->node[dir]) {
+ int last = dir;
+
+ // Update helpers.
+ g = p;
+ p = q;
+ q = q->node[dir];
+ dir = q->mem < node->mem;
+
+ // Save found node.
+ if (q == node)
+ f = q;
+
+ // Push the red node down.
+ if (!rbIsRed(q) && !rbIsRed(q->node[dir])) {
+ if (rbIsRed(q->node[!dir])) {
+ p = p->node[last] = rbRotateSingle(q, dir);
+ }
+ else if (!rbIsRed(q->node[!dir])) {
+ RbNode* s = p->node[!last];
+
+ if (s) {
+ if (!rbIsRed(s->node[!last]) && !rbIsRed(s->node[last])) {
+ // Color flip.
+ p->red = 0;
+ s->red = 1;
+ q->red = 1;
+ }
+ else {
+ int dir2 = g->node[1] == p;
+
+ if (rbIsRed(s->node[last]))
+ g->node[dir2] = rbRotateDouble(p, last);
+ else if (rbIsRed(s->node[!last]))
+ g->node[dir2] = rbRotateSingle(p, last);
+
+ // Ensure correct coloring.
+ q->red = g->node[dir2]->red = 1;
+ g->node[dir2]->node[0]->red = 0;
+ g->node[dir2]->node[1]->red = 0;
+ }
+ }
+ }
+ }
+ }
+
+ // Replace and remove.
+ ASMJIT_ASSERT(f);
+ ASMJIT_ASSERT(f != &head);
+ ASMJIT_ASSERT(q != &head);
+
+ if (f != q) {
+ ASMJIT_ASSERT(f != &head);
+ static_cast<MemNode*>(f)->fillData(static_cast<MemNode*>(q));
+ }
+
+ p->node[p->node[1] == q] = q->node[!q->node[0]];
+
+ // Update root and make it black.
+ self->_root = static_cast<MemNode*>(head.node[1]);
+ if (self->_root)
+ self->_root->red = 0;
+
+ // Unlink.
+ MemNode* next = static_cast<MemNode*>(q)->next;
+ MemNode* prev = static_cast<MemNode*>(q)->prev;
+
+ if (prev)
+ prev->next = next;
+ else
+ self->_first = next;
+
+ if (next)
+ next->prev = prev;
+ else
+ self->_last = prev;
+
+ if (self->_optimal == q)
+ self->_optimal = prev ? prev : next;
+
+ return static_cast<MemNode*>(q);
+}
+
+static MemNode* vMemMgrFindNodeByPtr(VMemMgr* self, uint8_t* mem) {
+ MemNode* node = self->_root;
+ while (node) {
+ uint8_t* nodeMem = node->mem;
+
+ // Go left.
+ if (mem < nodeMem) {
+ node = static_cast<MemNode*>(node->node[0]);
+ continue;
+ }
+
+ // Go right.
+ uint8_t* nodeEnd = nodeMem + node->size;
+ if (mem >= nodeEnd) {
+ node = static_cast<MemNode*>(node->node[1]);
+ continue;
+ }
+
+ // Match.
+ break;
+ }
+ return node;
+}
+
+static void* vMemMgrAllocPermanent(VMemMgr* self, size_t vSize) {
+ static const size_t permanentAlignment = 32;
+ static const size_t permanentNodeSize = 32768;
+
+ vSize = IntUtil::alignTo<size_t>(vSize, permanentAlignment);
+
+ AutoLock locked(self->_lock);
+ PermanentNode* node = self->_permanent;
+
+ // Try to find space in allocated chunks.
+ while (node && vSize > node->getAvailable())
+ node = node->prev;
+
+ // Or allocate new node.
+ if (!node) {
+ size_t nodeSize = permanentNodeSize;
+
+ if (nodeSize < vSize)
+ nodeSize = vSize;
+
+ node = static_cast<PermanentNode*>(ASMJIT_ALLOC(sizeof(PermanentNode)));
+
+ // Out of memory.
+ if (!node)
+ return nullptr;
+
+ node->mem = vMemMgrAllocVMem(self, nodeSize, &node->size);
+
+ // Out of memory.
+ if (!node->mem) {
+ ASMJIT_FREE(node);
+ return nullptr;
+ }
+
+ node->used = 0;
+ node->prev = self->_permanent;
+ self->_permanent = node;
+ }
+
+ // Finally, copy function code to our space we reserved for.
+ uint8_t* result = node->mem + node->used;
+
+ // Update Statistics.
+ node->used += vSize;
+ self->_usedBytes += vSize;
+
+ // Code can be null to only reserve space for code.
+ return static_cast<void*>(result);
+}
+
+static void* vMemMgrAllocFreeable(VMemMgr* self, size_t vSize) {
+ // Current index.
+ size_t i;
+
+ // How many we need to be freed.
+ size_t need;
+ size_t minVSize;
+
+ // Align to 32 bytes by default.
+ vSize = IntUtil::alignTo<size_t>(vSize, 32);
+ if (vSize == 0)
+ return nullptr;
+
+ AutoLock locked(self->_lock);
+ MemNode* node = self->_optimal;
+ minVSize = self->_blockSize;
+
+ // Try to find memory block in existing nodes.
+ while (node) {
+ // Skip this node?
+ if ((node->getAvailable() < vSize) || (node->largestBlock < vSize && node->largestBlock != 0)) {
+ MemNode* next = node->next;
+
+ if (node->getAvailable() < minVSize && node == self->_optimal && next)
+ self->_optimal = next;
+
+ node = next;
+ continue;
+ }
+
+ size_t* up = node->baUsed; // Current ubits address.
+ size_t ubits; // Current ubits[0] value.
+ size_t bit; // Current bit mask.
+ size_t blocks = node->blocks; // Count of blocks in node.
+ size_t cont = 0; // How many bits are currently freed in find loop.
+ size_t maxCont = 0; // Largest continuous block (bits count).
+ size_t j;
+
+ need = M_DIV((vSize + node->density - 1), node->density);
+ i = 0;
+
+ // Try to find node that is large enough.
+ while (i < blocks) {
+ ubits = *up++;
+
+ // Fast skip used blocks.
+ if (ubits == ~static_cast<size_t>(0)) {
+ if (cont > maxCont)
+ maxCont = cont;
+ cont = 0;
+
+ i += kBitsPerEntity;
+ continue;
+ }
+
+ size_t max = kBitsPerEntity;
+ if (i + max > blocks)
+ max = blocks - i;
+
+ for (j = 0, bit = 1; j < max; bit <<= 1) {
+ j++;
+ if ((ubits & bit) == 0) {
+ if (++cont == need) {
+ i += j;
+ i -= cont;
+ goto _Found;
+ }
+
+ continue;
+ }
+
+ if (cont > maxCont) maxCont = cont;
+ cont = 0;
+ }
+
+ i += kBitsPerEntity;
+ }
+
+ // Because we traversed the entire node, we can set largest node size that
+ // will be used to cache next traversing.
+ node->largestBlock = maxCont * node->density;
+
+ node = node->next;
+ }
+
+ // If we are here, we failed to find existing memory block and we must
+ // allocate a new one.
+ {
+ size_t blockSize = self->_blockSize;
+ if (blockSize < vSize)
+ blockSize = vSize;
+
+ node = vMemMgrCreateNode(self, blockSize, self->_blockDensity);
+ if (!node)
+ return nullptr;
+
+ // Update binary tree.
+ vMemMgrInsertNode(self, node);
+ ASMJIT_ASSERT(vMemMgrCheckTree(self));
+
+ // Alloc first node at start.
+ i = 0;
+ need = (vSize + node->density - 1) / node->density;
+
+ // Update statistics.
+ self->_allocatedBytes += node->size;
+ }
+
+_Found:
+ // Update bits.
+ _SetBits(node->baUsed, i, need);
+ _SetBits(node->baCont, i, need - 1);
+
+ // Update statistics.
+ {
+ size_t u = need * node->density;
+ node->used += u;
+ node->largestBlock = 0;
+ self->_usedBytes += u;
+ }
+
+ // And return pointer to allocated memory.
+ uint8_t* result = node->mem + i * node->density;
+ ASMJIT_ASSERT(result >= node->mem && result <= node->mem + node->size - vSize);
+ return result;
+}
+
+//! \internal
+//!
+//! Reset the whole `VMemMgr` instance, freeing all heap memory allocated an
+//! virtual memory allocated unless `keepVirtualMemory` is true (and this is
+//! only used when writing data to a remote process).
+static void vMemMgrReset(VMemMgr* self, bool keepVirtualMemory) {
+ MemNode* node = self->_first;
+
+ while (node) {
+ MemNode* next = node->next;
+
+ if (!keepVirtualMemory)
+ vMemMgrReleaseVMem(self, node->mem, node->size);
+
+ ASMJIT_FREE(node->baUsed);
+ ASMJIT_FREE(node);
+
+ node = next;
+ }
+
+ self->_allocatedBytes = 0;
+ self->_usedBytes = 0;
+
+ self->_root = nullptr;
+ self->_first = nullptr;
+ self->_last = nullptr;
+ self->_optimal = nullptr;
+}
+
+// ============================================================================
+// [asmjit::VMemMgr - Construction / Destruction]
+// ============================================================================
+
+#ifndef ASMJIT_OS_WINDOWS
+VMemMgr::VMemMgr()
+#else
+VMemMgr::VMemMgr(HANDLE hProcess) :
+ _hProcess(vMemGet().getSafeProcessHandle(hProcess))
+#endif // ASMJIT_OS_WINDOWS
+{
+
+ _blockSize = VMemUtil::getPageGranularity();
+ _blockDensity = 64;
+
+ _allocatedBytes = 0;
+ _usedBytes = 0;
+
+ _root = nullptr;
+ _first = nullptr;
+ _last = nullptr;
+ _optimal = nullptr;
+
+ _permanent = nullptr;
+ _keepVirtualMemory = false;
+}
+
+VMemMgr::~VMemMgr() {
+ // Freeable memory cleanup - Also frees the virtual memory if configured to.
+ vMemMgrReset(this, _keepVirtualMemory);
+
+ // Permanent memory cleanup - Never frees the virtual memory.
+ PermanentNode* node = _permanent;
+ while (node) {
+ PermanentNode* prev = node->prev;
+ ASMJIT_FREE(node);
+ node = prev;
+ }
+}
+
+// ============================================================================
+// [asmjit::VMemMgr - Reset]
+// ============================================================================
+
+void VMemMgr::reset() {
+ vMemMgrReset(this, false);
+}
+
+// ============================================================================
+// [asmjit::VMemMgr - Alloc / Release]
+// ============================================================================
+
+void* VMemMgr::alloc(size_t size, uint32_t type) {
+ if (type == kVMemAllocPermanent)
+ return vMemMgrAllocPermanent(this, size);
+ else
+ return vMemMgrAllocFreeable(this, size);
+}
+
+Error VMemMgr::release(void* p) {
+ if (!p)
+ return kErrorOk;
+
+ AutoLock locked(_lock);
+ MemNode* node = vMemMgrFindNodeByPtr(this, static_cast<uint8_t*>(p));
+
+ if (!node)
+ return kErrorInvalidArgument;
+
+ size_t offset = static_cast<size_t>(static_cast<uint8_t*>(p) - node->mem);
+ size_t bitpos = M_DIV(offset, node->density);
+ size_t i = (bitpos / kBitsPerEntity);
+
+ size_t* up = node->baUsed + i; // Current ubits address.
+ size_t* cp = node->baCont + i; // Current cbits address.
+ size_t ubits = *up; // Current ubits[0] value.
+ size_t cbits = *cp; // Current cbits[0] value.
+ size_t bit = static_cast<size_t>(1) << (bitpos % kBitsPerEntity);
+
+ size_t cont = 0;
+ bool stop;
+
+ for (;;) {
+ stop = (cbits & bit) == 0;
+ ubits &= ~bit;
+ cbits &= ~bit;
+
+ bit <<= 1;
+ cont++;
+
+ if (stop || bit == 0) {
+ *up = ubits;
+ *cp = cbits;
+ if (stop)
+ break;
+
+ ubits = *++up;
+ cbits = *++cp;
+ bit = 1;
+ }
+ }
+
+ // If the freed block is fully allocated node then it's needed to
+ // update 'optimal' pointer in memory manager.
+ if (node->used == node->size) {
+ MemNode* cur = _optimal;
+
+ do {
+ cur = cur->prev;
+ if (cur == node) {
+ _optimal = node;
+ break;
+ }
+ } while (cur);
+ }
+
+ // Statistics.
+ cont *= node->density;
+ if (node->largestBlock < cont)
+ node->largestBlock = cont;
+
+ node->used -= cont;
+ _usedBytes -= cont;
+
+ // If page is empty, we can free it.
+ if (node->used == 0) {
+ // Free memory associated with node (this memory is not accessed
+ // anymore so it's safe).
+ vMemMgrReleaseVMem(this, node->mem, node->size);
+ ASMJIT_FREE(node->baUsed);
+
+ node->baUsed = nullptr;
+ node->baCont = nullptr;
+
+ // Statistics.
+ _allocatedBytes -= node->size;
+
+ // Remove node. This function can return different node than
+ // passed into, but data is copied into previous node if needed.
+ ASMJIT_FREE(vMemMgrRemoveNode(this, node));
+ ASMJIT_ASSERT(vMemMgrCheckTree(this));
+ }
+
+ return kErrorOk;
+}
+
+Error VMemMgr::shrink(void* p, size_t used) {
+ if (!p)
+ return kErrorOk;
+
+ if (used == 0)
+ return release(p);
+
+ AutoLock locked(_lock);
+
+ MemNode* node = vMemMgrFindNodeByPtr(this, static_cast<uint8_t*>(p));
+ if (!node)
+ return kErrorInvalidArgument;
+
+ size_t offset = static_cast<size_t>(static_cast<uint8_t*>(p) - node->mem);
+ size_t bitpos = M_DIV(offset, node->density);
+ size_t i = (bitpos / kBitsPerEntity);
+
+ size_t* up = node->baUsed + i; // Current ubits address.
+ size_t* cp = node->baCont + i; // Current cbits address.
+ size_t ubits = *up; // Current ubits[0] value.
+ size_t cbits = *cp; // Current cbits[0] value.
+ size_t bit = static_cast<size_t>(1) << (bitpos % kBitsPerEntity);
+
+ size_t cont = 0;
+ size_t usedBlocks = (used + node->density - 1) / node->density;
+
+ bool stop;
+
+ // Find the first block we can mark as free.
+ for (;;) {
+ stop = (cbits & bit) == 0;
+ if (stop)
+ return kErrorOk;
+
+ if (++cont == usedBlocks)
+ break;
+
+ bit <<= 1;
+ if (bit == 0) {
+ ubits = *++up;
+ cbits = *++cp;
+ bit = 1;
+ }
+ }
+
+ // Free the tail blocks.
+ cont = ~static_cast<size_t>(0);
+ goto _EnterFreeLoop;
+
+ for (;;) {
+ stop = (cbits & bit) == 0;
+ ubits &= ~bit;
+
+_EnterFreeLoop:
+ cbits &= ~bit;
+
+ bit <<= 1;
+ cont++;
+
+ if (stop || bit == 0) {
+ *up = ubits;
+ *cp = cbits;
+ if (stop)
+ break;
+
+ ubits = *++up;
+ cbits = *++cp;
+ bit = 1;
+ }
+ }
+
+ // Statistics.
+ cont *= node->density;
+ if (node->largestBlock < cont)
+ node->largestBlock = cont;
+
+ node->used -= cont;
+ _usedBytes -= cont;
+
+ return kErrorOk;
+}
+
+} // asmjit namespace
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/vmem.h
@@ -1,1 +1,236 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Dependencies]
+#include "../base/error.h"
+#include "../base/lock.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::kVMemAlloc]
+// ============================================================================
+
+//! Type of virtual memory allocation, see `VMemMgr::alloc()`.
+ASMJIT_ENUM(kVMemAlloc) {
+ //! Normal memory allocation, has to be freed by `VMemMgr::release()`.
+ kVMemAllocFreeable = 0,
+ //! Allocate permanent memory, can't be freed.
+ kVMemAllocPermanent = 1
+};
+
+// ============================================================================
+// [asmjit::kVMemFlags]
+// ============================================================================
+
+//! Type of virtual memory allocation, see `VMemMgr::alloc()`.
+ASMJIT_ENUM(kVMemFlags) {
+ //! Memory is writable.
+ kVMemFlagWritable = 0x00000001,
+ //! Memory is executable.
+ kVMemFlagExecutable = 0x00000002
+};
+
+// ============================================================================
+// [asmjit::VMemUtil]
+// ============================================================================
+
+//! Virtual memory utilities.
+//!
+//! Defines functions that provide facility to allocate and free memory that is
+//! executable in a platform independent manner. If both the processor and host
+//! operating system support data-execution-prevention then the only way how to
+//! run machine code is to allocate it to a memory that has marked as executable.
+//! VMemUtil is just unified interface to platform dependent APIs.
+//!
+//! `VirtualAlloc()` function is used on Windows operating system and `mmap()`
+//! on POSIX. `VirtualAlloc()` and `mmap()` documentation provide a detailed
+//! overview on how to use a platform specific APIs.
+struct VMemUtil {
+ //! Get a size/alignment of a single virtual memory page.
+ static ASMJIT_API size_t getPageSize();
+
+ //! Get a recommended granularity for a single `alloc` call.
+ static ASMJIT_API size_t getPageGranularity();
+
+ //! 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 on failure.
+ static ASMJIT_API void* alloc(size_t length, size_t* allocated, uint32_t flags);
+
+#ifdef ASMJIT_OS_WINDOWS
+ //! Allocate virtual memory of `hProcess`.
+ //!
+ //! \note This function is Windows specific.
+ static ASMJIT_API void* allocProcessMemory(HANDLE hProcess, size_t length, size_t* allocated, uint32_t flags);
+#endif // ASMJIT_OS_WINDOWS
+
+ //! Free memory allocated by `alloc()`.
+ static ASMJIT_API Error release(void* addr, size_t length);
+
+#ifdef ASMJIT_OS_WINDOWS
+ //! Release virtual memory of `hProcess`.
+ //!
+ //! \note This function is Windows specific.
+ static ASMJIT_API Error releaseProcessMemory(HANDLE hProcess, void* addr, size_t length);
+#endif // ASMJIT_OS_WINDOWS
+};
+
+// ============================================================================
+// [asmjit::VMemMgr]
+// ============================================================================
+
+//! Reference implementation of memory manager that uses `VMemUtil` to allocate
+//! chunks of virtual memory and bit arrays to manage it.
+struct VMemMgr {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+#ifndef ASMJIT_OS_WINDOWS
+ //! Create a `VMemMgr` instance.
+ ASMJIT_API VMemMgr();
+#else
+ //! Create a `VMemMgr` instance.
+ //!
+ //! \note When running on Windows it's possible to specify a `hProcess` to
+ //! be used for memory allocation. This allows to allocate memory of remote
+ //! process.
+ ASMJIT_API VMemMgr(HANDLE hProcess = static_cast<HANDLE>(0));
+#endif // ASMJIT_OS_WINDOWS
+
+ //! Destroy the `VMemMgr` instance and free all blocks.
+ ASMJIT_API ~VMemMgr();
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ //! Free all allocated memory.
+ ASMJIT_API void reset();
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+#ifdef ASMJIT_OS_WINDOWS
+ //! Get the handle of the process memory manager is bound to.
+ ASMJIT_INLINE HANDLE getProcessHandle() const {
+ return _hProcess;
+ }
+#endif // ASMJIT_OS_WINDOWS
+
+ //! Get how many bytes are currently allocated.
+ ASMJIT_INLINE size_t getAllocatedBytes() const {
+ return _allocatedBytes;
+ }
+
+ //! Get how many bytes are currently used.
+ ASMJIT_INLINE size_t getUsedBytes() const {
+ return _usedBytes;
+ }
+
+ //! Get whether to keep allocated memory after the `VMemMgr` is destroyed.
+ //!
+ //! \sa \ref setKeepVirtualMemory.
+ ASMJIT_INLINE bool getKeepVirtualMemory() const {
+ return _keepVirtualMemory;
+ }
+
+ //! Set whether to keep allocated memory after memory manager is
+ //! destroyed.
+ //!
+ //! This method is usable when patching code of remote process. You need to
+ //! allocate process memory, store generated assembler into it and patch the
+ //! method you want to redirect (into your code). This method affects only
+ //! VMemMgr destructor. After destruction all internal
+ //! structures are freed, only the process virtual memory remains.
+ //!
+ //! \note Memory allocated with kVMemAllocPermanent is always kept.
+ //!
+ //! \sa \ref getKeepVirtualMemory.
+ ASMJIT_INLINE void setKeepVirtualMemory(bool keepVirtualMemory) {
+ _keepVirtualMemory = keepVirtualMemory;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Alloc / Release]
+ // --------------------------------------------------------------------------
+
+ //! Allocate 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.
+ ASMJIT_API void* alloc(size_t size, uint32_t type = kVMemAllocFreeable);
+
+ //! Free previously allocated memory at a given `address`.
+ ASMJIT_API Error release(void* p);
+
+ //! Free extra memory allocated with `p`.
+ ASMJIT_API Error shrink(void* p, size_t used);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+#ifdef ASMJIT_OS_WINDOWS
+ //! Process passed to `VirtualAllocEx` and `VirtualFree`.
+ HANDLE _hProcess;
+#endif // ASMJIT_OS_WINDOWS
+
+ //! Lock to enable thread-safe functionality.
+ Lock _lock;
+
+ //! Default block size.
+ size_t _blockSize;
+ //! Default block density.
+ size_t _blockDensity;
+
+ // Whether to keep virtual memory after destroy.
+ bool _keepVirtualMemory;
+
+ //! How many bytes are currently allocated.
+ size_t _allocatedBytes;
+ //! How many bytes are currently used.
+ size_t _usedBytes;
+
+ //! \internal
+ //! \{
+
+ struct RbNode;
+ struct MemNode;
+ struct PermanentNode;
+
+ // Memory nodes root.
+ MemNode* _root;
+ // Memory nodes list.
+ MemNode* _first;
+ MemNode* _last;
+ MemNode* _optimal;
+ // Permanent memory.
+ PermanentNode* _permanent;
+
+ //! \}
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/zone.cpp
@@ -1,1 +1,196 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Dependencies - AsmJit]
+#include "../base/intutil.h"
+#include "../base/zone.h"
+
+// [Dependencies - C]
+#include <cstdarg>
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! Zero size block used by `Zone` that doesn't have any memory allocated.
+static const Zone::Block Zone_zeroBlock = {
+ nullptr, nullptr, nullptr, nullptr, { 0 }
+};
+
+// ============================================================================
+// [asmjit::Zone - Construction / Destruction]
+// ============================================================================
+
+Zone::Zone(size_t blockSize) {
+ _block = const_cast<Zone::Block*>(&Zone_zeroBlock);
+ _blockSize = blockSize;
+}
+
+Zone::~Zone() {
+ reset(true);
+}
+
+// ============================================================================
+// [asmjit::Zone - Reset]
+// ============================================================================
+
+void Zone::reset(bool releaseMemory) {
+ Block* cur = _block;
+
+ // Can't be altered.
+ if (cur == &Zone_zeroBlock)
+ return;
+
+ if (releaseMemory) {
+ // Since cur can be in the middle of the double-linked list, we have to
+ // traverse to both directions `prev` and `next` separately.
+ Block* next = cur->next;
+ do {
+ Block* prev = cur->prev;
+ ASMJIT_FREE(cur);
+ cur = prev;
+ } while (cur);
+
+ cur = next;
+ while (cur) {
+ next = cur->next;
+ ASMJIT_FREE(cur);
+ cur = next;
+ }
+
+ _block = const_cast<Zone::Block*>(&Zone_zeroBlock);
+ }
+ else {
+ while (cur->prev)
+ cur = cur->prev;
+
+ cur->pos = cur->data;
+ _block = cur;
+ }
+}
+
+// ============================================================================
+// [asmjit::Zone - Alloc]
+// ============================================================================
+
+void* Zone::_alloc(size_t size) {
+ Block* curBlock = _block;
+ size_t blockSize = IntUtil::iMax<size_t>(_blockSize, size);
+
+ // The `_alloc()` method can only be called if there is not enough space
+ // in the current block, see `alloc()` implementation for more details.
+ ASMJIT_ASSERT(curBlock == &Zone_zeroBlock || curBlock->getRemainingSize() < size);
+
+ // If the `Zone` has been reset the current block doesn't have to be the
+ // last one. Check if there is a block that can be used instead of allocating
+ // a new one. If there is a `next` block it's completely unused, we don't have
+ // to check for remaining bytes.
+ Block* next = curBlock->next;
+ if (next && next->getBlockSize() >= size) {
+ next->pos = next->data + size;
+ _block = next;
+ return static_cast<void*>(next->data);
+ }
+
+ // Prevent arithmetic overflow.
+ if (blockSize > ~static_cast<size_t>(0) - sizeof(Block))
+ return nullptr;
+
+ Block* newBlock = static_cast<Block*>(ASMJIT_ALLOC(sizeof(Block) - sizeof(void*) + blockSize));
+ if (!newBlock)
+ return nullptr;
+
+ newBlock->pos = newBlock->data + size;
+ newBlock->end = newBlock->data + blockSize;
+ newBlock->prev = nullptr;
+ newBlock->next = nullptr;
+
+ if (curBlock != &Zone_zeroBlock) {
+ newBlock->prev = curBlock;
+ curBlock->next = newBlock;
+
+ // Does only happen if there is a next block, but the requested memory
+ // can't fit into it. In this case a new buffer is allocated and inserted
+ // between the current block and the next one.
+ if (next) {
+ newBlock->next = next;
+ next->prev = newBlock;
+ }
+ }
+
+ _block = newBlock;
+ return static_cast<void*>(newBlock->data);
+}
+
+void* Zone::allocZeroed(size_t size) {
+ void* p = alloc(size);
+ if (p)
+ ::memset(p, 0, size);
+ return p;
+}
+
+void* Zone::dup(const void* data, size_t size) {
+ if (!data)
+ return nullptr;
+
+ if (size == 0)
+ return nullptr;
+
+ void* m = alloc(size);
+ if (!m)
+ return nullptr;
+
+ ::memcpy(m, data, size);
+ return m;
+}
+
+char* Zone::sdup(const char* str) {
+ if (!str)
+ return nullptr;
+
+ size_t len = ::strlen(str);
+ if (len == 0)
+ return nullptr;
+
+ // Include NULL terminator and limit string length.
+ if (++len > 256)
+ len = 256;
+
+ char* m = static_cast<char*>(alloc(len));
+ if (!m)
+ return nullptr;
+
+ ::memcpy(m, str, len);
+ m[len - 1] = '\0';
+ return m;
+}
+
+char* Zone::sformat(const char* fmt, ...) {
+ if (!fmt)
+ return nullptr;
+
+ char buf[512];
+ size_t len;
+
+ va_list ap;
+ va_start(ap, fmt);
+
+ len = vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf) - 1, fmt, ap);
+ buf[len++] = 0;
+
+ va_end(ap);
+ return static_cast<char*>(dup(buf, len));
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/base/zone.h
@@ -1,1 +1,217 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Dependencies]
+#include "../base/globals.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::Zone]
+// ============================================================================
+
+//! Zone memory allocator.
+//!
+//! Zone is an incremental memory allocator that allocates memory by simply
+//! incrementing a pointer. It allocates blocks of memory by using standard
+//! C library `malloc/free`, but divides these blocks into smaller segments
+//! requirested by calling `Zone::alloc()` and friends.
+//!
+//! Zone memory allocators are designed to allocate data of short lifetime. The
+//! data used by `Assembler` and `Compiler` has a very short lifetime, thus, is
+//! allocated by `Zone`. The advantage is that `Zone` can free all of the data
+//! allocated at once by calling `reset()` or by `Zone` destructor.
+struct Zone {
+ // --------------------------------------------------------------------------
+ // [Block]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ //!
+ //! A single block of memory.
+ struct Block {
+ // ------------------------------------------------------------------------
+ // [Accessors]
+ // ------------------------------------------------------------------------
+
+ //! Get the size of the block.
+ ASMJIT_INLINE size_t getBlockSize() const {
+ return static_cast<size_t>(end - data);
+ }
+
+ //! Get count of remaining bytes in the block.
+ ASMJIT_INLINE size_t getRemainingSize() const {
+ return static_cast<size_t>(end - pos);
+ }
+
+ // ------------------------------------------------------------------------
+ // [Members]
+ // ------------------------------------------------------------------------
+
+ //! Current data pointer (pointer to the first available byte).
+ uint8_t* pos;
+ //! End data pointer (pointer to the first invalid byte).
+ uint8_t* end;
+
+ //! Link to the previous block.
+ Block* prev;
+ //! Link to the next block.
+ Block* next;
+
+ //! Data.
+ uint8_t data[sizeof(void*)];
+ };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new instance of `Zone` allocator.
+ //!
+ //! The `blockSize` parameter describes the default size of the block. If the
+ //! `size` parameter passed to `alloc()` is greater than the default size
+ //! `Zone` will allocate and use a larger block, but it will not change the
+ //! default `blockSize`.
+ //!
+ //! It's not required, but it's good practice to set `blockSize` to a
+ //! reasonable value that depends on the usage of `Zone`. Greater block sizes
+ //! are generally safer and performs better than unreasonably low values.
+ ASMJIT_API Zone(size_t blockSize);
+
+ //! Destroy the `Zone` instance.
+ //!
+ //! This will destroy the `Zone` instance and release all blocks of memory
+ //! allocated by it. It performs implicit `reset(true)`.
+ ASMJIT_API ~Zone();
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ //! Reset the `Zone` invalidating all blocks allocated.
+ //!
+ //! If `releaseMemory` is true all buffers will be released to the system.
+ ASMJIT_API void reset(bool releaseMemory = false);
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get the default block size.
+ ASMJIT_INLINE size_t getBlockSize() const {
+ return _blockSize;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Alloc]
+ // --------------------------------------------------------------------------
+
+ //! Allocate `size` bytes of memory.
+ //!
+ //! Pointer returned is valid until the `Zone` instance is destroyed or reset
+ //! by calling `reset()`. If you plan to make an instance of C++ from the
+ //! given pointer use placement `new` and `delete` operators:
+ //!
+ //! ~~~
+ //! using namespace asmjit;
+ //!
+ //! class SomeObject { ... };
+ //!
+ //! // Create Zone with default block size of 65536 bytes.
+ //! Zone zone(65536);
+ //!
+ //! // Create your objects using zone object allocating, for example:
+ //! Object* obj = static_cast<Object*>( zone.alloc(sizeof(SomeClass)) );
+ //
+ //! if (obj == NULL) {
+ //! // Handle out of memory error.
+ //! }
+ //!
+ //! // To instantiate class placement `new` and `delete` operators can be used.
+ //! new(obj) Object();
+ //!
+ //! // ... lifetime of your objects ...
+ //!
+ //! // To destroy the instance (if required).
+ //! obj->~Object();
+ //!
+ //! // Reset of destroy `Zone`.
+ //! zone.reset();
+ //! ~~~
+ ASMJIT_INLINE void* alloc(size_t size) {
+ Block* cur = _block;
+
+ uint8_t* ptr = cur->pos;
+ size_t remainingBytes = static_cast<size_t>(cur->end - ptr);
+
+ if (remainingBytes < size)
+ return _alloc(size);
+
+ cur->pos += size;
+ ASMJIT_ASSERT(cur->pos <= cur->end);
+
+ return ptr;
+ }
+
+ //! Allocate `size` bytes of zeroed memory.
+ //!
+ //! See \ref alloc() for more details.
+ ASMJIT_API void* allocZeroed(size_t size);
+
+ //! Like `alloc()`, but the return pointer is casted to `T*`.
+ template<typename T>
+ ASMJIT_INLINE T* allocT(size_t size = sizeof(T)) {
+ return static_cast<T*>(alloc(size));
+ }
+
+ //! Like `allocZeroed()`, but the return pointer is casted to `T*`.
+ template<typename T>
+ ASMJIT_INLINE T* allocZeroedT(size_t size = sizeof(T)) {
+ return static_cast<T*>(allocZeroed(size));
+ }
+
+ //! \internal
+ ASMJIT_API void* _alloc(size_t size);
+
+ //! Helper to duplicate data.
+ ASMJIT_API void* dup(const void* data, size_t size);
+
+ //! Helper to duplicate string.
+ ASMJIT_API char* sdup(const char* str);
+
+ //! Helper to duplicate formatted string, maximum length is 256 bytes.
+ ASMJIT_API char* sformat(const char* str, ...);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! The current block.
+ Block* _block;
+ //! Default block size.
+ size_t _blockSize;
+};
+
+enum {
+ //! Zone allocator overhead.
+ kZoneOverhead = static_cast<int>(sizeof(Zone::Block) - sizeof(void*)) + kMemAllocOverhead
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/build.h
@@ -1,1 +1,372 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Include]
+#ifdef ASMJIT_CONFIG_FILE
+# include ASMJIT_CONFIG_FILE
+#else
+# include "./config.h"
+#endif // ASMJIT_CONFIG_FILE
+
+// Turn off deprecation warnings when compiling AsmJit.
+#if defined(ASMJIT_EXPORTS) && defined(_MSC_VER)
+# ifndef _CRT_SECURE_NO_DEPRECATE
+# define _CRT_SECURE_NO_DEPRECATE
+# endif // !_CRT_SECURE_NO_DEPRECATE
+# ifndef _CRT_SECURE_NO_WARNINGS
+# define _CRT_SECURE_NO_WARNINGS
+# endif // !_CRT_SECURE_NO_WARNINGS
+#endif // ASMJIT_EXPORTS
+
+// [Dependencies - C]
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+// [Dependencies - C++]
+#include <new>
+
+// ============================================================================
+// [asmjit::build - Sanity]
+// ============================================================================
+
+#if defined(ASMJIT_DISABLE_NAMES) && !defined(ASMJIT_DISABLE_LOGGER)
+# error "ASMJIT_DISABLE_NAMES requires ASMJIT_DISABLE_LOGGER to be defined."
+#endif // ASMJIT_DISABLE_NAMES && !ASMJIT_DISABLE_LOGGER
+
+// ============================================================================
+// [asmjit::build - OS]
+// ============================================================================
+
+#if defined(_WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(_WIN64)
+# define ASMJIT_OS_WINDOWS
+#elif defined(__linux) || defined(__linux__)
+# define ASMJIT_OS_POSIX
+# define ASMJIT_OS_LINUX
+#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+# define ASMJIT_OS_POSIX
+# define ASMJIT_OS_BSD
+#elif defined(__APPLE__)
+# define ASMJIT_OS_POSIX
+# define ASMJIT_OS_MAC
+#else
+# warning "AsmJit - Unable to detect host operating system, using ASMJIT_OS_POSIX"
+# define ASMJIT_OS_POSIX
+#endif
+
+// ============================================================================
+// [asmjit::build - Arch]
+// ============================================================================
+
+#if defined(_M_X64 ) || \
+ defined(_M_AMD64 ) || \
+ defined(_WIN64 ) || \
+ defined(__amd64__ ) || \
+ defined(__LP64 ) || \
+ defined(__x86_64__)
+# define ASMJIT_HOST_X64
+# define ASMJIT_HOST_LE
+# define ASMJIT_HOST_UNALIGNED_16
+# define ASMJIT_HOST_UNALIGNED_32
+# define ASMJIT_HOST_UNALIGNED_64
+#elif \
+ defined(_M_IX86 ) || \
+ defined(__INTEL__) || \
+ defined(__i386__ )
+# define ASMJIT_HOST_X86
+# define ASMJIT_HOST_LE
+# define ASMJIT_HOST_UNALIGNED_16
+# define ASMJIT_HOST_UNALIGNED_32
+# define ASMJIT_HOST_UNALIGNED_64
+#elif \
+ defined(_ARM ) || \
+ defined(_M_ARM_FP ) || \
+ defined(__ARM_NEON__ ) || \
+ defined(__arm ) || \
+ defined(__arm__ ) || \
+ defined(__TARGET_ARCH_ARM ) || \
+ defined(__TARGET_ARCH_THUMB) || \
+ defined(__thumb__ )
+# define ASMJIT_HOST_ARM
+# define ASMJIT_HOST_LE
+#else
+# warning "AsmJit - Unable to detect host architecture"
+#endif
+
+// ============================================================================
+// [asmjit::build - Build]
+// ============================================================================
+
+// Build host architecture if no architecture is selected.
+#if !defined(ASMJIT_BUILD_HOST) && \
+ !defined(ASMJIT_BUILD_X86) && \
+ !defined(ASMJIT_BUILD_X64)
+# define ASMJIT_BUILD_HOST
+#endif
+
+// Autodetect host architecture if enabled.
+#ifdef ASMJIT_BUILD_HOST
+# if defined(ASMJIT_HOST_X86) && !defined(ASMJIT_BUILD_X86)
+# define ASMJIT_BUILD_X86
+# endif // ASMJIT_HOST_X86 && !ASMJIT_BUILD_X86
+# if defined(ASMJIT_HOST_X64) && !defined(ASMJIT_BUILD_X64)
+# define ASMJIT_BUILD_X64
+# endif // ASMJIT_HOST_X64 && !ASMJIT_BUILD_X64
+#endif // ASMJIT_BUILD_HOST
+
+// ============================================================================
+// [asmjit::build - Decorators]
+// ============================================================================
+
+#if defined(ASMJIT_EMBED) && !defined(ASMJIT_STATIC)
+# define ASMJIT_STATIC
+#endif // ASMJIT_EMBED && !ASMJIT_STATIC
+
+#ifdef ASMJIT_STATIC
+# define ASMJIT_API
+#elif defined(ASMJIT_OS_WINDOWS)
+# if (defined(__GNUC__) || defined(__clang__)) && !defined(__MINGW32__)
+# ifdef ASMJIT_EXPORTS
+# define ASMJIT_API __attribute__((dllexport))
+# else
+# define ASMJIT_API __attribute__((dllimport))
+# endif // ASMJIT_EXPORTS
+# else
+# ifdef ASMJIT_EXPORTS
+# define ASMJIT_API __declspec(dllexport)
+# else
+# define ASMJIT_API __declspec(dllimport)
+# endif
+# endif
+#elif defined(__GNUC__) && __GNUC__ >= 4
+# define ASMJIT_API __attribute__((visibility("default")))
+#endif
+
+#ifndef ASMJIT_API
+# define ASMJIT_API
+#endif // ASMJIT_API
+
+// This is basically a workaround. When using MSVC and marking class as DLL
+// export everything is exported, which is unwanted since there are many
+// inlines which mimic instructions. MSVC automatically exports typeinfo and
+// vtable if at least one symbol of that class is exported. However, GCC has
+// some strange behavior that even if one or more symbol is exported it doesn't
+// export `typeinfo` unless the class itself is marked as "visibility(default)".
+#if !defined(ASMJIT_OS_WINDOWS) && (defined(__GNUC__) || defined (__clang__))
+# define ASMJIT_VCLASS ASMJIT_API
+#else
+# define ASMJIT_VCLASS
+#endif
+
+#ifndef ASMJIT_VAR
+# define ASMJIT_VAR extern ASMJIT_API
+#endif // !ASMJIT_VAR
+
+#ifdef _MSC_VER
+# define ASMJIT_INLINE __forceinline
+#elif defined(__clang__)
+# define ASMJIT_INLINE inline __attribute__((always_inline)) __attribute__((visibility("hidden")))
+#elif defined(__GNUC__)
+# define ASMJIT_INLINE inline __attribute__((always_inline))
+#else
+# define ASMJIT_INLINE inline
+#endif
+
+#ifdef ASMJIT_HOST_X86
+# if defined(__GNUC__) || defined(__clang__)
+# define ASMJIT_REGPARM_1 __attribute__((regparm(1)))
+# define ASMJIT_REGPARM_2 __attribute__((regparm(2)))
+# define ASMJIT_REGPARM_3 __attribute__((regparm(3)))
+# define ASMJIT_FASTCALL __attribute__((fastcall))
+# define ASMJIT_STDCALL __attribute__((stdcall))
+# define ASMJIT_CDECL __attribute__((cdecl))
+# else
+# define ASMJIT_FASTCALL __fastcall
+# define ASMJIT_STDCALL __stdcall
+# define ASMJIT_CDECL __cdecl
+# endif
+#else
+# define ASMJIT_FASTCALL
+# define ASMJIT_STDCALL
+# define ASMJIT_CDECL
+#endif // ASMJIT_HOST_X86
+
+// ============================================================================
+// [asmjit::build - Enum]
+// ============================================================================
+
+#ifdef _MSC_VER
+# define ASMJIT_ENUM(_Name_) enum _Name_ : uint32_t
+#else
+# define ASMJIT_ENUM(_Name_) enum _Name_
+#endif
+
+// ============================================================================
+// [asmjit::build - Memory Management]
+// ============================================================================
+
+#if !defined(ASMJIT_ALLOC) && !defined(ASMJIT_REALLOC) && !defined(ASMJIT_FREE)
+# define ASMJIT_ALLOC(_Size_) ::malloc(_Size_)
+# define ASMJIT_REALLOC(_Ptr_, _Size_) ::realloc(_Ptr_, _Size_)
+# define ASMJIT_FREE(_Ptr_) ::free(_Ptr_)
+#else
+# if !defined(ASMJIT_ALLOC) || !defined(ASMJIT_REALLOC) || !defined(ASMJIT_FREE)
+# error "AsmJit - You must redefine ASMJIT_ALLOC, ASMJIT_REALLOC and ASMJIT_FREE."
+# endif
+#endif // !ASMJIT_ALLOC && !ASMJIT_REALLOC && !ASMJIT_FREE
+
+// ============================================================================
+// [asmjit::build - _ASMJIT_HOST_INDEX]
+// ============================================================================
+
+#ifdef ASMJIT_HOST_LE
+# define _ASMJIT_HOST_INDEX(_Total_, _Index_) (_Index_)
+#else
+# define _ASMJIT_HOST_INDEX(_Total_, _Index_) ((_Total_) - 1 - (_Index_))
+#endif
+
+// ============================================================================
+// [asmjit::build - BLEND_OFFSET_OF]
+// ============================================================================
+
+//! Cross-platform solution to get offset of `_Field_` in `_Struct_`.
+#define ASMJIT_OFFSET_OF(_Struct_, _Field_) \
+ (reinterpret_cast<size_t>(reinterpret_cast<const uint8_t*>(&reinterpret_cast<const _Struct_*>(0x1)->_Field_)) - 1)
+
+// ============================================================================
+// [asmjit::build - ASMJIT_ARRAY_SIZE]
+// ============================================================================
+
+#define ASMJIT_ARRAY_SIZE(_Array_) \
+ (sizeof(_Array_) / sizeof(*_Array_))
+
+// ============================================================================
+// [asmjit::build - ASMJIT_DEBUG / ASMJIT_TRACE]
+// ============================================================================
+
+// If ASMJIT_DEBUG and ASMJIT_RELEASE is not defined ASMJIT_DEBUG will be
+// detected using the compiler specific macros. This enables to set the build
+// type using IDE.
+#if !defined(ASMJIT_DEBUG) && !defined(ASMJIT_RELEASE)
+# ifdef _DEBUG
+# define ASMJIT_DEBUG
+# endif // _DEBUG
+#endif // !ASMJIT_DEBUG && !ASMJIT_RELEASE
+
+// ASMJIT_TRACE is only used by sources and private headers. It's safe to make
+// it unavailable outside of AsmJit.
+#ifdef ASMJIT_EXPORTS
+namespace asmjit { static inline int disabledTrace(...) { return 0; } }
+# ifdef ASMJIT_TRACE
+# define ASMJIT_TSEC(_Section_) _Section_
+# define ASMJIT_TLOG ::printf(__VA_ARGS__)
+# else
+# define ASMJIT_TSEC(_Section_) do {} while(0)
+# define ASMJIT_TLOG 0 && ::asmjit::disabledTrace
+# endif // ASMJIT_TRACE
+#endif // ASMJIT_EXPORTS
+
+// ============================================================================
+// [asmjit::build - ASMJIT_UNUSED]
+// ============================================================================
+
+#ifndef ASMJIT_UNUSED
+# define ASMJIT_UNUSED(_Var_) ((void)_Var_)
+#endif // ASMJIT_UNUSED
+
+// ============================================================================
+// [asmjit::build - ASMJIT_NOP]
+// ============================================================================
+
+#ifndef ASMJIT_NOP
+# define ASMJIT_NOP() ((void)0)
+#endif // ASMJIT_NOP
+
+// ============================================================================
+// [asmjit::build - ASMJIT_NO_COPY]
+// ============================================================================
+
+#define ASMJIT_NO_COPY(_Type_) \
+private: \
+ ASMJIT_INLINE _Type_(const _Type_& other); \
+ ASMJIT_INLINE _Type_& operator=(const _Type_& other); \
+public:
+
+// ============================================================================
+// [asmjit::build - StdInt]
+// ============================================================================
+
+#ifdef __MINGW32__
+# include <sys/types.h>
+#endif // __MINGW32__
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# ifndef ASMJIT_SUPRESS_STD_TYPES
+# if _MSC_VER < 1300
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed int int32_t;
+typedef signed __int64 int64_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned __int64 uint64_t;
+# else
+typedef signed __int8 int8_t;
+typedef signed __int16 int16_t;
+typedef signed __int32 int32_t;
+typedef signed __int64 int64_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+# endif // _MSC_VER
+# endif // ASMJIT_SUPRESS_STD_TYPES
+#else
+# include <cstdint>
+# include <climits>
+#endif
+
+#ifdef _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::build - Windows]
+// ============================================================================
+
+#if defined(ASMJIT_OS_WINDOWS) && !defined(ASMJIT_SUPRESS_WINDOWS_H)
+
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# define ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN
+# endif // !WIN32_LEAN_AND_MEAN
+
+# ifndef NOMINMAX
+# define NOMINMAX
+# define ASMJIT_UNDEF_NOMINMAX
+# endif // !NOMINMAX
+
+# include <windows.h>
+
+# ifdef ASMJIT_UNDEF_NOMINMAX
+# undef NOMINMAX
+# undef ASMJIT_UNDEF_NOMINMAX
+# endif
+
+# ifdef ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN
+# undef WIN32_LEAN_AND_MEAN
+# undef ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN
+# endif
+
+#endif // ASMJIT_OS_WINDOWS && !ASMJIT_SUPRESS_WINDOWS_H
+
--- a/src/in_2sf/desmume/utils/AsmJit/core.h
+++ /dev/null
@@ -1,33 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "core/build.h"
-
-#include "core/assembler.h"
-#include "core/assert.h"
-#include "core/buffer.h"
-#include "core/compiler.h"
-#include "core/compilercontext.h"
-#include "core/compilerfunc.h"
-#include "core/compileritem.h"
-#include "core/cpuinfo.h"
-#include "core/defs.h"
-#include "core/func.h"
-#include "core/intutil.h"
-#include "core/lock.h"
-#include "core/logger.h"
-#include "core/memorymanager.h"
-#include "core/memorymarker.h"
-#include "core/operand.h"
-#include "core/podvector.h"
-#include "core/stringbuilder.h"
-#include "core/stringutil.h"
-#include "core/virtualmemory.h"
-#include "core/zonememory.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/apibegin.h
+++ /dev/null
@@ -1,30 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-// [MSVC]
-#ifdef _MSC_VER
-// Disable some warnings we know about
-# 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
-# pragma warning(disable: 4800) // forcing value to bool 'true' or 'false'
-
-// Rename symbols.
-# define vsnprintf _vsnprintf
-# define snprintf _snprintf
-#endif // _MSC_VER
-
-// [GNUC]
-#ifdef __GNUC__
-// GCC warnings fix: I can't understand why GCC has no interface to push/pop
-// specific warnings.
-// # if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 402001
-// # pragma GCC diagnostic ignored "-w"
-// # endif
-#endif // __GNUC__
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/apiend.h
+++ /dev/null
@@ -1,20 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-// [MSVC]
-#ifdef _MSC_VER
-// Pop disabled warnings by ApiBegin.h
-# pragma warning(pop)
-
-// Rename symbols back.
-# undef vsnprintf
-# undef snprintf
-#endif // _MSC_VER
-
-// [GNUC]
-#ifdef __GNUC__
-#endif // __GNUC__
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/assembler.cpp
+++ /dev/null
@@ -1,203 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/assembler.h"
-#include "../core/memorymanager.h"
-#include "../core/intutil.h"
-
-// [Dependenceis - C]
-#include <stdarg.h>
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::Assembler - Construction / Destruction]
-// ============================================================================
-
-Assembler::Assembler(Context *context) : _zoneMemory(16384 - sizeof(ZoneChunk) - 32), _buffer(), _context(context ? context : static_cast<Context *>(JitContext::getGlobal())), _logger(nullptr), _error(kErrorOk),
- _properties(0), _emitOptions(0), _trampolineSize(0), _inlineComment(nullptr), _unusedLinks(nullptr), _labels(), _relocData()
-{
-}
-
-Assembler::~Assembler()
-{
-}
-
-// ============================================================================
-// [AsmJit::Assembler - Logging]
-// ============================================================================
-
-void Assembler::setLogger(Logger *logger)
-{
- this->_logger = logger;
-}
-
-// ============================================================================
-// [AsmJit::Assembler - Error Handling]
-// ============================================================================
-
-void Assembler::setError(uint32_t error)
-{
- this->_error = error;
- if (this->_error == kErrorOk)
- return;
-
- if (this->_logger)
- this->_logger->logFormat("*** ASSEMBLER ERROR: %s (%u).\n", getErrorString(error), static_cast<unsigned>(error));
-}
-
-// ============================================================================
-// [AsmJit::Assembler - Properties]
-// ============================================================================
-
-uint32_t Assembler::getProperty(uint32_t propertyId) const
-{
- if (propertyId > 31)
- return 0;
-
- return !!(this->_properties & IntUtil::maskFromIndex(propertyId));
-}
-
-void Assembler::setProperty(uint32_t propertyId, uint32_t value)
-{
- if (propertyId > 31)
- return;
-
- if (value)
- this->_properties |= IntUtil::maskFromIndex(propertyId);
- else
- this->_properties &= ~IntUtil::maskFromIndex(propertyId);
-}
-
-// ============================================================================
-// [AsmJit::Assembler - TakeCode]
-// ============================================================================
-
-uint8_t *Assembler::takeCode()
-{
- uint8_t *code = this->_buffer.take();
- this->_relocData.clear();
- this->_zoneMemory.clear();
-
- if (this->_error != kErrorOk)
- this->setError(kErrorOk);
-
- return code;
-}
-
-// ============================================================================
-// [AsmJit::Assembler - Clear / Reset]
-// ============================================================================
-
-void Assembler::clear()
-{
- this->_purge();
-
- if (this->_error != kErrorOk)
- this->setError(kErrorOk);
-}
-
-void Assembler::reset()
-{
- this->_purge();
-
- this->_zoneMemory.reset();
- this->_buffer.reset();
-
- this->_labels.clear();
- this->_relocData.clear();
-
- if (this->_error != kErrorOk)
- this->setError(kErrorOk);
-}
-
-void Assembler::_purge()
-{
- this->_zoneMemory.clear();
- this->_buffer.clear();
-
- this->_emitOptions = 0;
- this->_trampolineSize = 0;
-
- this->_inlineComment = nullptr;
- this->_unusedLinks = nullptr;
-
- this->_labels.clear();
- this->_relocData.clear();
-}
-
-// ============================================================================
-// [AsmJit::Assembler - Emit]
-// ============================================================================
-
-void Assembler::embed(const void *data, size_t len)
-{
- if (!this->canEmit())
- return;
-
- if (this->_logger)
- {
- char buf[128];
- const char dot[] = ".data ";
-
- memcpy(buf, dot, ASMJIT_ARRAY_SIZE(dot) - 1);
-
- for (size_t i = 0; i < len; i += 16)
- {
- size_t max = len - i < 16 ? len - i : 16;
- char *p = buf + ASMJIT_ARRAY_SIZE(dot) - 1;
-
- for (size_t j = 0; j < max; ++j)
- p += sprintf(p, "%02X", reinterpret_cast<const uint8_t *>(data)[i + j]);
-
- *p++ = '\n';
- *p = '\0';
-
- this->_logger->logString(buf);
- }
- }
-
- this->_buffer.emitData(data, len);
-}
-
-// ============================================================================
-// [AsmJit::Assembler - Helpers]
-// ============================================================================
-
-auto Assembler::_newLabelLink() -> LabelLink *
-{
- LabelLink *link = this->_unusedLinks;
-
- if (link)
- this->_unusedLinks = link->prev;
- else
- {
- link = static_cast<LabelLink *>(this->_zoneMemory.alloc(sizeof(LabelLink)));
- if (!link)
- return nullptr;
- }
-
- // clean link
- link->prev = nullptr;
- link->offset = 0;
- link->displacement = 0;
- link->relocId = -1;
-
- return link;
-}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/assembler.h
+++ /dev/null
@@ -1,460 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-#include <vector>
-
-// [Dependencies - AsmJit]
-#include "../core/buffer.h"
-#include "../core/context.h"
-#include "../core/defs.h"
-#include "../core/logger.h"
-#include "../core/podvector.h"
-#include "../core/zonememory.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Core
-//! @{
-
-// ============================================================================
-// [AsmJit::Assembler]
-// ============================================================================
-
-//! @brief Base class for @ref Assembler.
-//!
-//! This class implements core setialization API only. The platform specific
-//! methods and intrinsics is implemented by derived classes.
-//!
-//! @sa @c Assembler.
-struct Assembler
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Creates Assembler instance.
- ASMJIT_API Assembler(Context *context);
- //! @brief Destroys Assembler instance
- ASMJIT_API virtual ~Assembler();
-
- // --------------------------------------------------------------------------
- // [LabelLink]
- // --------------------------------------------------------------------------
-
- //! @brief Data structure used to link linked-labels.
- struct LabelLink
- {
- //! @brief Previous link.
- LabelLink *prev;
- //! @brief Offset.
- sysint_t offset;
- //! @brief Inlined displacement.
- sysint_t displacement;
- //! @brief RelocId if link must be absolute when relocated.
- sysint_t relocId;
- };
-
- // --------------------------------------------------------------------------
- // [LabelData]
- // --------------------------------------------------------------------------
-
- //! @brief Label data.
- struct LabelData
- {
- //! @brief Label offset.
- sysint_t offset;
- //! @brief Label links chain.
- LabelLink *links;
- };
-
- // --------------------------------------------------------------------------
- // [RelocData]
- // --------------------------------------------------------------------------
-
- // X86 architecture uses 32-bit absolute addressing model by memory operands,
- // but 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 Code relocation data (relative vs absolute addresses).
- struct RelocData
- {
- //! @brief Type of relocation.
- uint32_t type;
- //! @brief Size of relocation (4 or 8 bytes).
- uint32_t size;
- //! @brief Offset from code begin address.
- sysint_t offset;
-
- //! @brief Relative displacement or absolute address.
- union
- {
- //! @brief Relative displacement from code begin address (not to @c offset).
- sysint_t destination;
- //! @brief Absolute address where to jump;
- void *address;
- };
- };
-
- // --------------------------------------------------------------------------
- // [Context]
- // --------------------------------------------------------------------------
-
- //! @brief Get code generator.
- Context *getContext() const { return this->_context; }
-
- // --------------------------------------------------------------------------
- // [Memory Management]
- // --------------------------------------------------------------------------
-
- //! @brief Get zone memory manager.
- ZoneMemory *getZoneMemory() const { return const_cast<ZoneMemory *>(&this->_zoneMemory); }
-
- // --------------------------------------------------------------------------
- // [Logging]
- // --------------------------------------------------------------------------
-
- //! @brief Get logger.
- Logger *getLogger() const { return this->_logger; }
-
- //! @brief Set logger to @a logger.
- ASMJIT_API virtual void setLogger(Logger *logger);
-
- // --------------------------------------------------------------------------
- // [Error Handling]
- // --------------------------------------------------------------------------
-
- //! @brief Get error code.
- uint32_t getError() const { return this->_error; }
-
- //! @brief Set error code.
- //!
- //! This method is virtual, because higher classes can use it to catch all
- //! errors.
- ASMJIT_API virtual void setError(uint32_t error);
-
- // --------------------------------------------------------------------------
- // [Properties]
- // --------------------------------------------------------------------------
-
- //! @brief Get assembler property.
- ASMJIT_API virtual uint32_t getProperty(uint32_t propertyId) const;
-
- //! @brief Set assembler property.
- ASMJIT_API virtual void setProperty(uint32_t propertyId, uint32_t value);
-
- // --------------------------------------------------------------------------
- // [Capacity]
- // --------------------------------------------------------------------------
-
- //! @brief Get capacity of internal code buffer.
- size_t getCapacity() const { return this->_buffer.getCapacity(); }
-
- // --------------------------------------------------------------------------
- // [Offset]
- // --------------------------------------------------------------------------
-
- //! @brief Return current offset in buffer.
- size_t getOffset() const { return this->_buffer.getOffset(); }
-
- //! @brief Set 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.
- size_t toOffset(size_t o) { return this->_buffer.toOffset(o); }
-
- // --------------------------------------------------------------------------
- // [GetCode / GetCodeSize]
- // --------------------------------------------------------------------------
-
- //! @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.
- uint8_t *getCode() const { return this->_buffer.getData(); }
-
- //! @brief Return current offset in buffer (same as <code>getOffset() + getTramplineSize()</code>).
- size_t getCodeSize() const { return this->_buffer.getOffset() + this->getTrampolineSize(); }
-
- // --------------------------------------------------------------------------
- // [TakeCode]
- // --------------------------------------------------------------------------
-
- //! @brief Take internal code buffer and NULL all pointers (you take the ownership).
- ASMJIT_API uint8_t *takeCode();
-
- // --------------------------------------------------------------------------
- // [Clear / Reset]
- // --------------------------------------------------------------------------
-
- //! @brief Clear everything, but not deallocate buffers.
- ASMJIT_API void clear();
-
- //! @brief Reset everything (means also to free all buffers).
- ASMJIT_API void reset();
-
- //! @brief Called by clear() and reset() to clear all data related to derived
- //! class implementation.
- ASMJIT_API virtual void _purge();
-
- // --------------------------------------------------------------------------
- // [EnsureSpace]
- // --------------------------------------------------------------------------
-
- //! @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.
- bool ensureSpace() { return this->_buffer.ensureSpace(); }
-
- // --------------------------------------------------------------------------
- // [GetTrampolineSize]
- // --------------------------------------------------------------------------
-
- //! @brief Get 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.
- size_t getTrampolineSize() const { return this->_trampolineSize; }
-
- // --------------------------------------------------------------------------
- // [Buffer - Getters]
- // --------------------------------------------------------------------------
-
- //! @brief Get byte at position @a pos.
- uint8_t getByteAt(size_t pos) const { return this->_buffer.getByteAt(pos); }
-
- //! @brief Get word at position @a pos.
- uint16_t getWordAt(size_t pos) const { return this->_buffer.getWordAt(pos); }
-
- //! @brief Get dword at position @a pos.
- uint32_t getDWordAt(size_t pos) const { return this->_buffer.getDWordAt(pos); }
-
- //! @brief Get qword at position @a pos.
- uint64_t getQWordAt(size_t pos) const { return this->_buffer.getQWordAt(pos); }
-
- //! @brief Get int32_t at position @a pos.
- int32_t getInt32At(size_t pos) const { return static_cast<int32_t>(this->_buffer.getDWordAt(pos)); }
-
- //! @brief Get int64_t at position @a pos.
- int64_t getInt64At(size_t pos) const { return static_cast<int64_t>(this->_buffer.getQWordAt(pos)); }
-
- //! @brief Get intptr_t at position @a pos.
- intptr_t getIntPtrTAt(size_t pos) const { return this->_buffer.getIntPtrTAt(pos); }
-
- //! @brief Get uintptr_t at position @a pos.
- uintptr_t getUIntPtrTAt(size_t pos) const { return this->_buffer.getUIntPtrTAt(pos); }
-
- //! @brief Get uintptr_t at position @a pos.
- size_t getSizeTAt(size_t pos) const { return this->_buffer.getSizeTAt(pos); }
-
- // --------------------------------------------------------------------------
- // [Buffer - Setters]
- // --------------------------------------------------------------------------
-
- //! @brief Set byte at position @a pos.
- void setByteAt(size_t pos, uint8_t x) { this->_buffer.setByteAt(pos, x); }
-
- //! @brief Set word at position @a pos.
- void setWordAt(size_t pos, uint16_t x) { this->_buffer.setWordAt(pos, x); }
-
- //! @brief Set dword at position @a pos.
- void setDWordAt(size_t pos, uint32_t x) { this->_buffer.setDWordAt(pos, x); }
-
- //! @brief Set qword at position @a pos.
- void setQWordAt(size_t pos, uint64_t x) { this->_buffer.setQWordAt(pos, x); }
-
- //! @brief Set int32_t at position @a pos.
- void setInt32At(size_t pos, int32_t x) { this->_buffer.setDWordAt(pos, static_cast<uint32_t>(x)); }
-
- //! @brief Set int64_t at position @a pos.
- void setInt64At(size_t pos, int64_t x) { this->_buffer.setQWordAt(pos, static_cast<uint64_t>(x)); }
-
- //! @brief Set intptr_t at position @a pos.
- void setIntPtrTAt(size_t pos, intptr_t x) { this->_buffer.setIntPtrTAt(pos, x); }
-
- //! @brief Set uintptr_t at position @a pos.
- void setUInt64At(size_t pos, uintptr_t x) { this->_buffer.setUIntPtrTAt(pos, x); }
-
- //! @brief Set size_t at position @a pos.
- void setSizeTAt(size_t pos, size_t x) { this->_buffer.setSizeTAt(pos, x); }
-
- // --------------------------------------------------------------------------
- // [CanEmit]
- // --------------------------------------------------------------------------
-
- //! @brief Get whether the instruction can be emitted.
- //!
- //! This function behaves like @c ensureSpace(), but it also checks if
- //! assembler is in error state and in that case it returns @c false.
- //! Assembler internally always uses this function before new instruction is
- //! emitted.
- //!
- //! It's implemented like:
- //! <code>return ensureSpace() && !getError();</code>
- bool canEmit()
- {
- // If there is an error, we can't emit another instruction until last error
- // is cleared by calling @c setError(kErrorOk). If something caused the
- // error while generating code it's probably fatal in all cases. You can't
- // use generated code anymore, because you are not sure about the status.
- if (this->_error)
- return false;
-
- // The ensureSpace() method returns true on success and false on failure. We
- // are catching return value and setting error code here.
- if (this->ensureSpace())
- return true;
-
- // If we are here, there is memory allocation error. Note that this is HEAP
- // allocation error, virtual allocation error can be caused only by
- // AsmJit::VirtualMemory class!
- this->setError(kErrorNoHeapMemory);
- return false;
- }
-
- // --------------------------------------------------------------------------
- // [Emit]
- //
- // These functions are not protected against buffer overrun. Each place of
- // code which calls these functions ensures that there is some space using
- // canEmit() method. Emitters are internally protected in AsmJit::Buffer,
- // but only in debug builds.
- // --------------------------------------------------------------------------
-
- //! @brief Emit Byte to internal buffer.
- void _emitByte(uint8_t x) { this->_buffer.emitByte(x); }
-
- //! @brief Emit word (2 bytes) to internal buffer.
- void _emitWord(uint16_t x) { this->_buffer.emitWord(x); }
-
- //! @brief Emit dword (4 bytes) to internal buffer.
- void _emitDWord(uint32_t x) { this->_buffer.emitDWord(x); }
-
- //! @brief Emit qword (8 bytes) to internal buffer.
- void _emitQWord(uint64_t x) { this->_buffer.emitQWord(x); }
-
- //! @brief Emit Int32 (4 bytes) to internal buffer.
- void _emitInt32(int32_t x) { this->_buffer.emitDWord(static_cast<uint32_t>(x)); }
-
- //! @brief Emit Int64 (8 bytes) to internal buffer.
- void _emitInt64(int64_t x) { this->_buffer.emitQWord(static_cast<uint64_t>(x)); }
-
- //! @brief Emit intptr_t (4 or 8 bytes) to internal buffer.
- void _emitIntPtrT(intptr_t x) { this->_buffer.emitIntPtrT(x); }
-
- //! @brief Emit uintptr_t (4 or 8 bytes) to internal buffer.
- void _emitUIntPtrT(uintptr_t x) { this->_buffer.emitUIntPtrT(x); }
-
- //! @brief Emit size_t (4 or 8 bytes) to internal buffer.
- void _emitSizeT(size_t x) { this->_buffer.emitSizeT(x); }
-
- //! @brief Embed data into instruction stream.
- ASMJIT_API void embed(const void *data, size_t len);
-
- // --------------------------------------------------------------------------
- // [Reloc]
- // --------------------------------------------------------------------------
-
- //! @brief Relocate code to a given address @a dst.
- //!
- //! @param dst Where the relocated code should me stored. The pointer can be
- //! address returned by virtual memory allocator or your own address if you
- //! want only to store the code for later reuse (or load, etc...).
- //! @param addressBase Base address used for relocation. When using JIT code
- //! generation, this will be the same as @a dst, only casted to system
- //! integer type. But when generating code for remote process then the value
- //! can be different.
- //!
- //! @retval The bytes used. Code-generator can create trampolines which are
- //! used when calling other functions inside the JIT code. However, these
- //! trampolines can be unused so the relocCode() returns the exact size needed
- //! for the function.
- //!
- //! A given buffer will be overwritten, to get number of bytes required use
- //! @c getCodeSize().
- virtual size_t relocCode(void *dst, sysuint_t addressBase) const = 0;
-
- //! @brief Simplifed version of @c relocCode() method designed for JIT.
- //!
- //! @overload
- size_t relocCode(void *dst) const { return this->relocCode(dst, reinterpret_cast<uintptr_t>(dst)); }
-
- // --------------------------------------------------------------------------
- // [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 getError() method not
- //! returns @c kErrorOk (zero) then this function always return @c NULL and
- //! error value remains the same.
- virtual void *make() = 0;
-
- // --------------------------------------------------------------------------
- // [Helpers]
- // --------------------------------------------------------------------------
-
- ASMJIT_API LabelLink *_newLabelLink();
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief ZoneMemory management.
- ZoneMemory _zoneMemory;
- //! @brief Binary code buffer.
- Buffer _buffer;
-
- //! @brief Context (for example @ref JitContext).
- Context *_context;
- //! @brief Logger.
- Logger *_logger;
-
- //! @brief Error code.
- uint32_t _error;
- //! @brief Properties.
- uint32_t _properties;
- //! @brief Emit flags for next instruction (cleared after emit).
- uint32_t _emitOptions;
- //! @brief Size of possible trampolines.
- uint32_t _trampolineSize;
-
- //! @brief Inline comment that will be logged by the next instruction and
- //! set to NULL.
- const char *_inlineComment;
- //! @brief Linked list of unused links (@c LabelLink* structures)
- LabelLink *_unusedLinks;
-
- //! @brief Labels data.
- std::vector<LabelData> _labels;
- //! @brief Relocations data.
- std::vector<RelocData> _relocData;
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/assert.cpp
+++ /dev/null
@@ -1,34 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/assert.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-// helpers
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::Assert]
-// ============================================================================
-
-void assertionFailure(const char *file, int line, const char *exp)
-{
- fprintf(stderr, "*** ASSERTION FAILURE at %s (line %d)\n" "*** %s\n", file, line, exp);
-
- exit(1);
-}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/assert.h
+++ /dev/null
@@ -1,64 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/build.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Core
-//! @{
-
-// ============================================================================
-// [AsmJit::Assert]
-// ============================================================================
-
-//! @brief Called in debug build on assertion failure.
-//! @param file Source file name where it happened.
-//! @param line Line in the source file.
-//! @param exp Expression what failed.
-//!
-//! If you have problems with assertions simply put a breakpoint into
-//! AsmJit::assertionFailure() method (AsmJit/Core/Assert.cpp file) and examine
-//! call stack.
-ASMJIT_API void assertionFailure(const char *file, int line, const char *exp);
-
-// ============================================================================
-// [ASMJIT_ASSERT]
-// ============================================================================
-
-#ifdef ASMJIT_DEBUG
-
-#ifndef ASMJIT_ASSERT
-#define ASMJIT_ASSERT(exp) \
- do \
- { \
- if (!(exp)) \
- ::AsmJit::assertionFailure(__FILE__, __LINE__, #exp); \
- } while (0)
-#endif
-
-#else
-
-#ifndef ASMJIT_ASSERT
-#define ASMJIT_ASSERT(exp) ASMJIT_NOP()
-#endif
-
-#endif // DEBUG
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/buffer.cpp
+++ /dev/null
@@ -1,102 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/buffer.h"
-#include "../core/defs.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::Buffer]
-// ============================================================================
-
-void Buffer::emitData(const void *ptr, size_t len)
-{
- size_t max = this->getCapacity() - this->getOffset();
-
- if (max < len && !this->realloc(this->getOffset() + len))
- return;
-
- memcpy(this->_cur, ptr, len);
- this->_cur += len;
-}
-
-bool Buffer::realloc(size_t to)
-{
- if (this->getCapacity() < to)
- {
- size_t len = this->getOffset();
- uint8_t *newdata;
-
- if (this->_data)
- newdata = static_cast<uint8_t *>(ASMJIT_REALLOC(this->_data, to));
- else
- newdata = static_cast<uint8_t *>(ASMJIT_MALLOC(to));
-
- if (!newdata)
- return false;
-
- this->_data = newdata;
- this->_cur = newdata + len;
- this->_max = newdata + to;
- this->_max -= to >= kBufferGrow ? kBufferGrow : to;
-
- this->_capacity = to;
- }
-
- return true;
-}
-
-bool Buffer::grow()
-{
- size_t to = this->_capacity;
-
- if (to < 512)
- to = 1024;
- else if (to > 65536)
- to += 65536;
- else
- to <<= 1;
-
- return this->realloc(to);
-}
-
-void Buffer::reset()
-{
- if (!this->_data)
- return;
- ASMJIT_FREE(this->_data);
-
- this->_data = nullptr;
- this->_cur = nullptr;
- this->_max = nullptr;
- this->_capacity = 0;
-}
-
-uint8_t *Buffer::take()
-{
- uint8_t *data = this->_data;
-
- this->_data = nullptr;
- this->_cur = nullptr;
- this->_max = nullptr;
- this->_capacity = 0;
-
- return data;
-}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/buffer.h
+++ /dev/null
@@ -1,335 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/assert.h"
-#include "../core/build.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Core
-//! @{
-
-// ============================================================================
-// [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 Buffer
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- Buffer() : _data(nullptr), _cur(nullptr), _max(nullptr), _capacity(0) { }
-
- ~Buffer()
- {
- if (this->_data)
- ASMJIT_FREE(this->_data);
- }
-
- //! @brief Get start of buffer.
- uint8_t *getData() const { return this->_data; }
-
- //! @brief Get current pointer in code buffer.
- uint8_t *getCur() const { return this->_cur; }
-
- //! @brief Get maximum pointer in code buffer for growing.
- uint8_t *getMax() const { return this->_max; }
-
- //! @brief Get current offset in buffer.
- size_t getOffset() const { return static_cast<size_t>(this->_cur - this->_data); }
-
- //! @brief Get capacity of buffer.
- size_t getCapacity() const { return this->_capacity; }
-
- //! @brief Ensure space for next instruction
- bool ensureSpace() { return this->_cur >= this->_max ? this->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.
- size_t toOffset(size_t offset)
- {
- ASMJIT_ASSERT(offset < this->_capacity);
-
- size_t prev = static_cast<size_t>(this->_cur - this->_data);
- this->_cur = this->_data + offset;
- return prev;
- }
-
- //! @brief Reallocate buffer.
- //!
- //! It's only used for growing, buffer is never reallocated to smaller
- //! number than current capacity() is.
- ASMJIT_API bool realloc(size_t to);
-
- //! @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.
- ASMJIT_API bool grow();
-
- //! @brief Clear everything, but not deallocate buffer.
- void clear() { this->_cur = this->_data; }
-
- //! @brief Free buffer and NULL all pointers.
- ASMJIT_API void reset();
-
- //! @brief Take ownership of the buffer data and purge @c Buffer instance.
- ASMJIT_API uint8_t *take();
-
- // --------------------------------------------------------------------------
- // [Emit]
- // --------------------------------------------------------------------------
-
- //! @brief Emit Byte.
- void emitByte(uint8_t x)
- {
- ASMJIT_ASSERT(this->getOffset() + 1 <= this->_capacity);
-
- *this->_cur++ = x;
- }
-
- //! @brief Emit Word (2 bytes).
- void emitWord(uint16_t x)
- {
- ASMJIT_ASSERT(this->getOffset() + 2 <= this->_capacity);
-
- *reinterpret_cast<uint16_t *>(this->_cur) = x;
- this->_cur += 2;
- }
-
- //! @brief Emit DWord (4 bytes).
- void emitDWord(uint32_t x)
- {
- ASMJIT_ASSERT(this->getOffset() + 4 <= this->_capacity);
-
- *reinterpret_cast<uint32_t *>(this->_cur) = x;
- this->_cur += 4;
- }
-
- //! @brief Emit QWord (8 bytes).
- void emitQWord(uint64_t x)
- {
- ASMJIT_ASSERT(this->getOffset() + 8 <= this->_capacity);
-
- *reinterpret_cast<uint64_t *>(this->_cur) = x;
- this->_cur += 8;
- }
-
- //! @brief Emit intptr_t (4 or 8 bytes).
- void emitIntPtrT(intptr_t x)
- {
- ASMJIT_ASSERT(this->getOffset() + sizeof(intptr_t) <= this->_capacity);
-
- *reinterpret_cast<intptr_t *>(this->_cur) = x;
- this->_cur += sizeof(intptr_t);
- }
-
- //! @brief Emit uintptr_t (4 or 8 bytes).
- void emitUIntPtrT(uintptr_t x)
- {
- ASMJIT_ASSERT(this->getOffset() + sizeof(uintptr_t) <= this->_capacity);
-
- *reinterpret_cast<uintptr_t *>(this->_cur) = x;
- this->_cur += sizeof(uintptr_t);
- }
-
- //! @brief Emit size_t (4 or 8 bytes).
- void emitSizeT(size_t x)
- {
- ASMJIT_ASSERT(this->getOffset() + sizeof(size_t) <= this->_capacity);
-
- *reinterpret_cast<size_t *>(this->_cur) = x;
- this->_cur += sizeof(size_t);
- }
-
- //! @brief Emit custom data.
- ASMJIT_API void emitData(const void *ptr, size_t len);
-
- // --------------------------------------------------------------------------
- // [Get / Set]
- // --------------------------------------------------------------------------
-
- //! @brief Set byte at position @a pos.
- uint8_t getByteAt(size_t pos) const
- {
- ASMJIT_ASSERT(pos + 1 <= this->_capacity);
-
- return *(this->_data + pos);
- }
-
- //! @brief Set word at position @a pos.
- uint16_t getWordAt(size_t pos) const
- {
- ASMJIT_ASSERT(pos + 2 <= this->_capacity);
-
- return *reinterpret_cast<const uint16_t *>(this->_data + pos);
- }
-
- //! @brief Set dword at position @a pos.
- uint32_t getDWordAt(size_t pos) const
- {
- ASMJIT_ASSERT(pos + 4 <= this->_capacity);
-
- return *reinterpret_cast<const uint32_t *>(this->_data + pos);
- }
-
- //! @brief Set qword at position @a pos.
- uint64_t getQWordAt(size_t pos) const
- {
- ASMJIT_ASSERT(pos + 8 <= this->_capacity);
-
- return *reinterpret_cast<const uint64_t *>(this->_data + pos);
- }
-
- //! @brief Set intptr_t at position @a pos.
- intptr_t getIntPtrTAt(size_t pos) const
- {
- ASMJIT_ASSERT(pos + sizeof(intptr_t) <= this->_capacity);
-
- return *reinterpret_cast<const intptr_t *>(this->_data + pos);
- }
-
- //! @brief Set uintptr_t at position @a pos.
- uintptr_t getUIntPtrTAt(size_t pos) const
- {
- ASMJIT_ASSERT(pos + sizeof(uintptr_t) <= this->_capacity);
-
- return *reinterpret_cast<const uintptr_t *>(this->_data + pos);
- }
-
- //! @brief Set size_t at position @a pos.
- uintptr_t getSizeTAt(size_t pos) const
- {
- ASMJIT_ASSERT(pos + sizeof(size_t) <= this->_capacity);
-
- return *reinterpret_cast<const size_t *>(this->_data + pos);
- }
-
- //! @brief Set byte at position @a pos.
- void setByteAt(size_t pos, uint8_t x)
- {
- ASMJIT_ASSERT(pos + 1 <= this->_capacity);
-
- *(this->_data + pos) = x;
- }
-
- //! @brief Set word at position @a pos.
- void setWordAt(size_t pos, uint16_t x)
- {
- ASMJIT_ASSERT(pos + 2 <= this->_capacity);
-
- *reinterpret_cast<uint16_t *>(this->_data + pos) = x;
- }
-
- //! @brief Set dword at position @a pos.
- void setDWordAt(size_t pos, uint32_t x)
- {
- ASMJIT_ASSERT(pos + 4 <= this->_capacity);
-
- *reinterpret_cast<uint32_t *>(this->_data + pos) = x;
- }
-
- //! @brief Set qword at position @a pos.
- void setQWordAt(size_t pos, uint64_t x)
- {
- ASMJIT_ASSERT(pos + 8 <= this->_capacity);
-
- *reinterpret_cast<uint64_t *>(this->_data + pos) = x;
- }
-
- //! @brief Set intptr_t at position @a pos.
- void setIntPtrTAt(size_t pos, intptr_t x)
- {
- ASMJIT_ASSERT(pos + sizeof(intptr_t) <= this->_capacity);
-
- *reinterpret_cast<intptr_t *>(this->_data + pos) = x;
- }
-
- //! @brief Set uintptr_t at position @a pos.
- void setUIntPtrTAt(size_t pos, uintptr_t x)
- {
- ASMJIT_ASSERT(pos + sizeof(uintptr_t) <= this->_capacity);
-
- *reinterpret_cast<uintptr_t *>(this->_data + pos) = x;
- }
-
- //! @brief Set size_t at position @a pos.
- void setSizeTAt(size_t pos, size_t x)
- {
- ASMJIT_ASSERT(pos + sizeof(size_t) <= this->_capacity);
-
- *reinterpret_cast<size_t *>(this->_data + pos) = x;
- }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- // All members are public, because they can be accessed and modified by
- // Assembler/Compiler directly.
-
- //! @brief Beginning position of buffer.
- uint8_t *_data;
- //! @brief Current position in buffer.
- uint8_t *_cur;
- //! @brief Maximum position in buffer for realloc.
- uint8_t *_max;
-
- //! @brief Buffer capacity (in bytes).
- size_t _capacity;
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/build.h
+++ /dev/null
@@ -1,227 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Include]
-#include "../Config.h"
-
-#ifdef ASMJIT_EXPORTS
-# if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
-# define _CRT_SECURE_NO_WARNINGS
-# endif // _MSC_VER
-#endif // ASMJIT_EXPORTS
-
-// 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.
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-
-#include <new>
-
-// ============================================================================
-// [AsmJit - OS]
-// ============================================================================
-
-#if defined(WINDOWS) || 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]
-// ============================================================================
-
-// Make AsmJit as shared library by default.
-#ifndef ASMJIT_API
-# ifdef ASMJIT_WINDOWS
-# ifdef __GNUC__
-# ifdef ASMJIT_EXPORTS
-# define ASMJIT_API __attribute__((dllexport))
-# else
-# define ASMJIT_API __attribute__((dllimport))
-# endif // ASMJIT_EXPORTS
-# else
-# ifdef ASMJIT_EXPORTS
-# define ASMJIT_API __declspec(dllexport)
-# else
-# define ASMJIT_API __declspec(dllimport)
-# endif // ASMJIT_EXPORTS
-# endif // __GNUC__
-# else
-# ifdef (__GNUC__
-# if __GNUC__ >= 4
-# define ASMJIT_API __attribute__((visibility("default")))
-# define ASMJIT_VAR extern ASMJIT_API
-# endif // __GNUC__ >= 4
-# endif // __GNUC__
-# endif
-#endif // ASMJIT_API
-
-#ifndef ASMJIT_VAR
-# ifdef ASMJIT_API
-# define ASMJIT_VAR extern ASMJIT_API
-# else
-# define ASMJIT_VAR
-# endif // ASMJIT_API
-#endif // !ASMJIT_VAR
-
-// [AsmJit - Memory Management]
-#ifndef ASMJIT_MALLOC
-# define ASMJIT_MALLOC ::malloc
-#endif // ASMJIT_MALLOC
-
-#ifndef ASMJIT_REALLOC
-# define ASMJIT_REALLOC ::realloc
-#endif // ASMJIT_REALLOC
-
-#ifndef ASMJIT_FREE
-# define ASMJIT_FREE ::free
-#endif // ASMJIT_FREE
-
-// ============================================================================
-// [AsmJit - Calling Conventions]
-// ============================================================================
-
-#ifdef ASMJIT_X86
-# ifdef __GNUC__
-# define ASMJIT_REGPARM_1 __attribute__((regparm(1)))
-# define ASMJIT_REGPARM_2 __attribute__((regparm(2)))
-# define ASMJIT_REGPARM_3 __attribute__((regparm(3)))
-# define ASMJIT_FASTCALL __attribute__((fastcall))
-# define ASMJIT_STDCALL __attribute__((stdcall))
-# define ASMJIT_CDECL __attribute__((cdecl))
-# else
-# define ASMJIT_FASTCALL __fastcall
-# define ASMJIT_STDCALL __stdcall
-# define ASMJIT_CDECL __cdecl
-# endif
-#else
-# define ASMJIT_FASTCALL
-# define ASMJIT_STDCALL
-# define ASMJIT_CDECL
-#endif // ASMJIT_X86
-
-#ifndef ASMJIT_UNUSED
-# define ASMJIT_UNUSED(var) ((void)var)
-#endif // ASMJIT_UNUSED
-
-#ifndef ASMJIT_NOP
-# define ASMJIT_NOP() ((void)0)
-#endif // ASMJIT_NOP
-
-// [AsmJit - C++ Compiler Support]
-#define ASMJIT_TYPE_TO_TYPE(_Type_) _Type_
-#define ASMJIT_HAS_STANDARD_DEFINE_OPTIONS
-#define ASMJIT_HAS_PARTIAL_TEMPLATE_SPECIALIZATION
-
-// Support for VC6
-#if defined(_MSC_VER) && _MSC_VER < 1400
-
-namespace AsmJit
-{
- template<typename T> struct _Type2Type
- {
- typedef T Type;
- };
-}
-
-#undef ASMJIT_TYPE_TO_TYPE
-#define ASMJIT_TYPE_TO_TYPE(_Type_) ::AsmJit::_Type2Type<_Type_>::Type
-
-#undef ASMJIT_HAS_STANDARD_DEFINE_OPTIONS
-#undef ASMJIT_HAS_PARTIAL_TEMPLATE_SPECIALIZATION
-
-#endif
-
-// ============================================================================
-// [AsmJit - Types]
-// ============================================================================
-
-#include <cstdint>
-
-#ifdef ASMJIT_X86
-typedef int32_t sysint_t;
-typedef uint32_t sysuint_t;
-#else
-typedef int64_t sysint_t;
-typedef uint64_t sysuint_t;
-#endif
-
-#ifdef _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]
-// ============================================================================
-
-template<typename T, size_t N> inline size_t ASMJIT_ARRAY_SIZE(T (&)[N]) { return N; }
-
-#define ASMJIT_NO_COPY(__type__) \
-private: \
- __type__(const __type__ &other); \
- __type__& operator=(const __type__ &other); \
-public:
-
-// ============================================================================
-// [AsmJit - Debug]
-// ============================================================================
-
-// If ASMJIT_DEBUG and ASMJIT_NO_DEBUG is not defined then ASMJIT_DEBUG will be
-// detected using the compiler specific macros. This enables to set the build
-// type using IDE.
-#if !defined(ASMJIT_DEBUG) && !defined(ASMJIT_NO_DEBUG)
-# ifdef _DEBUG
-# define ASMJIT_DEBUG
-# endif // _DEBUG
-#endif // !ASMJIT_DEBUG && !ASMJIT_NO_DEBUG
-
-// ============================================================================
-// [AsmJit - Initialize/DontInitialize]
-// ============================================================================
-
-// TODO: This should be moved to AsmJit namespace!
-
-// Skip documenting this.
-#ifndef ASMJIT_NODOC
-struct _Initialize {};
-struct _DontInitialize {};
-#endif // !ASMJIT_NODOC
-
-// ============================================================================
-// [AsmJit - OS Support]
-// ============================================================================
-
-#ifdef ASMJIT_WINDOWS
-# include "windowsh_wrapper.h"
-#endif // ASMJIT_WINDOWS
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/compiler.cpp
+++ /dev/null
@@ -1,269 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/assembler.h"
-#include "../core/compiler.h"
-#include "../core/compilercontext.h"
-#include "../core/compilerfunc.h"
-#include "../core/compileritem.h"
-#include "../core/cpuinfo.h"
-#include "../core/intutil.h"
-#include "../core/logger.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::Compiler - Construction / Destruction]
-// ============================================================================
-
-Compiler::Compiler(Context *context) : _zoneMemory(16384 - sizeof(ZoneChunk) - 32), _linkMemory(1024 - 32), _context(context ? context : static_cast<Context *>(JitContext::getGlobal())), _logger(nullptr), _error(0),
- _properties(0), _emitOptions(0), _finished(false), _first(nullptr), _last(nullptr), _current(nullptr), _cc(nullptr), _varNameId(0)
-{
-}
-
-Compiler::~Compiler()
-{
- this->reset();
-}
-
-// ============================================================================
-// [AsmJit::Compiler - Logging]
-// ============================================================================
-
-void Compiler::setLogger(Logger *logger)
-{
- this->_logger = logger;
-}
-
-// ============================================================================
-// [AsmJit::Compiler - Error Handling]
-// ============================================================================
-
-void Compiler::setError(uint32_t error)
-{
- this->_error = error;
- if (this->_error == kErrorOk)
- return;
-
- if (this->_logger)
- this->_logger->logFormat("*** COMPILER ERROR: %s (%u).\n", getErrorString(error), static_cast<unsigned>(error));
-}
-
-// ============================================================================
-// [AsmJit::Compiler - Properties]
-// ============================================================================
-
-uint32_t Compiler::getProperty(uint32_t propertyId)
-{
- if (propertyId > 31)
- return 0;
-
- return !!(this->_properties & IntUtil::maskFromIndex(propertyId));
-}
-
-void Compiler::setProperty(uint32_t propertyId, uint32_t value)
-{
- if (propertyId > 31)
- return;
-
- if (value)
- this->_properties |= IntUtil::maskFromIndex(propertyId);
- else
- this->_properties &= ~IntUtil::maskFromIndex(propertyId);
-}
-
-// ============================================================================
-// [AsmJit::Compiler - Clear / Reset]
-// ============================================================================
-
-void Compiler::clear()
-{
- this->_purge();
-
- if (this->_error != kErrorOk)
- this->setError(kErrorOk);
-}
-
-void Compiler::reset()
-{
- this->_purge();
-
- this->_zoneMemory.reset();
- this->_linkMemory.reset();
-
- this->_targets.reset();
- this->_vars.reset();
-
- if (this->_error != kErrorOk)
- this->setError(kErrorOk);
-}
-
-void Compiler::_purge()
-{
- this->_zoneMemory.clear();
- this->_linkMemory.clear();
-
- this->_emitOptions = 0;
- this->_finished = false;
-
- this->_first = nullptr;
- this->_last = nullptr;
- this->_current = nullptr;
- this->_func = nullptr;
-
- this->_targets.clear();
- this->_vars.clear();
-
- this->_cc = nullptr;
- this->_varNameId = 0;
-}
-
-// ============================================================================
-// [AsmJit::Compiler - Item Management]
-// ============================================================================
-
-CompilerItem *Compiler::setCurrentItem(CompilerItem *item)
-{
- CompilerItem *old = this->_current;
- this->_current = item;
- return old;
-}
-
-void Compiler::addItem(CompilerItem *item)
-{
- ASMJIT_ASSERT(item);
- ASMJIT_ASSERT(!item->_prev);
- ASMJIT_ASSERT(!item->_next);
-
- if (!this->_current)
- {
- if (!this->_first)
- {
- this->_first = item;
- this->_last = item;
- }
- else
- {
- item->_next = this->_first;
- this->_first->_prev = item;
- this->_first = item;
- }
- }
- else
- {
- CompilerItem *prev = this->_current;
- CompilerItem *next = this->_current->_next;
-
- item->_prev = prev;
- item->_next = next;
-
- prev->_next = item;
- if (next)
- next->_prev = item;
- else
- this->_last = item;
- }
-
- this->_current = item;
-}
-
-void Compiler::addItemAfter(CompilerItem *item, CompilerItem *ref)
-{
- ASMJIT_ASSERT(item);
- ASMJIT_ASSERT(!item->_prev);
- ASMJIT_ASSERT(!item->_next);
- ASMJIT_ASSERT(ref);
-
- CompilerItem *prev = ref;
- CompilerItem *next = ref->_next;
-
- item->_prev = prev;
- item->_next = next;
-
- prev->_next = item;
- if (next)
- next->_prev = item;
- else
- this->_last = item;
-}
-
-void Compiler::removeItem(CompilerItem *item)
-{
- CompilerItem *prev = item->_prev;
- CompilerItem *next = item->_next;
-
- if (this->_first == item)
- this->_first = next;
- else
- prev->_next = next;
- if (this->_last == item)
- this->_last = prev;
- else
- next->_prev = prev;
-
- item->_prev = nullptr;
- item->_next = nullptr;
-
- if (this->_current == item)
- this->_current = prev;
-}
-
-// ============================================================================
-// [AsmJit::Compiler - Comment]
-// ============================================================================
-
-void Compiler::comment(const char *fmt, ...)
-{
- char buf[128];
- char *p = buf;
-
- if (fmt)
- {
- *p++ = ';';
- *p++ = ' ';
-
- va_list ap;
- va_start(ap, fmt);
- p += vsnprintf(p, 100, fmt, ap);
- va_end(ap);
- }
-
- *p++ = '\n';
- *p = '\0';
-
- CompilerComment *item = Compiler_newItem<CompilerComment>(this, buf);
- this->addItem(item);
-}
-
-// ============================================================================
-// [AsmJit::Compiler - Embed]
-// ============================================================================
-
-void Compiler::embed(const void *data, size_t len)
-{
- // Align length to 16 bytes.
- size_t alignedSize = IntUtil::align(len, sizeof(uintptr_t));
- void *p = this->_zoneMemory.alloc(sizeof(CompilerEmbed) - sizeof(void *) + alignedSize);
-
- if (!p)
- return;
-
- CompilerEmbed *item = new(p) CompilerEmbed(this, data, len);
- this->addItem(item);
-}
-
-} // AsmJit namespace
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/compiler.h
+++ /dev/null
@@ -1,333 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/assembler.h"
-#include "../core/context.h"
-#include "../core/func.h"
-#include "../core/operand.h"
-#include "../core/podvector.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
-struct CompilerContext;
-struct CompilerFuncDecl;
-struct CompilerFuncEnd;
-struct CompilerInst;
-struct CompilerItem;
-struct CompilerTarget;
-
-// ============================================================================
-// [AsmJit::CompilerState]
-// ============================================================================
-
-//! @brief Compiler state base.
-struct CompilerState
-{
-};
-
-// ============================================================================
-// [AsmJit::CompilerVar]
-// ============================================================================
-
-//! @brief Compiler variable base.
-struct CompilerVar
-{
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get variable name.
- const char *getName() const { return this->_name; }
- //! @brief Get variable id.
- uint32_t getId() const { return this->_id; }
-
- //! @brief Get variable type.
- uint32_t getType() const { return this->_type; }
- //! @brief Get variable class.
- uint32_t getClass() const { return this->_class; }
- //! @brief Get variable priority.
- uint32_t getPriority() const { return this->_priority; }
- //! @brief Get variable size.
- uint32_t getSize() const { return this->_size; }
-
- //! @brief Get whether the variable is a function argument.
- bool isArgument() const { return !!(this->_isRegArgument | this->_isMemArgument); }
- //! @brief Get whether the variable is a function argument passed through register.
- bool isRegArgument() const { return !!this->_isRegArgument; }
- //! @brief Get whether the variable is a function argument passed through memory.
- bool isMemArgument() const { return !!this->_isMemArgument; }
-
- //! @brief Get variable content can be calculated by a simple instruction.
- bool isCalculated() const { return !!this->_isCalculated; }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Variable name.
- const char *_name;
- //! @brief Variable id.
- uint32_t _id;
-
- //! @brief Variable type.
- uint8_t _type;
- //! @brief Variable class.
- uint8_t _class;
- //! @brief Variable priority.
- uint8_t _priority;
-
- //! @brief Whether the variable is a function argument passed through register.
- uint8_t _isRegArgument : 1;
- //! @brief Whether the variable is a function argument passed through memory.
- uint8_t _isMemArgument : 1;
- //! @brief Whether variable content can be calculated by a simple instruction.
- //!
- //! This is used mainly by MMX and SSE2 code. This flag indicates that
- //! register allocator should never reserve memory for this variable, because
- //! the content can be generated by a single instruction (for example PXOR).
- uint8_t _isCalculated : 1;
- //! @internal.
- uint8_t _unused : 5;
-
- //! @brief Variable size.
- uint32_t _size;
-};
-
-// ============================================================================
-// [AsmJit::Compiler]
-// ============================================================================
-
-//! @brief Compiler.
-//!
-//! @sa @ref Assembler.
-struct Compiler
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref Compiler instance.
- ASMJIT_API Compiler(Context *context);
- //! @brief Destroy the @ref Compiler instance.
- ASMJIT_API virtual ~Compiler();
-
- // --------------------------------------------------------------------------
- // [Context]
- // --------------------------------------------------------------------------
-
- //! @brief Get code generator.
- Context *getContext() const { return this->_context; }
-
- // --------------------------------------------------------------------------
- // [Memory Management]
- // --------------------------------------------------------------------------
-
- //! @brief Get zone memory manager.
- ZoneMemory &getZoneMemory() { return this->_zoneMemory; }
-
- //! @brief Get link memory manager.
- ZoneMemory &getLinkMemory() { return this->_linkMemory; }
-
- // --------------------------------------------------------------------------
- // [Logging]
- // --------------------------------------------------------------------------
-
- //! @brief Get logger.
- Logger *getLogger() const { return this->_logger; }
-
- //! @brief Set logger to @a logger.
- ASMJIT_API virtual void setLogger(Logger *logger);
-
- // --------------------------------------------------------------------------
- // [Error Handling]
- // --------------------------------------------------------------------------
-
- //! @brief Get error code.
- uint32_t getError() const { return this->_error; }
-
- //! @brief Set error code.
- //!
- //! This method is virtual, because higher classes can use it to catch all
- //! errors.
- ASMJIT_API virtual void setError(uint32_t error);
-
- // --------------------------------------------------------------------------
- // [Properties]
- // --------------------------------------------------------------------------
-
- //! @brief Get compiler property.
- ASMJIT_API virtual uint32_t getProperty(uint32_t propertyId);
- //! @brief Set compiler property.
- ASMJIT_API virtual void setProperty(uint32_t propertyId, uint32_t value);
-
- // --------------------------------------------------------------------------
- // [Clear / Reset]
- // --------------------------------------------------------------------------
-
- //! @brief Clear everything, but not deallocate buffers.
- //!
- //! @note This method will destroy your code.
- ASMJIT_API void clear();
-
- //! @brief Free internal buffer, all emitters and NULL all pointers.
- //!
- //! @note This method will destroy your code.
- ASMJIT_API void reset();
-
- //! @brief Called by clear() and reset() to clear all data related to derived
- //! class implementation.
- ASMJIT_API virtual void _purge();
-
- // --------------------------------------------------------------------------
- // [Item Management]
- // --------------------------------------------------------------------------
-
- //! @brief Get first item.
- CompilerItem *getFirstItem() const { return this->_first; }
-
- //! @brief Get last item.
- CompilerItem *getLastItem() const { return this->_last; }
-
- //! @brief Get current item.
- //!
- //! @note If this method returns @c NULL it means that nothing has been
- //! emitted yet.
- CompilerItem *getCurrentItem() const { return this->_current; }
-
- //! @brief Get current function.
- CompilerFuncDecl *getFunc() const { return this->_func; }
-
- //! @brief Set current item to @a item and return the previous current one.
- ASMJIT_API CompilerItem *setCurrentItem(CompilerItem *item);
-
- //! @brief Add item after current item to @a item and set current item to
- //! @a item.
- ASMJIT_API void addItem(CompilerItem *item);
-
- //! @brief Add item after @a ref.
- ASMJIT_API void addItemAfter(CompilerItem *item, CompilerItem *ref);
-
- //! @brief Remove item @a item.
- ASMJIT_API void removeItem(CompilerItem *item);
-
- // --------------------------------------------------------------------------
- // [Comment]
- // --------------------------------------------------------------------------
-
- //! @brief Emit a single comment line.
- //!
- //! @note Comment is not directly sent to logger, but instead it's stored as
- //! @ref CompilerComment item emitted when @c serialize() method is called.
- ASMJIT_API void comment(const char *fmt, ...);
-
- // --------------------------------------------------------------------------
- // [Embed]
- // --------------------------------------------------------------------------
-
- //! @brief Embed data.
- ASMJIT_API void embed(const void *data, size_t len);
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief ZoneMemory allocator, used to allocate compiler items.
- ZoneMemory _zoneMemory;
- //! @brief ZoneMemory allocator, used to alloc small data structures like
- //! linked lists.
- ZoneMemory _linkMemory;
-
- //! @brief Context.
- Context *_context;
- //! @brief Logger.
- Logger *_logger;
-
- //! @brief Error code.
- uint32_t _error;
- //! @brief Properties.
- uint32_t _properties;
- //! @brief Contains options for next emitted instruction, clear after each emit.
- uint32_t _emitOptions;
- //! @brief Whether compiler was finished the job (register allocator, etc...).
- uint32_t _finished;
-
- //! @brief First item.
- CompilerItem *_first;
- //! @brief Last item.
- CompilerItem *_last;
- //! @brief Current item.
- CompilerItem *_current;
- //! @brief Current function.
- CompilerFuncDecl *_func;
-
- //! @brief Targets.
- PodVector<CompilerTarget *> _targets;
- //! @brief Variables.
- PodVector<CompilerVar *> _vars;
-
- //! @brief Compiler context instance, only available after prepare().
- CompilerContext *_cc;
-
- //! @brief Variable name id (used to generate unique names per function).
- int _varNameId;
-};
-
-// ============================================================================
-// [AsmJit::Compiler - Helpers]
-// ============================================================================
-
-template<typename T, typename Compiler> inline T *Compiler_newItem(Compiler *self)
-{
- void *addr = self->getZoneMemory().alloc(sizeof(T));
- return new(addr) T(self);
-}
-
-template<typename T, typename Compiler, typename P1> inline T *Compiler_newItem(Compiler *self, P1 p1)
-{
- void *addr = self->getZoneMemory().alloc(sizeof(T));
- return new(addr) T(self, p1);
-}
-
-template<typename T, typename Compiler, typename P1, typename P2> inline T *Compiler_newItem(Compiler *self, P1 p1, P2 p2)
-{
- void *addr = self->getZoneMemory().alloc(sizeof(T));
- return new(addr) T(self, p1, p2);
-}
-
-template<typename T, typename Compiler, typename P1, typename P2, typename P3> inline T *Compiler_newItem(Compiler *self, P1 p1, P2 p2, P3 p3)
-{
- void* addr = self->getZoneMemory().alloc(sizeof(T));
- return new(addr) T(self, p1, p2, p3);
-}
-
-template<typename T, typename Compiler, typename P1, typename P2, typename P3, typename P4> inline T *Compiler_newItem(Compiler *self, P1 p1, P2 p2, P3 p3, P4 p4)
-{
- void *addr = self->getZoneMemory().alloc(sizeof(T));
- return new(addr) T(self, p1, p2, p3, p4);
-}
-
-template<typename T, typename Compiler, typename P1, typename P2, typename P3, typename P4, typename P5> inline T *Compiler_newItem(Compiler *self, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
-{
- void *addr = self->getZoneMemory().alloc(sizeof(T));
- return new(addr) T(self, p1, p2, p3, p4, p5);
-}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/compilercontext.cpp
+++ /dev/null
@@ -1,35 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/compilercontext.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::CompilerContext - Construction / Destruction]
-// ============================================================================
-
-CompilerContext::CompilerContext(Compiler *compiler) : _zoneMemory(8192 - sizeof(ZoneChunk) - 32), _compiler(compiler), _func(nullptr), _start(nullptr), _stop(nullptr), _extraBlock(nullptr), _state(nullptr),
- _active(nullptr), _currentOffset(0), _isUnreachable(0)
-{
-}
-
-CompilerContext::~CompilerContext()
-{
-}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/compilercontext.h
+++ /dev/null
@@ -1,83 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/compiler.h"
-#include "../core/compilerfunc.h"
-#include "../core/compileritem.h"
-#include "../core/zonememory.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::CompilerContext]
-// ============================================================================
-
-struct CompilerContext
-{
- ASMJIT_NO_COPY(CompilerContext)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- ASMJIT_API CompilerContext(Compiler *compiler);
- ASMJIT_API virtual ~CompilerContext();
-
- // --------------------------------------------------------------------------
- // [Accessor]
- // --------------------------------------------------------------------------
-
- Compiler *getCompiler() const { return this->_compiler; }
-
- CompilerFuncDecl *getFunc() const { return this->_func; }
-
- CompilerItem *getExtraBlock() const { return this->_extraBlock; }
-
- void setExtraBlock(CompilerItem *item) { this->_extraBlock = item; }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief ZoneMemory manager.
- ZoneMemory _zoneMemory;
-
- //! @brief Compiler.
- Compiler *_compiler;
- //! @brief Function.
- CompilerFuncDecl *_func;
-
- //! @brief Start of the current active scope.
- CompilerItem *_start;
- //! @brief End of the current active scope.
- CompilerItem *_stop;
- //! @brief Item that is used to insert some code after the function body.
- CompilerItem *_extraBlock;
-
- //! @brief Current state (used by register allocator).
- CompilerState *_state;
- //! @brief Link to circular double-linked list containing all active variables
- //! of the current state.
- CompilerVar *_active;
-
- //! @brief Current offset, used in prepare() stage. Each item should increment it.
- uint32_t _currentOffset;
- //! @brief Whether current code is unreachable.
- uint32_t _isUnreachable;
-};
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/compilerfunc.cpp
+++ /dev/null
@@ -1,163 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/assembler.h"
-#include "../core/compiler.h"
-#include "../core/compilerfunc.h"
-#include "../core/compileritem.h"
-#include "../core/intutil.h"
-#include "../core/logger.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit {
-
-// ============================================================================
-// [AsmJit::CompilerFuncDecl - Construction / Destruction]
-// ============================================================================
-
-CompilerFuncDecl::CompilerFuncDecl(Compiler *compiler) : CompilerItem(compiler, kCompilerItemFuncDecl), _entryTarget(nullptr), _exitTarget(nullptr), _end(nullptr), _decl(nullptr), _vars(nullptr), _funcHints(0),
- _funcFlags(0), _funcCallStackSize(0)
-{
-}
-
-CompilerFuncDecl::~CompilerFuncDecl()
-{
-}
-
-// ============================================================================
-// [AsmJit::CompilerFuncDecl - Hints]
-// ============================================================================
-
-void CompilerFuncDecl::setHint(uint32_t hint, uint32_t value)
-{
- if (hint > 31)
- return;
-
- if (value)
- this->_funcHints |= IntUtil::maskFromIndex(hint);
- else
- this->_funcHints &= ~IntUtil::maskFromIndex(hint);
-}
-
-uint32_t CompilerFuncDecl::getHint(uint32_t hint) const
-{
- if (hint > 31)
- return 0;
-
- return !!(this->_funcHints & IntUtil::maskFromIndex(hint));
-}
-
-// ============================================================================
-// [AsmJit::CompilerFuncEnd - Construction / Destruction]
-// ============================================================================
-
-CompilerFuncEnd::CompilerFuncEnd(Compiler *compiler, CompilerFuncDecl *func) : CompilerItem(compiler, kCompilerItemFuncEnd), _func(func)
-{
-}
-
-CompilerFuncEnd::~CompilerFuncEnd()
-{
-}
-
-// ============================================================================
-// [AsmJit::CompilerFuncEnd - Interface]
-// ============================================================================
-
-CompilerItem *CompilerFuncEnd::translate(CompilerContext &cc)
-{
- this->_isTranslated = true;
- return nullptr;
-}
-
-// ============================================================================
-// [AsmJit::CompilerFuncRet - Construction / Destruction]
-// ============================================================================
-
-CompilerFuncRet::CompilerFuncRet(Compiler *compiler, CompilerFuncDecl *func, const Operand *first, const Operand *second) : CompilerItem(compiler, kCompilerItemFuncRet), _func(func)
-{
- if (first)
- this->_ret[0] = *first;
-
- if (second)
- this->_ret[1] = *second;
-}
-
-CompilerFuncRet::~CompilerFuncRet()
-{
-}
-
-// ============================================================================
-// [AsmJit::CompilerFuncRet - Misc]
-// ============================================================================
-
-bool CompilerFuncRet::mustEmitJump() const
-{
- // Iterate over next items until we found an item which emits a real instruction.
- CompilerItem *item = this->getNext();
-
- while (item)
- {
- switch (item->getType())
- {
- // Interesting item.
- case kCompilerItemEmbed:
- case kCompilerItemInst:
- case kCompilerItemFuncCall:
- case kCompilerItemFuncRet:
- return true;
-
- // Non-interesting item.
- case kCompilerItemComment:
- case kCompilerItemMark:
- case kCompilerItemAlign:
- case kCompilerItemHint:
- break;
-
- case kCompilerItemTarget:
- if (static_cast<CompilerTarget *>(item)->getLabel().getId() == this->getFunc()->getExitLabel().getId())
- return false;
- break;
-
- // Invalid items - these items shouldn't be here. We are inside the
- // function, after prolog.
- case kCompilerItemFuncDecl:
- break;
-
- // We can't go forward from here.
- case kCompilerItemFuncEnd:
- return false;
- }
-
- item = item->getNext();
- }
-
- return false;
-}
-
-// ============================================================================
-// [AsmJit::CompilerFuncCall - Construction / Destruction]
-// ============================================================================
-
-CompilerFuncCall::CompilerFuncCall(Compiler *compiler, CompilerFuncDecl *caller, const Operand *target) : CompilerItem(compiler, kCompilerItemFuncCall), _caller(caller), _decl(nullptr), _args(nullptr)
-{
- if (target)
- this->_target = *target;
-}
-
-CompilerFuncCall::~CompilerFuncCall()
-{
-}
-
-} // AsmJit namespace
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/compilerfunc.h
+++ /dev/null
@@ -1,322 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/compiler.h"
-#include "../core/compileritem.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::CompilerFuncDecl]
-// ============================================================================
-
-//! @brief Compiler function declaration item.
-//!
-//! Functions are base blocks for generating assembler output. Each generated
-//! assembler stream needs standard entry and leave sequences thats compatible
-//! with the operating system conventions (ABI).
-//!
-//! Function class can be used to generate function prolog) and epilog sequences
-//! that are compatible with the demanded calling convention and to allocate and
-//! manage variables that can be allocated/spilled during compilation time.
-//!
-//! @note To create a function use @c Compiler::newFunc() method, do not
-//! create any form of compiler function items using new operator.
-//!
-//! @sa @ref CompilerState, @ref CompilerVar.
-struct CompilerFuncDecl : public CompilerItem
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @c CompilerFuncDecl instance.
- //!
- //! @note Always use @c AsmJit::Compiler::newFunc() to create @c Function
- //! instance.
- ASMJIT_API CompilerFuncDecl(Compiler *compiler);
- //! @brief Destroy the @c CompilerFuncDecl instance.
- ASMJIT_API virtual ~CompilerFuncDecl();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get function entry label.
- //!
- //! Entry label can be used to call this function from another code that's
- //! being generated.
- const Label &getEntryLabel() const { return this->_entryLabel; }
-
- //! @brief Get function exit label.
- //!
- //! Use exit label to jump to function epilog.
- const Label &getExitLabel() const { return this->_exitLabel; }
-
- //! @brief Get function entry target.
- CompilerTarget *getEntryTarget() const { return this->_entryTarget; }
-
- //! @brief Get function exit target.
- CompilerTarget *getExitTarget() const { return this->_exitTarget; }
-
- //! @brief Get function end item.
- CompilerFuncEnd *getEnd() const { return this->_end; }
-
- //! @brief Get function declaration.
- FuncDecl *getDecl() const { return this->_decl; }
-
- //! @brief Get function arguments as variables.
- CompilerVar **getVars() const { return this->_vars; }
-
- //! @brief Get function argument at @a index.
- CompilerVar *getVar(uint32_t index) const
- {
- ASMJIT_ASSERT(index < this->_decl->getArgumentsCount());
- return this->_vars[index];
- }
-
- //! @brief Get function hints.
- uint32_t getFuncHints() const { return this->_funcHints; }
-
- //! @brief Get function flags.
- uint32_t getFuncFlags() const { return this->_funcFlags; }
-
- //! @brief Get whether the _funcFlags has @a flag
- bool hasFuncFlag(uint32_t flag) const { return !!(this->_funcFlags & flag); }
-
- //! @brief Set function @a flag.
- void setFuncFlag(uint32_t flag) { this->_funcFlags |= flag; }
-
- //! @brief Clear function @a flag.
- void clearFuncFlag(uint32_t flag) { this->_funcFlags &= ~flag; }
-
- //! @brief Get whether the function is also a caller.
- bool isCaller() const { return this->hasFuncFlag(kFuncFlagIsCaller); }
-
- //! @brief Get whether the function is finished.
- bool isFinished() const { return this->hasFuncFlag(kFuncFlagIsFinished); }
-
- //! @brief Get whether the function is naked.
- bool isNaked() const { return this->hasFuncFlag(kFuncFlagIsNaked); }
-
- //! @brief Get stack size needed to call other functions.
- int32_t getFuncCallStackSize() const { return this->_funcCallStackSize; }
-
- // --------------------------------------------------------------------------
- // [Hints]
- // --------------------------------------------------------------------------
-
- //! @brief Set function hint.
- ASMJIT_API virtual void setHint(uint32_t hint, uint32_t value);
- //! @brief Get function hint.
- ASMJIT_API virtual uint32_t getHint(uint32_t hint) const;
-
- // --------------------------------------------------------------------------
- // [Prototype]
- // --------------------------------------------------------------------------
-
- virtual void setPrototype(uint32_t convention, uint32_t returnType, const uint32_t *arguments, uint32_t argumentsCount) = 0;
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Function entry label.
- Label _entryLabel;
- //! @brief Function exit label.
- Label _exitLabel;
-
- //! @brief Function entry target.
- CompilerTarget *_entryTarget;
- //! @brief Function exit target.
- CompilerTarget *_exitTarget;
-
- //! @brief Function end item.
- CompilerFuncEnd *_end;
-
- //! @brief Function declaration.
- FuncDecl *_decl;
- //! @brief Function arguments as compiler variables.
- CompilerVar **_vars;
-
- //! @brief Function hints;
- uint32_t _funcHints;
- //! @brief Function flags.
- uint32_t _funcFlags;
-
- //! @brief Stack size needed to call other functions.
- int32_t _funcCallStackSize;
-};
-
-// ============================================================================
-// [AsmJit::CompilerFuncEnd]
-// ============================================================================
-
-//! @brief Compiler function end item.
-//!
-//! This item does nothing; it's only used by @ref Compiler to mark specific
-//! location in the code. The @c CompilerFuncEnd is similar to @c CompilerMark,
-//! except that it overrides @c translate() to return @c NULL.
-struct CompilerFuncEnd : public CompilerItem
-{
- ASMJIT_NO_COPY(CompilerFuncEnd)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref CompilerMark instance.
- ASMJIT_API CompilerFuncEnd(Compiler *compiler, CompilerFuncDecl *func);
- //! @brief Destroy the @ref CompilerMark instance.
- ASMJIT_API virtual ~CompilerFuncEnd();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get related function.
- CompilerFuncDecl *getFunc() const { return this->_func; }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual CompilerItem* translate(CompilerContext &cc);
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Related function.
- CompilerFuncDecl *_func;
-};
-
-// ============================================================================
-// [AsmJit::CompilerFuncRet]
-// ============================================================================
-
-//! @brief Compiler return from function item.
-struct CompilerFuncRet : public CompilerItem
-{
- ASMJIT_NO_COPY(CompilerFuncRet)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref CompilerFuncRet instance.
- ASMJIT_API CompilerFuncRet(Compiler *compiler, CompilerFuncDecl *func, const Operand *first, const Operand *second);
- //! @brief Destroy the @ref CompilerFuncRet instance.
- ASMJIT_API virtual ~CompilerFuncRet();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @Brief Get the related function.
- CompilerFuncDecl *getFunc() const { return this->_func; }
-
- //! @brief Get the first return operand.
- Operand &getFirst() { return this->_ret[0]; }
-
- //! @overload
- const Operand &getFirst() const { return this->_ret[0]; }
-
- //! @brief Get the second return operand.
- Operand &getSecond() { return this->_ret[1]; }
-
- //! @overload
- const Operand &getSecond() const { return this->_ret[1]; }
-
- // --------------------------------------------------------------------------
- // [Misc]
- // --------------------------------------------------------------------------
-
- //! @brief Get whether jump to epilog has to be emitted.
- ASMJIT_API bool mustEmitJump() const;
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Related function.
- CompilerFuncDecl *_func;
- //! @brief Return operand(s).
- Operand _ret[2];
-};
-
-// ============================================================================
-// [AsmJit::CompilerFuncCall]
-// ============================================================================
-
-//! @brief Compiler function call item.
-struct CompilerFuncCall : public CompilerItem
-{
- ASMJIT_NO_COPY(CompilerFuncCall)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref CompilerFuncCall instance.
- ASMJIT_API CompilerFuncCall(Compiler *compiler, CompilerFuncDecl *caller, const Operand *target);
- //! @brief Destroy the @ref CompilerFuncCall instance.
- ASMJIT_API virtual ~CompilerFuncCall();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get caller.
- CompilerFuncDecl *getCaller() const { return this->_caller; }
-
- //! @brief Get function declaration.
- FuncDecl *getDecl() const { return this->_decl; }
-
- //! @brief Get target operand.
- Operand &getTarget() { return this->_target; }
-
- //! @overload
- const Operand &getTarget() const { return this->_target; }
-
- // --------------------------------------------------------------------------
- // [Prototype]
- // --------------------------------------------------------------------------
-
- virtual void setPrototype(uint32_t convention, uint32_t returnType, const uint32_t *arguments, uint32_t argumentsCount) = 0;
-
- //! @brief Set function prototype.
- void setPrototype(uint32_t convention, const FuncPrototype &func) { this->setPrototype(convention, func.getReturnType(), func.getArguments(), func.getArgumentsCount()); }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Caller (the function which does the call).
- CompilerFuncDecl *_caller;
- //! @brief Function declaration.
- FuncDecl *_decl;
-
- //! @brief Operand (address of function, register, label, ...).
- Operand _target;
- //! @brief Return operands.
- Operand _ret[2];
- //! @brief Arguments operands.
- Operand *_args;
-};
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/compileritem.cpp
+++ /dev/null
@@ -1,274 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/assembler.h"
-#include "../core/compiler.h"
-#include "../core/compilercontext.h"
-#include "../core/compilerfunc.h"
-#include "../core/compileritem.h"
-#include "../core/intutil.h"
-#include "../core/logger.h"
-
-// [Dependencies - C]
-#include <stdarg.h>
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::CompilerItem - Construction / Destruction]
-// ============================================================================
-
-CompilerItem::CompilerItem(Compiler *compiler, uint32_t type) : _compiler(compiler), _prev(nullptr), _next(nullptr), _comment(nullptr), _type(static_cast<uint8_t>(type)), _isTranslated(false), _isUnreachable(false),
- _reserved(0), _offset(kInvalidValue)
-{
-}
-
-CompilerItem::~CompilerItem()
-{
-}
-
-// ============================================================================
-// [AsmJit::CompilerItem - Interface]
-// ============================================================================
-
-void CompilerItem::prepare(CompilerContext &cc)
-{
- this->_offset = cc._currentOffset;
-}
-
-CompilerItem *CompilerItem::translate(CompilerContext &cc)
-{
- return this->translated();
-}
-
-void CompilerItem::emit(Assembler &a) { }
-void CompilerItem::post(Assembler &a) { }
-
-// ============================================================================
-// [AsmJit::CompilerItem - Misc]
-// ============================================================================
-
-int CompilerItem::getMaxSize() const
-{
- // Default maximum size is -1 which means that it's not known.
- return -1;
-}
-
-bool CompilerItem::_tryUnuseVar(CompilerVar *v)
-{
- return false;
-}
-
-// ============================================================================
-// [AsmJit::CompilerItem - Comment]
-// ============================================================================
-
-void CompilerItem::setComment(const char *str)
-{
- this->_comment = this->_compiler->getZoneMemory().sdup(str);
-}
-
-void CompilerItem::formatComment(const char *fmt, ...)
-{
- // The capacity should be large enough.
- char buf[128];
-
- va_list ap;
- va_start(ap, fmt);
- vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap);
- va_end(ap);
-
- // I don't know if vsnprintf can produce non-null terminated string, in case
- // it can, we terminate it here.
- buf[ASMJIT_ARRAY_SIZE(buf) - 1] = '\0';
-
- this->setComment(buf);
-}
-
-// ============================================================================
-// [AsmJit::CompilerMark - Construction / Destruction]
-// ============================================================================
-
-CompilerMark::CompilerMark(Compiler *compiler) : CompilerItem(compiler, kCompilerItemMark)
-{
-}
-
-CompilerMark::~CompilerMark()
-{
-}
-
-// ============================================================================
-// [AsmJit::CompilerMark - Misc]
-// ============================================================================
-
-int CompilerMark::getMaxSize() const
-{
- return 0;
-}
-
-// ============================================================================
-// [AsmJit::CompilerComment - Construction / Destruction]
-// ============================================================================
-
-CompilerComment::CompilerComment(Compiler *compiler, const char *str) : CompilerItem(compiler, kCompilerItemComment)
-{
- if (str)
- this->setComment(str);
-}
-
-CompilerComment::~CompilerComment()
-{
-}
-
-// ============================================================================
-// [AsmJit::CompilerComment - Interface]
-// ============================================================================
-
-void CompilerComment::emit(Assembler &a)
-{
- Logger *logger = a.getLogger();
- if (!logger || !logger->isUsed())
- return;
-
- logger->logString(logger->getInstructionPrefix());
- logger->logString(this->getComment());
-}
-
-// ============================================================================
-// [AsmJit::CompilerComment - Misc]
-// ============================================================================
-
-int CompilerComment::getMaxSize() const
-{
- return 0;
-}
-
-// ============================================================================
-// [AsmJit::CompilerEmbed - Construction / Destruction]
-// ============================================================================
-
-CompilerEmbed::CompilerEmbed(Compiler *compiler, const void *data, size_t length) : CompilerItem(compiler, kCompilerItemEmbed)
-{
- this->_length = length;
- memcpy(this->_data, data, length);
-}
-
-CompilerEmbed::~CompilerEmbed()
-{
-}
-
-// ============================================================================
-// [AsmJit::CompilerEmbed - Interface]
-// ============================================================================
-
-void CompilerEmbed::emit(Assembler &a)
-{
- a.embed(this->_data, this->_length);
-}
-
-// ============================================================================
-// [AsmJit::CompilerEmbed - Misc]
-// ============================================================================
-
-int CompilerEmbed::getMaxSize() const
-{
- return static_cast<int>(_length);
-}
-
-// ============================================================================
-// [AsmJit::CompilerAlign - Construction / Destruction]
-// ============================================================================
-
-CompilerAlign::CompilerAlign(Compiler *compiler, uint32_t size) : CompilerItem(compiler, kCompilerItemAlign), _size(size)
-{
-}
-
-CompilerAlign::~CompilerAlign()
-{
-}
-
-// ============================================================================
-// [AsmJit::CompilerAlign - Misc]
-// ============================================================================
-
-int CompilerAlign::getMaxSize() const
-{
- if (!this->_size)
- return 0;
- else
- return static_cast<int>(this->_size - 1);
-}
-
-// ============================================================================
-// [AsmJit::CompilerHint - Construction / Destruction]
-// ============================================================================
-
-CompilerHint::CompilerHint(Compiler *compiler, CompilerVar *var, uint32_t hintId, uint32_t hintValue) : CompilerItem(compiler, kCompilerItemHint), _var(var), _hintId(hintId), _hintValue(hintValue)
-{
- ASMJIT_ASSERT(var);
-}
-
-CompilerHint::~CompilerHint()
-{
-}
-
-// ============================================================================
-// [AsmJit::CompilerTarget - Construction / Destruction]
-// ============================================================================
-
-CompilerTarget::CompilerTarget(Compiler *compiler, const Label &label) : CompilerItem(compiler, kCompilerItemTarget), _label(label), _from(nullptr), _state(nullptr), _jumpsCount(0)
-{
-}
-
-CompilerTarget::~CompilerTarget()
-{
-}
-
-// ============================================================================
-// [AsmJit::CompilerTarget - Misc]
-// ============================================================================
-
-int CompilerTarget::getMaxSize() const
-{
- return 0;
-}
-
-// ============================================================================
-// [AsmJit::CompilerInst - Construction / Destruction]
-// ============================================================================
-
-CompilerInst::CompilerInst(Compiler *compiler, uint32_t code, Operand *opData, uint32_t opCount) : CompilerItem(compiler, kCompilerItemInst), _code(code), _emitOptions(static_cast<uint8_t>(compiler->_emitOptions)),
- _instFlags(0), _operandsCount(static_cast<uint8_t>(opCount)), _variablesCount(0), _operands(opData)
-{
- // Each created instruction takes emit options and clears it.
- compiler->_emitOptions = 0;
-}
-
-CompilerInst::~CompilerInst()
-{
-}
-
-// ============================================================================
-// [AsmJit::CompilerInst - GetJumpTarget]
-// ============================================================================
-
-CompilerTarget *CompilerInst::getJumpTarget() const
-{
- return nullptr;
-}
-
-} // AsmJit namespace
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/compileritem.h
+++ /dev/null
@@ -1,513 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/compiler.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::CompilerItem]
-// ============================================================================
-
-//! @brief Compiler item.
-//!
-//! @ref CompilerItem represents items generated by compiler by calling its
-//! methods to build functions, instruction stream, bind labels, etc... Each
-//! item contains its type information and virtual methods which are called at
-//! various compilation steps.
-struct CompilerItem
-{
- ASMJIT_NO_COPY(CompilerItem)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create new @ref CompilerItem.
- //!
- //! @note Always use @ref Compiler to create an item!
- ASMJIT_API CompilerItem(Compiler *compiler, uint32_t type);
-
- //! @brief Destroy @ref CompilerItem.
- //!
- //! @note @ref Compiler keeps links into all items so it can destroy them
- //! when code generation finished or in the case that @ref Compiler was
- //! destroyed early (for example if an error happened). Never destroy items
- //! manually!
- ASMJIT_API virtual ~CompilerItem();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get associated compiler instance.
- Compiler *getCompiler() const { return this->_compiler; }
-
- //! @brief Get previous item in the compiler stream.
- CompilerItem *getPrev() const { return this->_prev; }
-
- //! @brief Get next item in the compiler stream.
- CompilerItem *getNext() const { return this->_next; }
-
- //! @brief Get comment string.
- const char *getComment() const { return this->_comment; }
-
- //! @brief Get type of item, see @ref kCompilerItem.
- uint32_t getType() const { return this->_type; }
-
- //! @brief Get whether the item was translated.
- bool isTranslated() const { return this->_isTranslated; }
-
- //! @brief Get whether the item is unreachable.
- bool isUnreachable() const { return this->_isUnreachable; }
-
- //! @brief Get the item offset in the compiler stream.
- //!
- //! The offset is not byte offset, each item increments offset by 1 and this
- //! value is then used by register allocator. The offset is set by compiler
- //! by the register allocator, don't use it in your code.
- uint32_t getOffset() const { return this->_offset; }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- //! @brief Step 1. Extract item variables, update statistics, ...
- ASMJIT_API virtual void prepare(CompilerContext &cc);
- //! @brief Step 2. Translate instruction, alloc variables, ...
- ASMJIT_API virtual CompilerItem *translate(CompilerContext &cc);
- //! @brief Step 3. Emit to @c Assembler.
- ASMJIT_API virtual void emit(Assembler &a);
- //! @brief Step 4. Last post step (verify, add data, etc).
- ASMJIT_API virtual void post(Assembler &a);
-
- // --------------------------------------------------------------------------
- // [Misc]
- // --------------------------------------------------------------------------
-
- //! @brief Get maximum size of of this when serialized into @ref Assembler
- //! item in bytes.
- ASMJIT_API virtual int getMaxSize() const;
-
- //! @brief Try to unuse the variable @a.
- //!
- //! Returns @c true only if the variable will be unused by the instruction,
- //! otherwise @c false is returned.
- ASMJIT_API virtual bool _tryUnuseVar(CompilerVar *v);
-
- // --------------------------------------------------------------------------
- // [Comment]
- // --------------------------------------------------------------------------
-
- //! @brief Set comment string to @a str.
- ASMJIT_API void setComment(const char *str);
-
- //! @brief Format comment string using @a fmt string and variable argument list.
- ASMJIT_API void formatComment(const char *fmt, ...);
-
- // --------------------------------------------------------------------------
- // [Protected]
- // --------------------------------------------------------------------------
-
-protected:
- //! @brief Mark item as translated and return next.
- CompilerItem *translated()
- {
- ASMJIT_ASSERT(!this->_isTranslated);
-
- this->_isTranslated = true;
- return this->_next;
- }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
-public:
- //! @brief Compiler which owns this item.
- Compiler *_compiler;
- //! @brief Previous item.
- CompilerItem *_prev;
- //! @brief Next item.
- CompilerItem *_next;
- //! @brief Inline comment string, initially set to NULL.
- const char *_comment;
-
- //! @brief Type of the item, see @ref kCompilerItem.
- uint32_t _type : 8;
- //! @brief Whether the item was translated, see @c translate().
- uint32_t _isTranslated : 1;
- //! @brief Whether the item is unreachable.
- uint32_t _isUnreachable : 1;
- //! @brief Reserved for future use.
- uint32_t _reserved : 22;
-
- //! @brief Stream offset (not byte-offset).
- uint32_t _offset;
-};
-
-// ============================================================================
-// [AsmJit::CompilerMark]
-// ============================================================================
-
-//! @brief Compiler mark item.
-//!
-//! This item does nothing and it's only used by @ref Compiler to mark some
-//! specific location in the compiler stream.
-struct CompilerMark : public CompilerItem
-{
- ASMJIT_NO_COPY(CompilerMark)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref CompilerMark instance.
- ASMJIT_API CompilerMark(Compiler *compiler);
- //! @brief Destroy the @ref CompilerMark instance.
- ASMJIT_API virtual ~CompilerMark();
-
- // --------------------------------------------------------------------------
- // [Misc]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual int getMaxSize() const;
-};
-
-// ============================================================================
-// [AsmJit::CompilerComment]
-// ============================================================================
-
-//! @brief Compiler comment item.
-//!
-//! Comments allows to comment your assembler stream for better debugging
-//! and visualization. Comments are usually ignored in release builds unless
-//! the logger is present.
-struct CompilerComment : public CompilerItem
-{
- ASMJIT_NO_COPY(CompilerComment)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref CompilerComment instance.
- ASMJIT_API CompilerComment(Compiler *compiler, const char *comment = nullptr);
- //! @brief Destroy the @ref CompilerComment instance.
- ASMJIT_API virtual ~CompilerComment();
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void emit(Assembler &a);
-
- // --------------------------------------------------------------------------
- // [Misc]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual int getMaxSize() const;
-};
-
-// ============================================================================
-// [AsmJit::CompilerEmbed]
-// ============================================================================
-
-//! @brief Compiler embed item.
-//!
-//! Embed item is used to embed data into final assembler stream. The data is
-//! considered to be RAW, there is no analysis.
-struct CompilerEmbed : public CompilerItem
-{
- ASMJIT_NO_COPY(CompilerEmbed)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref CompilerEmbed instance.
- ASMJIT_API CompilerEmbed(Compiler *compiler, const void *data, size_t length);
- //! @brief Destroy the @ref CompilerEmbed instance.
- ASMJIT_API virtual ~CompilerEmbed();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get pointer to embedded data.
- uint8_t *getData() const { return const_cast<uint8_t *>(this->_data); }
-
- //! @brief Get length of embedded data.
- size_t getLength() const { return this->_length; }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void emit(Assembler &a);
-
- // --------------------------------------------------------------------------
- // [Misc]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual int getMaxSize() const;
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Data length.
- size_t _length;
- //! @brief Data buffer (that will be embedded to the assembler stream).
- uint8_t _data[sizeof(void *)];
-};
-
-// ============================================================================
-// [AsmJit::CompilerAlign]
-// ============================================================================
-
-//! @brief Compiler align item.
-struct CompilerAlign : public CompilerItem
-{
- ASMJIT_NO_COPY(CompilerAlign)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref CompilerAlign instance.
- ASMJIT_API CompilerAlign(Compiler *compiler, uint32_t size = 0);
- //! @brief Destroy the @ref CompilerAlign instance.
- ASMJIT_API virtual ~CompilerAlign();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get align size in bytes.
- uint32_t getSize() const { return this->_size; }
-
- //! @brief Set align size in bytes to @a size.
- void setSize(uint32_t size) { this->_size = size; }
-
- // --------------------------------------------------------------------------
- // [Misc]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual int getMaxSize() const;
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Align size.
- uint32_t _size;
-};
-
-// ============================================================================
-// [AsmJit::CompilerHint]
-// ============================================================================
-
-//! @brief Compiler variable hint item.
-struct CompilerHint : public CompilerItem
-{
- ASMJIT_NO_COPY(CompilerHint)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref CompilerHint instance.
- ASMJIT_API CompilerHint(Compiler *compiler, CompilerVar *var, uint32_t hintId, uint32_t hintValue);
- //! @brief Destroy the @ref CompilerHint instance.
- ASMJIT_API virtual ~CompilerHint();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get variable.
- CompilerVar *getVar() const { return this->_var; }
-
- //! @brief Get hint it (see @ref kVarHint).
- uint32_t getHintId() const { return this->_hintId; }
-
- //! @brief Set hint it (see @ref kVarHint).
- void setHintId(uint32_t hintId) { this->_hintId = hintId; }
-
- //! @brief Get hint value.
- uint32_t getHintValue() const { return this->_hintValue; }
-
- //! @brief Set hint value.
- void setHintValue(uint32_t hintValue) { this->_hintValue = hintValue; }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Variable.
- CompilerVar *_var;
- //! @brief Variable hint id.
- uint32_t _hintId;
- //! @brief Variable hint value.
- uint32_t _hintValue;
-};
-
-// ============================================================================
-// [AsmJit::CompilerTarget]
-// ============================================================================
-
-//! @brief Compiler target item.
-struct CompilerTarget : public CompilerItem
-{
- ASMJIT_NO_COPY(CompilerTarget)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref CompilerTarget instance.
- ASMJIT_API CompilerTarget(Compiler *compiler, const Label &target);
- //! @brief Destroy the @ref CompilerTarget instance.
- ASMJIT_API virtual ~CompilerTarget();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Return label bound to this target.
- const Label &getLabel() const { return this->_label; }
-
- //! @brief Get first jmp instruction.
- CompilerInst *getFrom() const { return this->_from; }
-
- //! @brief Get register allocator state for this target.
- CompilerState *getState() const { return this->_state; }
-
- //! @brief Get number of jumps to this target.
- uint32_t getJumpsCount() const { return this->_jumpsCount; }
-
- // --------------------------------------------------------------------------
- // [Misc]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual int getMaxSize() const;
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Label.
- Label _label;
- //! @brief First jump instruction that points to this target (label).
- CompilerInst *_from;
- //! @brief State at this location.
- CompilerState *_state;
- //! @brief Count of jumps here.
- uint32_t _jumpsCount;
-};
-
-// ============================================================================
-// [AsmJit::CompilerInst]
-// ============================================================================
-
-//! @brief Compiler instruction item.
-struct CompilerInst : public CompilerItem
-{
- ASMJIT_NO_COPY(CompilerInst)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref CompilerInst instance.
- ASMJIT_API CompilerInst(Compiler *compiler, uint32_t code, Operand *opData, uint32_t opCount);
- //! @brief Destroy the @ref CompilerInst instance.
- ASMJIT_API virtual ~CompilerInst();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get instruction code, see @c kInstCode.
- uint32_t getCode() const { return this->_code; }
-
- //! @brief Set instruction code to @a code.
- //!
- //! Please do not modify instruction code if you are not know what you are
- //! doing. Incorrect instruction code or operands can raise assertion() at
- //! runtime.
- void setCode(uint32_t code) { this->_code = code; }
-
- //! @brief Get emit options (compiler specific).
- uint32_t getEmitOptions() const { return this->_emitOptions; }
-
- //! @brief Get instruction flags (compiler specific).
- uint32_t getInstFlags() const { return this->_instFlags; }
-
- //! @brief Get whether the instruction has flag @a flag.
- bool hasInstFlag(uint8_t flag) const { return !!(this->_instFlags & flag); }
-
- //! @brief Set instruction @a flag.
- void setInstFlag(uint8_t flag) { this->_instFlags |= flag; }
-
- //! @brief Clear instruction @a flag.
- void clearInstFlag(uint8_t flag) { this->_instFlags &= ~flag; }
-
- //! @brief Get count of operands in operands array.
- uint32_t getOperandsCount() const { return this->_operandsCount; }
-
- //! @brief Get count of variables in variables array.
- uint32_t getVariablesCount() const { return this->_variablesCount; }
-
- //! @brief Get operands array (3 operands total).
- Operand *getOperands() { return this->_operands; }
- //! @brief Get operands array (3 operands total).
- const Operand *getOperands() const { return this->_operands; }
-
- // --------------------------------------------------------------------------
- // [GetJumpTarget]
- // --------------------------------------------------------------------------
-
- //! @brief Get possible jump target.
- //!
- //! If this instruction is conditional or normal jump then return value is
- //! the label location (@ref CompilerTarget), otherwise the return value is
- //! @c NULL.
- ASMJIT_API virtual CompilerTarget *getJumpTarget() const;
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Instruction code, see @c kInstCode.
- uint32_t _code;
-
- //! @brief Emit options.
- uint8_t _emitOptions;
- //! @brief Instruction flags.
- uint8_t _instFlags;
- //! @brief Operands count.
- uint8_t _operandsCount;
- //! @brief Variables count.
- uint8_t _variablesCount;
-
- //! @brief Operands.
- Operand *_operands;
-};
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/context.cpp
+++ /dev/null
@@ -1,92 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/assembler.h"
-#include "../core/context.h"
-#include "../core/defs.h"
-#include "../core/memorymanager.h"
-#include "../core/memorymarker.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::Context - Construction / Destruction]
-// ============================================================================
-
-Context::Context() { }
-Context::~Context() { }
-
-// ============================================================================
-// [AsmJit::JitContext - Construction / Destruction]
-// ============================================================================
-
-JitContext::JitContext() : _memoryManager(nullptr), _memoryMarker(nullptr), _allocType(kMemAllocFreeable)
-{
-}
-
-JitContext::~JitContext()
-{
-}
-
-// ============================================================================
-// [AsmJit::JitContext - Generate]
-// ============================================================================
-
-uint32_t JitContext::generate(void **dest, Assembler *assembler)
-{
- // Disallow empty code generation.
- size_t codeSize = assembler->getCodeSize();
- if (!codeSize)
- {
- *dest = nullptr;
- return kErrorNoFunction;
- }
-
- // Switch to global memory manager if not provided.
- MemoryManager *memmgr = this->getMemoryManager();
-
- if (!memmgr)
- memmgr = MemoryManager::getGlobal();
-
- void *p = memmgr->alloc(codeSize, getAllocType());
- if (!p)
- {
- *dest = nullptr;
- return kErrorNoVirtualMemory;
- }
-
- // Relocate the code.
- size_t relocatedSize = assembler->relocCode(p);
-
- // Return unused memory to MemoryManager.
- if (relocatedSize < codeSize)
- memmgr->shrink(p, relocatedSize);
-
- // Mark memory if MemoryMarker provided.
- if (this->_memoryMarker)
- this->_memoryMarker->mark(p, relocatedSize);
-
- // Return the code.
- *dest = p;
- return kErrorOk;
-}
-
-// ============================================================================
-// [AsmJit::JitContext - GetGlobal]
-// ============================================================================
-
-JitContext *JitContext::getGlobal()
-{
- static JitContext global;
- return &global;
-}
-
-} // AsmJit namespace
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/context.h
+++ /dev/null
@@ -1,136 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/build.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
-struct Assembler;
-struct MemoryManager;
-struct MemoryMarker;
-
-// ============================================================================
-// [AsmJit::Context]
-// ============================================================================
-
-//! @brief Class for changing behavior of code generated by @ref Assembler and
-//! @ref Compiler.
-struct Context
-{
- ASMJIT_NO_COPY(Context)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a @c Context instance.
- ASMJIT_API Context();
- //! @brief Destroy the @c Context instance.
- ASMJIT_API virtual ~Context();
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- //! @brief Allocate memory for code generated in @a assembler and reloc it
- //! to target location.
- //!
- //! This method is universal allowing any pre-process / post-process work
- //! with code generated by @c Assembler or @c Compiler. Because @c Compiler
- //! always uses @c Assembler it's allowed to access only the @c Assembler
- //! instance.
- //!
- //! This method is always last step when using code generation. You can use
- //! it to allocate memory for JIT code, saving code to remote process or a
- //! shared library.
- //!
- //! @retrurn Error value, see @c kError.
- virtual uint32_t generate(void **dest, Assembler *assembler) = 0;
-};
-
-// ============================================================================
-// [AsmJit::JitContext]
-// ============================================================================
-
-struct JitContext : public Context
-{
- ASMJIT_NO_COPY(JitContext)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a @c JitContext instance.
- ASMJIT_API JitContext();
- //! @brief Destroy the @c JitContext instance.
- ASMJIT_API virtual ~JitContext();
-
- // --------------------------------------------------------------------------
- // [Memory Manager and Alloc Type]
- // --------------------------------------------------------------------------
-
- // Note: These members can be ignored by all derived classes. They are here
- // only to privide default implementation. All other implementations (remote
- // code patching or making dynamic loadable libraries/executables) ignore
- // members accessed by these accessors.
-
- //! @brief Get the @c MemoryManager instance.
- MemoryManager *getMemoryManager() const { return this->_memoryManager; }
-
- //! @brief Set the @c MemoryManager instance.
- void setMemoryManager(MemoryManager *memoryManager) { this->_memoryManager = memoryManager; }
-
- //! @brief Get the type of allocation.
- uint32_t getAllocType() const { return this->_allocType; }
-
- //! @brief Set the type of allocation.
- void setAllocType(uint32_t allocType) { this->_allocType = allocType; }
-
- // --------------------------------------------------------------------------
- // [Memory Marker]
- // --------------------------------------------------------------------------
-
- //! @brief Get the @c MemoryMarker instance.
- MemoryMarker *getMemoryMarker() const { return this->_memoryMarker; }
-
- //! @brief Set the @c MemoryMarker instance.
- void setMemoryMarker(MemoryMarker *memoryMarker) { this->_memoryMarker = memoryMarker; }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual uint32_t generate(void **dest, Assembler *assembler);
-
- // --------------------------------------------------------------------------
- // [Statics]
- // --------------------------------------------------------------------------
-
- ASMJIT_API static JitContext *getGlobal();
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Memory manager.
- MemoryManager *_memoryManager;
- //! @brief Memory marker.
- MemoryMarker *_memoryMarker;
-
- //! @brief Type of allocation.
- uint32_t _allocType;
-};
-
-} // AsmJit namespace
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/cpuinfo.cpp
+++ /dev/null
@@ -1,90 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/cpuinfo.h"
-
-#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
-# include "../x86/x86cpuinfo.h"
-#else
-// ?
-#endif // ASMJIT_X86 || ASMJIT_X64
-
-// [Dependencies - Windows]
-#ifdef ASMJIT_WINDOWS
-# include "windowsh_wrapper.h"
-#endif // ASMJIT_WINDOWS
-
-// [Dependencies - Posix]
-#ifdef ASMJIT_POSIX
-# include <errno.h>
-# include <sys/statvfs.h>
-# include <sys/utsname.h>
-# include <unistd.h>
-#endif // ASMJIT_POSIX
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::CpuInfo - DetectNumberOfProcessors]
-// ============================================================================
-
-uint32_t CpuInfo::detectNumberOfProcessors()
-{
-#ifdef ASMJIT_WINDOWS
- SYSTEM_INFO info;
- ::GetSystemInfo(&info);
- return info.dwNumberOfProcessors;
-#elif defined(ASMJIT_POSIX) && defined(_SC_NPROCESSORS_ONLN)
- // It seems that sysconf returns the number of "logical" processors on both
- // mac and linux. So we get the number of "online logical" processors.
- long res = ::sysconf(_SC_NPROCESSORS_ONLN);
- if (res == -1)
- return 1;
-
- return static_cast<uint32_t>(res);
-#else
- return 1;
-#endif
-}
-
-// ============================================================================
-// [AsmJit::CpuInfo - GetGlobal]
-// ============================================================================
-
-#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
-struct InitializedCpuInfo : public X86CpuInfo
-{
- InitializedCpuInfo() : X86CpuInfo()
- {
- x86CpuDetect(this);
- }
-};
-#else
-# error "AsmJit::CpuInfo - Unsupported CPU or compiler."
-#endif // ASMJIT_X86 || ASMJIT_X64
-
-const CpuInfo *CpuInfo::getGlobal()
-{
-#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
- static InitializedCpuInfo cpuInfo;
-#else
-# error "AsmJit::CpuInfo - Unsupported CPU or compiler."
-#endif // ASMJIT_X86 || ASMJIT_X64
- return &cpuInfo;
-}
-
-} // AsmJit
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/cpuinfo.h
+++ /dev/null
@@ -1,107 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/build.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Core
-//! @{
-
-// ============================================================================
-// [AsmJit::CpuInfo]
-// ============================================================================
-
-//! @brief Informations about host cpu.
-struct CpuInfo
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- CpuInfo(uint32_t size = sizeof(CpuInfo)) : _size(size) { }
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get CPU vendor string.
- const char *getVendorString() const { return this->_vendorString; }
- //! @brief Get CPU brand string.
- const char *getBrandString() const { return this->_brandString; }
-
- //! @brief Get CPU vendor ID.
- uint32_t getVendorId() const { return this->_vendorId; }
- //! @brief Get CPU family ID.
- uint32_t getFamily() const { return this->_family; }
- //! @brief Get CPU model ID.
- uint32_t getModel() const { return this->_model; }
- //! @brief Get CPU stepping.
- uint32_t getStepping() const { return this->_stepping; }
- //! @brief Get CPU count.
- uint32_t getNumberOfProcessors() const { return this->_numberOfProcessors; }
- //! @brief Get CPU features.
- uint32_t getFeatures() const { return this->_features; }
- //! @brief Get CPU bugs.
- uint32_t getBugs() const { return this->_bugs; }
-
- //! @brief Get whether CPU has feature @a feature.
- bool hasFeature(uint32_t feature) { return !!(this->_features & feature); }
- //! @brief Get whether CPU has bug @a bug.
- bool hasBug(uint32_t bug) { return !!(this->_bugs & bug); }
-
- // --------------------------------------------------------------------------
- // [Statics]
- // --------------------------------------------------------------------------
-
- //! @brief Detect number of processors.
- ASMJIT_API static uint32_t detectNumberOfProcessors();
-
- //! @brief Get global instance of @ref CpuInfo.
- ASMJIT_API static const CpuInfo *getGlobal();
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Size of CpuInfo structure (in bytes).
- uint32_t _size;
-
- //! @brief Cpu short vendor string.
- char _vendorString[16];
- //! @brief Cpu long vendor string (brand).
- char _brandString[64];
-
- //! @brief Cpu vendor id (see @c AsmJit::CpuInfo::VendorId enum).
- uint32_t _vendorId;
- //! @brief Cpu family ID.
- uint32_t _family;
- //! @brief Cpu model ID.
- uint32_t _model;
- //! @brief Cpu stepping.
- uint32_t _stepping;
- //! @brief Number of processors or cores.
- uint32_t _numberOfProcessors;
- //! @brief Cpu features bitfield, see @c AsmJit::CpuInfo::Feature enum).
- uint32_t _features;
- //! @brief Cpu bugs bitfield, see @c AsmJit::CpuInfo::Bug enum).
- uint32_t _bugs;
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/defs.cpp
+++ /dev/null
@@ -1,59 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/defs.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::getErrorString]
-// ============================================================================
-
-const char *getErrorString(uint32_t error)
-{
- static const char *errorMessage[] =
- {
- "No error",
-
- "No heap memory",
- "No virtual memory",
-
- "Unknown instruction",
- "Illegal instruction",
- "Illegal addressing",
- "Illegal short jump",
-
- "No function defined",
- "Incomplete function",
-
- "Not enough registers",
- "Registers overlap",
-
- "Incompatible argument",
- "Incompatible return value",
-
- "Unknown error"
- };
-
- // Saturate error code to be able to use errorMessage[].
- if (error > kErrorCount)
- error = kErrorCount;
-
- return errorMessage[error];
-}
-
-} // AsmJit
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/defs.h
+++ /dev/null
@@ -1,595 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/build.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Core
-//! @{
-
-// ============================================================================
-// [AsmJit::Global]
-// ============================================================================
-
-enum
-{
- //! @brief Invalid operand identifier.
- kInvalidValue = 0xFFFFFFFFU,
- //! @brief Minimum reserved bytes in @ref Buffer.
- kBufferGrow = 32U
-};
-
-const size_t kInvalidSize = static_cast<size_t>(-1);
-
-// ============================================================================
-// [AsmJit::kStringBuilderOpType]
-// ============================================================================
-
-//! @brief String builder operation.
-enum kStringBuilderOpType
-{
- //! @brief Replace the current content by a given content.
- kStringBuilderOpSet = 0,
- //! @brief Append a given content to the current content.
- kStringBuilderOpAppend = 1
-};
-
-// ============================================================================
-// [AsmJit::kStringBuilderNumType]
-// ============================================================================
-
-enum kStringBuilderNumFlags
-{
- kStringBuilderNumShowSign = 1U,
- kStringBuilderNumShowSpace = 1U << 1,
- kStringBuilderNumAlternate = 1U << 2,
- kStringBuilderNumSigned = 1U << 31
-};
-
-// ============================================================================
-// [AsmJit::kLoggerOption]
-// ============================================================================
-
-enum kLoggerFlag
-{
- //! @brief Whether logger is enabled or disabled.
- //!
- //! Default @c true.
- kLoggerIsEnabled = 0x00000001,
-
- //! @brief Whether logger is enabled and can be used.
- //!
- //! This value can be set by inherited classes to inform @c Logger that
- //! assigned stream (or something that can log output) is invalid. If
- //! @c _used is false it means that there is no logging output and AsmJit
- //! shouldn't use this logger (because all messages will be lost).
- //!
- //! This is designed only to optimize cases that logger exists, but its
- //! configured not to output messages. The API inside Logging and AsmJit
- //! should only check this value when needed. The API outside AsmJit should
- //! check only whether logging is @c _enabled.
- //!
- //! Default @c true.
- kLoggerIsUsed = 0x00000002,
-
- //! @brief Whether to output instructions also in binary form.
- kLoggerOutputBinary = 0x00000010,
- //! @brief Whether to output immediates as hexadecimal numbers.
- kLoggerOutputHexImmediate = 0x00000020,
- //! @brief Whether to output displacements as hexadecimal numbers.
- kLoggerOutputHexDisplacement = 0x00000040
-};
-
-// ============================================================================
-// [AsmJit::kCpu]
-// ============================================================================
-
-//! @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 kCpu
-{
- //! @brief Unknown CPU vendor.
- kCpuUnknown = 0,
-
- //! @brief Intel CPU vendor.
- kCpuIntel = 1,
- //! @brief AMD CPU vendor.
- kCpuAmd = 2,
- //! @brief National Semiconductor CPU vendor (applies also to Cyrix processors).
- kCpuNSM = 3,
- //! @brief Transmeta CPU vendor.
- kCpuTransmeta = 4,
- //! @brief VIA CPU vendor.
- kCpuVia = 5
-};
-
-// ============================================================================
-// [AsmJit::kMemAllocType]
-// ============================================================================
-
-//! @brief Types of allocation used by @c AsmJit::MemoryManager::alloc() method.
-enum kMemAllocType
-{
- //! @brief Allocate memory that can be freed by @c AsmJit::MemoryManager::free()
- //! method.
- kMemAllocFreeable = 0,
- //! @brief Allocate permanent memory that will be never freed.
- kMemAllocPermanent = 1
-};
-
-// ============================================================================
-// [AsmJit::kOperandType]
-// ============================================================================
-
-//! @brief Operand types that can be encoded in @c Op operand.
-enum kOperandType
-{
- //! @brief Operand is none, used only internally (not initialized Operand).
- //!
- //! This operand is not valid.
- kOperandNone = 0x00,
- //! @brief Operand is label.
- kOperandLabel = 0x01,
- //! @brief Operand is register.
- kOperandReg = 0x02,
- //! @brief Operand is variable.
- kOperandVar = 0x04,
- //! @brief Operand is memory.
- kOperandMem = 0x08,
- //! @brief Operand is immediate.
- kOperandImm = 0x10
-};
-
-// ============================================================================
-// [AsmJit::kOperandMemType]
-// ============================================================================
-
-//! @brief Type of memory operand.
-enum kOperandMemType
-{
- //! @brief Operand is combination of register(s) and displacement (native).
- kOperandMemNative = 0,
- //! @brief Operand is label.
- kOperandMemLabel = 1,
- //! @brief Operand is absolute memory location (supported mainly in 32-bit mode)
- kOperandMemAbsolute = 2,
-};
-
-// ============================================================================
-// [AsmJit::kOperandId]
-// ============================================================================
-
-//! @brief Operand ID masks used to determine the operand type.
-enum kOperandId
-{
- //! @brief Operand id type mask (part used for operand type).
- kOperandIdTypeMask = 0xC0000000,
- //! @brief Label operand mark id.
- kOperandIdTypeLabel = 0x40000000,
- //! @brief Variable operand mark id.
- kOperandIdTypeVar = 0x80000000,
-
- //! @brief Operand id value mask (part used for IDs).
- kOperandIdValueMask = 0x3FFFFFFF
-};
-
-// ============================================================================
-// [AsmJit::kRegType / kRegIndex]
-// ============================================================================
-
-enum
-{
- //! @brief Mask for register type.
- kRegTypeMask = 0xFF00,
-
- //! @brief Mask for register code (index).
- kRegIndexMask = 0xFF,
- //! @brief Invalid register index.
- kRegIndexInvalid = 0xFF
-};
-
-// ============================================================================
-// [AsmJit::kCondHint]
-// ============================================================================
-
-//! @brief Condition hint.
-enum kCondHint
-{
- //! @brief No hint.
- kCondHintNone = 0x00,
- //! @brief Condition is likely to be taken.
- kCondHintLikely = 0x01,
- //! @brief Condition is unlikely to be taken.
- kCondHintUnlikely = 0x02
-};
-
-// ============================================================================
-// [AsmJit::kFuncAnonymous]
-// ============================================================================
-
-enum
-{
- //! @brief Maximum allowed arguments per function declaration / call.
- kFuncArgsMax = 32,
- //! @brief Invalid stack offset in function or function parameter.
- kFuncStackInvalid = -1
-};
-
-// ============================================================================
-// [AsmJit::kFuncConv]
-// ============================================================================
-
-enum kFuncConv
-{
- //! @brief Calling convention is invalid (can't be used).
- kFuncConvNone = 0
-};
-
-// ============================================================================
-// [AsmJit::kFuncHint]
-// ============================================================================
-
-//! @brief Function hints.
-enum kFuncHint
-{
- //! @brief Make naked function (without using ebp/erp in prolog / epilog).
- kFuncHintNaked = 0
-};
-
-// ============================================================================
-// [AsmJit::kFuncFlags]
-// ============================================================================
-
-//! @brief Function flags.
-enum kFuncFlags
-{
- //! @brief Whether another function is called from this function.
- //!
- //! If another function is called from this function, it's needed to prepare
- //! stack for it. If this member is true then it's likely that true will be
- //! also @c _isEspAdjusted one.
- kFuncFlagIsCaller = 1U,
-
- //! @brief Whether the function is finished using @c Compiler::endFunc().
- kFuncFlagIsFinished = 1U << 1,
-
- //! @brief Whether the function is using naked (minimal) prolog / epilog.
- kFuncFlagIsNaked = 1U << 2
-};
-
-// ============================================================================
-// [AsmJit::kFuncArgsDirection]
-// ============================================================================
-
-//! @brief Function arguments direction.
-enum kFuncArgsDirection
-{
- //! @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).
- kFuncArgsLTR = 0,
- //! @brief Arguments are passed right ro left
- //!
- //! This is default argument direction in C programming.
- kFuncArgsRTL = 1
-};
-
-// ============================================================================
-// [AsmJit::kInstCode]
-// ============================================================================
-
-enum kInstCode
-{
- //! @brief No instruction.
- kInstNone = 0
-};
-
-// ============================================================================
-// [AsmJit::kVarAllocFlags]
-// ============================================================================
-
-//! @brief Variable alloc mode.
-enum kVarAllocFlags
-{
- //! @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).
- kVarAllocRead = 0x01,
- //! @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.
- kVarAllocWrite = 0x02,
- //! @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.
- kVarAllocReadWrite = 0x03,
-
- //! @brief Variable can be allocated in register.
- kVarAllocRegister = 0x04,
- //! @brief Variable can be allocated only to a special register.
- kVarAllocSpecial = 0x08,
-
- //! @brief Variable can be allocated in memory.
- kVarAllocMem = 0x10,
-
- //! @brief Unuse the variable after use.
- kVarAllocUnuseAfterUse = 0x20
-};
-
-// ============================================================================
-// [AsmJit::kVarHint]
-// ============================================================================
-
-//! @brief Variable hint (used by @ref Compiler).
-//!
-//! @sa @ref Compiler.
-enum kVarHint
-{
- //! @brief Alloc variable.
- kVarHintAlloc = 0,
- //! @brief Spill variable.
- kVarHintSpill = 1,
- //! @brief Save variable if modified.
- kVarHintSave = 2,
- //! @brief Save variable if modified and mark it as unused.
- kVarHintSaveAndUnuse = 3,
- //! @brief Mark variable as unused.
- kVarHintUnuse = 4
-};
-
-// ============================================================================
-// [AsmJit::kVarPolicy]
-// ============================================================================
-
-//! @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 kVarPolicy
-{
- //! @brief Allocate preserved registers first.
- kVarPolicyPreservedFirst = 0,
- //! @brief Allocate preserved registers last (default).
- kVarPolicyPreservedLast = 1
-};
-
-// ============================================================================
-// [AsmJit::kVarState]
-// ============================================================================
-
-//! @brief State of variable.
-//!
-//! @note State of variable is used only during make process and it's not
-//! visible to the developer.
-enum kVarState
-{
- //! @brief Variable is currently not used.
- kVarStateUnused = 0,
- //! @brief Variable is in register.
- //!
- //! Variable is currently allocated in register.
- kVarStateReg = 1,
- //! @brief Variable is in memory location or spilled.
- //!
- //! Variable was spilled from register to memory or variable is used for
- //! memory only storage.
- kVarStateMem = 2
-};
-
-// ============================================================================
-// [AsmJit::kVarType]
-// ============================================================================
-
-enum kVarType
-{
- //! @brief Invalid variable type.
- kVarTypeInvalid = 0xFF
-};
-
-// ============================================================================
-// [AsmJit::kScale]
-// ============================================================================
-
-//! @brief Scale which can be used for addressing (it the target instruction
-//! supports it).
-//!
-//! See @c Op and addressing methods like @c byte_ptr(), @c word_ptr(),
-//! @c dword_ptr(), etc...
-enum kScale
-{
- //! @brief No scale.
- kScaleNone = 0,
- //! @brief Scale 2 times (same as shifting to left by 1).
- kScale2Times = 1,
- //! @brief Scale 4 times (same as shifting to left by 2).
- kScale4Times = 2,
- //! @brief Scale 8 times (same as shifting to left by 3).
- kScale8Times = 3
-};
-
-// ============================================================================
-// [AsmJit::kSize]
-// ============================================================================
-
-//! @brief Size of registers and pointers.
-enum kSize
-{
- //! @brief 1 byte size.
- kSizeByte = 1,
- //! @brief 2 bytes size.
- kSizeWord = 2,
- //! @brief 4 bytes size.
- kSizeDWord = 4,
- //! @brief 8 bytes size.
- kSizeQWord = 8,
- //! @brief 10 bytes size.
- kSizeTWord = 10,
- //! @brief 16 bytes size.
- kSizeDQWord = 16
-};
-
-// ============================================================================
-// [AsmJit::kRelocMode]
-// ============================================================================
-
-enum kRelocMode
-{
- kRelocAbsToAbs = 0,
- kRelocRelToAbs = 1,
- kRelocAbsToRel = 2,
- kRelocTrampoline = 3
-};
-
-// ============================================================================
-// [AsmJit::kCompilerItem]
-// ============================================================================
-
-//! @brief Type of @ref CompilerItem.
-//!
-//! Each @c CompilerItem contains information about its type. Compiler can
-//! optimize instruction stream by analyzing items and each type is hint
-//! for it. The most used/serialized items are instructions
-//! (@c kCompilerItemInst).
-enum kCompilerItem
-{
- //! @brief Invalid item (can't be used).
- kCompilerItemNone = 0,
- //! @brief Item is mark, see @ref CompilerMark.
- kCompilerItemMark,
- //! @brief Item is comment, see @ref CompilerComment.
- kCompilerItemComment,
- //! @brief Item is embedded data, see @ref CompilerEmbed.
- kCompilerItemEmbed,
- //! @brief Item is .align directive, see @ref CompilerAlign.
- kCompilerItemAlign,
- //! @brief Item is variable hint (alloc, spill, use, unuse), see @ref CompilerHint.
- kCompilerItemHint,
- //! @brief Item is instruction, see @ref CompilerInst.
- kCompilerItemInst,
- //! @brief Item is target, see @ref CompilerTarget.
- kCompilerItemTarget,
- //! @brief Item is function call, see @ref CompilerFuncCall.
- kCompilerItemFuncCall,
- //! @brief Item is function declaration, see @ref CompilerFuncDecl.
- kCompilerItemFuncDecl,
- //! @brief Item is an end of the function, see @ref CompilerFuncEnd.
- kCompilerItemFuncEnd,
- //! @brief Item is function return, see @ref CompilerFuncRet.
- kCompilerItemFuncRet
-};
-
-// ============================================================================
-// [AsmJit::kError]
-// ============================================================================
-
-//! @brief Error codes.
-enum kError
-{
- //! @brief No error (success).
- //!
- //! This is default state and state you want.
- kErrorOk = 0,
-
- //! @brief Memory allocation error (@c ASMJIT_MALLOC returned @c NULL).
- kErrorNoHeapMemory = 1,
- //! @brief Virtual memory allocation error (@c VirtualMemory returned @c NULL).
- kErrorNoVirtualMemory = 2,
-
- //! @brief Unknown instruction. This happens only if instruction code is
- //! out of bounds. Shouldn't happen.
- kErrorUnknownInstruction = 3,
- //! @brief Illegal instruction, usually generated by AsmJit::Assembler
- //! class when emitting instruction opcode. If this error is generated the
- //! target buffer is not affected by this invalid instruction.
- //!
- //! You can also get this error code if you are under x64 (64-bit x86) and
- //! you tried to decode instruction using AH, BH, CH or DH register with REX
- //! prefix. These registers can't be accessed if REX prefix is used and AsmJit
- //! didn't check for this situation in intrinsics (@c Compiler takes care of
- //! this and rearrange registers if needed).
- //!
- //! Examples that will raise @c kErrorIllegalInstruction error (a is
- //! @c Assembler instance):
- //!
- //! @code
- //! a.mov(dword_ptr(eax), al); // Invalid address size.
- //! a.mov(byte_ptr(r10), ah); // Undecodable instruction (AH used with r10
- //! // which can be encoded only using REX prefix)
- //! @endcode
- //!
- //! @note In debug mode you get assertion failure instead of setting error
- //! code.
- kErrorIllegalInstruction = 4,
- //! @brief Illegal addressing used (unencodable).
- kErrorIllegalAddressing = 5,
- //! @brief Short jump instruction used, but displacement is out of bounds.
- kErrorIllegalShortJump = 6,
-
- //! @brief No function defined.
- kErrorNoFunction = 7,
- //! @brief Function generation is not finished by using @c Compiler::endFunc()
- //! or something bad happened during generation related to function. This can
- //! be missing compiler item, etc...
- kErrorIncompleteFunction = 8,
-
- //! @brief Compiler can't allocate registers, because all of them are used.
- //!
- //! @note AsmJit is able to spill registers so this error really shouldn't
- //! happen unless all registers have priority 0 (which means never spill).
- kErrorNoRegisters = 9,
- //! @brief Compiler can't allocate one register to multiple destinations.
- //!
- //! This error can only happen using special instructions like cmpxchg8b and
- //! others where there are more destination operands (implicit).
- kErrorOverlappedRegisters = 10,
-
- //! @brief Tried to call function using incompatible argument.
- kErrorIncompatibleArgumentType = 11,
- //! @brief Incompatible return value.
- kErrorIncompatibleReturnType = 12,
-
- //! @brief Count of error codes by AsmJit. Can grow in future.
- kErrorCount
-};
-
-// ============================================================================
-// [AsmJit::API]
-// ============================================================================
-
-//! @brief Translates error code (see @c kError) into text representation.
-ASMJIT_API const char *getErrorString(uint32_t error);
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/func.h
+++ /dev/null
@@ -1,450 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/assert.h"
-#include "../core/defs.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::TypeId]
-// ============================================================================
-
-#ifdef ASMJIT_HAS_PARTIAL_TEMPLATE_SPECIALIZATION
-#define ASMJIT_DECLARE_TYPE_CORE(_PtrId_) \
- template<typename T> struct TypeId \
- { \
- enum \
- { \
- Id = static_cast<int>(::AsmJit::kVarTypeInvalid) \
- }; \
- }; \
- \
- template<typename T> struct TypeId<T *> { enum { Id = _PtrId_ }; }
-#else
-// Code without partial template specialization is a bit complex. We need to
-// determine whether the size of the return value of this function is equal
-// to sizeof(char) or sizeof(void*). Any sizeof() can be used to distinguish
-// between these two, but these are commonly used in other libraries as well.
-template<typename T> char TypeId_NoPtiHelper(T *(*)());
-// And specialization.
-void *TypeId_NoPtiHelper(...);
-
-#define ASMJIT_DECLARE_TYPE_CORE(_PtrId_) \
- template<typename T> struct TypeId \
- { \
- enum \
- { \
- Id = (sizeof(::AsmJit::TypeId_NoPtiHelper((T (*)())0) ) == sizeof(char) ? static_cast<int>(_PtrId_) : static_cast<int>(::AsmJit::kVarTypeInvalid)) \
- }; \
- }
-#endif // ASMJIT_HAS_PARTIAL_TEMPLATE_SPECIALIZATION
-
-//! @brief Declare C/C++ type-id mapped to @c AsmJit::kX86VarType.
-#define ASMJIT_DECLARE_TYPE_ID(_T_, _Id_) template<> struct TypeId<_T_> { enum { Id = _Id_ }; }
-
-// ============================================================================
-// [AsmJit::FuncArg]
-// ============================================================================
-
-//! @brief Function argument translated from @ref FuncPrototype.
-struct FuncArg
-{
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- uint32_t getVarType() const { return this->_varType; }
-
- uint32_t getRegIndex() const { return this->_regIndex; }
-
- bool hasRegIndex() const { return this->_regIndex != kRegIndexInvalid; }
-
- int32_t getStackOffset() const { return static_cast<int32_t>(this->_stackOffset); }
-
- bool hasStackOffset() const { return this->_stackOffset != kFuncStackInvalid; }
-
- //! @brief Get whether the argument is assigned, for private use only.
- bool isAssigned() const { return (this->_regIndex != kRegIndexInvalid) | (this->_stackOffset != kFuncStackInvalid); }
-
- // --------------------------------------------------------------------------
- // [Reset]
- // --------------------------------------------------------------------------
-
- //! @brief Reset the function argument to "unassigned state".
- void reset() { this->_packed = 0xFFFFFFFF; }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- union
- {
- struct
- {
- //! @brief Variable type, see @c kVarType.
- uint8_t _varType;
- //! @brief Register index is argument is passed through register.
- uint8_t _regIndex;
- //! @brief Stack offset if argument is passed through stack.
- int16_t _stackOffset;
- };
-
- //! @brief All members packed into single 32-bit integer.
- uint32_t _packed;
- };
-};
-
-// ============================================================================
-// [AsmJit::FuncPrototype]
-// ============================================================================
-
-//! @brief Function prototype.
-//!
-//! Function prototype contains information about function return type, count
-//! of arguments and their types. Function definition is low level structure
-//! which doesn't contain platform or calling convention specific information.
-struct FuncPrototype
-{
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get function return value.
- uint32_t getReturnType() const { return this->_returnType; }
-
- //! @brief Get count of function arguments.
- uint32_t getArgumentsCount() const { return this->_argumentsCount; }
-
- //! @brief Get argument at index @a id.
- uint32_t getArgument(uint32_t id) const
- {
- ASMJIT_ASSERT(id < this->_argumentsCount);
- return this->_arguments[id];
- }
-
- //! @brief Get function arguments' IDs.
- const uint32_t *getArguments() const { return this->_arguments; }
-
- //! @brief Set function definition - return type and arguments.
- void _setPrototype(uint32_t returnType, const uint32_t *arguments, uint32_t argumentsCount)
- {
- this->_returnType = returnType;
- this->_arguments = arguments;
- this->_argumentsCount = argumentsCount;
- }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- uint32_t _returnType;
- uint32_t _argumentsCount;
- const uint32_t *_arguments;
-};
-
-// ============================================================================
-// [AsmJit::FuncDecl]
-// ============================================================================
-
-//! @brief Function declaration.
-struct FuncDecl
-{
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get function return value or @ref kInvalidValue if it's void.
- uint32_t getReturnType() const { return this->_returnType; }
-
- //! @brief Get count of function arguments.
- uint32_t getArgumentsCount() const { return this->_argumentsCount; }
-
- //! @brief Get function arguments array.
- FuncArg *getArguments() { return this->_arguments; }
-
- //! @brief Get function arguments array (const).
- const FuncArg *getArguments() const { return this->_arguments; }
-
- //! @brief Get function argument at index @a index.
- FuncArg &getArgument(size_t index)
- {
- ASMJIT_ASSERT(index < static_cast<size_t>(this->_argumentsCount));
- return this->_arguments[index];
- }
-
- //! @brief Get function argument at index @a index.
- const FuncArg &getArgument(size_t index) const
- {
- ASMJIT_ASSERT(index < static_cast<size_t>(this->_argumentsCount));
- return this->_arguments[index];
- }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Function return type.
- uint8_t _returnType;
- //! @brief Count of arguments (in @c _argumentsList).
- uint8_t _argumentsCount;
- //! @brief Reserved for future use (alignment).
- uint8_t _reserved0[2];
-
- //! @brief Function arguments array.
- FuncArg _arguments[kFuncArgsMax];
-};
-
-// ============================================================================
-// [AsmJit::FuncBuilderX]
-// ============================================================================
-
-//! @brief Custom function builder for up to 32 function arguments.
-struct FuncBuilderX : public FuncPrototype
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- FuncBuilderX() { this->_setPrototype(kVarTypeInvalid, this->_argumentsData, 0); }
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- template<typename T> void setReturnTypeT() { this->setReturnTypeRaw(TypeId<ASMJIT_TYPE_TO_TYPE(T)>::Id); }
-
- template<typename T> void setArgumentT(uint32_t id) { this->setArgumentRaw(id, TypeId<ASMJIT_TYPE_TO_TYPE(T)>::Id); }
-
- template<typename T> void addArgumentT() { this->addArgumentRaw(TypeId<ASMJIT_TYPE_TO_TYPE(T)>::Id); }
-
- void setReturnTypeRaw(uint32_t returnType) { this->_returnType = returnType; }
-
- void setArgumentRaw(uint32_t id, uint32_t type)
- {
- ASMJIT_ASSERT(id < this->_argumentsCount);
- this->_argumentsData[id] = type;
- }
-
- void addArgumentRaw(uint32_t type)
- {
- ASMJIT_ASSERT(this->_argumentsCount < kFuncArgsMax);
- this->_argumentsData[this->_argumentsCount++] = type;
- }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- uint32_t _argumentsData[kFuncArgsMax];
-};
-
-//! @brief Class used to build function without arguments.
-template<typename RET> struct FuncBuilder0 : public FuncPrototype
-{
- FuncBuilder0()
- {
- this->_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, nullptr, 0);
- }
-};
-
-//! @brief Class used to build function with 1 argument.
-template<typename RET, typename P0> struct FuncBuilder1 : public FuncPrototype
-{
- FuncBuilder1()
- {
- static const uint32_t arguments[] =
- {
- TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id
- };
-
- this->_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
- }
-};
-
-//! @brief Class used to build function with 2 arguments.
-template<typename RET, typename P0, typename P1> struct FuncBuilder2 : public FuncPrototype
-{
- FuncBuilder2()
- {
- static const uint32_t arguments[] =
- {
- TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id
- };
-
- this->_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
- }
-};
-
-//! @brief Class used to build function with 3 arguments.
-template<typename RET, typename P0, typename P1, typename P2> struct FuncBuilder3 : public FuncPrototype
-{
- FuncBuilder3()
- {
- static const uint32_t arguments[] =
- {
- TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id
- };
-
- this->_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
- }
-};
-
-//! @brief Class used to build function with 4 arguments.
-template<typename RET, typename P0, typename P1, typename P2, typename P3> struct FuncBuilder4 : public FuncPrototype
-{
- FuncBuilder4()
- {
- static const uint32_t arguments[] =
- {
- TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id
- };
-
- this->_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
- }
-};
-
-//! @brief Class used to build function with 5 arguments.
-template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4> struct FuncBuilder5 : public FuncPrototype
-{
- FuncBuilder5()
- {
- static const uint32_t arguments[] =
- {
- TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P4)>::Id
- };
-
- this->_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
- }
-};
-
-//! @brief Class used to build function with 6 arguments.
-template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5> struct FuncBuilder6 : public FuncPrototype
-{
- FuncBuilder6()
- {
- static const uint32_t arguments[] =
- {
- TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P4)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P5)>::Id
- };
-
- this->_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
- }
-};
-
-//! @brief Class used to build function with 7 arguments.
-template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> struct FuncBuilder7 : public FuncPrototype
-{
- FuncBuilder7()
- {
- static const uint32_t arguments[] =
- {
- TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P4)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P5)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P6)>::Id
- };
-
- this->_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
- }
-};
-
-//! @brief Class used to build function with 8 arguments.
-template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7> struct FuncBuilder8 : public FuncPrototype
-{
- FuncBuilder8()
- {
- static const uint32_t arguments[] =
- {
- TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P4)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P5)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P6)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P7)>::Id
- };
-
- this->_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
- }
-};
-
-//! @brief Class used to build function with 9 arguments.
-template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8> struct FuncBuilder9 : public FuncPrototype
-{
- FuncBuilder9()
- {
- static const uint32_t arguments[] =
- {
- TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P4)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P5)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P6)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P7)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P8)>::Id
- };
-
- this->_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
- }
-};
-
-//! @brief Class used to build function with 10 arguments.
-template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9> struct FuncBuilder10 : public FuncPrototype
-{
- FuncBuilder10()
- {
- static const uint32_t arguments[] =
- {
- TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P4)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P5)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P6)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P7)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P8)>::Id,
- TypeId<ASMJIT_TYPE_TO_TYPE(P9)>::Id
- };
-
- this->_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
- }
-};
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/intutil.h
+++ /dev/null
@@ -1,252 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/assert.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Core
-//! @{
-
-// ============================================================================
-// [AsmJit::I32FPUnion]
-// ============================================================================
-
-//! @internal
-//!
-//! @brief used to cast from float to 32-bit integer and vica versa.
-union I32FPUnion
-{
- //! @brief 32-bit signed integer value.
- int32_t i;
- //! @brief 32-bit SP-FP value.
- float f;
-};
-
-// ============================================================================
-// [AsmJit::I64FPUnion]
-// ============================================================================
-
-//! @internal
-//!
-//! @brief used to cast from double to 64-bit integer and vica versa.
-union I64FPUnion
-{
- //! @brief 64-bit signed integer value.
- int64_t i;
- //! @brief 64-bit DP-FP value.
- double f;
-};
-
-// ============================================================================
-// [AsmJit::IntUtil]
-// ============================================================================
-
-namespace IntUtil
-{
- // --------------------------------------------------------------------------
- // [Min/Max]
- // --------------------------------------------------------------------------
-
- // NOTE: Because some environments declare min() and max() as macros, we
- // decided to use different name so we never collide.
-
- template<typename T> inline T _min(const T &a, const T &b) { return a < b ? a : b; }
- template<typename T> inline T _max(const T &a, const T &b) { return a > b ? a : b; }
-
- // --------------------------------------------------------------------------
- // [Limits]
- // --------------------------------------------------------------------------
-
- template<typename T> inline T maxValue() { return ~T(0); }
-
- // --------------------------------------------------------------------------
- // [IsInt / IsUInt]
- // --------------------------------------------------------------------------
-
- //! @brief Returns @c true if a given integer @a x is signed 8-bit integer
- inline bool isInt8(intptr_t x) { return x >= -128 && x <= 127; }
- //! @brief Returns @c true if a given integer @a x is unsigned 8-bit integer
- inline bool isUInt8(intptr_t x) { return x >= 0 && x <= 255; }
-
- //! @brief Returns @c true if a given integer @a x is signed 16-bit integer
- inline bool isInt16(intptr_t x) { return x >= -32768 && x <= 32767; }
- //! @brief Returns @c true if a given integer @a x is unsigned 16-bit integer
- inline bool isUInt16(intptr_t x) { return x >= 0 && x <= 65535; }
-
- //! @brief Returns @c true if a given integer @a x is signed 16-bit integer
- inline bool isInt32(intptr_t x)
- {
-#ifdef ASMJIT_X86
- 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
- inline bool isUInt32(intptr_t x)
- {
-#ifdef ASMJIT_X86
- return x >= 0;
-#else
- return x >= 0 && x <= ASMJIT_INT64_C(4294967295);
-#endif
- }
-
- // --------------------------------------------------------------------------
- // [Masking]
- // --------------------------------------------------------------------------
-
- inline uint32_t maskFromIndex(uint32_t x)
- {
- ASMJIT_ASSERT(x < 32);
- return 1U << x;
- }
-
- inline uint32_t maskUpToIndex(uint32_t x)
- {
- if (x >= 32)
- return 0xFFFFFFFF;
- else
- return (1U << x) - 1;
- }
-
- // --------------------------------------------------------------------------
- // [Bits]
- // --------------------------------------------------------------------------
-
- // From http://graphics.stanford.edu/~seander/bithacks.html .
- inline uint32_t bitCount(uint32_t x)
- {
- x -= (x >> 1) & 0x55555555U;
- x = (x & 0x33333333U) + ((x >> 2) & 0x33333333U);
- return (((x + (x >> 4)) & 0x0F0F0F0FU) * 0x01010101U) >> 24;
- }
-
- inline uint32_t findFirstBit(uint32_t mask)
- {
- for (uint32_t i = 0; i < sizeof(uint32_t) * 8; ++i, mask >>= 1)
- if (mask & 0x1)
- return i;
-
- // kInvalidValue.
- return 0xFFFFFFFF;
- }
-
- // --------------------------------------------------------------------------
- // [Alignment]
- // --------------------------------------------------------------------------
-
- template<typename T> inline bool isAligned(T base, T alignment)
- {
- return !(base % alignment);
- }
-
- //! @brief Align @a base to @a alignment.
- template<typename T> inline T align(T base, T alignment)
- {
- return (base + (alignment - 1)) & ~(alignment - 1);
- }
-
- //! @brief Get delta required to align @a base to @a alignment.
- template<typename T> inline T delta(T base, T alignment)
- {
- return align(base, alignment) - base;
- }
-
- // --------------------------------------------------------------------------
- // [Round]
- // --------------------------------------------------------------------------
-
- template<typename T> inline T roundUp(T base, T alignment)
- {
- T over = base % alignment;
- return base + (over > 0 ? alignment - over : 0);
- }
-
- template<typename T> inline T roundUpToPowerOf2(T base)
- {
- // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
- // figure 3-3, page 48, where the function is called clp2.
- base -= 1;
-
- // I'm trying to make this portable and MSVC strikes me the warning C4293:
- // "Shift count negative or too big, undefined behavior"
- // Fixing...
-#ifdef _MSC_VER
-# pragma warning(push)
-# pragma warning(disable: 4293)
-#endif // _MSC_VER
-
- base |= base >> 1;
- base |= base >> 2;
- base |= base >> 4;
-
- if (sizeof(T) >= 2)
- base |= base >> 8;
- if (sizeof(T) >= 4)
- base |= base >> 16;
- if (sizeof(T) >= 8)
- base |= base >> 32;
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif // _MSC_VER
-
- return base + 1;
- }
-
- // --------------------------------------------------------------------------
- // [Cast]
- // --------------------------------------------------------------------------
-
- //! @brief Binary cast from 32-bit integer to SP-FP value (@c float).
- inline float int32AsFloat(int32_t i)
- {
- I32FPUnion u;
- u.i = i;
- return u.f;
- }
-
- //! @brief Binary cast SP-FP value (@c float) to 32-bit integer.
- inline int32_t floatAsInt32(float f)
- {
- I32FPUnion u;
- u.f = f;
- return u.i;
- }
-
- //! @brief Binary cast from 64-bit integer to DP-FP value (@c double).
- inline double int64AsDouble(int64_t i)
- {
- I64FPUnion u;
- u.i = i;
- return u.f;
- }
-
- //! @brief Binary cast from DP-FP value (@c double) to 64-bit integer.
- inline int64_t doubleAsInt64(double f)
- {
- I64FPUnion u;
- u.f = f;
- return u.i;
- }
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/lock.h
+++ /dev/null
@@ -1,132 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/build.h"
-
-// [Dependencies - Windows]
-#ifdef ASMJIT_WINDOWS
-# include "windowsh_wrapper.h"
-#endif // ASMJIT_WINDOWS
-
-// [Dependencies - Posix]
-#ifdef ASMJIT_POSIX
-# include <pthread.h>
-#endif // ASMJIT_POSIX
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Core
-//! @{
-
-// ============================================================================
-// [AsmJit::Lock]
-// ============================================================================
-
-//! @brief Lock - used in thread-safe code for locking.
-struct Lock
-{
- ASMJIT_NO_COPY(Lock)
-
- // --------------------------------------------------------------------------
- // [Windows]
- // --------------------------------------------------------------------------
-
-#ifdef ASMJIT_WINDOWS
- typedef CRITICAL_SECTION Handle;
-
- //! @brief Create a new @ref Lock instance.
- Lock() { InitializeCriticalSection(&this->_handle); }
- //! @brief Destroy the @ref Lock instance.
- ~Lock() { DeleteCriticalSection(&this->_handle); }
-
- //! @brief Lock.
- void lock() { EnterCriticalSection(&this->_handle); }
- //! @brief Unlock.
- void unlock() { LeaveCriticalSection(&this->_handle); }
-#endif // ASMJIT_WINDOWS
-
- // --------------------------------------------------------------------------
- // [Posix]
- // --------------------------------------------------------------------------
-
-#ifdef ASMJIT_POSIX
- typedef pthread_mutex_t Handle;
-
- //! @brief Create a new @ref Lock instance.
- Lock() { pthread_mutex_init(&this->_handle, nullptr); }
- //! @brief Destroy the @ref Lock instance.
- ~Lock() { pthread_mutex_destroy(&this->_handle); }
-
- //! @brief Lock.
- void lock() { pthread_mutex_lock(&this->_handle); }
- //! @brief Unlock.
- void unlock() { pthread_mutex_unlock(&this->_handle); }
-#endif // ASMJIT_POSIX
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get handle.
- Handle &getHandle() { return this->_handle; }
- //! @overload
- const Handle &getHandle() const { return this->_handle; }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Handle.
- Handle _handle;
-};
-
-// ============================================================================
-// [AsmJit::AutoLock]
-// ============================================================================
-
-//! @brief Scope auto locker.
-struct AutoLock
-{
- ASMJIT_NO_COPY(AutoLock)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Locks @a target.
- AutoLock(Lock &target) : _target(target)
- {
- this->_target.lock();
- }
-
- //! @brief Unlocks target.
- ~AutoLock()
- {
- this->_target.unlock();
- }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Pointer to target (lock).
- Lock &_target;
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/logger.cpp
+++ /dev/null
@@ -1,195 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/logger.h"
-
-// [Dependencies - C]
-#include <stdarg.h>
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::Logger - Construction / Destruction]
-// ============================================================================
-
-Logger::Logger() : _flags(kLoggerIsEnabled | kLoggerIsUsed)
-{
- memset(this->_instructionPrefix, 0, ASMJIT_ARRAY_SIZE(this->_instructionPrefix));
-}
-
-Logger::~Logger()
-{
-}
-
-// ============================================================================
-// [AsmJit::Logger - Logging]
-// ============================================================================
-
-void Logger::logFormat(const char *fmt, ...)
-{
- char buf[1024];
-
- va_list ap;
- va_start(ap, fmt);
- size_t len = vsnprintf(buf, 1023, fmt, ap);
- va_end(ap);
-
- this->logString(buf, len);
-}
-
-// ============================================================================
-// [AsmJit::Logger - Enabled]
-// ============================================================================
-
-void Logger::setEnabled(bool enabled)
-{
- if (enabled)
- this->_flags |= kLoggerIsEnabled | kLoggerIsUsed;
- else
- this->_flags &= ~(kLoggerIsEnabled | kLoggerIsUsed);
-}
-
-// ============================================================================
-// [AsmJit::Logger - LogBinary]
-// ============================================================================
-
-void Logger::setLogBinary(bool value)
-{
- if (value)
- this->_flags |= kLoggerOutputBinary;
- else
- this->_flags &= ~kLoggerOutputBinary;
-}
-
-// ============================================================================
-// [AsmJit::Logger - HexImmediate]
-// ============================================================================
-
-void Logger::setHexImmediate(bool value)
-{
- if (value)
- this->_flags |= kLoggerOutputHexImmediate;
- else
- this->_flags &= ~kLoggerOutputHexImmediate;
-}
-
-// ============================================================================
-// [AsmJit::Logger - HexDisplacement]
-// ============================================================================
-
-void Logger::setHexDisplacement(bool value)
-{
- if (value)
- this->_flags |= kLoggerOutputHexDisplacement;
- else
- this->_flags &= ~kLoggerOutputHexDisplacement;
-}
-
-// ============================================================================
-// [AsmJit::Logger - InstructionPrefix]
-// ============================================================================
-
-void Logger::setInstructionPrefix(const char *prefix)
-{
- memset(this->_instructionPrefix, 0, ASMJIT_ARRAY_SIZE(this->_instructionPrefix));
-
- if (!prefix)
- return;
-
- size_t length = strnlen(prefix, ASMJIT_ARRAY_SIZE(this->_instructionPrefix) - 1);
- memcpy(this->_instructionPrefix, prefix, length);
-}
-
-// ============================================================================
-// [AsmJit::FileLogger - Construction / Destruction]
-// ============================================================================
-
-FileLogger::FileLogger(FILE *stream) : _stream(nullptr)
-{
- this->setStream(stream);
-}
-
-FileLogger::~FileLogger()
-{
-}
-
-// ============================================================================
-// [AsmJit::FileLogger - Accessors]
-// ============================================================================
-
-//! @brief Set file stream.
-void FileLogger::setStream(FILE *stream)
-{
- this->_stream = stream;
-
- if (this->isEnabled() && this->_stream)
- this->_flags |= kLoggerIsUsed;
- else
- this->_flags &= ~kLoggerIsUsed;
-}
-
-// ============================================================================
-// [AsmJit::FileLogger - Logging]
-// ============================================================================
-
-void FileLogger::logString(const char *buf, size_t len)
-{
- if (!this->isUsed())
- return;
-
- if (len == kInvalidSize)
- len = strlen(buf);
-
- fwrite(buf, 1, len, this->_stream);
-}
-
-// ============================================================================
-// [AsmJit::FileLogger - Enabled]
-// ============================================================================
-
-void FileLogger::setEnabled(bool enabled)
-{
- if (enabled)
- this->_flags |= kLoggerIsEnabled | (this->_stream ? kLoggerIsUsed : 0);
- else
- this->_flags &= ~(kLoggerIsEnabled | kLoggerIsUsed);
-}
-
-// ============================================================================
-// [AsmJit::StringLogger - Construction / Destruction]
-// ============================================================================
-
-StringLogger::StringLogger()
-{
-}
-
-StringLogger::~StringLogger()
-{
-}
-
-// ============================================================================
-// [AsmJit::StringLogger - Logging]
-// ============================================================================
-
-void StringLogger::logString(const char *buf, size_t len)
-{
- if (!this->isUsed())
- return;
- this->_stringBuilder.appendString(buf, len);
-}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/logger.h
+++ /dev/null
@@ -1,241 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/build.h"
-#include "../core/defs.h"
-#include "../core/stringbuilder.h"
-
-// [Dependencies - C]
-#include <cstdarg>
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Logging
-//! @{
-
-// ============================================================================
-// [AsmJit::Logger]
-// ============================================================================
-
-//! @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 Logger
-{
- ASMJIT_NO_COPY(Logger)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create logger.
- ASMJIT_API Logger();
- //! @brief Destroy logger.
- ASMJIT_API virtual ~Logger();
-
- // --------------------------------------------------------------------------
- // [Logging]
- // --------------------------------------------------------------------------
-
- //! @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 logString(const char *buf, size_t len = kInvalidSize) = 0;
-
- //! @brief Log formatter message (like sprintf) sending output to @c logString() method.
- ASMJIT_API virtual void logFormat(const char *fmt, ...);
-
- // --------------------------------------------------------------------------
- // [Flags]
- // --------------------------------------------------------------------------
-
- //! @brief Get logger flags (used internally by Assembler/Compiler).
- uint32_t getFlags() const { return this->_flags; }
-
- // --------------------------------------------------------------------------
- // [Enabled]
- // --------------------------------------------------------------------------
-
- //! @brief Return @c true if logging is enabled.
- bool isEnabled() const { return !!(this->_flags & kLoggerIsEnabled); }
-
- //! @brief Set logging to enabled or disabled.
- ASMJIT_API virtual void setEnabled(bool enabled);
-
- // --------------------------------------------------------------------------
- // [Used]
- // --------------------------------------------------------------------------
-
- //! @brief Get whether the logger should be used.
- bool isUsed() const { return !!(this->_flags & kLoggerIsUsed); }
-
- // --------------------------------------------------------------------------
- // [LogBinary]
- // --------------------------------------------------------------------------
-
- //! @brief Get whether logging of binary output is enabled.
- bool getLogBinary() const { return !!(this->_flags & kLoggerOutputBinary); }
- //! @brief Enable or disable binary output logging.
- ASMJIT_API void setLogBinary(bool value);
-
- // --------------------------------------------------------------------------
- // [HexImmediate]
- // --------------------------------------------------------------------------
-
- bool getHexImmediate() const { return !!(this->_flags & kLoggerOutputHexImmediate); }
- ASMJIT_API void setHexImmediate(bool value);
-
- // --------------------------------------------------------------------------
- // [HexDisplacement]
- // --------------------------------------------------------------------------
-
- bool getHexDisplacement() const { return !!(this->_flags & kLoggerOutputHexDisplacement); }
- ASMJIT_API void setHexDisplacement(bool value);
-
- // --------------------------------------------------------------------------
- // [InstructionPrefix]
- // --------------------------------------------------------------------------
-
- //! @brief Get instruction prefix.
- const char *getInstructionPrefix() const { return this->_instructionPrefix; }
- //! @brief Set instruction prefix.
- ASMJIT_API void setInstructionPrefix(const char *prefix);
- //! @brief Reset instruction prefix.
- void resetInstructionPrefix() { this->setInstructionPrefix(nullptr); }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Flags, see @ref kLoggerFlag.
- uint32_t _flags;
-
- //! @brief Instrictions and macro-instructions prefix.
- char _instructionPrefix[12];
-};
-
-// ============================================================================
-// [AsmJit::FileLogger]
-// ============================================================================
-
-//! @brief Logger that can log to standard C @c FILE* stream.
-struct FileLogger : public Logger
-{
- ASMJIT_NO_COPY(FileLogger)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @c FileLogger.
- //! @param stream FILE stream where logging will be sent (can be @c NULL
- //! to disable logging).
- ASMJIT_API FileLogger(FILE *stream = nullptr);
-
- //! @brief Destroy the @ref FileLogger.
- ASMJIT_API virtual ~FileLogger();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get @c FILE* stream.
- //!
- //! @note Return value can be @c NULL.
- FILE *getStream() const { return this->_stream; }
-
- //! @brief Set @c FILE* stream.
- //!
- //! @param stream @c FILE stream where to log output (can be @c NULL to
- //! disable logging).
- ASMJIT_API void setStream(FILE *stream);
-
- // --------------------------------------------------------------------------
- // [Logging]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void logString(const char *buf, size_t len = kInvalidSize);
-
- // --------------------------------------------------------------------------
- // [Enabled]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void setEnabled(bool enabled);
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief C file stream.
- FILE *_stream;
-};
-
-// ============================================================================
-// [AsmJit::StringLogger]
-// ============================================================================
-
-//! @brief String logger.
-struct StringLogger : public Logger
-{
- ASMJIT_NO_COPY(StringLogger)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create new @ref StringLogger.
- ASMJIT_API StringLogger();
-
- //! @brief Destroy the @ref StringLogger.
- ASMJIT_API virtual ~StringLogger();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get <code>char*</code> pointer which represents the serialized
- //! string.
- //!
- //! The pointer is owned by @ref StringLogger, it can't be modified or freed.
- const char *getString() const { return this->_stringBuilder.getData(); }
-
- //! @brief Clear the serialized string.
- void clearString() { this->_stringBuilder.clear(); }
-
- // --------------------------------------------------------------------------
- // [Logging]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void logString(const char *buf, size_t len = kInvalidSize);
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Output.
- StringBuilder _stringBuilder;
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/memorymanager.cpp
+++ /dev/null
@@ -1,1187 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/assert.h"
-#include "../core/lock.h"
-#include "../core/memorymanager.h"
-#include "../core/virtualmemory.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-// This file contains implementation of virtual memory management for AsmJit
-// library. The initial concept is to keep this implementation simple but
-// efficient. There are several goals I decided to write implementation myself.
-//
-// Goals:
-// - We need usually to allocate blocks of 64 bytes long and more.
-// - Alignment of allocated blocks is large - 32 bytes or 64 bytes.
-// - Keep memory manager information outside allocated virtual memory pages
-// (these pages allows execution of code).
-// - Keep implementation small.
-//
-// I think that implementation is not small and probably not too much readable,
-// so there is small know how.
-//
-// - Implementation is based on bit arrays and binary trees. Bit arrays
-// contains information about allocated and unused blocks of memory. Each
-// block size describes MemNode::density member. Count of blocks are
-// stored in MemNode::blocks member. For example if density is 64 and
-// count of blocks is 20, memory node contains 64*20 bytes of memory and
-// smallest possible allocation (and also alignment) is 64 bytes. So density
-// describes also memory alignment. Binary trees are used to enable fast
-// lookup into all addresses allocated by memory manager instance. This is
-// used mainly in MemoryManagerPrivate::free().
-//
-// Bit array looks like this (empty = unused, X = used) - Size of block 64
-// -------------------------------------------------------------------------
-// | |X|X| | | | | |X|X|X|X|X|X| | | | | | | | | | | | |X| | | | |X|X|X| | |
-// -------------------------------------------------------------------------
-// Bits array shows that there are 12 allocated blocks of 64 bytes, so total
-// allocated size is 768 bytes. Maximum count of continuous blocks is 12
-// (see largest gap).
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [Bits Manipulation]
-// ============================================================================
-
-static const size_t BITS_PER_ENTITY = sizeof(size_t) * 8;
-
-static void _SetBits(size_t *buf, size_t index, size_t len)
-{
- if (!len)
- return;
-
- size_t i = index / BITS_PER_ENTITY; // size_t[]
- size_t j = index % BITS_PER_ENTITY; // size_t[][] bit index
-
- // How many bytes process in the first group.
- size_t c = BITS_PER_ENTITY - j;
- if (c > len)
- c = len;
-
- // Offset.
- buf += i;
-
- *buf++ |= (~static_cast<size_t>(0) >> (BITS_PER_ENTITY - c)) << j;
- len -= c;
-
- while (len >= BITS_PER_ENTITY)
- {
- *buf++ = ~static_cast<size_t>(0);
- len -= BITS_PER_ENTITY;
- }
-
- if (len)
- *buf |= ~static_cast<size_t>(0) >> (BITS_PER_ENTITY - len);
-}
-
-// ============================================================================
-// [AsmJit::MemNode]
-// ============================================================================
-
-template<typename T> static inline T M_DIV(T x, T y) { return x / y; }
-template<typename T> static inline T M_MOD(T x, T y) { return x % y; }
-
-template<typename T> struct RbNode
-{
- // --------------------------------------------------------------------------
- // [Node red-black tree tree, key is mem pointer].
- // --------------------------------------------------------------------------
-
- // Implementation is based on article by Julienne Walker (Public Domain),
- // including C code and original comments. Thanks for the excellent article.
-
- // Left[0] and right[1] nodes.
- T *node[2];
- // Whether the node is RED.
- uint32_t red;
-
- // --------------------------------------------------------------------------
- // [Chunk Memory]
- // --------------------------------------------------------------------------
-
- // Virtual memory address.
- uint8_t *mem;
-};
-
-// Get whether the node is red (NULL or node with red flag).
-template<typename T> static inline bool isRed(RbNode<T> *node)
-{
- return node && node->red;
-}
-
-struct MemNode : public RbNode<MemNode>
-{
- // --------------------------------------------------------------------------
- // [Node double-linked list]
- // --------------------------------------------------------------------------
-
- MemNode *prev; // Prev node in list.
- MemNode *next; // Next node in list.
-
- // --------------------------------------------------------------------------
- // [Chunk Data]
- // --------------------------------------------------------------------------
-
- size_t size; // How many bytes contain this node.
- size_t blocks; // How many blocks are here.
- size_t density; // Minimum count of allocated bytes in this node (also alignment).
- size_t used; // How many bytes are used in this node.
- size_t largestBlock; // Contains largest block that can be allocated.
-
- size_t *baUsed; // Contains bits about used blocks. (0 = unused, 1 = used).
- size_t *baCont; // Contains bits about continuous blocks. (0 = stop, 1 = continue).
-
- // --------------------------------------------------------------------------
- // [Methods]
- // --------------------------------------------------------------------------
-
- // Get available space.
- size_t getAvailable() const { return this->size - this->used; }
-
- void fillData(MemNode *other)
- {
- this->mem = other->mem;
-
- this->size = other->size;
- this->blocks = other->blocks;
- this->density = other->density;
- this->used = other->used;
- this->largestBlock = other->largestBlock;
- this->baUsed = other->baUsed;
- this->baCont = other->baCont;
- }
-};
-
-// ============================================================================
-// [AsmJit::M_Permanent]
-// ============================================================================
-
-//! @brief Permanent node.
-struct PermanentNode
-{
- uint8_t *mem; // Base pointer (virtual memory address).
- size_t size; // Count of bytes allocated.
- size_t used; // Count of bytes used.
- PermanentNode *prev; // Pointer to prev chunk or NULL.
-
- // Get available space.
- size_t getAvailable() const { return this->size - this->used; }
-};
-
-// ============================================================================
-// [AsmJit::MemoryManagerPrivate]
-// ============================================================================
-
-struct MemoryManagerPrivate
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_WINDOWS
- MemoryManagerPrivate();
-#else
- MemoryManagerPrivate(HANDLE hProcess);
-#endif // ASMJIT_WINDOWS
- ~MemoryManagerPrivate();
-
- // --------------------------------------------------------------------------
- // [Allocation]
- // --------------------------------------------------------------------------
-
- MemNode *createNode(size_t size, size_t density);
-
- void *allocPermanent(size_t vsize);
- void *allocFreeable(size_t vsize);
-
- bool free(void *address);
- bool shrink(void *address, size_t used);
- void freeAll(bool keepVirtualMemory);
-
- // Helpers to avoid ifdefs in the code.
- uint8_t *allocVirtualMemory(size_t size, size_t *vsize)
- {
-#ifndef ASMJIT_WINDOWS
- return static_cast<uint8_t *>(VirtualMemory::alloc(size, vsize, true));
-#else
- return static_cast<uint8_t *>(VirtualMemory::allocProcessMemory(this->_hProcess, size, vsize, true));
-#endif
- }
-
- void freeVirtualMemory(void *vmem, size_t vsize)
- {
-#ifndef ASMJIT_WINDOWS
- VirtualMemory::free(vmem, vsize);
-#else
- VirtualMemory::freeProcessMemory(this->_hProcess, vmem, vsize);
-#endif
- }
-
- // --------------------------------------------------------------------------
- // [NodeList RB-Tree]
- // --------------------------------------------------------------------------
-
- bool checkTree();
-
- void insertNode(MemNode *node);
- MemNode *removeNode(MemNode *node);
- MemNode *findPtr(uint8_t *mem);
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
-#ifdef ASMJIT_WINDOWS
- HANDLE _hProcess; // Process where to allocate memory.
-#endif // ASMJIT_WINDOWS
- Lock _lock; // Lock for thread safety.
-
- size_t _newChunkSize; // Default node size.
- size_t _newChunkDensity; // Default node density.
- size_t _allocated; // How many bytes are allocated.
- size_t _used; // How many bytes are used.
-
- // Memory nodes list.
- MemNode *_first;
- MemNode *_last;
- MemNode *_optimal;
-
- // Memory nodes tree.
- MemNode *_root;
-
- // Permanent memory.
- PermanentNode *_permanent;
-
- // Whether to keep virtual memory after destroy.
- bool _keepVirtualMemory;
-};
-
-// ============================================================================
-// [AsmJit::MemoryManagerPrivate - Construction / Destruction]
-// ============================================================================
-
-#ifndef ASMJIT_WINDOWS
-MemoryManagerPrivate::MemoryManagerPrivate() :
-#else
-MemoryManagerPrivate::MemoryManagerPrivate(HANDLE hProcess) : _hProcess(hProcess),
-#endif
- _newChunkSize(65536), _newChunkDensity(64), _allocated(0), _used(0), _root(nullptr), _first(nullptr), _last(nullptr), _optimal(nullptr), _permanent(nullptr), _keepVirtualMemory(false)
-{
-}
-
-MemoryManagerPrivate::~MemoryManagerPrivate()
-{
- // Freeable memory cleanup - Also frees the virtual memory if configured to.
- this->freeAll(this->_keepVirtualMemory);
-
- // Permanent memory cleanup - Never frees the virtual memory.
- PermanentNode *node = this->_permanent;
- while (node)
- {
- PermanentNode *prev = node->prev;
- ASMJIT_FREE(node);
- node = prev;
- }
-}
-
-// ============================================================================
-// [AsmJit::MemoryManagerPrivate - Allocation]
-// ============================================================================
-
-// Allocates virtual memory node and MemNode structure.
-//
-// Returns MemNode* on success, otherwise NULL.
-MemNode *MemoryManagerPrivate::createNode(size_t size, size_t density)
-{
- size_t vsize;
- uint8_t *vmem = this->allocVirtualMemory(size, &vsize);
-
- // Out of memory.
- if (!vmem)
- return nullptr;
-
- size_t blocks = vsize / density;
- size_t bsize = (((blocks + 7) >> 3) + sizeof(size_t) - 1) & ~static_cast<size_t>(sizeof(size_t) - 1);
-
- MemNode *node = reinterpret_cast<MemNode *>(ASMJIT_MALLOC(sizeof(MemNode)));
- uint8_t *data = reinterpret_cast<uint8_t *>(ASMJIT_MALLOC(bsize * 2));
-
- // Out of memory.
- if (!node || !data)
- {
- this->freeVirtualMemory(vmem, vsize);
- if (node)
- ASMJIT_FREE(node);
- if (data)
- ASMJIT_FREE(data);
- return nullptr;
- }
-
- // Initialize RbNode data.
- node->node[0] = nullptr;
- node->node[1] = nullptr;
- node->red = 1;
- node->mem = vmem;
-
- // Initialize MemNode data.
- node->prev = nullptr;
- node->next = nullptr;
-
- node->size = vsize;
- node->blocks = blocks;
- node->density = density;
- node->used = 0;
- node->largestBlock = vsize;
-
- memset(data, 0, bsize * 2);
- node->baUsed = reinterpret_cast<size_t *>(data);
- node->baCont = reinterpret_cast<size_t *>(data + bsize);
-
- return node;
-}
-
-void *MemoryManagerPrivate::allocPermanent(size_t vsize)
-{
- static const size_t permanentAlignment = 32;
- static const size_t permanentNodeSize = 32768;
-
- size_t over = vsize % permanentAlignment;
- if (over)
- over = permanentAlignment - over;
-
- size_t alignedSize = vsize + over;
- AutoLock locked(this->_lock);
-
- PermanentNode *node = this->_permanent;
-
- // Try to find space in allocated chunks.
- while (node && alignedSize > node->getAvailable())
- node = node->prev;
-
- // Or allocate new node.
- if (!node)
- {
- size_t nodeSize = permanentNodeSize;
- if (vsize > nodeSize)
- nodeSize = vsize;
-
- node = static_cast<PermanentNode *>(ASMJIT_MALLOC(sizeof(PermanentNode)));
- // Out of memory.
- if (!node)
- return nullptr;
-
- node->mem = this->allocVirtualMemory(nodeSize, &node->size);
- // Out of memory.
- if (!node->mem)
- {
- ASMJIT_FREE(node);
- return nullptr;
- }
-
- node->used = 0;
- node->prev = this->_permanent;
- this->_permanent = node;
- }
-
- // Finally, copy function code to our space we reserved for.
- uint8_t *result = node->mem + node->used;
-
- // Update Statistics.
- node->used += alignedSize;
- this->_used += alignedSize;
-
- // Code can be null to only reserve space for code.
- return static_cast<void *>(result);
-}
-
-void *MemoryManagerPrivate::allocFreeable(size_t vsize)
-{
- size_t i; // Current index.
- size_t need; // How many we need to be freed.
-
- // Align to 32 bytes (our default alignment).
- vsize = (vsize + 31) & ~static_cast<size_t>(31);
- if (!vsize)
- return nullptr;
-
- AutoLock locked(this->_lock);
- MemNode *node = this->_optimal;
-
- size_t minVSize = this->_newChunkSize;
-
- // Try to find memory block in existing nodes.
- while (node)
- {
- // Skip this node?
- if (node->getAvailable() < vsize || (node->largestBlock < vsize && node->largestBlock))
- {
- MemNode *next = node->next;
- if (node->getAvailable() < minVSize && node == _optimal && next)
- this->_optimal = next;
- node = next;
- continue;
- }
-
- size_t *up = node->baUsed; // Current ubits address.
- size_t ubits; // Current ubits[0] value.
- size_t bit; // Current bit mask.
- size_t blocks = node->blocks; // Count of blocks in node.
- size_t cont = 0; // How many bits are currently freed in find loop.
- size_t maxCont = 0; // Largest continuous block (bits count).
- size_t j;
-
- need = M_DIV(vsize + node->density - 1, node->density);
- i = 0;
-
- // Try to find node that is large enough.
- while (i < blocks)
- {
- ubits = *up++;
-
- // Fast skip used blocks.
- if (ubits == ~static_cast<size_t>(0))
- {
- if (cont > maxCont)
- maxCont = cont;
- cont = 0;
-
- i += BITS_PER_ENTITY;
- continue;
- }
-
- size_t max = BITS_PER_ENTITY;
- if (i + max > blocks)
- max = blocks - i;
-
- for (j = 0, bit = 1; j < max; bit <<= 1)
- {
- ++j;
- if (!(ubits & bit))
- {
- if (++cont == need)
- {
- i += j;
- i -= cont;
- goto _Found;
- }
- continue;
- }
-
- if (cont > maxCont)
- maxCont = cont;
- cont = 0;
- }
-
- i += BITS_PER_ENTITY;
- }
-
- // Because we traversed entire node, we can set largest node size that
- // will be used to cache next traversing..
- node->largestBlock = maxCont * node->density;
-
- node = node->next;
- }
-
- // If we are here, we failed to find existing memory block and we must
- // allocate new.
- size_t chunkSize = this->_newChunkSize;
- if (chunkSize < vsize)
- chunkSize = vsize;
-
- node = this->createNode(chunkSize, this->_newChunkDensity);
- if (!node)
- return nullptr;
-
- // Update binary tree.
- this->insertNode(node);
- ASMJIT_ASSERT(this->checkTree());
-
- // Alloc first node at start.
- i = 0;
- need = (vsize + node->density - 1) / node->density;
-
- // Update statistics.
- this->_allocated += node->size;
-
-_Found:
- // Update bits.
- _SetBits(node->baUsed, i, need);
- _SetBits(node->baCont, i, need - 1);
-
- // Update statistics.
- size_t u = need * node->density;
- node->used += u;
- node->largestBlock = 0;
- this->_used += u;
-
- // And return pointer to allocated memory.
- uint8_t *result = node->mem + i * node->density;
- ASMJIT_ASSERT(result >= node->mem && result <= node->mem + node->size - vsize);
- return result;
-}
-
-bool MemoryManagerPrivate::free(void *address)
-{
- if (!address)
- return true;
-
- AutoLock locked(this->_lock);
-
- MemNode *node = this->findPtr(static_cast<uint8_t *>(address));
- if (!node)
- return false;
-
- size_t offset = static_cast<size_t>(static_cast<uint8_t *>(address) - node->mem);
- size_t bitpos = M_DIV(offset, node->density);
- size_t i = bitpos / BITS_PER_ENTITY;
-
- size_t *up = node->baUsed + i; // Current ubits address.
- size_t *cp = node->baCont + i; // Current cbits address.
- size_t ubits = *up; // Current ubits[0] value.
- size_t cbits = *cp; // Current cbits[0] value.
- size_t bit = static_cast<size_t>(1) << (bitpos % BITS_PER_ENTITY);
-
- size_t cont = 0;
-
- for (;;)
- {
- bool stop = !(cbits & bit);
- ubits &= ~bit;
- cbits &= ~bit;
-
- bit <<= 1;
- ++cont;
-
- if (stop || !bit)
- {
- *up = ubits;
- *cp = cbits;
- if (stop)
- break;
-
- ubits = *++up;
- cbits = *++cp;
- bit = 1;
- }
- }
-
- // If the freed block is fully allocated node then it's needed to
- // update 'optimal' pointer in memory manager.
- if (node->used == node->size)
- {
- MemNode *cur = this->_optimal;
-
- do
- {
- cur = cur->prev;
- if (cur == node)
- {
- this->_optimal = node;
- break;
- }
- } while (cur);
- }
-
- // Statistics.
- cont *= node->density;
- if (node->largestBlock < cont)
- node->largestBlock = cont;
- node->used -= cont;
- this->_used -= cont;
-
- // If page is empty, we can free it.
- if (!node->used)
- {
- // Free memory associated with node (this memory is not accessed
- // anymore so it's safe).
- this->freeVirtualMemory(node->mem, node->size);
- ASMJIT_FREE(node->baUsed);
-
- node->baUsed = nullptr;
- node->baCont = nullptr;
-
- // Statistics.
- this->_allocated -= node->size;
-
- // Remove node. This function can return different node than
- // passed into, but data is copied into previous node if needed.
- ASMJIT_FREE(this->removeNode(node));
- ASMJIT_ASSERT(this->checkTree());
- }
-
- return true;
-}
-
-bool MemoryManagerPrivate::shrink(void *address, size_t used)
-{
- if (!address)
- return false;
- if (!used)
- return free(address);
-
- AutoLock locked(this->_lock);
-
- MemNode *node = this->findPtr(static_cast<uint8_t *>(address));
- if (!node)
- return false;
-
- size_t offset = static_cast<size_t>(static_cast<uint8_t *>(address) - node->mem);
- size_t bitpos = M_DIV(offset, node->density);
- size_t i = bitpos / BITS_PER_ENTITY;
-
- size_t *up = node->baUsed + i; // Current ubits address.
- size_t *cp = node->baCont + i; // Current cbits address.
- size_t ubits = *up; // Current ubits[0] value.
- size_t cbits = *cp; // Current cbits[0] value.
- size_t bit = static_cast<size_t>(1) << (bitpos % BITS_PER_ENTITY);
-
- size_t cont = 0;
- size_t usedBlocks = (used + node->density - 1) / node->density;
-
- bool stop;
- // Find the first block we can mark as free.
- for (;;)
- {
- stop = !(cbits & bit);
- if (stop)
- return true;
-
- if (++cont == usedBlocks)
- break;
-
- bit <<= 1;
- if (!bit)
- {
- ubits = *++up;
- cbits = *++cp;
- bit = 1;
- }
- }
-
- // Free the tail blocks.
- cont = ~static_cast<size_t>(0);
- goto _EnterFreeLoop;
-
- for (;;)
- {
- stop = !(cbits & bit);
- ubits &= ~bit;
- _EnterFreeLoop:
- cbits &= ~bit;
-
- bit <<= 1;
- ++cont;
-
- if (stop || !bit)
- {
- *up = ubits;
- *cp = cbits;
- if (stop)
- break;
-
- ubits = *++up;
- cbits = *++cp;
- bit = 1;
- }
- }
-
- // Statistics.
- cont *= node->density;
- if (node->largestBlock < cont)
- node->largestBlock = cont;
- node->used -= cont;
- this->_used -= cont;
-
- return true;
-}
-
-void MemoryManagerPrivate::freeAll(bool keepVirtualMemory)
-{
- MemNode *node = this->_first;
-
- while (node)
- {
- MemNode *next = node->next;
-
- if (!keepVirtualMemory)
- this->freeVirtualMemory(node->mem, node->size);
-
- ASMJIT_FREE(node->baUsed);
- ASMJIT_FREE(node);
-
- node = next;
- }
-
- this->_allocated = 0;
- this->_used = 0;
-
- this->_root = nullptr;
- this->_first = nullptr;
- this->_last = nullptr;
- this->_optimal = nullptr;
-}
-
-// ============================================================================
-// [AsmJit::MemoryManagerPrivate - NodeList RB-Tree]
-// ============================================================================
-
-static int rbAssert(MemNode *root)
-{
- if (!root)
- return 1;
-
- MemNode *ln = root->node[0];
- MemNode *rn = root->node[1];
-
- // Red violation.
- //ASMJIT_ASSERT(!(isRed(root) && (isRed(ln) || isRed(rn))));
-
- int lh = rbAssert(ln);
- int rh = rbAssert(rn);
-
- // Invalid btree.
- //ASMJIT_ASSERT(ln || ln->mem < root->mem);
- //ASMJIT_ASSERT(rn || rn->mem > root->mem);
-
- // Black violation.
- //ASMJIT_ASSERT(!(lh && rh && lh != rh));
-
- // Only count black links.
- if (lh && rh)
- return isRed(root) ? lh : lh + 1;
- else
- return 0;
-}
-
-static inline MemNode *rbRotateSingle(MemNode *root, int dir)
-{
- MemNode *save = root->node[!dir];
-
- root->node[!dir] = save->node[dir];
- save->node[dir] = root;
-
- root->red = 1;
- save->red = 0;
-
- return save;
-}
-
-static inline MemNode *rbRotateDouble(MemNode *root, int dir)
-{
- root->node[!dir] = rbRotateSingle(root->node[!dir], !dir);
- return rbRotateSingle(root, dir);
-}
-
-bool MemoryManagerPrivate::checkTree()
-{
- return rbAssert(_root) > 0;
-}
-
-void MemoryManagerPrivate::insertNode(MemNode *node)
-{
- if (!this->_root)
- // Empty tree case.
- this->_root = node;
- else
- {
- // False tree root.
- RbNode<MemNode> head = { 0 };
-
- // Grandparent & parent.
- MemNode *g = nullptr;
- MemNode *t = reinterpret_cast<MemNode *>(&head);
-
- // Iterator & parent.
- MemNode *p = nullptr;
- MemNode *q = t->node[1] = this->_root;
-
- int dir = 0, last = 0;
-
- // Search down the tree.
- for (;;)
- {
- if (!q)
- {
- // Insert new node at the bottom.
- q = node;
- p->node[dir] = node;
- }
- else if (isRed(q->node[0]) && isRed(q->node[1]))
- {
- // Color flip.
- q->red = 1;
- q->node[0]->red = 0;
- q->node[1]->red = 0;
- }
-
- // Fix red violation.
- if (isRed(q) && isRed(p))
- {
- int dir2 = t->node[1] == g;
- t->node[dir2] = q == p->node[last] ? rbRotateSingle(g, !last) : rbRotateDouble(g, !last);
- }
-
- // Stop if found.
- if (q == node)
- break;
-
- last = dir;
- dir = q->mem < node->mem;
-
- // Update helpers.
- if (g)
- t = g;
- g = p;
- p = q;
- q = q->node[dir];
- }
-
- // Update root.
- this->_root = head.node[1];
- }
-
- // Make root black.
- this->_root->red = 0;
-
- // Link with others.
- node->prev = this->_last;
-
- if (!this->_first)
- {
- this->_first = node;
- this->_last = node;
- this->_optimal = node;
- }
- else
- {
- node->prev = this->_last;
- this->_last->next = node;
- this->_last = node;
- }
-}
-
-MemNode *MemoryManagerPrivate::removeNode(MemNode *node)
-{
- // False tree root.
- RbNode<MemNode> head = { 0 };
-
- // Helpers.
- MemNode *q = reinterpret_cast<MemNode *>(&head);
- MemNode *p = nullptr;
- MemNode *g = nullptr;
- // Found item.
- MemNode *f = nullptr;
- int dir = 1;
-
- // Set up.
- q->node[1] = this->_root;
-
- // Search and push a red down.
- while (q->node[dir])
- {
- int last = dir;
-
- // Update helpers.
- g = p;
- p = q;
- q = q->node[dir];
- dir = q->mem < node->mem;
-
- // Save found node.
- if (q == node)
- f = q;
-
- // Push the red node down.
- if (!isRed(q) && !isRed(q->node[dir]))
- {
- if (isRed(q->node[!dir]))
- p = p->node[last] = rbRotateSingle(q, dir);
- else if (!isRed(q->node[!dir]))
- {
- MemNode *s = p->node[!last];
-
- if (s)
- {
- if (!isRed(s->node[!last]) && !isRed(s->node[last]))
- {
- // Color flip.
- p->red = 0;
- s->red = 1;
- q->red = 1;
- }
- else
- {
- int dir2 = g->node[1] == p;
-
- if (isRed(s->node[last]))
- g->node[dir2] = rbRotateDouble(p, last);
- else if (isRed(s->node[!last]))
- g->node[dir2] = rbRotateSingle(p, last);
-
- // Ensure correct coloring.
- q->red = g->node[dir2]->red = 1;
- g->node[dir2]->node[0]->red = 0;
- g->node[dir2]->node[1]->red = 0;
- }
- }
- }
- }
- }
-
- // Replace and remove.
- ASMJIT_ASSERT(f);
- ASMJIT_ASSERT(f != reinterpret_cast<MemNode *>(&head));
- ASMJIT_ASSERT(q != reinterpret_cast<MemNode *>(&head));
-
- if (f != q)
- f->fillData(q);
- p->node[p->node[1] == q] = q->node[!q->node[0]];
-
- // Update root and make it black.
- if ((this->_root = head.node[1]))
- this->_root->red = 0;
-
- // Unlink.
- MemNode *next = q->next;
- MemNode *prev = q->prev;
-
- if (prev)
- prev->next = next;
- else
- this->_first = next;
- if (next)
- next->prev = prev;
- else
- this->_last = prev;
- if (this->_optimal == q)
- this->_optimal = prev ? prev : next;
-
- return q;
-}
-
-MemNode *MemoryManagerPrivate::findPtr(uint8_t *mem)
-{
- MemNode *cur = this->_root;
- while (cur)
- {
- uint8_t *curMem = cur->mem;
- if (mem < curMem)
- {
- // Go left.
- cur = cur->node[0];
- continue;
- }
- else
- {
- uint8_t *curEnd = curMem + cur->size;
- if (mem >= curEnd)
- {
- // Go right.
- cur = cur->node[1];
- continue;
- }
- else
- // Match.
- break;
- }
- }
- return cur;
-}
-
-// ============================================================================
-// [AsmJit::MemoryManager]
-// ============================================================================
-
-MemoryManager::MemoryManager()
-{
-}
-
-MemoryManager::~MemoryManager()
-{
-}
-
-MemoryManager *MemoryManager::getGlobal()
-{
- static VirtualMemoryManager memmgr;
- return &memmgr;
-}
-
-// ============================================================================
-// [AsmJit::VirtualMemoryManager]
-// ============================================================================
-
-#ifndef ASMJIT_WINDOWS
-VirtualMemoryManager::VirtualMemoryManager()
-{
- MemoryManagerPrivate *d = new(std::nothrow) MemoryManagerPrivate();
- this->_d = static_cast<void *>(d);
-}
-#else
-VirtualMemoryManager::VirtualMemoryManager()
-{
- MemoryManagerPrivate *d = new(std::nothrow) MemoryManagerPrivate(GetCurrentProcess());
- this->_d = static_cast<void *>(d);
-}
-
-VirtualMemoryManager::VirtualMemoryManager(HANDLE hProcess)
-{
- MemoryManagerPrivate *d = new(std::nothrow) MemoryManagerPrivate(hProcess);
- this->_d = static_cast<void *>(d);
-}
-#endif // ASMJIT_WINDOWS
-
-VirtualMemoryManager::~VirtualMemoryManager()
-{
- MemoryManagerPrivate *d = static_cast<MemoryManagerPrivate *>(this->_d);
- delete d;
-}
-
-void *VirtualMemoryManager::alloc(size_t size, uint32_t type)
-{
- MemoryManagerPrivate *d = static_cast<MemoryManagerPrivate *>(this->_d);
-
- if (type == kMemAllocPermanent)
- return d->allocPermanent(size);
- else
- return d->allocFreeable(size);
-}
-
-bool VirtualMemoryManager::free(void *address)
-{
- MemoryManagerPrivate *d = static_cast<MemoryManagerPrivate *>(this->_d);
- return d->free(address);
-}
-
-bool VirtualMemoryManager::shrink(void *address, size_t used)
-{
- MemoryManagerPrivate *d = static_cast<MemoryManagerPrivate *>(this->_d);
- return d->shrink(address, used);
-}
-
-void VirtualMemoryManager::freeAll()
-{
- MemoryManagerPrivate *d = static_cast<MemoryManagerPrivate *>(this->_d);
-
- // Calling MemoryManager::freeAll() will never keep allocated memory.
- return d->freeAll(false);
-}
-
-size_t VirtualMemoryManager::getUsedBytes()
-{
- MemoryManagerPrivate *d = static_cast<MemoryManagerPrivate *>(this->_d);
- return d->_used;
-}
-
-size_t VirtualMemoryManager::getAllocatedBytes()
-{
- MemoryManagerPrivate *d = static_cast<MemoryManagerPrivate *>(this->_d);
- return d->_allocated;
-}
-
-bool VirtualMemoryManager::getKeepVirtualMemory() const
-{
- MemoryManagerPrivate *d = static_cast<MemoryManagerPrivate *>(this->_d);
- return d->_keepVirtualMemory;
-}
-
-void VirtualMemoryManager::setKeepVirtualMemory(bool keepVirtualMemory)
-{
- MemoryManagerPrivate *d = static_cast<MemoryManagerPrivate *>(this->_d);
- d->_keepVirtualMemory = keepVirtualMemory;
-}
-
-// ============================================================================
-// [AsmJit::VirtualMemoryManager - Debug]
-// ============================================================================
-
-#ifdef ASMJIT_MEMORY_MANAGER_DUMP
-
-struct GraphVizContext
-{
- GraphVizContext();
- ~GraphVizContext();
-
- bool openFile(const char *fileName);
- void closeFile();
-
- void dumpNode(MemNode *node);
- void connect(MemNode *node, MemNode *other, const char *dst);
-
- FILE *file;
-};
-
-GraphVizContext::GraphVizContext() : file(nullptr)
-{
-}
-
-GraphVizContext::~GraphVizContext()
-{
- this->closeFile();
-}
-
-bool GraphVizContext::openFile(const char *fileName)
-{
- this->file = fopen(fileName, "w");
- return !!this->file;
-}
-
-void GraphVizContext::closeFile()
-{
- if (this->file)
- {
- fclose(this->file);
- this->file = nullptr;
- }
-}
-
-void GraphVizContext::dumpNode(MemNode* node)
-{
- fprintf(file, " NODE_%p [shape=record, style=filled, color=%s, label=\"<L>|<C>Mem: %p, Used: %d/%d|<R>\"];\n", node, node->red ? "red" : "gray", node->mem, node->used, node->size);
-
- if (node->node[0])
- this->connect(node, node->node[0], "L");
- if (node->node[1])
- this->connect(node, node->node[1], "R");
-}
-
-void GraphVizContext::connect(MemNode *node, MemNode *other, const char *dst)
-{
- this->dumpNode(other);
-
- fprintf(file, " NODE_%p:%s -> NODE_%p:C", node, dst, other);
- if (other->red)
- fprintf(file, " [style=bold, color=red]");
- fprintf(file, ";\n");
-}
-
-void VirtualMemoryManager::dump(const char *fileName)
-{
- MemoryManagerPrivate *d = static_cast<MemoryManagerPrivate *>(this->_d);
- GraphVizContext ctx;
-
- if (!ctx.openFile(fileName))
- return;
-
- fprintf(ctx.file, "digraph {\n");
- if (d->_root)
- ctx.dumpNode(d->_root);
- fprintf(ctx.file, "}\n");
-}
-#endif // ASMJIT_MEMORY_MANAGER_DUMP
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/memorymanager.h
+++ /dev/null
@@ -1,169 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/build.h"
-#include "../core/defs.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-// [Debug]
-// #define ASMJIT_MEMORY_MANAGER_DUMP
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_MemoryManagement
-//! @{
-
-// ============================================================================
-// [AsmJit::MemoryManager]
-// ============================================================================
-
-//! @brief Virtual memory manager interface.
-//!
-//! This class is pure virtual. You can get default virtual memory manager using
-//! @c getGlobal() method. If you want to create more memory managers with same
-//! functionality as global memory manager use @c VirtualMemoryManager class.
-struct MemoryManager
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create memory manager instance.
- ASMJIT_API MemoryManager();
- //! @brief Destroy memory manager instance, this means also to free all memory
- //! blocks.
- ASMJIT_API virtual ~MemoryManager();
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- //! @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(size_t size, uint32_t type = kMemAllocFreeable) = 0;
- //! @brief Free previously allocated memory at a given @a address.
- virtual bool free(void *address) = 0;
- //! @brief Free some tail memory.
- virtual bool shrink(void *address, size_t used) = 0;
- //! @brief Free all allocated memory.
- virtual void freeAll() = 0;
-
- //! @brief Get how many bytes are currently used.
- virtual size_t getUsedBytes() = 0;
- //! @brief Get how many bytes are currently allocated.
- virtual size_t getAllocatedBytes() = 0;
-
- // --------------------------------------------------------------------------
- // [Statics]
- // --------------------------------------------------------------------------
-
- //! @brief Get global memory manager instance.
- //!
- //! Global instance is instance of @c VirtualMemoryManager class. Global memory
- //! manager is used by default by @ref Assembler::make() and @ref Compiler::make()
- //! methods.
- ASMJIT_API static MemoryManager *getGlobal();
-};
-
-// ============================================================================
-// [AsmJit::VirtualMemoryManager]
-// ============================================================================
-
-//! @brief Reference implementation of memory manager that uses
-//! @ref AsmJit::VirtualMemory class to allocate chunks of virtual memory
-//! and bit arrays to manage it.
-struct VirtualMemoryManager : public MemoryManager
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a @c VirtualMemoryManager instance.
- ASMJIT_API VirtualMemoryManager();
-
-#ifdef ASMJIT_WINDOWS
- //! @brief Create a @c VirtualMemoryManager instance for process @a hProcess.
- //!
- //! This is specialized version of constructor available only for windows and
- //! usable to alloc/free memory of different process.
- ASMJIT_API VirtualMemoryManager(HANDLE hProcess);
-#endif // ASMJIT_WINDOWS
-
- //! @brief Destroy the @c VirtualMemoryManager instance, this means also to
- //! free all blocks.
- ASMJIT_API virtual ~VirtualMemoryManager();
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void *alloc(size_t size, uint32_t type = kMemAllocFreeable);
- ASMJIT_API virtual bool free(void *address);
- ASMJIT_API virtual bool shrink(void *address, size_t used);
- ASMJIT_API virtual void freeAll();
-
- ASMJIT_API virtual size_t getUsedBytes();
- ASMJIT_API virtual size_t getAllocatedBytes();
-
- // --------------------------------------------------------------------------
- // [Virtual Memory Manager Specific]
- // --------------------------------------------------------------------------
-
- //! @brief Get whether to keep allocated memory after memory manager is
- //! destroyed.
- //!
- //! @sa @c setKeepVirtualMemory().
- ASMJIT_API bool getKeepVirtualMemory() const;
-
- //! @brief Set whether to keep allocated memory after memory manager is
- //! destroyed.
- //!
- //! This method is usable when patching code of remote process. You need to
- //! allocate process memory, store generated assembler into it and patch the
- //! method you want to redirect (into your code). This method affects only
- //! VirtualMemoryManager destructor. After destruction all internal
- //! structures are freed, only the process virtual memory remains.
- //!
- //! @note Memory allocated with kMemAllocPermanent is always kept.
- //!
- //! @sa @c getKeepVirtualMemory().
- ASMJIT_API void setKeepVirtualMemory(bool keepVirtualMemory);
-
- // --------------------------------------------------------------------------
- // [Debug]
- // --------------------------------------------------------------------------
-
-#ifdef ASMJIT_MEMORY_MANAGER_DUMP
- //! @brief Dump memory manager tree into file.
- //!
- //! Generated output is using DOT language (from graphviz package).
- ASMJIT_API void dump(const char *fileName);
-#endif // ASMJIT_MEMORY_MANAGER_DUMP
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Pointer to private data hidden from the public API.
- void *_d;
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/memorymarker.h
+++ /dev/null
@@ -1,51 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/build.h"
-#include "../core/defs.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_MemoryManagement
-//! @{
-
-// ============================================================================
-// [AsmJit::MemoryMarker]
-// ============================================================================
-
-//! @brief Virtual memory marker interface.
-struct MemoryMarker
-{
- ASMJIT_NO_COPY(MemoryMarker)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- ASMJIT_API MemoryMarker() { }
- ASMJIT_API virtual ~MemoryMarker() { }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- virtual void mark(const void *ptr, size_t size) = 0;
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/operand.cpp
+++ /dev/null
@@ -1,44 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/operand.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::Operand]
-// ============================================================================
-
-const Operand noOperand;
-
-// ============================================================================
-// [AsmJit::Imm]
-// ============================================================================
-
-//! @brief Create signed immediate value operand.
-Imm imm(sysint_t i)
-{
- return Imm(i, false);
-}
-
-//! @brief Create unsigned immediate value operand.
-Imm uimm(sysuint_t i)
-{
- return Imm((sysint_t)i, true);
-}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/operand.h
+++ /dev/null
@@ -1,522 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/defs.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Core
-//! @{
-
-// ============================================================================
-// [AsmJit::_OperandData]
-// ============================================================================
-
-//! @internal
-//!
-//! @brief Base operand data.
-struct _OpBase
-{
- //! @brief Type of operand, see @c kOperandType.
- uint8_t op;
- //! @brief Size of operand (register, address, immediate, or variable).
- uint8_t size;
- //! @brief Not used.
- uint8_t reserved[2];
-
- //! @brief Operand ID (private variable for @c Assembler and @c Compiler classes).
- //!
- //! @note Uninitialized operand has always zero id.
- uint32_t id;
-};
-
-//! @internal
-//!
-//! @brief Label operand data.
-struct _OpLabel
-{
- //! @brief Type of operand, see @c kOperandType (in this case @c kOperandLabel).
- uint8_t op;
- //! @brief Size of label, currently not used.
- uint8_t size;
- //! @brief Not used.
- uint8_t reserved[2];
-
- //! @brief Operand ID.
- uint32_t id;
-};
-
-//! @internal
-//!
-//! @brief Register operand data.
-struct _OpReg
-{
- //! @brief Type of operand, see @c kOperandType (in this case @c kOperandReg).
- uint8_t op;
- //! @brief Size of register.
- uint8_t size;
- //! @brief Not used.
- uint8_t reserved[2];
-
- //! @brief Operand id.
- uint32_t id;
- //! @brief Register/Variable code, see @c REG.
- uint32_t code;
-};
-
-//! @internal
-//!
-//! @brief Variable operand data.
-struct _OpVar
-{
- //! @brief Type of operand, see @c kOperandType (in this case @c kOperandVar).
- uint8_t op;
- //! @brief Size of variable (0 if don't known).
- uint8_t size;
- //! @brief Not used.
- uint8_t reserved[2];
-
- //! @brief Operand ID.
- uint32_t id;
-
- //! @brief Type (and later also code) of register, see @c kX86RegType, @c kX86RegCode.
- //!
- //! @note Register code and variable code are two different things. In most
- //! cases regCode is very related to varType, but general purpose registers
- //! are divided to 64-bit, 32-bit, 16-bit and 8-bit entities so the regCode
- //! can be used to access these, varType remains unchanged from the
- //! initialization state. Variable type describes mainly variable type and
- //! home memory size.
- uint32_t regCode;
-
- //! @brief Type of variable. See @c kX86VarType enum.
- uint32_t varType;
-};
-
-//! @internal
-//!
-//! @brief Memory operand data.
-struct _OpMem
-{
- //! @brief Type of operand, see @c kOperandType (in this case @c kOperandMem).
- uint8_t op;
- //! @brief Size of pointer.
- uint8_t size;
-
- //! @brief Memory operand type, see @c kOperandMemType.
- uint8_t type;
- //! @brief Segment override prefix, see @c kX86Seg.
- uint8_t segment : 4;
- //! @brief Emit MOV/LEA instruction using 16-bit/32-bit form of base/index
- //! registers.
- uint8_t sizePrefix : 1;
- //! @brief Index register shift/scale (0 to 3 inclusive, see @c kScale).
- uint8_t shift : 3;
-
- //! @brief Operand ID.
- uint32_t id;
-
- //! @brief Base register index, variable or label id.
- uint32_t base;
- //! @brief Index register index or variable id.
- uint32_t index;
-
- //! @brief Target (for 32-bit, absolute address).
- void *target;
- //! @brief Displacement.
- sysint_t displacement;
-};
-
-//! @internal
-//!
-//! @brief Immediate operand data.
-struct _OpImm
-{
- //! @brief Type of operand, see @c kOperandType (in this case @c kOperandImm)..
- uint8_t op;
- //! @brief Size of immediate (or 0 to autodetect).
- uint8_t size;
- //! @brief @c true if immediate is unsigned.
- uint8_t isUnsigned;
- //! @brief Not used.
- uint8_t reserved;
-
- //! @brief Operand ID.
- uint32_t id;
- //! @brief Immediate value.
- sysint_t value;
-};
-
-//! @internal
-//!
-//! @brief Binary operand data.
-struct _OpBin
-{
- //! @brief First four 32-bit integers.
- uint32_t u32[4];
- //! @brief Second two 32-bit or 64-bit integers.
- uintptr_t uptr[2];
-};
-
-// ============================================================================
-// [AsmJit::Operand]
-// ============================================================================
-
-//! @brief Operand can contain register, memory location, immediate, or label.
-struct Operand
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create an uninitialized operand.
- Operand()
- {
- memset(this, 0, sizeof(Operand));
- this->_base.id = kInvalidValue;
- }
-
- //! @brief Create a reference to @a other operand.
- Operand(const Operand &other)
- {
- this->_init(other);
- }
-
-#ifndef ASMJIT_NODOC
- Operand(const _DontInitialize &) { }
-#endif // ASMJIT_NODOC
-
- // --------------------------------------------------------------------------
- // [Init & Copy]
- // --------------------------------------------------------------------------
-
- //! @internal
- //!
- //! @brief Initialize operand to @a other (used by constructors).
- void _init(const Operand &other) { memcpy(this, &other, sizeof(Operand)); }
-
- //! @internal
- //!
- //! @brief Initialize operand to @a other (used by assign operators).
- void _copy(const Operand &other) { memcpy(this, &other, sizeof(Operand)); }
-
- // --------------------------------------------------------------------------
- // [Data]
- // --------------------------------------------------------------------------
-
- template<typename T> T &getData() { return reinterpret_cast<T &>(this->_base); }
-
- template<typename T> const T &getData() const { return reinterpret_cast<const T &>(this->_base); }
-
- // --------------------------------------------------------------------------
- // [Type]
- // --------------------------------------------------------------------------
-
- //! @brief Get type of the operand, see @c kOperandType.
- uint32_t getType() const { return this->_base.op; }
-
- //! @brief Get whether the operand is none (@c kOperandNone).
- bool isNone() const { return this->_base.op == kOperandNone; }
-
- //! @brief Get whether the operand is any (general purpose, mmx or sse) register (@c kOperandReg).
- bool isReg() const { return this->_base.op == kOperandReg; }
-
- //! @brief Get whether the operand is memory address (@c kOperandMem).
- bool isMem() const { return this->_base.op == kOperandMem; }
-
- //! @brief Get whether the operand is immediate (@c kOperandImm).
- bool isImm() const { return this->_base.op == kOperandImm; }
-
- //! @brief Get whether the operand is label (@c kOperandLabel).
- bool isLabel() const { return this->_base.op == kOperandLabel; }
-
- //! @brief Get whether the operand is variable (@c kOperandVar).
- bool isVar() const { return this->_base.op == kOperandVar; }
-
- //! @brief Get whether the operand is variable or memory.
- bool isVarMem() const { return !!(this->_base.op & (kOperandVar | kOperandMem)); }
-
- //! @brief Get whether the operand is register and type of register is @a regType.
- bool isRegType(uint32_t regType) const { return this->_base.op == kOperandReg && (this->_reg.code & kRegTypeMask) == regType; }
-
- //! @brief Get whether the operand is register and code of register is @a regCode.
- bool isRegCode(uint32_t regCode) const { return this->_base.op == kOperandReg && this->_reg.code == regCode; }
-
- //! @brief Get whether the operand is register and index of register is @a regIndex.
- bool isRegIndex(uint32_t regIndex) const { return this->_base.op == kOperandReg && (this->_reg.code & kRegIndexMask) == (regIndex & kRegIndexMask); }
-
- //! @brief Get whether the operand is any register or memory.
- bool isRegMem() const { return !!(this->_base.op & (kOperandReg | kOperandMem)); }
-
- //! @brief Get whether the operand is register of @a regType type or memory.
- bool isRegTypeMem(uint32_t regType) const { return (this->_base.op == kOperandReg && (this->_reg.code & kRegTypeMask) == regType) || this->_base.op == kOperandMem; }
-
- // --------------------------------------------------------------------------
- // [Size]
- // --------------------------------------------------------------------------
-
- //! @brief Get size of the operand in bytes.
- uint32_t getSize() const { return this->_base.size; }
-
- // --------------------------------------------------------------------------
- // [Id]
- // --------------------------------------------------------------------------
-
- //! @brief Return operand Id (Operand Id's are used internally by
- //! @c Assembler and @c Compiler classes).
- //!
- //! @note There is no way how to change or remove operand id. If you don't
- //! need the operand just assign different operand to this one.
- uint32_t getId() const { return this->_base.id; }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- union
- {
- //! @brief Base operand data.
- _OpBase _base;
- //! @brief Label operand data.
- _OpLabel _lbl;
- //! @brief Register operand data.
- _OpReg _reg;
- //! @brief Variable operand data.
- _OpVar _var;
- //! @brief Memory operand data.
- _OpMem _mem;
- //! @brief Immediate operand data.
- _OpImm _imm;
- //! @brief Binary data.
- _OpBin _bin;
- };
-};
-
-ASMJIT_VAR const Operand noOperand;
-
-// ============================================================================
-// [AsmJit::Reg]
-// ============================================================================
-
-//! @brief Base class for all register operands.
-struct Reg : public Operand
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new base register.
- Reg(uint32_t code, uint32_t size) : Operand(_DontInitialize())
- {
- this->_reg.op = kOperandReg;
- this->_reg.size = static_cast<uint8_t>(size);
- this->_reg.id = kInvalidValue;
- this->_reg.code = code;
- }
-
- //! @brief Create a new reference to @a other.
- Reg(const Reg &other) : Operand(other) { }
-
-#ifndef ASMJIT_NODOC
- Reg(const _DontInitialize &dontInitialize) : Operand(dontInitialize) { }
-#endif // ASMJIT_NODOC
-
- // --------------------------------------------------------------------------
- // [Reg Specific]
- // --------------------------------------------------------------------------
-
- //! @brief Get register code, see @c REG.
- uint32_t getRegCode() const { return this->_reg.code; }
-
- //! @brief Get register type, see @c REG.
- uint32_t getRegType() const { return this->_reg.code & kRegTypeMask; }
-
- //! @brief Get register index (value from 0 to 7/15).
- uint32_t getRegIndex() const { return this->_reg.code & kRegIndexMask; }
-
- //! @brief Get whether register code is equal to @a code.
- bool isRegCode(uint32_t code) const { return this->_reg.code == code; }
-
- //! @brief Get whether register code is equal to @a type.
- bool isRegType(uint32_t type) const { return (this->_reg.code & kRegTypeMask) == type; }
-
- //! @brief Get whether register index is equal to @a index.
- bool isRegIndex(uint32_t index) const { return (this->_reg.code & kRegIndexMask) == index; }
-
- //! @brief Set register code to @a code.
- Reg &setCode(uint32_t code)
- {
- this->_reg.code = code;
- return *this;
- }
-
- //! @brief Set register size to @a size.
- Reg &setSize(uint32_t size)
- {
- this->_reg.size = static_cast<uint8_t>(size);
- return *this;
- }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
- Reg &operator=(const Reg &other) { this->_copy(other); return *this; }
-
- bool operator==(const Reg &other) const { return this->getRegCode() == other.getRegCode(); }
-
- bool operator!=(const Reg &other) const { return this->getRegCode() != other.getRegCode(); }
-};
-
-// ============================================================================
-// [AsmJit::Imm]
-// ============================================================================
-
-//! @brief Immediate operand.
-//!
-//! Immediate operand is part of instruction (it's inlined after it).
-//!
-//! To create immediate operand, use @c imm() and @c uimm() constructors
-//! or constructors provided by @c Immediate class itself.
-struct Imm : public Operand
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new signed or unsigned immediate value, assigning the value to @a i.
- Imm(sysint_t i = 0, bool isUnsigned = false) : Operand(_DontInitialize())
- {
- this->_imm.op = kOperandImm;
- this->_imm.size = 0;
- this->_imm.isUnsigned = isUnsigned;
- this->_imm.reserved = 0;
-
- this->_imm.id = kInvalidValue;
- this->_imm.value = i;
- }
-
- //! @brief Create a new immediate value from @a other.
- Imm(const Imm &other) : Operand(other) { }
-
- // --------------------------------------------------------------------------
- // [Immediate Specific]
- // --------------------------------------------------------------------------
-
- //! @brief Get whether an immediate is unsigned value.
- bool isUnsigned() const { return !!this->_imm.isUnsigned; }
-
- //! @brief Get signed immediate value.
- sysint_t getValue() const { return this->_imm.value; }
-
- //! @brief Get unsigned immediate value.
- sysuint_t getUValue() const { return static_cast<sysuint_t>(this->_imm.value); }
-
- //! @brief Set immediate value as signed type to @a val.
- Imm &setValue(sysint_t val, bool isUnsigned = false)
- {
- this->_imm.value = val;
- this->_imm.isUnsigned = isUnsigned;
- return *this;
- }
-
- //! @brief Set immediate value as unsigned type to @a val.
- Imm &setUValue(sysuint_t val)
- {
- this->_imm.value = static_cast<sysint_t>(val);
- this->_imm.isUnsigned = true;
- return *this;
- }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
- //! @brief Assign a signed value @a val to the immediate operand.
- Imm &operator=(sysint_t val) { this->setValue(val); return *this; }
-
- //! @brief Assign @a other to the immediate operand.
- Imm &operator=(const Imm &other) { this->_copy(other); return *this; }
-};
-
-//! @brief Create signed immediate value operand.
-ASMJIT_API Imm imm(sysint_t i);
-
-//! @brief Create unsigned immediate value operand.
-ASMJIT_API Imm uimm(sysuint_t i);
-
-// ============================================================================
-// [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. If you
-//! want to use @c Label you need first to associate it with @c Assembler or
-//! @c Compiler instance. To create new label use @c Assembler::newLabel() or
-//! @c Compiler::newLabel().
-//!
-//! Example of using labels:
-//!
-//! @code
-//! // Create Assembler or Compiler instance.
-//! X86Assembler a;
-//!
-//! // Create Label instance.
-//! Label L_1(a);
-//!
-//! // ... your code ...
-//!
-//! // Using label, see @c AsmJit::Assembler or @c AsmJit::Compiler.
-//! a.jump(L_1);
-//!
-//! // ... your code ...
-//!
-//! // Bind label to current position, see @c AsmJit::Assembler::bind() or
-//! // @c AsmJit::Compiler::bind().
-//! a.bind(L_1);
-//! @endcode
-struct Label : public Operand
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create new, unassociated label.
- Label() : Operand(_DontInitialize())
- {
- this->_lbl.op = kOperandLabel;
- this->_lbl.size = 0;
- this->_lbl.id = kInvalidValue;
- }
-
- //! @brief Create reference to another label.
- Label(const Label &other) : Operand(other) { }
-
- //! @brief Destroy the label.
- ~Label() { }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_NODOC
- Label &operator=(const Label &other) { this->_copy(other); return *this; }
-
- bool operator==(const Label &other) const { return this->_base.id == other._base.id; }
- bool operator!=(const Label &other) const { return this->_base.id != other._base.id; }
-#endif // ASMJIT_NODOC
-};
-
-//! @}
-
-} // AsmJit namespace
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/podvector.h
+++ /dev/null
@@ -1,221 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/assert.h"
-#include "../core/defs.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Core
-//! @{
-
-// ============================================================================
-// [AsmJit::PodVector<T>]
-// ============================================================================
-
-//! @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 <typename T> struct PodVector
-{
- ASMJIT_NO_COPY(PodVector<T>)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create new instance of PodVector template. Data will not
- //! be allocated (will be NULL).
- PodVector() : _data(nullptr), _length(0), _capacity(0) { }
-
- //! @brief Destroy PodVector and free all data.
- ~PodVector()
- {
- if (this->_data)
- ASMJIT_FREE(this->_data);
- }
-
- // --------------------------------------------------------------------------
- // [Data]
- // --------------------------------------------------------------------------
-
- //! @brief Get data.
- T *getData() { return this->_data; }
- //! @overload
- const T *getData() const { return this->_data; }
-
- //! @brief Get length.
- size_t getLength() const { return this->_length; }
- //! @brief Get capacity.
- size_t getCapacity() const { return this->_capacity; }
-
- // --------------------------------------------------------------------------
- // [Manipulation]
- // --------------------------------------------------------------------------
-
- //! @brief Clear vector data, but not free internal buffer.
- void clear()
- {
- this->_length = 0;
- }
-
- //! @brief Clear vector data and free internal buffer.
- void reset()
- {
- if (this->_data)
- {
- ASMJIT_FREE(this->_data);
- this->_data = nullptr;
- this->_length = 0;
- this->_capacity = 0;
- }
- }
-
- //! @brief Prepend @a item to vector.
- bool prepend(const T &item)
- {
- if (this->_length == this->_capacity && !this->_grow())
- return false;
-
- memmove(this->_data + 1, this->_data, sizeof(T) * this->_length);
- memcpy(this->_data, &item, sizeof(T));
-
- ++this->_length;
- return true;
- }
-
- //! @brief Insert an @a item at the @a index.
- bool insert(size_t index, const T &item)
- {
- ASMJIT_ASSERT(index <= this->_length);
- if (this->_length == this->_capacity && !this->_grow())
- return false;
-
- T *dst = this->_data + index;
- memmove(dst + 1, dst, this->_length - index);
- memcpy(dst, &item, sizeof(T));
-
- ++this->_length;
- return true;
- }
-
- //! @brief Append @a item to vector.
- bool append(const T &item)
- {
- if (this->_length == this->_capacity && !this->_grow())
- return false;
-
- memcpy(this->_data + this->_length, &item, sizeof(T));
-
- ++this->_length;
- return true;
- }
-
- //! @brief Get index of @a val or kInvalidSize if not found.
- size_t indexOf(const T &val) const
- {
- for (size_t i = 0, len = this->_length; i < len; ++i)
- if (this->_data[i] == val)
- return i;
- return kInvalidSize;
- }
-
- //! @brief Remove element at index @a i.
- void removeAt(size_t i)
- {
- ASMJIT_ASSERT(i < this->_length);
-
- T *dst = this->_data + i;
- --this->_length;
- memmove(dst, dst + 1, this->_length - i);
- }
-
- //! @brief Swap this pod-vector with @a other.
- void swap(PodVector<T> &other)
- {
- T *_tmp_data = this->_data;
- size_t _tmp_length = this->_length;
- size_t _tmp_capacity = this->_capacity;
-
- this->_data = other._data;
- this->_length = other._length;
- this->_capacity = other._capacity;
-
- other._data = _tmp_data;
- other._length = _tmp_length;
- other._capacity = _tmp_capacity;
- }
-
- //! @brief Get item at position @a i.
- T &operator[](size_t i)
- {
- ASMJIT_ASSERT(i < this->_length);
- return this->_data[i];
- }
- //! @brief Get item at position @a i.
- const T &operator[](size_t i) const
- {
- ASMJIT_ASSERT(i < this->_length);
- return this->_data[i];
- }
-
- //! @brief Append the item and return address so it can be initialized.
- T *newItem()
- {
- if (this->_length == this->_capacity && !this->_grow())
- return nullptr;
- return this->_data + this->_length++;
- }
-
- // --------------------------------------------------------------------------
- // [Private]
- // --------------------------------------------------------------------------
-
- //! @brief Called to grow internal array.
- bool _grow()
- {
- return this->_realloc(this->_capacity < 16 ? 16 : this->_capacity * 2);
- }
-
- //! @brief Realloc internal array to fit @a to items.
- bool _realloc(size_t to)
- {
- ASMJIT_ASSERT(to >= this->_length);
-
- T *p = reinterpret_cast<T *>(this->_data ? ASMJIT_REALLOC(this->_data, to * sizeof(T)) : ASMJIT_MALLOC(to * sizeof(T)));
-
- if (!p)
- return false;
-
- this->_data = p;
- this->_capacity = to;
- return true;
- }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Items data.
- T *_data;
- //! @brief Length of buffer (count of items in array).
- size_t _length;
- //! @brief Capacity of buffer (maximum items that can fit to current array).
- size_t _capacity;
-};
-
-//! @}
-
-} // AsmJit namespace
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/stringbuilder.cpp
+++ /dev/null
@@ -1,385 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/defs.h"
-#include "../core/intutil.h"
-#include "../core/stringbuilder.h"
-
-// [Dependencies - C]
-#include <cstdarg>
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// Should be placed in read-only memory.
-static const char StringBuilder_empty[4] = { 0 };
-
-// ============================================================================
-// [AsmJit::StringBuilder - Construction / Destruction]
-// ============================================================================
-
-StringBuilder::StringBuilder() : _data(const_cast<char *>(StringBuilder_empty)), _length(0), _capacity(0), _canFree(false)
-{
-}
-
-StringBuilder::~StringBuilder()
-{
- if (this->_canFree)
- ASMJIT_FREE(this->_data);
-}
-
-// ============================================================================
-// [AsmJit::StringBuilder - Prepare / Reserve]
-// ============================================================================
-
-char *StringBuilder::prepare(uint32_t op, size_t len)
-{
- // --------------------------------------------------------------------------
- // [Set]
- // --------------------------------------------------------------------------
-
- if (op == kStringBuilderOpSet)
- {
- // We don't care here, but we can't return a NULL pointer since it indicates
- // failure in memory allocation.
- if (!len)
- {
- if (this->_data != StringBuilder_empty)
- this->_data[0] = 0;
-
- this->_length = 0;
- return this->_data;
- }
-
- if (this->_capacity < len)
- {
- if (len >= IntUtil::maxValue<size_t>() - sizeof(uintptr_t) * 2)
- return nullptr;
-
- size_t to = IntUtil::align(len, sizeof(uintptr_t));
- if (to < 256 - sizeof(uintptr_t))
- to = 256 - sizeof(uintptr_t);
-
- char *newData = static_cast<char *>(ASMJIT_MALLOC(to + sizeof(uintptr_t)));
- if (!newData)
- {
- this->clear();
- return nullptr;
- }
-
- if (this->_canFree)
- ASMJIT_FREE(this->_data);
-
- this->_data = newData;
- this->_capacity = to + sizeof(uintptr_t) - 1;
- this->_canFree = true;
- }
-
- this->_data[len] = 0;
- this->_length = len;
-
- ASMJIT_ASSERT(this->_length <= this->_capacity);
- return this->_data;
- }
-
- // --------------------------------------------------------------------------
- // [Append]
- // --------------------------------------------------------------------------
-
- else
- {
- // We don't care here, but we can't return a NULL pointer since it indicates
- // failure in memory allocation.
- if (!len)
- return this->_data + this->_length;
-
- // Overflow.
- if (IntUtil::maxValue<size_t>() - sizeof(uintptr_t) * 2 - this->_length < len)
- return nullptr;
-
- size_t after = this->_length + len;
- if (this->_capacity < after)
- {
- size_t to = this->_capacity;
-
- if (to < 256)
- to = 256;
-
- while (to < 1024 * 1024 && to < after)
- to *= 2;
-
- if (to < after)
- {
- to = after;
- if (to < IntUtil::maxValue<size_t>() - 1024 * 32)
- to = IntUtil::align<size_t>(to, 1024 * 32);
- }
-
- to = IntUtil::align(to, sizeof(uintptr_t));
- char *newData = static_cast<char *>(ASMJIT_MALLOC(to + sizeof(uintptr_t)));
-
- if (!newData)
- return nullptr;
-
- ::memcpy(newData, this->_data, this->_length);
-
- if (this->_canFree)
- ASMJIT_FREE(this->_data);
-
- this->_data = newData;
- this->_capacity = to + sizeof(uintptr_t) - 1;
- this->_canFree = true;
- }
-
- char *ret = this->_data + this->_length;
- this->_data[after] = 0;
- this->_length = after;
-
- ASMJIT_ASSERT(this->_length <= this->_capacity);
- return ret;
- }
-}
-
-bool StringBuilder::reserve(size_t to)
-{
- if (this->_capacity >= to)
- return true;
-
- if (to >= IntUtil::maxValue<size_t>() - sizeof(uintptr_t) * 2)
- return false;
-
- to = IntUtil::align(to, sizeof(uintptr_t));
-
- char *newData = static_cast<char *>(ASMJIT_MALLOC(to + sizeof(uintptr_t)));
- if (!newData)
- return false;
-
- ::memcpy(newData, this->_data, this->_length + 1);
- if (this->_canFree)
- ASMJIT_FREE(this->_data);
-
- this->_data = newData;
- this->_capacity = to + sizeof(uintptr_t) - 1;
- this->_canFree = true;
- return true;
-}
-
-// ============================================================================
-// [AsmJit::StringBuilder - Clear]
-// ============================================================================
-
-void StringBuilder::clear()
-{
- if (this->_data != StringBuilder_empty)
- this->_data[0] = 0;
- this->_length = 0;
-}
-
-// ============================================================================
-// [AsmJit::StringBuilder - Methods]
-// ============================================================================
-
-bool StringBuilder::_opString(uint32_t op, const char *str, size_t len)
-{
- if (len == kInvalidSize)
- len = ::strlen(str);
-
- char *p = this->prepare(op, len);
- if (!p)
- return false;
-
- ::memcpy(p, str, len);
- return true;
-}
-
-bool StringBuilder::_opChars(uint32_t op, char c, size_t len)
-{
- char *p = this->prepare(op, len);
- if (!p)
- return false;
-
- ::memset(p, c, len);
- return true;
-}
-
-static const char StringBuilder_numbers[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-bool StringBuilder::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, uint32_t flags)
-{
- if (base < 2 || base > 36)
- base = 10;
-
- char buf[128];
- char *p = buf + ASMJIT_ARRAY_SIZE(buf);
-
- uint64_t orig = i;
- char sign = 0;
-
- // --------------------------------------------------------------------------
- // [Sign]
- // --------------------------------------------------------------------------
-
- if ((flags & kStringBuilderNumSigned) && static_cast<int64_t>(i) < 0)
- {
- i = static_cast<uint64_t>(-static_cast<int64_t>(i));
- sign = '-';
- }
- else if (flags & kStringBuilderNumShowSign)
- sign = '+';
- else if (flags & kStringBuilderNumShowSpace)
- sign = ' ';
-
- // --------------------------------------------------------------------------
- // [Number]
- // --------------------------------------------------------------------------
-
- do
- {
- uint64_t d = i / base;
- uint64_t r = i % base;
-
- *--p = StringBuilder_numbers[r];
- i = d;
- } while (i);
-
- size_t numberLength = static_cast<size_t>(buf + ASMJIT_ARRAY_SIZE(buf) - p);
-
- // --------------------------------------------------------------------------
- // [Alternate Form]
- // --------------------------------------------------------------------------
-
- if (flags & kStringBuilderNumAlternate)
- {
- if (base == 8 && orig)
- *--p = '0';
- if (base == 16)
- {
- *--p = 'x';
- *--p = '0';
- }
- }
-
- // --------------------------------------------------------------------------
- // [Width]
- // --------------------------------------------------------------------------
-
- if (sign)
- *--p = sign;
-
- if (width > 256)
- width = 256;
-
- if (width <= numberLength)
- width = 0;
- else
- width -= numberLength;
-
- // --------------------------------------------------------------------------
- // [Write]
- // --------------------------------------------------------------------------
-
- size_t prefixLength = static_cast<size_t>(buf + ASMJIT_ARRAY_SIZE(buf) - p) - numberLength;
- char *data = this->prepare(op, prefixLength + width + numberLength);
-
- if (!data)
- return false;
-
- ::memcpy(data, p, prefixLength);
- data += prefixLength;
-
- ::memset(data, '0', width);
- data += width;
-
- ::memcpy(data, p + prefixLength, numberLength);
- return true;
-}
-
-bool StringBuilder::_opHex(uint32_t op, const void *data, size_t len)
-{
- if (len >= IntUtil::maxValue<size_t>() / 2)
- return false;
-
- char *dst = this->prepare(op, len);
- if (!dst)
- return false;
-
- const char *src = static_cast<const char *>(data);
- for (size_t i = 0; i < len; ++i, dst += 2, ++src)
- {
- dst[0] = StringBuilder_numbers[(src[0] >> 4) & 0xF];
- dst[1] = StringBuilder_numbers[src[0] & 0xF];
- }
-
- return true;
-}
-
-bool StringBuilder::_opVFormat(uint32_t op, const char *fmt, va_list ap)
-{
- char buf[1024];
-
- vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap);
- buf[ASMJIT_ARRAY_SIZE(buf) - 1] = 0;
-
- return this->_opString(op, buf);
-}
-
-bool StringBuilder::setFormat(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- bool result = this->_opVFormat(kStringBuilderOpSet, fmt, ap);
- va_end(ap);
-
- return result;
-}
-
-bool StringBuilder::appendFormat(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- bool result = _opVFormat(kStringBuilderOpAppend, fmt, ap);
- va_end(ap);
-
- return result;
-}
-
-bool StringBuilder::eq(const char *str, size_t len) const
-{
- const char *aData = this->_data;
- const char *bData = str;
-
- size_t aLength = this->_length;
- size_t bLength = len;
-
- if (bLength == kInvalidSize)
- {
- size_t i;
- for (i = 0; i < aLength; ++i)
- if (aData[i] != bData[i] || !bData[i])
- return false;
-
- return !bData[i];
- }
- else
- {
- if (aLength != bLength)
- return false;
-
- return !::memcmp(aData, bData, aLength);
- }
-}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/stringbuilder.h
+++ /dev/null
@@ -1,180 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/assert.h"
-#include "../core/defs.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Core
-//! @{
-
-// ============================================================================
-// [AsmJit::StringBuilder]
-// ============================================================================
-
-//! @brief String builder.
-//!
-//! String builder was designed to be able to build a string using append like
-//! operation to append numbers, other strings, or signle characters. It can
-//! allocate it's own buffer or use a buffer created on the stack.
-//!
-//! String builder contains method specific to AsmJit functionality, used for
-//! logging or HTML output.
-struct StringBuilder
-{
- ASMJIT_NO_COPY(StringBuilder)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- ASMJIT_API StringBuilder();
- ASMJIT_API ~StringBuilder();
-
- StringBuilder(const _DontInitialize &) { }
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get string builder capacity.
- size_t getCapacity() const { return this->_capacity; }
-
- //! @brief Get length.
- size_t getLength() const { return this->_length; }
-
- //! @brief Get null-terminated string data.
- char *getData() { return this->_data; }
-
- //! @brief Get null-terminated string data (const).
- const char *getData() const { return this->_data; }
-
- // --------------------------------------------------------------------------
- // [Prepare / Reserve]
- // --------------------------------------------------------------------------
-
- //! @brief Prepare to set/append.
- ASMJIT_API char *prepare(uint32_t op, size_t len);
-
- //! @brief Reserve @a to bytes in string builder.
- ASMJIT_API bool reserve(size_t to);
-
- // --------------------------------------------------------------------------
- // [Clear]
- // --------------------------------------------------------------------------
-
- //! @brief Clear the content in String builder.
- ASMJIT_API void clear();
-
- // --------------------------------------------------------------------------
- // [Methods]
- // --------------------------------------------------------------------------
-
- ASMJIT_API bool _opString(uint32_t op, const char *str, size_t len = kInvalidSize);
- ASMJIT_API bool _opVFormat(uint32_t op, const char *fmt, va_list ap);
- ASMJIT_API bool _opChars(uint32_t op, char c, size_t len);
- ASMJIT_API bool _opNumber(uint32_t op, uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0);
- ASMJIT_API bool _opHex(uint32_t op, const void *data, size_t length);
-
- //! @brief Replace the current content by @a str of @a len.
- bool setString(const char *str, size_t len = kInvalidSize) { return this->_opString(kStringBuilderOpSet, str, len); }
-
- //! @brief Replace the current content by formatted string @a fmt.
- bool setVFormat(const char *fmt, va_list ap) { return this->_opVFormat(kStringBuilderOpSet, fmt, ap); }
-
- //! @brief Replace the current content by formatted string @a fmt.
- ASMJIT_API bool setFormat(const char *fmt, ...);
-
- //! @brief Replace the current content by @a c of @a len.
- bool setChars(char c, size_t len) { return this->_opChars(kStringBuilderOpSet, c, len); }
-
- //! @brief Replace the current content by @a i..
- bool setNumber(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) { return this->_opNumber(kStringBuilderOpSet, i, base, width, flags); }
-
- //! @brief Append @a str of @a len.
- bool appendString(const char *str, size_t len = kInvalidSize) { return this->_opString(kStringBuilderOpAppend, str, len); }
-
- //! @brief Append a formatted string @a fmt to the current content.
- bool appendVFormat(const char *fmt, va_list ap) { return this->_opVFormat(kStringBuilderOpAppend, fmt, ap); }
-
- //! @brief Append a formatted string @a fmt to the current content.
- ASMJIT_API bool appendFormat(const char *fmt, ...);
-
- //! @brief Append @a c of @a len.
- bool appendChars(char c, size_t len) { return this->_opChars(kStringBuilderOpAppend, c, len); }
-
- //! @brief Append @a i.
- bool appendNumber(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) { return this->_opNumber(kStringBuilderOpAppend, i, base, width, flags); }
-
- //! @brief Check for equality with other @a str.
- ASMJIT_API bool eq(const char *str, size_t len = kInvalidSize) const;
-
- //! @brief Check for equality with StringBuilder @a other.
- bool eq(const StringBuilder &other) const { return this->eq(other._data); }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
- bool operator==(const StringBuilder &other) const { return this->eq(other); }
- bool operator!=(const StringBuilder &other) const { return !this->eq(other); }
-
- bool operator==(const char *str) const { return this->eq(str); }
- bool operator!=(const char *str) const { return !this->eq(str); }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief String data.
- char *_data;
- //! @brief Length.
- size_t _length;
- //! @brief Capacity.
- size_t _capacity;
- //! @brief Whether the string can be freed.
- size_t _canFree;
-};
-
-// ============================================================================
-// [AsmJit::StringBuilderT]
-// ============================================================================
-
-template<size_t N> struct StringBuilderT : public StringBuilder
-{
- ASMJIT_NO_COPY(StringBuilderT<N>)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- StringBuilderT() : StringBuilder(_DontInitialize())
- {
- this->_data = this->_embeddedData;
- this->_data[0] = 0;
-
- this->_length = 0;
- this->_capacity = 0;
- this->_canFree = false;
- }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Embedded data.
- char _embeddedData[(N + sizeof(uintptr_t)) & ~(sizeof(uintptr_t) - 1)];
-};
-
-//! @}
-
-} // AsmJit namespace
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/stringutil.cpp
+++ /dev/null
@@ -1,94 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/assert.h"
-#include "../core/stringutil.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::StringUtil]
-// ============================================================================
-
-static const char letters[] = "0123456789ABCDEF";
-
-char *StringUtil::copy(char *dst, const char *src, size_t len)
-{
- if (!src)
- return dst;
-
- if (len == kInvalidSize)
- {
- while (*src)
- *dst++ = *src++;
- }
- else
- {
- memcpy(dst, src, len);
- dst += len;
- }
-
- return dst;
-}
-
-char *StringUtil::fill(char *dst, int c, size_t len)
-{
- memset(dst, c, len);
- return dst + len;
-}
-
-char *StringUtil::hex(char *dst, const uint8_t *src, size_t len)
-{
- for (size_t i = len; i; --i, dst += 2, ++src)
- {
- dst[0] = letters[(src[0] >> 4) & 0xF];
- dst[1] = letters[src[0] & 0xF];
- }
-
- return dst;
-}
-
-// Not too efficient, but this is mainly for debugging:)
-char *StringUtil::utoa(char *dst, uintptr_t i, size_t base)
-{
- ASMJIT_ASSERT(base <= 16);
-
- char buf[128];
- char *p = buf + 128;
-
- do
- {
- uintptr_t b = i % base;
- *--p = letters[b];
- i /= base;
- } while (i);
-
- return StringUtil::copy(dst, p, static_cast<size_t>(buf + 128 - p));
-}
-
-char *StringUtil::itoa(char *dst, intptr_t i, size_t base)
-{
- if (i < 0)
- {
- *dst++ = '-';
- i = -i;
- }
-
- return StringUtil::utoa(dst, static_cast<uintptr_t>(i), base);
-}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/stringutil.h
+++ /dev/null
@@ -1,42 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/defs.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Core
-//! @{
-
-// ============================================================================
-// [AsmJit::StringUtil]
-// ============================================================================
-
-//! @brief String utilities.
-struct StringUtil
-{
- ASMJIT_API static char *copy(char *dst, const char *src, size_t len = kInvalidSize);
- ASMJIT_API static char *fill(char *dst, int c, size_t len);
- ASMJIT_API static char *hex(char *dst, const uint8_t *src, size_t len);
-
- ASMJIT_API static char *utoa(char *dst, uintptr_t i, size_t base = 10);
- ASMJIT_API static char *itoa(char *dst, intptr_t i, size_t base = 10);
-
- static void memset32(uint32_t *p, uint32_t c, size_t len)
- {
- for (size_t i = 0; i < len; ++i)
- p[i] = c;
- }
-};
-
-//! @}
-
-} // AsmJit namespace
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/virtualmemory.cpp
+++ /dev/null
@@ -1,163 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/intutil.h"
-#include "../core/virtualmemory.h"
-
-// [Dependencies - Windows]
-#ifdef ASMJIT_WINDOWS
-# include "windowsh_wrapper.h"
-#endif // ASMJIT_WINDOWS
-
-// [Dependencies - Posix]
-#ifdef ASMJIT_POSIX
-# include <sys/types.h>
-# include <sys/mman.h>
-# include <unistd.h>
-#endif // ASMJIT_POSIX
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::VirtualMemory - Windows]
-// ============================================================================
-
-#ifdef ASMJIT_WINDOWS
-struct VirtualMemoryLocal
-{
- VirtualMemoryLocal()
- {
- SYSTEM_INFO info;
- GetSystemInfo(&info);
-
- this->alignment = info.dwAllocationGranularity;
- this->pageSize = IntUtil::roundUpToPowerOf2<uint32_t>(info.dwPageSize);
- }
-
- size_t alignment;
- size_t pageSize;
-};
-
-static VirtualMemoryLocal &vm()
-{
- static VirtualMemoryLocal vm;
- return vm;
-};
-
-void *VirtualMemory::alloc(size_t length, size_t *allocated, bool canExecute)
-{
- return allocProcessMemory(GetCurrentProcess(), length, allocated, canExecute);
-}
-
-void VirtualMemory::free(void *addr, size_t length)
-{
- return freeProcessMemory(GetCurrentProcess(), addr, length);
-}
-
-void *VirtualMemory::allocProcessMemory(HANDLE hProcess, size_t length, size_t *allocated, bool canExecute)
-{
- // VirtualAlloc rounds allocated size to page size automatically.
- size_t msize = IntUtil::roundUp(length, vm().pageSize);
-
- // Windows XP SP2 / Vista allow Data Excution Prevention (DEP).
- WORD protect = canExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
- LPVOID mbase = VirtualAllocEx(hProcess, nullptr, msize, MEM_COMMIT | MEM_RESERVE, protect);
- if (!mbase)
- return nullptr;
-
- ASMJIT_ASSERT(IntUtil::isAligned<size_t>(reinterpret_cast<size_t>(mbase), vm().alignment));
-
- if (allocated)
- *allocated = msize;
- return mbase;
-}
-
-void VirtualMemory::freeProcessMemory(HANDLE hProcess, void *addr, size_t /* length */)
-{
- VirtualFreeEx(hProcess, addr, 0, MEM_RELEASE);
-}
-
-size_t VirtualMemory::getAlignment()
-{
- return vm().alignment;
-}
-
-size_t VirtualMemory::getPageSize()
-{
- return vm().pageSize;
-}
-#endif // ASMJIT_WINDOWS
-
-// ============================================================================
-// [AsmJit::VirtualMemory - Posix]
-// ============================================================================
-
-#ifdef ASMJIT_POSIX
-
-// MacOS uses MAP_ANON instead of MAP_ANONYMOUS.
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif // MAP_ANONYMOUS
-
-struct VirtualMemoryLocal
-{
- VirtualMemoryLocal()
- {
- this->alignment = this->pageSize = ::getpagesize();
- }
-
- size_t alignment;
- size_t pageSize;
-};
-
-static VirtualMemoryLocal &vm()
-{
- static VirtualMemoryLocal vm;
- return vm;
-}
-
-void *VirtualMemory::alloc(size_t length, size_t *allocated, bool canExecute)
-{
- size_t msize = IntUtil::roundUp<size_t>(length, vm().pageSize);
- int protection = PROT_READ | PROT_WRITE | (canExecute ? PROT_EXEC : 0);
-
- void *mbase = ::mmap(nullptr, msize, protection, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (mbase == MAP_FAILED)
- return nullptr;
-
- if (allocated)
- *allocated = msize;
- return mbase;
-}
-
-void VirtualMemory::free(void *addr, size_t length)
-{
- munmap(addr, length);
-}
-
-size_t VirtualMemory::getAlignment()
-{
- return vm().alignment;
-}
-
-size_t VirtualMemory::getPageSize()
-{
- return vm().pageSize;
-}
-#endif // ASMJIT_POSIX
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/virtualmemory.h
+++ /dev/null
@@ -1,77 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/build.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Core
-//! @{
-
-// ============================================================================
-// [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 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.
- ASMJIT_API static void *alloc(size_t length, size_t *allocated, bool canExecute);
-
- //! @brief Free memory allocated by @c alloc()
- ASMJIT_API static void free(void *addr, size_t length);
-
-#ifdef ASMJIT_WINDOWS
- //! @brief Allocate virtual memory of @a hProcess.
- //!
- //! @note This function is Windows specific.
- ASMJIT_API static void *allocProcessMemory(HANDLE hProcess, size_t length, size_t *allocated, bool canExecute);
-
- //! @brief Free virtual memory of @a hProcess.
- //!
- //! @note This function is Windows specific.
- ASMJIT_API static void freeProcessMemory(HANDLE hProcess, void *addr, size_t length);
-#endif // ASMJIT_WINDOWS
-
- //! @brief Get the alignment guaranteed by alloc().
- ASMJIT_API static size_t getAlignment();
-
- //! @brief Get size of single page.
- ASMJIT_API static size_t getPageSize();
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/zonememory.cpp
+++ /dev/null
@@ -1,130 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/defs.h"
-#include "../core/intutil.h"
-#include "../core/zonememory.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::ZoneMemory]
-// ============================================================================
-
-ZoneMemory::ZoneMemory(size_t chunkSize)
-{
- this->_chunks = nullptr;
- this->_total = 0;
- this->_chunkSize = chunkSize;
-}
-
-ZoneMemory::~ZoneMemory()
-{
- this->reset();
-}
-
-void *ZoneMemory::alloc(size_t size)
-{
- ZoneChunk *cur = this->_chunks;
-
- // Align to 4 or 8 bytes.
- size = IntUtil::align(size, sizeof(size_t));
-
- if (!cur || cur->getRemainingBytes() < size)
- {
- size_t chSize = this->_chunkSize;
-
- if (chSize < size)
- chSize = size;
-
- cur = static_cast<ZoneChunk *>(ASMJIT_MALLOC(sizeof(ZoneChunk) - sizeof(void *) + chSize));
- if (!cur)
- return nullptr;
-
- cur->prev = this->_chunks;
- cur->pos = 0;
- cur->size = chSize;
-
- this->_chunks = cur;
- }
-
- uint8_t *p = cur->data + cur->pos;
- cur->pos += size;
- this->_total += size;
-
- ASMJIT_ASSERT(cur->pos <= cur->size);
- return static_cast<void *>(p);
-}
-
-char *ZoneMemory::sdup(const char *str)
-{
- if (!str)
- return nullptr;
-
- size_t len = strlen(str);
- if (!len)
- return nullptr;
-
- // Include NULL terminator and limit string length.
- if (++len > 256)
- len = 256;
-
- char *m = static_cast<char *>(alloc(IntUtil::align<size_t>(len, 16)));
- if (!m)
- return nullptr;
-
- memcpy(m, str, len);
- m[len - 1] = 0;
- return m;
-}
-
-void ZoneMemory::clear()
-{
- ZoneChunk *cur = this->_chunks;
-
- if (!cur)
- return;
-
- cur = cur->prev;
- while (cur)
- {
- ZoneChunk *prev = cur->prev;
- ASMJIT_FREE(cur);
- cur = prev;
- }
-
- this->_chunks->pos = 0;
- this->_chunks->prev = nullptr;
- this->_total = 0;
-}
-
-void ZoneMemory::reset()
-{
- ZoneChunk *cur = this->_chunks;
-
- this->_chunks = nullptr;
- this->_total = 0;
-
- while (cur)
- {
- ZoneChunk *prev = cur->prev;
- ASMJIT_FREE(cur);
- cur = prev;
- }
-}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/core/zonememory.h
+++ /dev/null
@@ -1,149 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/build.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_Core
-//! @{
-
-// ============================================================================
-// [AsmJit::ZoneChunk]
-// ============================================================================
-
-//! @internal
-//!
-//! @brief One allocated chunk of memory.
-struct ZoneChunk
-{
- // --------------------------------------------------------------------------
- // [Methods]
- // --------------------------------------------------------------------------
-
- //! @brief Get count of remaining (unused) bytes in chunk.
- size_t getRemainingBytes() const { return this->size - this->pos; }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Link to previous chunk.
- ZoneChunk *prev;
- //! @brief Position in this chunk.
- size_t pos;
- //! @brief Size of this chunk (in bytes).
- size_t size;
-
- //! @brief Data.
- uint8_t data[sizeof(void *)];
-};
-
-// ============================================================================
-// [AsmJit::ZoneMemory]
-// ============================================================================
-
-//! @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 ZoneMemory are freed all at once. This means that lifetime of
-//! these objects are the same as the zone object itself.
-struct ZoneMemory
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create new instance of @c ZoneMemory.
- //! @param chunkSize Default size for one zone chunk.
- ASMJIT_API ZoneMemory(size_t chunkSize);
-
- //! @brief Destroy @ref ZoneMemory instance.
- ASMJIT_API ~ZoneMemory();
-
- // --------------------------------------------------------------------------
- // [Methods]
- // --------------------------------------------------------------------------
-
- //! @brief Allocate @c size bytes of memory and return pointer to it.
- //!
- //! Pointer allocated by this way will be valid until @c ZoneMemory 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.
- //! ZoneMemory 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();
- //!
- //! // ZoneMemory destructor will free all memory allocated through it,
- //! // alternative is to call @c zone.reset().
- //! }
- //! @endcode
- ASMJIT_API void *alloc(size_t size);
-
- //! @brief Helper to duplicate string.
- ASMJIT_API char *sdup(const char *str);
-
- //! @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.
- ASMJIT_API void clear();
-
- //! @brief Free all allocated memory at once.
- //!
- //! Note that this method will invalidate all instances using this memory
- //! allocated by this zone instance.
- ASMJIT_API void reset();
-
- //! @brief Get total size of allocated objects - by @c alloc().
- size_t getTotal() const { return this->_total; }
- //! @brief Get (default) chunk size.
- size_t getChunkSize() const { return this->_chunkSize; }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Last allocated chunk of memory.
- ZoneChunk *_chunks;
- //! @brief Total size of allocated objects - by @c alloc() method.
- size_t _total;
- //! @brief One chunk size.
- size_t _chunkSize;
-};
-
-//! @}
-
-} // AsmJit namespace
-
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/host.h
@@ -1,1 +1,55 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+#pragma once
+
+// [Dependencies - Core]
+#include "base.h"
+
+// ============================================================================
+// [asmjit::host - X86 / X64]
+// ============================================================================
+
+#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
+#include "x86.h"
+
+namespace asmjit {
+
+// Define `asmjit::host` namespace wrapping `asmjit::x86`.
+namespace host { using namespace ::asmjit::x86; }
+
+// Define host assembler.
+typedef X86Assembler HostAssembler;
+
+// Define host operands.
+typedef X86GpReg GpReg;
+typedef X86FpReg FpReg;
+typedef X86MmReg MmReg;
+typedef X86XmmReg XmmReg;
+typedef X86YmmReg YmmReg;
+typedef X86SegReg SegReg;
+typedef X86Mem Mem;
+
+// Define host utilities.
+typedef X86CpuInfo HostCpuInfo;
+
+// Define host compiler and related.
+#ifndef ASMJIT_DISABLE_COMPILER
+typedef X86Compiler HostCompiler;
+typedef X86CallNode HostCallNode;
+typedef X86FuncDecl HostFuncDecl;
+typedef X86FuncNode HostFuncNode;
+
+typedef X86GpVar GpVar;
+typedef X86MmVar MmVar;
+typedef X86XmmVar XmmVar;
+typedef X86YmmVar YmmVar;
+#endif // !ASMJIT_DISABLE_COMPILER
+
+} // asmjit namespace
+
+#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/revision.txt
@@ -1,1 +1,3 @@
+https://github.com/kobalicek/asmjit
+eef8f7895336af40b3b2701c36dd991c366deadc
--- a/src/in_2sf/desmume/utils/AsmJit/x86.h
+++ b/src/in_2sf/desmume/utils/AsmJit/x86.h
@@ -1,22 +1,17 @@
// [AsmJit]
-// Complete JIT Assembler for C++ Language.
+// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
-// Zlib - See COPYING file in this package.
+// Zlib - See LICENSE.md file in the package.
#pragma once
// [Dependencies - AsmJit]
-#include "core.h"
+#include "base.h"
#include "x86/x86assembler.h"
#include "x86/x86compiler.h"
-#include "x86/x86compilercontext.h"
-#include "x86/x86compilerfunc.h"
-#include "x86/x86compileritem.h"
#include "x86/x86cpuinfo.h"
-#include "x86/x86defs.h"
-#include "x86/x86func.h"
+#include "x86/x86inst.h"
#include "x86/x86operand.h"
-#include "x86/x86util.h"
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86assembler.cpp
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86assembler.cpp
@@ -1,2791 +1,4190 @@
// [AsmJit]
-// Complete JIT Assembler for C++ Language.
+// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
-// Zlib - See COPYING file in this package.
-
+// Zlib - See LICENSE.md file in the package.
+
+// [Export]
#define ASMJIT_EXPORTS
+// [Guard]
+#include "../build.h"
+#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
+
// [Dependencies - AsmJit]
-#include "../core/assembler.h"
-#include "../core/context.h"
-#include "../core/cpuinfo.h"
-#include "../core/defs.h"
-#include "../core/intutil.h"
-#include "../core/logger.h"
-#include "../core/memorymanager.h"
-#include "../core/memorymarker.h"
-#include "../core/stringutil.h"
-
+#include "../base/intutil.h"
+#include "../base/logger.h"
+#include "../base/runtime.h"
+#include "../base/string.h"
+#include "../base/vmem.h"
#include "../x86/x86assembler.h"
#include "../x86/x86cpuinfo.h"
-#include "../x86/x86defs.h"
-#include "../x86/x86operand.h"
-#include "../x86/x86util.h"
// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
+#include "../apibegin.h"
+
+namespace asmjit {
// ============================================================================
// [Constants]
// ============================================================================
+enum { kRexShift = 6 };
+enum { kRexForbidden = 0x80 };
enum { kMaxCommentLength = 80 };
+// 2-byte VEX prefix.
+// [0] kVex2Byte.
+// [1] RvvvvLpp.
+enum { kVex2Byte = 0xC5 };
+
+// 3-byte VEX prefix.
+// [0] kVex3Byte.
+// [1] RXBmmmmm.
+// [2] WvvvvLpp.
+enum { kVex3Byte = 0xC4 };
+
+// 3-byte XOP prefix.
+// [0] kXopByte
+// [1] RXBmmmmm
+// [2] WvvvvLpp
+enum { kXopByte = 0x8F };
+
+// AsmJit specific (used to encode VVVV field in XOP/VEX).
+enum kVexVVVV {
+ kVexVVVVShift = 12,
+ kVexVVVVMask = 0xF << kVexVVVVShift
+};
+
+//! \internal
+//!
+//! Instruction 2-byte/3-byte opcode prefix definition.
+struct X86OpCodeMM {
+ uint8_t len;
+ uint8_t data[3];
+};
+
+//! \internal
+//!
+//! Mandatory prefixes encoded in 'asmjit' opcode [66, F3, F2] and asmjit
+//! extensions
+static const uint8_t x86OpCodePP[8] = {
+ 0x00,
+ 0x66,
+ 0xF3,
+ 0xF2,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x9B
+};
+
+//! \internal
+//!
+//! Instruction 2-byte/3-byte opcode prefix data.
+static const X86OpCodeMM x86OpCodeMM[] = {
+ { 0, { 0x00, 0x00, 0 } },
+ { 1, { 0x0F, 0x00, 0 } },
+ { 2, { 0x0F, 0x38, 0 } },
+ { 2, { 0x0F, 0x3A, 0 } },
+ { 0, { 0x00, 0x00, 0 } },
+ { 0, { 0x00, 0x00, 0 } },
+ { 0, { 0x00, 0x00, 0 } },
+ { 0, { 0x00, 0x00, 0 } },
+ { 0, { 0x00, 0x00, 0 } },
+ { 0, { 0x00, 0x00, 0 } },
+ { 0, { 0x00, 0x00, 0 } },
+ { 0, { 0x00, 0x00, 0 } },
+ { 0, { 0x00, 0x00, 0 } },
+ { 0, { 0x00, 0x00, 0 } },
+ { 0, { 0x00, 0x00, 0 } },
+ { 2, { 0x0F, 0x01, 0 } }
+};
+
+static const uint8_t x86SegmentPrefix[8] = { 0x00, 0x26, 0x2E, 0x36, 0x3E, 0x64, 0x65 };
+static const uint8_t x86OpCodePushSeg[8] = { 0x00, 0x06, 0x0E, 0x16, 0x1E, 0xA0, 0xA8 };
+static const uint8_t x86OpCodePopSeg[8] = { 0x00, 0x07, 0x00, 0x17, 0x1F, 0xA1, 0xA9 };
+
// ============================================================================
-// [AsmJit::X64TrampolineWriter]
+// [Utils]
// ============================================================================
-#ifdef ASMJIT_X64
-//! @brief Class used to determine size of trampoline and as trampoline writer.
-struct X64TrampolineWriter
-{
- // Size of trampoline
- enum
- {
- kSizeJmp = 6,
- kSizeAddr = 8,
- kSizeTotal = kSizeJmp + kSizeAddr
- };
-
- // Write trampoline into code at address @a code that will jump to @a target.
- static void writeTrampoline(uint8_t *code, uint64_t target)
- {
- code[0] = 0xFF; // Jmp OpCode.
- code[1] = 0x25; // ModM (RIP addressing).
- reinterpret_cast<uint32_t *>(code + 2)[0] = 0; // Offset (zero).
- reinterpret_cast<uint64_t *>(code + kSizeJmp)[0] = target; // Absolute address.
- }
+//! Encode MODR/M.
+static ASMJIT_INLINE uint32_t x86EncodeMod(uint32_t m, uint32_t o, uint32_t rm) {
+ return (m << 6) + (o << 3) + rm;
+}
+
+//! Encode SIB.
+static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) {
+ return (s << 6) + (i << 3) + b;
+}
+
+//! Get whether the two pointers `a` and `b` can be encoded by using relative
+//! displacement, which fits into a signed 32-bit integer.
+static ASMJIT_INLINE bool x64IsRelative(Ptr a, Ptr b) {
+ SignedPtr diff = static_cast<SignedPtr>(a) - static_cast<SignedPtr>(b);
+ return IntUtil::isInt32(diff);
+}
+
+// ============================================================================
+// [Macros]
+// ============================================================================
+
+#define ENC_OPS(_Op0_, _Op1_, _Op2_) \
+ ((kOperandType##_Op0_) + ((kOperandType##_Op1_) << 3) + ((kOperandType##_Op2_) << 6))
+
+#define ADD_66H_P(_Exp_) \
+ do { \
+ opCode |= (static_cast<uint32_t>(_Exp_) << kX86InstOpCode_PP_Shift); \
+ } while (0)
+
+#define ADD_66H_P_BY_SIZE(_Size_) \
+ do { \
+ opCode |= (static_cast<uint32_t>(_Size_) & 0x02) << (kX86InstOpCode_PP_Shift - 1); \
+ } while (0)
+
+#define ADD_REX_W(_Exp_) \
+ do { \
+ if (Arch == kArchX64) \
+ opX |= static_cast<uint32_t>(_Exp_) << 3; \
+ } while (0)
+
+#define ADD_REX_W_BY_SIZE(_Size_) \
+ do { \
+ if (Arch == kArchX64) \
+ opX |= static_cast<uint32_t>(_Size_) & 0x08; \
+ } while (0)
+
+#define ADD_REX_B(_Reg_) \
+ do { \
+ if (Arch == kArchX64) \
+ opX |= static_cast<uint32_t>(_Reg_) >> 3; \
+ } while (0)
+
+#define ADD_VEX_W(_Exp_) \
+ do { \
+ opX |= static_cast<uint32_t>(_Exp_) << 3; \
+ } while (0)
+
+#define ADD_VEX_L(_Exp_) \
+ do { \
+ opCode |= static_cast<uint32_t>(_Exp_) << kX86InstOpCode_L_Shift; \
+ } while (0)
+
+#define EMIT_BYTE(_Val_) \
+ do { \
+ cursor[0] = static_cast<uint8_t>(_Val_); \
+ cursor += 1; \
+ } while (0)
+
+#define EMIT_WORD(_Val_) \
+ do { \
+ reinterpret_cast<uint16_t*>(cursor)[0] = static_cast<uint16_t>(_Val_); \
+ cursor += 2; \
+ } while (0)
+
+#define EMIT_DWORD(_Val_) \
+ do { \
+ reinterpret_cast<uint32_t*>(cursor)[0] = static_cast<uint32_t>(_Val_); \
+ cursor += 4; \
+ } while (0)
+
+#define EMIT_QWORD(_Val_) \
+ do { \
+ reinterpret_cast<uint64_t*>(cursor)[0] = static_cast<uint64_t>(_Val_); \
+ cursor += 8; \
+ } while (0)
+
+#define EMIT_OP(_Val_) \
+ do { \
+ EMIT_BYTE((_Val_) & 0xFF); \
+ } while (0)
+
+#define EMIT_PP(_Val_) \
+ do { \
+ uint32_t ppIndex = ((_Val_) >> kX86InstOpCode_PP_Shift) & (kX86InstOpCode_PP_Mask >> kX86InstOpCode_PP_Shift); \
+ uint8_t ppCode = x86OpCodePP[ppIndex]; \
+ \
+ if (!ppIndex) \
+ break; \
+ \
+ cursor[0] = ppCode; \
+ cursor++; \
+ } while (0)
+
+#define EMIT_MM(_Val_) \
+ do { \
+ uint32_t mmIndex = ((_Val_) >> kX86InstOpCode_MM_Shift) & (kX86InstOpCode_MM_Mask >> kX86InstOpCode_MM_Shift); \
+ const X86OpCodeMM& mmCode = x86OpCodeMM[mmIndex]; \
+ \
+ if (!mmIndex) \
+ break; \
+ \
+ cursor[0] = mmCode.data[0]; \
+ cursor[1] = mmCode.data[1]; \
+ cursor += mmCode.len; \
+ } while (0)
+
+// ============================================================================
+// [asmjit::X86Assembler - Construction / Destruction]
+// ============================================================================
+
+X86Assembler::X86Assembler(Runtime* runtime, uint32_t arch) :
+ Assembler(runtime),
+ zax(NoInit),
+ zcx(NoInit),
+ zdx(NoInit),
+ zbx(NoInit),
+ zsp(NoInit),
+ zbp(NoInit),
+ zsi(NoInit),
+ zdi(NoInit) {
+
+ setArch(arch);
+}
+
+X86Assembler::~X86Assembler() {}
+
+// ============================================================================
+// [asmjit::X86Assembler - Arch]
+// ============================================================================
+
+Error X86Assembler::setArch(uint32_t arch) {
+#ifdef ASMJIT_BUILD_X86
+ if (arch == kArchX86) {
+ _arch = kArchX86;
+ _regSize = 4;
+
+ _regCount.reset();
+ _regCount._gp = 8;
+ _regCount._fp = 8;
+ _regCount._mm = 8;
+ _regCount._xy = 8;
+
+ zax = x86::eax;
+ zcx = x86::ecx;
+ zdx = x86::edx;
+ zbx = x86::ebx;
+ zsp = x86::esp;
+ zbp = x86::ebp;
+ zsi = x86::esi;
+ zdi = x86::edi;
+
+ return kErrorOk;
+ }
+#endif // ASMJIT_BUILD_X86
+
+#ifdef ASMJIT_BUILD_X64
+ if (arch == kArchX64) {
+ _arch = kArchX64;
+ _regSize = 8;
+
+ _regCount.reset();
+ _regCount._gp = 16;
+ _regCount._fp = 8;
+ _regCount._mm = 8;
+ _regCount._xy = 16;
+
+ zax = x86::rax;
+ zcx = x86::rcx;
+ zdx = x86::rdx;
+ zbx = x86::rbx;
+ zsp = x86::rsp;
+ zbp = x86::rbp;
+ zsi = x86::rsi;
+ zdi = x86::rdi;
+
+ return kErrorOk;
+ }
+#endif // ASMJIT_BUILD_X64
+
+ ASMJIT_ASSERT(!"Reached");
+ return kErrorInvalidArgument;
+}
+
+// ============================================================================
+// [asmjit::X86Assembler - Embed]
+// ============================================================================
+
+Error X86Assembler::embedLabel(const Label& op) {
+ ASMJIT_ASSERT(op.getId() != kInvalidValue);
+ uint32_t regSize = _regSize;
+
+ if (getRemainingSpace() < regSize)
+ ASMJIT_PROPAGATE_ERROR(_grow(regSize));
+
+ uint8_t* cursor = getCursor();
+
+ LabelData* label = getLabelData(op.getId());
+ RelocData reloc;
+
+#ifndef ASMJIT_DISABLE_LOGGER
+ if (_logger)
+ _logger->logFormat(kLoggerStyleData, regSize == 4 ? ".dd L%u\n" : ".dq L%u\n", op.getId());
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ reloc.type = kRelocRelToAbs;
+ reloc.size = regSize;
+ reloc.from = static_cast<Ptr>(getOffset());
+ reloc.data = 0;
+
+ if (label->offset != -1) {
+ // Bound label.
+ reloc.data = static_cast<Ptr>(static_cast<SignedPtr>(label->offset));
+ }
+ else {
+ // Non-bound label. Need to chain.
+ LabelLink* link = _newLabelLink();
+
+ link->prev = label->links;
+ link->offset = getOffset();
+ link->displacement = 0;
+ link->relocId = _relocList.getLength();
+
+ label->links = link;
+ }
+
+ if (_relocList.append(reloc) != kErrorOk)
+ return setError(kErrorNoHeapMemory);
+
+ // Emit dummy intptr_t (4 or 8 bytes; depends on the address size).
+ if (regSize == 4)
+ EMIT_DWORD(0);
+ else
+ EMIT_QWORD(0);
+
+ setCursor(cursor);
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86Assembler - Align]
+// ============================================================================
+
+Error X86Assembler::align(uint32_t mode, uint32_t offset) {
+#ifndef ASMJIT_DISABLE_LOGGER
+ if (_logger)
+ _logger->logFormat(kLoggerStyleDirective,
+ "%s.align %u\n", _logger->getIndentation(), static_cast<unsigned int>(offset));
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ if (offset <= 1 || !IntUtil::isPowerOf2(offset) || offset > 64)
+ return setError(kErrorInvalidArgument);
+
+ uint32_t i = static_cast<uint32_t>(IntUtil::deltaTo<size_t>(getOffset(), offset));
+ if (i == 0)
+ return kErrorOk;
+
+ if (getRemainingSpace() < i)
+ ASMJIT_PROPAGATE_ERROR(_grow(i));
+
+ uint8_t* cursor = getCursor();
+ uint8_t alignPattern = 0xCC;
+
+ if (mode == kAlignCode) {
+ alignPattern = 0x90;
+
+ if (hasFeature(kCodeGenOptimizedAlign)) {
+ const X86CpuInfo* cpuInfo = static_cast<const X86CpuInfo*>(getRuntime()->getCpuInfo());
+
+ // NOPs optimized for Intel:
+ // Intel 64 and IA-32 Architectures Software Developer's Manual
+ // - Volume 2B
+ // - Instruction Set Reference N-Z
+ // - NOP
+
+ // NOPs optimized for AMD:
+ // Software Optimization Guide for AMD Family 10h Processors (Quad-Core)
+ // - 4.13 - Code Padding with Operand-Size Override and Multibyte NOP
+
+ // Intel and AMD.
+ static const uint8_t nop1[] = { 0x90 };
+ static const uint8_t nop2[] = { 0x66, 0x90 };
+ static const uint8_t nop3[] = { 0x0F, 0x1F, 0x00 };
+ static const uint8_t nop4[] = { 0x0F, 0x1F, 0x40, 0x00 };
+ static const uint8_t nop5[] = { 0x0F, 0x1F, 0x44, 0x00, 0x00 };
+ static const uint8_t nop6[] = { 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00 };
+ static const uint8_t nop7[] = { 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00 };
+ static const uint8_t nop8[] = { 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uint8_t nop9[] = { 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ // AMD.
+ static const uint8_t nop10[] = { 0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uint8_t nop11[] = { 0x66, 0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ const uint8_t* p;
+ uint32_t n;
+
+ if (cpuInfo->getVendorId() == kCpuVendorIntel && (
+ (cpuInfo->getFamily() & 0x0F) == 0x06 ||
+ (cpuInfo->getFamily() & 0x0F) == 0x0F)) {
+ do {
+ switch (i) {
+ case 1: p = nop1; n = 1; break;
+ case 2: p = nop2; n = 2; break;
+ case 3: p = nop3; n = 3; break;
+ case 4: p = nop4; n = 4; break;
+ case 5: p = nop5; n = 5; break;
+ case 6: p = nop6; n = 6; break;
+ case 7: p = nop7; n = 7; break;
+ case 8: p = nop8; n = 8; break;
+ default: p = nop9; n = 9; break;
+ }
+
+ i -= n;
+ do {
+ EMIT_BYTE(*p++);
+ } while (--n);
+ } while (i);
+ }
+ else if (cpuInfo->getVendorId() == kCpuVendorAmd && cpuInfo->getFamily() >= 0x0F) {
+ do {
+ switch (i) {
+ case 1: p = nop1 ; n = 1; break;
+ case 2: p = nop2 ; n = 2; break;
+ case 3: p = nop3 ; n = 3; break;
+ case 4: p = nop4 ; n = 4; break;
+ case 5: p = nop5 ; n = 5; break;
+ case 6: p = nop6 ; n = 6; break;
+ case 7: p = nop7 ; n = 7; break;
+ case 8: p = nop8 ; n = 8; break;
+ case 9: p = nop9 ; n = 9; break;
+ case 10: p = nop10; n = 10; break;
+ default: p = nop11; n = 11; break;
+ }
+
+ i -= n;
+ do {
+ EMIT_BYTE(*p++);
+ } while (--n);
+ } while (i);
+ }
+ }
+ }
+
+ while (i) {
+ EMIT_BYTE(alignPattern);
+ i--;
+ }
+
+ setCursor(cursor);
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86Assembler - Reloc]
+// ============================================================================
+
+size_t X86Assembler::_relocCode(void* _dst, Ptr baseAddress) const {
+ uint32_t arch = getArch();
+ uint8_t* dst = static_cast<uint8_t*>(_dst);
+
+#ifndef ASMJIT_DISABLE_LOGGER
+ Logger* logger = getLogger();
+#endif // ASMJIT_DISABLE_LOGGER
+
+ size_t minCodeSize = getOffset(); // Current offset is the minimum code size.
+ size_t maxCodeSize = getCodeSize(); // Includes all possible trampolines.
+
+ // We will copy the exact size of the generated code. Extra code for trampolines
+ // is generated on-the-fly by the relocator (this code doesn't exist at the moment).
+ ::memcpy(dst, _buffer, minCodeSize);
+
+ // Trampoline pointer.
+ uint8_t* tramp = dst + minCodeSize;
+
+ // Relocate all recorded locations.
+ size_t relocCount = _relocList.getLength();
+ const RelocData* relocData = _relocList.getData();
+
+ for (size_t i = 0; i < relocCount; i++) {
+ const RelocData& r = relocData[i];
+
+ // Make sure that the `RelocData` is correct.
+ Ptr ptr = r.data;
+
+ size_t offset = static_cast<size_t>(r.from);
+ ASMJIT_ASSERT(offset + r.size <= static_cast<Ptr>(maxCodeSize));
+
+ // Whether to use trampoline, can be only used if relocation type is
+ // kRelocAbsToRel on 64-bit.
+ bool useTrampoline = false;
+
+ switch (r.type) {
+ case kRelocAbsToAbs:
+ break;
+
+ case kRelocRelToAbs:
+ ptr += baseAddress;
+ break;
+
+ case kRelocAbsToRel:
+ ptr -= baseAddress + r.from + 4;
+ break;
+
+ case kRelocTrampoline:
+ ptr -= baseAddress + r.from + 4;
+ if (!IntUtil::isInt32(static_cast<SignedPtr>(ptr))) {
+ ptr = reinterpret_cast<Ptr>(tramp) - (baseAddress + r.from + 4);
+ useTrampoline = true;
+ }
+ break;
+
+ default:
+ ASMJIT_ASSERT(!"Reached");
+ }
+
+ switch (r.size) {
+ case 8:
+ *reinterpret_cast<int64_t*>(dst + offset) = static_cast<int64_t>(ptr);
+ break;
+
+ case 4:
+ *reinterpret_cast<int32_t*>(dst + offset) = static_cast<int32_t>(static_cast<SignedPtr>(ptr));
+ break;
+
+ default:
+ ASMJIT_ASSERT(!"Reached");
+ }
+
+ // Handle the case where trampoline has been used.
+ if (useTrampoline) {
+ // Bytes that replace [REX, OPCODE] bytes.
+ uint32_t byte0 = 0xFF;
+ uint32_t byte1 = dst[offset - 1];
+
+ // Call, patch to FF/2 (-> 0x15).
+ if (byte1 == 0xE8)
+ byte1 = x86EncodeMod(0, 2, 5);
+ // Jmp, patch to FF/4 (-> 0x25).
+ else if (byte1 == 0xE9)
+ byte1 = x86EncodeMod(0, 4, 5);
+
+ // Patch `jmp/call` instruction.
+ ASMJIT_ASSERT(offset >= 2);
+ dst[offset - 2] = byte0;
+ dst[offset - 1] = byte1;
+
+ // Absolute address.
+ reinterpret_cast<uint64_t*>(tramp)[0] = static_cast<uint64_t>(r.data);
+
+ // Advance trampoline pointer.
+ tramp += 8;
+
+#ifndef ASMJIT_DISABLE_LOGGER
+ if (logger)
+ logger->logFormat(kLoggerStyleComment, "; Trampoline %llX\n", r.data);
+#endif // !ASMJIT_DISABLE_LOGGER
+ }
+ }
+
+ if (arch == kArchX64)
+ return static_cast<size_t>(tramp - dst);
+ else
+ return minCodeSize;
+}
+
+// ============================================================================
+// [asmjit::X86Assembler - Logging]
+// ============================================================================
+
+#ifndef ASMJIT_DISABLE_LOGGER
+// Logging helpers.
+static const char* AssemblerX86_operandSize[] = {
+ "",
+ "byte ptr ",
+ "word ptr ",
+ nullptr,
+ "dword ptr ",
+ nullptr,
+ nullptr,
+ nullptr,
+ "qword ptr ",
+ nullptr,
+ "tword ptr ",
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ "oword ptr "
};
-#endif // ASMJIT_X64
+
+static const char X86Assembler_segName[] =
+ "\0\0\0\0"
+ "es:\0"
+ "cs:\0"
+ "ss:\0"
+ "ds:\0"
+ "fs:\0"
+ "gs:\0"
+ "\0\0\0\0";
+
+static void X86Assembler_dumpRegister(StringBuilder& sb, uint32_t type, uint32_t index) {
+ // -- (Not-Encodable).
+ static const char reg8l[] = "al\0\0" "cl\0\0" "dl\0\0" "bl\0\0" "spl\0" "bpl\0" "sil\0" "dil\0" ;
+ static const char reg8h[] = "ah\0\0" "ch\0\0" "dh\0\0" "bh\0\0" "--\0\0" "--\0\0" "--\0\0" "--\0\0";
+ static const char reg16[] = "ax\0\0" "cx\0\0" "dx\0\0" "bx\0\0" "sp\0\0" "bp\0\0" "si\0\0" "di\0\0";
+
+ char suffix = '\0';
+
+ switch (type) {
+ case kX86RegTypeGpbLo:
+ if (index >= 8) {
+ sb._appendChar('r');
+ suffix = 'b';
+ goto _EmitID;
+ }
+
+ sb._appendString(®8l[index * 4]);
+ return;
+
+ case _kX86RegTypePatchedGpbHi:
+ if (index < 4)
+ goto _EmitNE;
+
+ index -= 4;
+ // ... Fall through ...
+
+ case kX86RegTypeGpbHi:
+ if (index >= 4)
+ goto _EmitNE;
+
+ sb._appendString(®8h[index * 4]);
+ return;
+
+_EmitNE:
+ sb._appendString("--", 2);
+ return;
+
+ case kX86RegTypeGpw:
+ if (index >= 8) {
+ sb._appendChar('r');
+ suffix = 'w';
+ goto _EmitID;
+ }
+
+ sb._appendString(®16[index * 4]);
+ return;
+
+ case kX86RegTypeGpd:
+ if (index >= 8) {
+ sb._appendChar('r');
+ suffix = 'd';
+ goto _EmitID;
+ }
+
+ sb._appendChar('e');
+ sb._appendString(®16[index * 4]);
+ return;
+
+ case kX86RegTypeGpq:
+ sb._appendChar('r');
+ if (index >= 8)
+ goto _EmitID;
+
+ sb._appendString(®16[index * 4]);
+ return;
+
+ case kX86RegTypeFp:
+ sb._appendString("fp", 2);
+ goto _EmitID;
+
+ case kX86RegTypeMm:
+ sb._appendString("mm", 2);
+ goto _EmitID;
+
+ case kX86RegTypeXmm:
+ sb._appendString("xmm", 3);
+ goto _EmitID;
+
+ case kX86RegTypeYmm:
+ sb._appendString("ymm", 3);
+ goto _EmitID;
+
+ case kX86RegTypeSeg:
+ if (index >= kX86SegCount)
+ goto _EmitNE;
+
+ sb._appendString(&X86Assembler_segName[index * 4], 2);
+ return;
+
+ default:
+ return;
+ }
+
+_EmitID:
+ sb._appendUInt32(index);
+
+ if (suffix)
+ sb._appendChar(suffix);
+}
+
+static void X86Assembler_dumpOperand(StringBuilder& sb, uint32_t arch, const Operand* op, uint32_t loggerOptions) {
+ if (op->isReg()) {
+ X86Assembler_dumpRegister(sb,
+ static_cast<const X86Reg*>(op)->getRegType(),
+ static_cast<const X86Reg*>(op)->getRegIndex());
+ }
+ else if (op->isMem()) {
+ const X86Mem* m = static_cast<const X86Mem*>(op);
+
+ uint32_t type = kX86RegTypeGpd;
+ uint32_t seg = m->getSegment();
+ bool isAbsolute = false;
+
+ if (arch == kArchX86) {
+ if (!m->hasGpdBase())
+ type = kX86RegTypeGpw;
+ }
+ else {
+ if (!m->hasGpdBase())
+ type = kX86RegTypeGpq;
+ }
+
+ if (op->getSize() <= 16)
+ sb._appendString(AssemblerX86_operandSize[op->getSize()]);
+
+ if (seg < kX86SegCount)
+ sb._appendString(&X86Assembler_segName[seg * 4]);
+
+ sb._appendChar('[');
+ switch (m->getMemType()) {
+ case kMemTypeBaseIndex:
+ case kMemTypeStackIndex:
+ // [base + index << shift + displacement]
+ X86Assembler_dumpRegister(sb, type, m->getBase());
+ break;
+
+ case kMemTypeLabel:
+ // [label + index << shift + displacement]
+ sb.appendFormat("L%u", m->getBase());
+ break;
+
+ case kMemTypeAbsolute:
+ // [absolute]
+ isAbsolute = true;
+ sb.appendUInt(static_cast<uint32_t>(m->getDisplacement()), 16);
+ break;
+ }
+
+ if (m->hasIndex()) {
+ switch (m->getVSib()) {
+ case kX86MemVSibXmm: type = kX86RegTypeXmm; break;
+ case kX86MemVSibYmm: type = kX86RegTypeYmm; break;
+ }
+
+ sb._appendChar('+');
+ X86Assembler_dumpRegister(sb, type, m->getIndex());
+
+ if (m->getShift()) {
+ sb._appendChar('*');
+ sb._appendChar("1248"[m->getShift() & 3]);
+ }
+ }
+
+ if (m->getDisplacement() && !isAbsolute) {
+ uint32_t base = 10;
+ int32_t dispOffset = m->getDisplacement();
+
+ char prefix = '+';
+ if (dispOffset < 0) {
+ dispOffset = -dispOffset;
+ prefix = '-';
+ }
+
+ sb._appendChar(prefix);
+ if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) {
+ sb._appendString("0x", 2);
+ base = 16;
+ }
+ sb.appendUInt(static_cast<uint32_t>(dispOffset), base);
+ }
+
+ sb._appendChar(']');
+ }
+ else if (op->isImm()) {
+ const Imm* i = static_cast<const Imm*>(op);
+ int64_t val = i->getInt64();
+
+ if ((loggerOptions & (1 << kLoggerOptionHexImmediate)) && static_cast<uint64_t>(val) > 9)
+ sb.appendUInt(static_cast<uint64_t>(val), 16);
+ else
+ sb.appendInt(val, 10);
+ }
+ else if (op->isLabel()) {
+ sb.appendFormat("L%u", op->getId());
+ }
+ else {
+ sb._appendString("None", 4);
+ }
+}
+
+static bool X86Assembler_dumpInstruction(StringBuilder& sb,
+ uint32_t arch,
+ uint32_t code, uint32_t options,
+ const Operand* o0,
+ const Operand* o1,
+ const Operand* o2,
+ const Operand* o3,
+ uint32_t loggerOptions) {
+
+ if (!sb.reserve(sb.getLength() + 128))
+ return false;
+
+ // Rex, lock and short prefix.
+ if (options & kX86InstOptionRex)
+ sb._appendString("rex ", 4);
+
+ if (options & kX86InstOptionLock)
+ sb._appendString("lock ", 5);
+
+ if (options & kInstOptionShortForm)
+ sb._appendString("short ", 6);
+
+ // Dump instruction name.
+ sb._appendString(_x86InstInfo[code].getInstName());
+
+ // Dump operands.
+ if (!o0->isNone()) {
+ sb._appendChar(' ');
+ X86Assembler_dumpOperand(sb, arch, o0, loggerOptions);
+ }
+
+ if (!o1->isNone()) {
+ sb._appendString(", ", 2);
+ X86Assembler_dumpOperand(sb, arch, o1, loggerOptions);
+ }
+
+ if (!o2->isNone()) {
+ sb._appendString(", ", 2);
+ X86Assembler_dumpOperand(sb, arch, o2, loggerOptions);
+ }
+
+ if (!o3->isNone()) {
+ sb._appendString(", ", 2);
+ X86Assembler_dumpOperand(sb, arch, o3, loggerOptions);
+ }
+
+ return true;
+}
+
+static bool X86Assembler_dumpComment(StringBuilder& sb, size_t len, const uint8_t* binData, size_t binLength, size_t dispSize, const char* comment) {
+ size_t currentLength = len;
+ size_t commentLength = comment ? StringUtil::nlen(comment, kMaxCommentLength) : 0;
+
+ ASMJIT_ASSERT(binLength >= dispSize);
+
+ if (binLength || commentLength) {
+ size_t align = 36;
+ char sep = ';';
+
+ for (size_t i = (binLength == 0); i < 2; i++) {
+ size_t begin = sb.getLength();
+
+ // Append align.
+ if (currentLength < align) {
+ if (!sb.appendChars(' ', align - currentLength))
+ return false;
+ }
+
+ // Append separator.
+ if (sep) {
+ if (!(sb.appendChar(sep) & sb.appendChar(' ')))
+ return false;
+ }
+
+ // Append binary data or comment.
+ if (i == 0) {
+ if (!sb.appendHex(binData, binLength - dispSize))
+ return false;
+ if (!sb.appendChars('.', dispSize * 2))
+ return false;
+ if (commentLength == 0)
+ break;
+ }
+ else {
+ if (!sb.appendString(comment, commentLength))
+ return false;
+ }
+
+ currentLength += sb.getLength() - begin;
+ align += 22;
+ sep = '|';
+ }
+ }
+
+ return sb.appendChar('\n');
+}
+#endif // !ASMJIT_DISABLE_LOGGER
// ============================================================================
-// [AsmJit::X86Assembler - Construction / Destruction]
+// [asmjit::X86Assembler - Emit]
// ============================================================================
-X86Assembler::X86Assembler(Context *context) : Assembler(context)
-{
- this->_properties = IntUtil::maskFromIndex(kX86PropertyOptimizedAlign);
+//! \internal
+static const Operand::VRegOp x86PatchedHiRegs[4] = {
+ // --------------+---+--------------------------------+--------------+------+
+ // Operand | S | Register Code | OperandId |Unused|
+ // --------------+---+--------------------------------+--------------+------+
+ { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 4, kInvalidValue, 0, 0 },
+ { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 5, kInvalidValue, 0, 0 },
+ { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 6, kInvalidValue, 0, 0 },
+ { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 7, kInvalidValue, 0, 0 }
+};
+
+template<int Arch>
+static Error ASMJIT_CDECL X86Assembler_emit(Assembler* self_, uint32_t code, const Operand* o0, const Operand* o1, const Operand* o2, const Operand* o3) {
+ X86Assembler* self = static_cast<X86Assembler*>(self_);
+
+ uint8_t* cursor = self->getCursor();
+ uint32_t encoded = o0->getOp() + (o1->getOp() << 3) + (o2->getOp() << 6);
+ uint32_t options = self->getInstOptionsAndReset();
+
+ // Invalid instruction.
+ if (code >= _kX86InstIdCount) {
+ self->_comment = nullptr;
+ return self->setError(kErrorUnknownInst);
+ }
+
+ // Instruction opcode.
+ uint32_t opCode;
+ // MODR/R opcode or register code.
+ uint32_t opReg;
+
+ // REX or VEX prefix data.
+ //
+ // REX:
+ // 0x0008 - REX.W.
+ // 0x0040 - Always emit REX prefix.
+ //
+ // AVX:
+ // 0x0008 - AVX.W.
+ // 0xF000 - VVVV, zeros by default, see `kVexVVVV`.
+ //
+ uint32_t opX;
+
+ // MOD/RM, both rmReg and rmMem should refer to the same variable since they
+ // are never used together - either rmReg or rmMem.
+ union {
+ // MODR/M - register code.
+ uintptr_t rmReg;
+ // MODR/M - Memory operand.
+ const X86Mem* rmMem;
+ };
+
+ // Immediate value.
+ int64_t imVal;
+ // Immediate length.
+ uint32_t imLen = 0;
+
+ // Memory operand base register index.
+ uint32_t mBase;
+ // Memory operand index register index.
+ uint32_t mIndex;
+
+ // Label.
+ LabelData* label;
+ // Displacement offset
+ int32_t dispOffset;
+ // Displacement size.
+ uint32_t dispSize = 0;
+ // Displacement relocation id.
+ intptr_t relocId;
+
+#ifdef ASMJIT_DEBUG
+ bool assertIllegal = false;
+#endif // ASMJIT_DEBUG
+
+ const X86InstInfo& info = _x86InstInfo[code];
+ const X86InstExtendedInfo& extendedInfo = info.getExtendedInfo();
+
+ // Grow request happens rarely. C++ compiler generates better code if it is
+ // handled at the end of the function.
+ if (static_cast<size_t>(self->_end - cursor) < 16)
+ goto _GrowBuffer;
+
+ // --------------------------------------------------------------------------
+ // [Prepare]
+ // --------------------------------------------------------------------------
+
+_Prepare:
+ opCode = info.getPrimaryOpCode();
+ opReg = opCode >> kX86InstOpCode_O_Shift;
+ opX = extendedInfo.getInstFlags() >> (15 - 3);
+
+ if (Arch == kArchX86) {
+ // AVX.W prefix.
+ opX &= 0x08;
+
+ // Check if one or more register operand is one of AH, BH, CH, or DH and
+ // patch them to ensure that the binary code with correct byte-index (4-7)
+ // is generated.
+ if (o0->isRegType(kX86RegTypeGpbHi))
+ o0 = reinterpret_cast<const Operand *>(&x86PatchedHiRegs[static_cast<const X86Reg*>(o0)->getRegIndex()]);
+
+ if (o1->isRegType(kX86RegTypeGpbHi))
+ o1 = reinterpret_cast<const Operand *>(&x86PatchedHiRegs[static_cast<const X86Reg*>(o1)->getRegIndex()]);
+ }
+ else {
+ ASMJIT_ASSERT(kX86InstOptionRex == 0x40);
+
+ // AVX.W prefix and REX prefix.
+ opX |= options;
+ opX &= 0x48;
+
+ // Check if one or more register operand is one of BPL, SPL, SIL, DIL and
+ // force a REX prefix in such case.
+ if (X86Reg::isGpbReg(*o0)) {
+ uint32_t index = static_cast<const X86Reg*>(o0)->getRegIndex();
+ if (static_cast<const X86Reg*>(o0)->isGpbLo()) {
+ opX |= (index >= 4) << kRexShift;
+ }
+ else {
+ opX |= kRexForbidden;
+ o0 = reinterpret_cast<const Operand*>(&x86PatchedHiRegs[index]);
+ }
+ }
+
+ if (X86Reg::isGpbReg(*o1)) {
+ uint32_t index = static_cast<const X86Reg*>(o1)->getRegIndex();
+ if (static_cast<const X86Reg*>(o1)->isGpbLo()) {
+ opX |= (index >= 4) << kRexShift;
+ }
+ else {
+ opX |= kRexForbidden;
+ o1 = reinterpret_cast<const Operand*>(&x86PatchedHiRegs[index]);
+ }
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // [Lock-Prefix]
+ // --------------------------------------------------------------------------
+
+ if (options & kX86InstOptionLock) {
+ if (!extendedInfo.isLockable())
+ goto _IllegalInst;
+ EMIT_BYTE(0xF0);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Group]
+ // --------------------------------------------------------------------------
+
+ switch (info.getInstGroup()) {
+ // ------------------------------------------------------------------------
+ // [None]
+ // ------------------------------------------------------------------------
+
+ case kX86InstGroupNone:
+ goto _EmitDone;
+
+ // ------------------------------------------------------------------------
+ // [X86]
+ // ------------------------------------------------------------------------
+
+ case kX86InstGroupX86Op_66H:
+ ADD_66H_P(true);
+ // ... Fall through ...
+
+ case kX86InstGroupX86Op:
+ goto _EmitX86Op;
+
+ case kX86InstGroupX86Rm_B:
+ opCode += o0->getSize() != 1;
+ // ... Fall through ...
+
+ case kX86InstGroupX86Rm:
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ if (encoded == ENC_OPS(Reg, None, None)) {
+ rmReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86RmReg:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opCode += o0->getSize() != 1;
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ opCode += o1->getSize() != 1;
+ ADD_66H_P_BY_SIZE(o1->getSize());
+ ADD_REX_W_BY_SIZE(o1->getSize());
+
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86RegRm:
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ ASMJIT_ASSERT(o0->getSize() != 1);
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ ASMJIT_ASSERT(o0->getSize() != 1);
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86M:
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86Arith:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opCode +=(o0->getSize() != 1) + 2;
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ opCode +=(o0->getSize() != 1) + 2;
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ opCode += o1->getSize() != 1;
+ ADD_66H_P_BY_SIZE(o1->getSize());
+ ADD_REX_W_BY_SIZE(o1->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+
+ // The remaining instructions use 0x80 opcode.
+ opCode = 0x80;
+
+ if (encoded == ENC_OPS(Reg, Imm, None)) {
+ imVal = static_cast<const Imm*>(o1)->getInt64();
+ imLen = IntUtil::isInt8(imVal) ? static_cast<uint32_t>(1) : IntUtil::iMin<uint32_t>(o0->getSize(), 4);
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ // Alternate Form - AL, AX, EAX, RAX.
+ if (rmReg == 0 && (o0->getSize() == 1 || imLen != 1)) {
+ opCode = ((opReg << 3) | (0x04 + (o0->getSize() != 1)));
+ imLen = IntUtil::iMin<uint32_t>(o0->getSize(), 4);
+ goto _EmitX86OpI;
+ }
+
+ opCode += o0->getSize() != 1 ? (imLen != 1 ? 1 : 3) : 0;
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, Imm, None)) {
+ uint32_t memSize = o0->getSize();
+
+ if (memSize == 0)
+ goto _IllegalInst;
+
+ imVal = static_cast<const Imm*>(o1)->getInt64();
+ imLen = IntUtil::isInt8(imVal) ? static_cast<uint32_t>(1) : IntUtil::iMin<uint32_t>(memSize, 4);
+
+ opCode += memSize != 1 ? (imLen != 1 ? 1 : 3) : 0;
+ ADD_66H_P_BY_SIZE(memSize);
+ ADD_REX_W_BY_SIZE(memSize);
+
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86BSwap:
+ if (encoded == ENC_OPS(Reg, None, None)) {
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ opCode += opReg & 0x7;
+
+ ADD_REX_W_BY_SIZE(o0->getSize());
+ ADD_REX_B(opReg);
+ goto _EmitX86Op;
+ }
+ break;
+
+ case kX86InstGroupX86BTest:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ ADD_66H_P_BY_SIZE(o1->getSize());
+ ADD_REX_W_BY_SIZE(o1->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ ADD_66H_P_BY_SIZE(o1->getSize());
+ ADD_REX_W_BY_SIZE(o1->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+
+ // The remaining instructions use the secondary opcode/r.
+ imVal = static_cast<const Imm*>(o1)->getInt64();
+ imLen = 1;
+
+ opCode = extendedInfo.getSecondaryOpCode();
+ opReg = opCode >> kX86InstOpCode_O_Shift;
+
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ if (encoded == ENC_OPS(Reg, Imm, None)) {
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, Imm, None)) {
+ if (o0->getSize() == 0)
+ goto _IllegalInst;
+
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86Call:
+ if (encoded == ENC_OPS(Reg, None, None)) {
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+
+ // The following instructions use the secondary opcode.
+ opCode = extendedInfo.getSecondaryOpCode();
+
+ if (encoded == ENC_OPS(Imm, None, None)) {
+ imVal = static_cast<const Imm*>(o0)->getInt64();
+ goto _EmitJmpOrCallAbs;
+ }
+
+ if (encoded == ENC_OPS(Label, None, None)) {
+ label = self->getLabelData(static_cast<const Label*>(o0)->getId());
+ if (label->offset != -1) {
+ // Bound label.
+ static const intptr_t kRel32Size = 5;
+ intptr_t offs = label->offset - static_cast<intptr_t>(cursor - self->_buffer);
+
+ ASMJIT_ASSERT(offs <= 0);
+ EMIT_OP(opCode);
+ EMIT_DWORD(static_cast<int32_t>(offs - kRel32Size));
+ }
+ else {
+ // Non-bound label.
+ EMIT_OP(opCode);
+ dispOffset = -4;
+ dispSize = 4;
+ relocId = -1;
+ goto _EmitDisplacement;
+ }
+ goto _EmitDone;
+ }
+ break;
+
+ case kX86InstGroupX86Enter:
+ if (encoded == ENC_OPS(Imm, Imm, None)) {
+ EMIT_BYTE(0xC8);
+ EMIT_WORD(static_cast<const Imm*>(o1)->getUInt16());
+ EMIT_BYTE(static_cast<const Imm*>(o0)->getUInt8());
+ goto _EmitDone;
+ }
+ break;
+
+ case kX86InstGroupX86Imul:
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ if (encoded == ENC_OPS(Reg, None, None)) {
+ opCode = 0xF6 + (o0->getSize() != 1);
+
+ opReg = 5;
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ opCode = 0xF6 + (o0->getSize() != 1);
+
+ opReg = 5;
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+
+ // The following instructions use 0x0FAF opcode.
+ opCode &= kX86InstOpCode_PP_66;
+ opCode |= kX86InstOpCode_MM_0F | 0xAF;
+
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ ASMJIT_ASSERT(o0->getSize() != 1);
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ ASMJIT_ASSERT(o0->getSize() != 1);
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+
+ goto _EmitX86M;
+ }
+
+ // The following instructions use 0x69/0x6B opcode.
+ opCode &= kX86InstOpCode_PP_66;
+ opCode |= 0x6B;
+
+ if (encoded == ENC_OPS(Reg, Imm, None)) {
+ ASMJIT_ASSERT(o0->getSize() != 1);
+
+ imVal = static_cast<const Imm*>(o1)->getInt64();
+ imLen = 1;
+
+ if (!IntUtil::isInt8(imVal)) {
+ opCode -= 2;
+ imLen = o0->getSize() == 2 ? 2 : 4;
+ }
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmReg = opReg;
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Imm)) {
+ ASMJIT_ASSERT(o0->getSize() != 1);
+
+ imVal = static_cast<const Imm*>(o2)->getInt64();
+ imLen = 1;
+
+ if (!IntUtil::isInt8(imVal)) {
+ opCode -= 2;
+ imLen = o0->getSize() == 2 ? 2 : 4;
+ }
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, Imm)) {
+ ASMJIT_ASSERT(o0->getSize() != 1);
+
+ imVal = static_cast<const Imm*>(o2)->getInt64();
+ imLen = 1;
+
+ if (!IntUtil::isInt8(imVal)) {
+ opCode -= 2;
+ imLen = o0->getSize() == 2 ? 2 : 4;
+ }
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86IncDec:
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ if (encoded == ENC_OPS(Reg, None, None)) {
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+
+ // INC r16|r32 is not encodable in 64-bit mode.
+ if (Arch == kArchX86 && (o0->getSize() == 2 || o0->getSize() == 4)) {
+ opCode &= kX86InstOpCode_PP_66;
+ opCode |= extendedInfo.getSecondaryOpCode() + (static_cast<uint32_t>(rmReg) & 0x7);
+ goto _EmitX86Op;
+ }
+ else {
+ opCode += o0->getSize() != 1;
+ goto _EmitX86R;
+ }
+ }
+
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ opCode += o0->getSize() != 1;
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86Int:
+ if (encoded == ENC_OPS(Imm, None, None)) {
+ imVal = static_cast<const Imm*>(o0)->getInt64();
+ uint8_t imm8 = static_cast<uint8_t>(imVal & 0xFF);
+
+ if (imm8 == 0x03) {
+ EMIT_OP(opCode);
+ }
+ else {
+ EMIT_OP(opCode + 1);
+ EMIT_BYTE(imm8);
+ }
+ goto _EmitDone;
+ }
+ break;
+
+ case kX86InstGroupX86Jcc:
+ if (encoded == ENC_OPS(Label, None, None)) {
+ label = self->getLabelData(static_cast<const Label*>(o0)->getId());
+
+ if (self->hasFeature(kCodeGenPredictedJumps)) {
+ if (options & kInstOptionTaken)
+ EMIT_BYTE(0x3E);
+ if (options & kInstOptionNotTaken)
+ EMIT_BYTE(0x2E);
+ }
+
+ if (label->offset != -1) {
+ // Bound label.
+ static const intptr_t kRel8Size = 2;
+ static const intptr_t kRel32Size = 6;
+
+ intptr_t offs = label->offset - static_cast<intptr_t>(cursor - self->_buffer);
+ ASMJIT_ASSERT(offs <= 0);
+
+ if ((options & kInstOptionLongForm) == 0 && IntUtil::isInt8(offs - kRel8Size)) {
+ EMIT_OP(opCode);
+ EMIT_BYTE(offs - kRel8Size);
+
+ options |= kInstOptionShortForm;
+ goto _EmitDone;
+ }
+ else {
+ EMIT_BYTE(0x0F);
+ EMIT_OP(opCode + 0x10);
+ EMIT_DWORD(static_cast<int32_t>(offs - kRel32Size));
+
+ options &= ~kInstOptionShortForm;
+ goto _EmitDone;
+ }
+ }
+ else {
+ // Non-bound label.
+ if (options & kInstOptionShortForm) {
+ EMIT_OP(opCode);
+ dispOffset = -1;
+ dispSize = 1;
+ relocId = -1;
+ goto _EmitDisplacement;
+ }
+ else {
+ EMIT_BYTE(0x0F);
+ EMIT_OP(opCode + 0x10);
+ dispOffset = -4;
+ dispSize = 4;
+ relocId = -1;
+ goto _EmitDisplacement;
+ }
+ }
+ }
+ break;
+
+ case kX86InstGroupX86Jecxz:
+ if (encoded == ENC_OPS(Reg, Label, None)) {
+ ASMJIT_ASSERT(static_cast<const X86Reg*>(o0)->getRegIndex() == kX86RegIndexCx);
+
+ if ((Arch == kArchX86 && o0->getSize() == 2) ||
+ (Arch == kArchX64 && o0->getSize() == 4)) {
+ EMIT_BYTE(0x67);
+ }
+
+ EMIT_BYTE(0xE3);
+ label = self->getLabelData(static_cast<const Label*>(o1)->getId());
+
+ if (label->offset != -1) {
+ // Bound label.
+ intptr_t offs = label->offset - static_cast<intptr_t>(cursor - self->_buffer) - 1;
+ if (!IntUtil::isInt8(offs))
+ goto _IllegalInst;
+
+ EMIT_BYTE(offs);
+ goto _EmitDone;
+ }
+ else {
+ // Non-bound label.
+ dispOffset = -1;
+ dispSize = 1;
+ relocId = -1;
+ goto _EmitDisplacement;
+ }
+ }
+ break;
+
+ case kX86InstGroupX86Jmp:
+ if (encoded == ENC_OPS(Reg, None, None)) {
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+
+ // The following instructions use the secondary opcode (0xE9).
+ opCode = 0xE9;
+
+ if (encoded == ENC_OPS(Imm, None, None)) {
+ imVal = static_cast<const Imm*>(o0)->getInt64();
+ goto _EmitJmpOrCallAbs;
+ }
+
+ if (encoded == ENC_OPS(Label, None, None)) {
+ label = self->getLabelData(static_cast<const Label*>(o0)->getId());
+ if (label->offset != -1) {
+ // Bound label.
+ const intptr_t kRel8Size = 2;
+ const intptr_t kRel32Size = 5;
+
+ intptr_t offs = label->offset - static_cast<intptr_t>(cursor - self->_buffer);
+
+ if ((options & kInstOptionLongForm) == 0 && IntUtil::isInt8(offs - kRel8Size)) {
+ options |= kInstOptionShortForm;
+
+ EMIT_BYTE(0xEB);
+ EMIT_BYTE(offs - kRel8Size);
+ goto _EmitDone;
+ }
+ else {
+ options &= ~kInstOptionShortForm;
+
+ EMIT_BYTE(0xE9);
+ EMIT_DWORD(static_cast<int32_t>(offs - kRel32Size));
+ goto _EmitDone;
+ }
+ }
+ else {
+ // Non-bound label.
+ if ((options & kInstOptionShortForm) != 0) {
+ EMIT_BYTE(0xEB);
+ dispOffset = -1;
+ dispSize = 1;
+ relocId = -1;
+ goto _EmitDisplacement;
+ }
+ else {
+ EMIT_BYTE(0xE9);
+ dispOffset = -4;
+ dispSize = 4;
+ relocId = -1;
+ goto _EmitDisplacement;
+ }
+ }
+ }
+ break;
+
+ case kX86InstGroupX86Lea:
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86Mov:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+
+ // Sreg <- Reg
+ if (static_cast<const X86Reg*>(o0)->isSeg()) {
+ ASMJIT_ASSERT(static_cast<const X86Reg*>(o1)->isGpw() ||
+ static_cast<const X86Reg*>(o1)->isGpd() ||
+ static_cast<const X86Reg*>(o1)->isGpq() );
+ opCode = 0x8E;
+ ADD_66H_P_BY_SIZE(o1->getSize());
+ ADD_REX_W_BY_SIZE(o1->getSize());
+ goto _EmitX86R;
+ }
+
+ // Reg <- Sreg
+ if (static_cast<const X86Reg*>(o1)->isSeg()) {
+ ASMJIT_ASSERT(static_cast<const X86Reg*>(o0)->isGpw() ||
+ static_cast<const X86Reg*>(o0)->isGpd() ||
+ static_cast<const X86Reg*>(o0)->isGpq() );
+ opCode = 0x8C;
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+ goto _EmitX86R;
+ }
+ // Reg <- Reg
+ else {
+ ASMJIT_ASSERT(static_cast<const X86Reg*>(o0)->isGpb() ||
+ static_cast<const X86Reg*>(o0)->isGpw() ||
+ static_cast<const X86Reg*>(o0)->isGpd() ||
+ static_cast<const X86Reg*>(o0)->isGpq() );
+ opCode = 0x8A + (o0->getSize() != 1);
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+ goto _EmitX86R;
+ }
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+
+ // Sreg <- Mem
+ if (static_cast<const X86Reg*>(o0)->isRegType(kX86RegTypeSeg)) {
+ opCode = 0x8E;
+ opReg--;
+ ADD_66H_P_BY_SIZE(o1->getSize());
+ ADD_REX_W_BY_SIZE(o1->getSize());
+ goto _EmitX86M;
+ }
+ // Reg <- Mem
+ else {
+ ASMJIT_ASSERT(static_cast<const X86Reg*>(o0)->isGpb() ||
+ static_cast<const X86Reg*>(o0)->isGpw() ||
+ static_cast<const X86Reg*>(o0)->isGpd() ||
+ static_cast<const X86Reg*>(o0)->isGpq() );
+ opCode = 0x8A + (o0->getSize() != 1);
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+ goto _EmitX86M;
+ }
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+
+ // X86Mem <- Sreg
+ if (static_cast<const X86Reg*>(o1)->isSeg()) {
+ opCode = 0x8C;
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+ goto _EmitX86M;
+ }
+ // X86Mem <- Reg
+ else {
+ ASMJIT_ASSERT(static_cast<const X86Reg*>(o1)->isGpb() ||
+ static_cast<const X86Reg*>(o1)->isGpw() ||
+ static_cast<const X86Reg*>(o1)->isGpd() ||
+ static_cast<const X86Reg*>(o1)->isGpq() );
+ opCode = 0x88 + (o1->getSize() != 1);
+ ADD_66H_P_BY_SIZE(o1->getSize());
+ ADD_REX_W_BY_SIZE(o1->getSize());
+ goto _EmitX86M;
+ }
+ }
+
+ if (encoded == ENC_OPS(Reg, Imm, None)) {
+ // 64-bit immediate in 64-bit mode is allowed.
+ imVal = static_cast<const Imm*>(o1)->getInt64();
+ imLen = o0->getSize();
+
+ opReg = 0;
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+
+ // Optimize instruction size by using 32-bit immediate if possible.
+ if (Arch == kArchX64 && imLen == 8 && IntUtil::isInt32(imVal)) {
+ opCode = 0xC7;
+ ADD_REX_W(1);
+ imLen = 4;
+ goto _EmitX86R;
+ }
+ else {
+ opCode = 0xB0 + (static_cast<uint32_t>(o0->getSize() != 1) << 3) + (static_cast<uint32_t>(rmReg) & 0x7);
+ ADD_REX_W_BY_SIZE(imLen);
+ ADD_REX_B(rmReg);
+ goto _EmitX86OpI;
+ }
+ }
+
+ if (encoded == ENC_OPS(Mem, Imm, None)) {
+ uint32_t memSize = o0->getSize();
+
+ if (memSize == 0)
+ goto _IllegalInst;
+
+ imVal = static_cast<const Imm*>(o1)->getInt64();
+ imLen = IntUtil::iMin<uint32_t>(memSize, 4);
+
+ opCode = 0xC6 + (memSize != 1);
+ opReg = 0;
+ ADD_66H_P_BY_SIZE(memSize);
+ ADD_REX_W_BY_SIZE(memSize);
+
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86MovSxZx:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opCode += o1->getSize() != 1;
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ opCode += o1->getSize() != 1;
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86MovSxd:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ ADD_REX_W(true);
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ ADD_REX_W(true);
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86MovPtr:
+ if (encoded == ENC_OPS(Reg, Imm, None)) {
+ ASMJIT_ASSERT(static_cast<const X86GpReg*>(o0)->getRegIndex() == 0);
+
+ opCode += o0->getSize() != 1;
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ imVal = static_cast<const Imm*>(o1)->getInt64();
+ imLen = self->_regSize;
+ goto _EmitX86OpI;
+ }
+
+ // The following instruction uses the secondary opcode.
+ opCode = extendedInfo.getSecondaryOpCode();
+
+ if (encoded == ENC_OPS(Imm, Reg, None)) {
+ ASMJIT_ASSERT(static_cast<const X86GpReg*>(o1)->getRegIndex() == 0);
+
+ opCode += o1->getSize() != 1;
+ ADD_66H_P_BY_SIZE(o1->getSize());
+ ADD_REX_W_BY_SIZE(o1->getSize());
+
+ imVal = static_cast<const Imm*>(o0)->getInt64();
+ imLen = self->_regSize;
+ goto _EmitX86OpI;
+ }
+ break;
+
+ case kX86InstGroupX86Push:
+ if (encoded == ENC_OPS(Reg, None, None)) {
+ if (o0->isRegType(kX86RegTypeSeg)) {
+ uint32_t segment = static_cast<const X86SegReg*>(o0)->getRegIndex();
+ ASMJIT_ASSERT(segment < kX86SegCount);
+
+ if (segment >= kX86SegFs)
+ EMIT_BYTE(0x0F);
+
+ EMIT_BYTE(x86OpCodePushSeg[segment]);
+ goto _EmitDone;
+ }
+ else {
+ goto _GroupPop_Gp;
+ }
+ }
+
+ if (encoded == ENC_OPS(Imm, None, None)) {
+ imVal = static_cast<const Imm*>(o0)->getInt64();
+ imLen = IntUtil::isInt8(imVal) ? 1 : 4;
+
+ EMIT_BYTE(imLen == 1 ? 0x6A : 0x68);
+ goto _EmitImm;
+ }
+ // ... Fall through ...
+
+ case kX86InstGroupX86Pop:
+ if (encoded == ENC_OPS(Reg, None, None)) {
+ if (o0->isRegType(kX86RegTypeSeg)) {
+ uint32_t segment = static_cast<const X86SegReg*>(o0)->getRegIndex();
+ ASMJIT_ASSERT(segment < kX86SegCount);
+
+ if (segment >= kX86SegFs)
+ EMIT_BYTE(0x0F);
+
+ EMIT_BYTE(x86OpCodePopSeg[segment]);
+ goto _EmitDone;
+ }
+ else {
+_GroupPop_Gp:
+ ASMJIT_ASSERT(static_cast<const X86Reg*>(o0)->getSize() == 2 ||
+ static_cast<const X86Reg*>(o0)->getSize() == self->_regSize);
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ opCode = extendedInfo.getSecondaryOpCode() + (opReg & 7);
+
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_B(opReg);
+
+ goto _EmitX86Op;
+ }
+ }
+
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ ADD_66H_P_BY_SIZE(o0->getSize());
+
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86Rep:
+ // Emit REP 0xF2 or 0xF3 prefix first.
+ EMIT_BYTE(0xF2 + opReg);
+ goto _EmitX86Op;
+
+ case kX86InstGroupX86Ret:
+ if (encoded == ENC_OPS(None, None, None)) {
+ EMIT_BYTE(0xC3);
+ goto _EmitDone;
+ }
+
+ if (encoded == ENC_OPS(Imm, None, None)) {
+ imVal = static_cast<const Imm*>(o0)->getInt64();
+ if (imVal == 0) {
+ EMIT_BYTE(0xC3);
+ goto _EmitDone;
+ }
+ else {
+ EMIT_BYTE(0xC2);
+ imLen = 2;
+ goto _EmitImm;
+ }
+ }
+ break;
+
+ case kX86InstGroupX86Rot:
+ opCode += o0->getSize() != 1;
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ ASMJIT_ASSERT(static_cast<const X86Reg*>(o1)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx));
+ opCode += 2;
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ ASMJIT_ASSERT(static_cast<const X86Reg*>(o1)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx));
+ opCode += 2;
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+
+ if (encoded == ENC_OPS(Reg, Imm, None)) {
+ imVal = static_cast<const Imm*>(o1)->getInt64() & 0xFF;
+ imLen = imVal != 1;
+ if (imLen)
+ opCode -= 0x10;
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, Imm, None)) {
+ if (o0->getSize() == 0)
+ goto _IllegalInst;
+
+ imVal = static_cast<const Imm*>(o1)->getInt64() & 0xFF;
+ imLen = imVal != 1;
+ if (imLen)
+ opCode -= 0x10;
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86Set:
+ if (encoded == ENC_OPS(Reg, None, None)) {
+ ASMJIT_ASSERT(o0->getSize() == 1);
+
+ rmReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ ASMJIT_ASSERT(o0->getSize() <= 1);
+
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86Shlrd:
+ if (encoded == ENC_OPS(Reg, Reg, Imm)) {
+ ASMJIT_ASSERT(o0->getSize() == o1->getSize());
+
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ imVal = static_cast<const Imm*>(o2)->getInt64();
+ imLen = 1;
+
+ opReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, Imm)) {
+ ADD_66H_P_BY_SIZE(o1->getSize());
+ ADD_REX_W_BY_SIZE(o1->getSize());
+
+ imVal = static_cast<const Imm*>(o2)->getInt64();
+ imLen = 1;
+
+ opReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+
+ // The following instructions use opCode + 1.
+ opCode++;
+
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ ASMJIT_ASSERT(static_cast<const X86Reg*>(o2)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx));
+ ASMJIT_ASSERT(o0->getSize() == o1->getSize());
+
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, Reg)) {
+ ASMJIT_ASSERT(static_cast<const X86Reg*>(o2)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx));
+
+ ADD_66H_P_BY_SIZE(o1->getSize());
+ ADD_REX_W_BY_SIZE(o1->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86Test:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ ASMJIT_ASSERT(o0->getSize() == o1->getSize());
+
+ opCode += o0->getSize() != 1;
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ opCode += o1->getSize() != 1;
+ ADD_66H_P_BY_SIZE(o1->getSize());
+ ADD_REX_W_BY_SIZE(o1->getSize());
+
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+
+ // The following instructions use the secondary opcode.
+ opCode = extendedInfo.getSecondaryOpCode() + (o0->getSize() != 1);
+ opReg = opCode >> kX86InstOpCode_O_Shift;
+
+ if (encoded == ENC_OPS(Reg, Imm, None)) {
+ imVal = static_cast<const Imm*>(o1)->getInt64();
+ imLen = IntUtil::iMin<uint32_t>(o0->getSize(), 4);
+
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ // Alternate Form - AL, AX, EAX, RAX.
+ if (static_cast<const X86GpReg*>(o0)->getRegIndex() == 0) {
+ opCode &= kX86InstOpCode_PP_66;
+ opCode |= 0xA8 + (o0->getSize() != 1);
+ goto _EmitX86OpI;
+ }
+
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, Imm, None)) {
+ if (o0->getSize() == 0)
+ goto _IllegalInst;
+
+ imVal = static_cast<const Imm*>(o1)->getInt64();
+ imLen = IntUtil::iMin<uint32_t>(o0->getSize(), 4);
+
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupX86Xchg:
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ opCode += o0->getSize() != 1;
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+ // ... fall through ...
+
+ case kX86InstGroupX86Xadd:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ rmReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ // Special opcode for 'xchg ?ax, reg'.
+ if (code == kX86InstIdXchg && o0->getSize() > 1 && (opReg == 0 || rmReg == 0)) {
+ // One of them is zero, it doesn't matter if the instruction's form is
+ // 'xchg ?ax, reg' or 'xchg reg, ?ax'.
+ opReg += rmReg;
+
+ // Rex.B (0x01).
+ if (Arch == kArchX64) {
+ opX += opReg >> 3;
+ opReg &= 0x7;
+ }
+
+ opCode &= kX86InstOpCode_PP_66;
+ opCode |= 0x90 + opReg;
+ goto _EmitX86Op;
+ }
+
+ opCode += o0->getSize() != 1;
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ opCode += o1->getSize() != 1;
+ ADD_66H_P_BY_SIZE(o1->getSize());
+ ADD_REX_W_BY_SIZE(o1->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ // ------------------------------------------------------------------------
+ // [Fpu]
+ // ------------------------------------------------------------------------
+
+ case kX86InstGroupFpuOp:
+ goto _EmitFpuOp;
+
+ case kX86InstGroupFpuArith:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opReg = static_cast<const X86FpReg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86FpReg*>(o1)->getRegIndex();
+ rmReg += opReg;
+
+ // We switch to the alternative opcode if the first operand is zero.
+ if (opReg == 0) {
+_EmitFpArith_Reg:
+ opCode = 0xD800 + ((opCode >> 8) & 0xFF) + static_cast<uint32_t>(rmReg);
+ goto _EmitFpuOp;
+ }
+ else {
+ opCode = 0xDC00 + ((opCode >> 0) & 0xFF) + static_cast<uint32_t>(rmReg);
+ goto _EmitFpuOp;
+ }
+ }
+
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ // 0xD8/0xDC, depends on the size of the memory operand; opReg has been
+ // set already.
+_EmitFpArith_Mem:
+ opCode = (o0->getSize() == 4) ? 0xD8 : 0xDC;
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupFpuCom:
+ if (encoded == ENC_OPS(None, None, None)) {
+ rmReg = 1;
+ goto _EmitFpArith_Reg;
+ }
+
+ if (encoded == ENC_OPS(Reg, None, None)) {
+ rmReg = static_cast<const X86FpReg*>(o0)->getRegIndex();
+ goto _EmitFpArith_Reg;
+ }
+
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ goto _EmitFpArith_Mem;
+ }
+ break;
+
+ case kX86InstGroupFpuFldFst:
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ rmMem = static_cast<const X86Mem*>(o0);
+
+ if (o0->getSize() == 4 && info.hasInstFlag(kX86InstFlagMem4)) {
+ goto _EmitX86M;
+ }
+
+ if (o0->getSize() == 8 && info.hasInstFlag(kX86InstFlagMem8)) {
+ opCode += 4;
+ goto _EmitX86M;
+ }
+
+ if (o0->getSize() == 10 && info.hasInstFlag(kX86InstFlagMem10)) {
+ opCode = extendedInfo.getSecondaryOpCode();
+ opReg = opCode >> kX86InstOpCode_O_Shift;
+ goto _EmitX86M;
+ }
+ }
+
+ if (encoded == ENC_OPS(Reg, None, None)) {
+ if (code == kX86InstIdFld) {
+ opCode = 0xD9C0 + static_cast<const X86FpReg*>(o0)->getRegIndex();
+ goto _EmitFpuOp;
+ }
+
+ if (code == kX86InstIdFst) {
+ opCode = 0xDDD0 + static_cast<const X86FpReg*>(o0)->getRegIndex();
+ goto _EmitFpuOp;
+ }
+
+ if (code == kX86InstIdFstp) {
+ opCode = 0xDDD8 + static_cast<const X86FpReg*>(o0)->getRegIndex();
+ goto _EmitFpuOp;
+ }
+ }
+ break;
+
+
+ case kX86InstGroupFpuM:
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ rmMem = static_cast<const X86Mem*>(o0);
+
+ if (o0->getSize() == 2 && info.hasInstFlag(kX86InstFlagMem2)) {
+ opCode += 4;
+ goto _EmitX86M;
+ }
+
+ if (o0->getSize() == 4 && info.hasInstFlag(kX86InstFlagMem4)) {
+ goto _EmitX86M;
+ }
+
+ if (o0->getSize() == 8 && info.hasInstFlag(kX86InstFlagMem8)) {
+ opCode = extendedInfo.getSecondaryOpCode();
+ opReg = opCode >> kX86InstOpCode_O_Shift;
+ goto _EmitX86M;
+ }
+ }
+ break;
+
+ case kX86InstGroupFpuRDef:
+ if (encoded == ENC_OPS(None, None, None)) {
+ opCode += 1;
+ goto _EmitFpuOp;
+ }
+ // ... Fall through ...
+
+ case kX86InstGroupFpuR:
+ if (encoded == ENC_OPS(Reg, None, None)) {
+ opCode += static_cast<const X86FpReg*>(o0)->getRegIndex();
+ goto _EmitFpuOp;
+ }
+ break;
+
+ case kX86InstGroupFpuStsw:
+ if (encoded == ENC_OPS(Reg, None, None)) {
+ if (static_cast<const X86GpReg*>(o0)->getRegIndex() != 0)
+ goto _IllegalInst;
+
+ opCode = extendedInfo.getSecondaryOpCode();
+ goto _EmitX86Op;
+ }
+
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ // ------------------------------------------------------------------------
+ // [Ext]
+ // ------------------------------------------------------------------------
+
+ case kX86InstGroupExtCrc:
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ ASMJIT_ASSERT(static_cast<const Reg*>(o0)->getRegType() == kX86RegTypeGpd ||
+ static_cast<const Reg*>(o0)->getRegType() == kX86RegTypeGpq);
+
+ opCode += o0->getSize() != 1;
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ ASMJIT_ASSERT(static_cast<const Reg*>(o0)->getRegType() == kX86RegTypeGpd ||
+ static_cast<const Reg*>(o0)->getRegType() == kX86RegTypeGpq);
+
+ opCode += o0->getSize() != 1;
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupExtExtract:
+ if (encoded == ENC_OPS(Reg, Reg, Imm)) {
+ ADD_66H_P(static_cast<const X86Reg*>(o1)->isXmm());
+
+ imVal = static_cast<const Imm*>(o2)->getInt64();
+ imLen = 1;
+
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, Imm)) {
+ // Secondary opcode for 'pextrw' instruction (SSE2).
+ opCode = extendedInfo.getSecondaryOpCode();
+ ADD_66H_P(static_cast<const X86Reg*>(o1)->isXmm());
+
+ imVal = static_cast<const Imm*>(o2)->getInt64();
+ imLen = 1;
+
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupExtFence:
+ if (Arch == kArchX64 && opX) {
+ EMIT_BYTE(0x40 | opX);
+ }
+
+ EMIT_BYTE(0x0F);
+ EMIT_OP(opCode);
+ EMIT_BYTE(0xC0 | (opReg << 3));
+ goto _EmitDone;
+
+ case kX86InstGroupExtMov:
+ case kX86InstGroupExtMovNoRexW:
+ ASMJIT_ASSERT(extendedInfo._opFlags[0] != 0);
+ ASMJIT_ASSERT(extendedInfo._opFlags[1] != 0);
+
+ // Check parameters Gpd|Gpq|Mm|Xmm <- Gpd|Gpq|Mm|Xmm|X86Mem|Imm.
+ ASMJIT_ASSERT(!((o0->isMem() && (extendedInfo._opFlags[0] & kX86InstOpMem) == 0) ||
+ (o0->isRegType(kX86RegTypeMm ) && (extendedInfo._opFlags[0] & kX86InstOpMm ) == 0) ||
+ (o0->isRegType(kX86RegTypeXmm) && (extendedInfo._opFlags[0] & kX86InstOpXmm) == 0) ||
+ (o0->isRegType(kX86RegTypeGpd) && (extendedInfo._opFlags[0] & kX86InstOpGd ) == 0) ||
+ (o0->isRegType(kX86RegTypeGpq) && (extendedInfo._opFlags[0] & kX86InstOpGq ) == 0) ||
+ (o1->isMem() && (extendedInfo._opFlags[1] & kX86InstOpMem) == 0) ||
+ (o1->isRegType(kX86RegTypeMm ) && (extendedInfo._opFlags[1] & kX86InstOpMm ) == 0) ||
+ (o1->isRegType(kX86RegTypeXmm) && (extendedInfo._opFlags[1] & kX86InstOpXmm) == 0) ||
+ (o1->isRegType(kX86RegTypeGpd) && (extendedInfo._opFlags[1] & kX86InstOpGd ) == 0) ||
+ (o1->isRegType(kX86RegTypeGpq) && (extendedInfo._opFlags[1] & kX86InstOpGq ) == 0) ));
+
+ // Gp|Mm|Xmm <- Gp|Mm|Xmm
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ ADD_REX_W(static_cast<const X86Reg*>(o0)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW));
+ ADD_REX_W(static_cast<const X86Reg*>(o1)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW));
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ // Gp|Mm|Xmm <- Mem
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ ADD_REX_W(static_cast<const X86Reg*>(o0)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW));
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+
+ // The following instruction uses opCode[1].
+ opCode = extendedInfo.getSecondaryOpCode();
+
+ // X86Mem <- Gp|Mm|Xmm
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ ADD_REX_W(static_cast<const X86Reg*>(o1)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW));
+
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupExtMovBe:
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ ADD_66H_P_BY_SIZE(o0->getSize());
+ ADD_REX_W_BY_SIZE(o0->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+
+ // The following instruction uses the secondary opcode.
+ opCode = extendedInfo.getSecondaryOpCode();
+
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ ADD_66H_P_BY_SIZE(o1->getSize());
+ ADD_REX_W_BY_SIZE(o1->getSize());
+
+ opReg = static_cast<const X86GpReg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupExtMovD:
+_EmitMmMovD:
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ ADD_66H_P(static_cast<const X86Reg*>(o0)->isXmm());
+
+ // Mm/Xmm <- Gp
+ if (encoded == ENC_OPS(Reg, Reg, None) && static_cast<const X86Reg*>(o1)->isGp()) {
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ // Mm/Xmm <- Mem
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+
+ // The following instructions use the secondary opcode.
+ opCode = extendedInfo.getSecondaryOpCode();
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ ADD_66H_P(static_cast<const X86Reg*>(o1)->isXmm());
+
+ // Gp <- Mm/Xmm
+ if (encoded == ENC_OPS(Reg, Reg, None) && static_cast<const X86Reg*>(o0)->isGp()) {
+ rmReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ // X86Mem <- Mm/Xmm
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupExtMovQ:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+
+ // Mm <- Mm
+ if (static_cast<const X86Reg*>(o0)->isMm() && static_cast<const X86Reg*>(o1)->isMm()) {
+ opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x6F;
+ goto _EmitX86R;
+ }
+
+ // Xmm <- Xmm
+ if (static_cast<const X86Reg*>(o0)->isXmm() && static_cast<const X86Reg*>(o1)->isXmm()) {
+ opCode = kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | 0x7E;
+ goto _EmitX86R;
+ }
+
+ // Mm <- Xmm (Movdq2q)
+ if (static_cast<const X86Reg*>(o0)->isMm() && static_cast<const X86Reg*>(o1)->isXmm()) {
+ opCode = kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F | 0xD6;
+ goto _EmitX86R;
+ }
+
+ // Xmm <- Mm (Movq2dq)
+ if (static_cast<const X86Reg*>(o0)->isXmm() && static_cast<const X86Reg*>(o1)->isMm()) {
+ opCode = kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | 0xD6;
+ goto _EmitX86R;
+ }
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+
+ // Mm <- Mem
+ if (static_cast<const X86Reg*>(o0)->isMm()) {
+ opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x6F;
+ goto _EmitX86M;
+ }
+
+ // Xmm <- Mem
+ if (static_cast<const X86Reg*>(o0)->isXmm()) {
+ opCode = kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | 0x7E;
+ goto _EmitX86M;
+ }
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+
+ // X86Mem <- Mm
+ if (static_cast<const X86Reg*>(o1)->isMm()) {
+ opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x7F;
+ goto _EmitX86M;
+ }
+
+ // X86Mem <- Xmm
+ if (static_cast<const X86Reg*>(o1)->isXmm()) {
+ opCode = kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F | 0xD6;
+ goto _EmitX86M;
+ }
+ }
+
+ if (Arch == kArchX64) {
+ // Movq in other case is simply a promoted MOVD instruction to 64-bit.
+ ADD_REX_W(true);
+
+ opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x6E;
+ goto _EmitMmMovD;
+ }
+ break;
+
+ case kX86InstGroupExtPrefetch:
+ if (encoded == ENC_OPS(Mem, Imm, None)) {
+ opReg = static_cast<const Imm*>(o1)->getUInt32() & 0x3;
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupExtRm_PQ:
+ ADD_66H_P(o0->isRegType(kX86RegTypeXmm) || o1->isRegType(kX86RegTypeXmm));
+ // ... Fall through ...
+
+ case kX86InstGroupExtRm_Q:
+ ADD_REX_W(o0->isRegType(kX86RegTypeGpq) || o1->isRegType(kX86RegTypeGpq) || (o1->isMem() && o1->getSize() == 8));
+ // ... Fall through ...
+
+ case kX86InstGroupExtRm:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupExtRm_P:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ ADD_66H_P(static_cast<const X86Reg*>(o0)->isXmm() | static_cast<const X86Reg*>(o1)->isXmm());
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ ADD_66H_P(static_cast<const X86Reg*>(o0)->isXmm());
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupExtRmRi:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+
+ // The following instruction uses the secondary opcode.
+ opCode = extendedInfo.getSecondaryOpCode();
+ opReg = opCode >> kX86InstOpCode_O_Shift;
+
+ if (encoded == ENC_OPS(Reg, Imm, None)) {
+ imVal = static_cast<const Imm*>(o1)->getInt64();
+ imLen = 1;
+
+ rmReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+ break;
+
+ case kX86InstGroupExtRmRi_P:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ ADD_66H_P(static_cast<const X86Reg*>(o0)->isXmm() | static_cast<const X86Reg*>(o1)->isXmm());
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ ADD_66H_P(static_cast<const X86Reg*>(o0)->isXmm());
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+
+ // The following instruction uses the secondary opcode.
+ opCode = extendedInfo.getSecondaryOpCode();
+ opReg = opCode >> kX86InstOpCode_O_Shift;
+
+ if (encoded == ENC_OPS(Reg, Imm, None)) {
+ ADD_66H_P(static_cast<const X86Reg*>(o0)->isXmm());
+
+ imVal = static_cast<const Imm*>(o1)->getInt64();
+ imLen = 1;
+
+ rmReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ goto _EmitX86R;
+ }
+ break;
+
+ case kX86InstGroupExtRmi:
+ imVal = static_cast<const Imm*>(o2)->getInt64();
+ imLen = 1;
+
+ if (encoded == ENC_OPS(Reg, Reg, Imm)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, Imm)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+ break;
+
+ case kX86InstGroupExtRmi_P:
+ imVal = static_cast<const Imm*>(o2)->getInt64();
+ imLen = 1;
+
+ if (encoded == ENC_OPS(Reg, Reg, Imm)) {
+ ADD_66H_P(static_cast<const X86Reg*>(o0)->isXmm() | static_cast<const X86Reg*>(o1)->isXmm());
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, Imm)) {
+ ADD_66H_P(static_cast<const X86Reg*>(o0)->isXmm());
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+ break;
+
+ // ------------------------------------------------------------------------
+ // [Group - 3dNow]
+ // ------------------------------------------------------------------------
+
+ case kX86InstGroup3dNow:
+ // Every 3dNow instruction starts with 0x0F0F and the actual opcode is
+ // stored as 8-bit immediate.
+ imVal = opCode & 0xFF;
+ imLen = 1;
+
+ opCode = kX86InstOpCode_MM_0F | 0x0F;
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitX86R;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitX86M;
+ }
+ break;
+
+ // ------------------------------------------------------------------------
+ // [Avx]
+ // ------------------------------------------------------------------------
+
+ case kX86InstGroupAvxOp:
+ goto _EmitAvxOp;
+
+ case kX86InstGroupAvxM:
+ if (encoded == ENC_OPS(Mem, None, None)) {
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxMr_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupAvxMr:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxMri_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupAvxMri:
+ imVal = static_cast<const Imm*>(o2)->getInt64();
+ imLen = 1;
+
+ if (encoded == ENC_OPS(Reg, Reg, Imm)) {
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, Imm)) {
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxRm_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupAvxRm:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxRmi_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupAvxRmi:
+ imVal = static_cast<const Imm*>(o2)->getInt64();
+ imLen = 1;
+
+ if (encoded == ENC_OPS(Reg, Reg, Imm)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, Imm)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxRvm_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupAvxRvm:
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+_EmitAvxRvm:
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o2)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxRvmr_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupAvxRvmr:
+ if (!o3->isReg())
+ goto _IllegalInst;
+
+ imVal = static_cast<const X86Reg*>(o3)->getRegIndex() << 4;
+ imLen = 1;
+
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o2)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxRvmi_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupAvxRvmi:
+ if (!o3->isImm())
+ goto _IllegalInst;
+
+ imVal = static_cast<const Imm*>(o3)->getInt64();
+ imLen = 1;
+
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o2)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxRmv:
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o2)->getRegIndex() << kVexVVVVShift;
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o2)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxRmvi:
+ if (!o3->isImm())
+ goto _IllegalInst;
+
+ imVal = static_cast<const Imm*>(o3)->getInt64();
+ imLen = 1;
+
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o2)->getRegIndex() << kVexVVVVShift;
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o2)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxRmMr_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupAvxRmMr:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitAvxM;
+ }
+
+ // The following instruction uses the secondary opcode.
+ opCode = extendedInfo.getSecondaryOpCode();
+
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxRvmRmi_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupAvxRvmRmi:
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o2)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+ goto _EmitAvxM;
+ }
+
+ // The following instructions use the secondary opcode.
+ opCode &= kX86InstOpCode_L_Mask;
+ opCode |= extendedInfo.getSecondaryOpCode();
+
+ imVal = static_cast<const Imm*>(o2)->getInt64();
+ imLen = 1;
+
+ if (encoded == ENC_OPS(Reg, Reg, Imm)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, Imm)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxRvmMr:
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o2)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+ goto _EmitAvxM;
+ }
+
+ // The following instructions use the secondary opcode.
+ opCode = extendedInfo.getSecondaryOpCode();
+
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxRvmMvr_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupAvxRvmMvr:
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o2)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+ goto _EmitAvxM;
+ }
+
+ // The following instruction uses the secondary opcode.
+ opCode &= kX86InstOpCode_L_Mask;
+ opCode |= extendedInfo.getSecondaryOpCode();
+
+ if (encoded == ENC_OPS(Mem, Reg, Reg)) {
+ opReg = static_cast<const X86Reg*>(o2)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxRvmVmi_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupAvxRvmVmi:
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o2)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+ goto _EmitAvxM;
+ }
+
+ // The following instruction uses the secondary opcode.
+ opCode &= kX86InstOpCode_L_Mask;
+ opCode |= extendedInfo.getSecondaryOpCode();
+ opReg = opCode >> kX86InstOpCode_O_Shift;
+
+ imVal = static_cast<const Imm*>(o2)->getInt64();
+ imLen = 1;
+
+ if (encoded == ENC_OPS(Reg, Reg, Imm)) {
+ opX |= static_cast<const X86Reg*>(o0)->getRegIndex() << kVexVVVVShift;
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, Imm)) {
+ opX |= static_cast<const X86Reg*>(o0)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxVm:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opX |= static_cast<const X86Reg*>(o0)->getRegIndex() << kVexVVVVShift;
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ opX |= static_cast<const X86Reg*>(o0)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxVmi_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupAvxVmi:
+ imVal = static_cast<const Imm*>(o3)->getInt64();
+ imLen = 1;
+
+ if (encoded == ENC_OPS(Reg, Reg, Imm)) {
+ opX |= static_cast<const X86Reg*>(o0)->getRegIndex() << kVexVVVVShift;
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, Imm)) {
+ opX |= static_cast<const X86Reg*>(o0)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxRvrmRvmr_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupAvxRvrmRvmr:
+ if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isReg()) {
+ imVal = static_cast<const X86Reg*>(o3)->getRegIndex() << 4;
+ imLen = 1;
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmReg = static_cast<const X86Reg*>(o2)->getRegIndex();
+
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isMem()) {
+ imVal = static_cast<const X86Reg*>(o2)->getRegIndex() << 4;
+ imLen = 1;
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o3);
+
+ ADD_VEX_W(true);
+ goto _EmitAvxM;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem) && o3->isReg()) {
+ imVal = static_cast<const X86Reg*>(o3)->getRegIndex() << 4;
+ imLen = 1;
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxMovSsSd:
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ goto _EmitAvxRvm;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ opX |= static_cast<const X86Reg*>(o0)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitAvxM;
+ }
+
+ if (encoded == ENC_OPS(Mem, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o0);
+ goto _EmitAvxM;
+ }
+ break;
+
+ case kX86InstGroupAvxGatherEx:
+ if (encoded == ENC_OPS(Reg, Mem, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o2)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o1);
+
+ uint32_t vSib = rmMem->getVSib();
+ if (vSib == kX86MemVSibGpz)
+ goto _IllegalInst;
+
+ ADD_VEX_L(vSib == kX86MemVSibYmm);
+ goto _EmitAvxV;
+ }
+ break;
+
+ case kX86InstGroupAvxGather:
+ if (encoded == ENC_OPS(Reg, Mem, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o2)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o1);
+
+ uint32_t vSib = rmMem->getVSib();
+ if (vSib == kX86MemVSibGpz)
+ goto _IllegalInst;
+
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o2)->isYmm());
+ goto _EmitAvxV;
+ }
+ break;
+
+ // ------------------------------------------------------------------------
+ // [FMA4]
+ // ------------------------------------------------------------------------
+
+ case kX86InstGroupFma4_P:
+ // It's fine to just check the first operand, second is just for sanity.
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupFma4:
+ if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isReg()) {
+ imVal = static_cast<const X86Reg*>(o3)->getRegIndex() << 4;
+ imLen = 1;
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmReg = static_cast<const X86Reg*>(o2)->getRegIndex();
+
+ goto _EmitAvxR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isMem()) {
+ imVal = static_cast<const X86Reg*>(o2)->getRegIndex() << 4;
+ imLen = 1;
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o3);
+
+ ADD_VEX_W(true);
+ goto _EmitAvxM;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem) && o3->isReg()) {
+ imVal = static_cast<const X86Reg*>(o3)->getRegIndex() << 4;
+ imLen = 1;
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+
+ goto _EmitAvxM;
+ }
+ break;
+
+ // ------------------------------------------------------------------------
+ // [XOP]
+ // ------------------------------------------------------------------------
+
+ case kX86InstGroupXopRm_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupXopRm:
+ if (encoded == ENC_OPS(Reg, Reg, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitXopR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, None)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitXopM;
+ }
+ break;
+
+ case kX86InstGroupXopRvmRmv:
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o2)->getRegIndex() << kVexVVVVShift;
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+
+ goto _EmitXopR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o2)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o1);
+
+ goto _EmitXopM;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+
+ ADD_VEX_W(true);
+ goto _EmitXopM;
+ }
+
+ break;
+
+ case kX86InstGroupXopRvmRmi:
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o2)->getRegIndex() << kVexVVVVShift;
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitXopR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o2)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o1);
+
+ goto _EmitXopM;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+
+ ADD_VEX_W(true);
+ goto _EmitXopM;
+ }
+
+ // The following instructions use the secondary opcode.
+ opCode = extendedInfo.getSecondaryOpCode();
+
+ imVal = static_cast<const Imm*>(o2)->getInt64();
+ imLen = 1;
+
+ if (encoded == ENC_OPS(Reg, Reg, Imm)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o1)->getRegIndex();
+ goto _EmitXopR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Mem, Imm)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmMem = static_cast<const X86Mem*>(o1);
+ goto _EmitXopM;
+ }
+ break;
+
+ case kX86InstGroupXopRvmr_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupXopRvmr:
+ if (!o3->isReg())
+ goto _IllegalInst;
+
+ imVal = static_cast<const X86Reg*>(o3)->getRegIndex() << 4;
+ imLen = 1;
+
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o2)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ goto _EmitXopR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+ goto _EmitXopM;
+ }
+ break;
+
+ case kX86InstGroupXopRvmi_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupXopRvmi:
+ if (!o3->isImm())
+ goto _IllegalInst;
+
+ imVal = static_cast<const Imm*>(o3)->getInt64();
+ imLen = 1;
+
+ if (encoded == ENC_OPS(Reg, Reg, Reg)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ rmReg = static_cast<const X86Reg*>(o2)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ goto _EmitXopR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem)) {
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+ goto _EmitXopM;
+ }
+ break;
+
+ case kX86InstGroupXopRvrmRvmr_P:
+ ADD_VEX_L(static_cast<const X86Reg*>(o0)->isYmm() | static_cast<const X86Reg*>(o1)->isYmm());
+ // ... Fall through ...
+
+ case kX86InstGroupXopRvrmRvmr:
+ if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isReg()) {
+ imVal = static_cast<const X86Reg*>(o3)->getRegIndex() << 4;
+ imLen = 1;
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmReg = static_cast<const X86Reg*>(o2)->getRegIndex();
+
+ goto _EmitXopR;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isMem()) {
+ imVal = static_cast<const X86Reg*>(o2)->getRegIndex() << 4;
+ imLen = 1;
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o3);
+
+ ADD_VEX_W(true);
+ goto _EmitXopM;
+ }
+
+ if (encoded == ENC_OPS(Reg, Reg, Mem) && o3->isReg()) {
+ imVal = static_cast<const X86Reg*>(o3)->getRegIndex() << 4;
+ imLen = 1;
+
+ opReg = static_cast<const X86Reg*>(o0)->getRegIndex();
+ opX |= static_cast<const X86Reg*>(o1)->getRegIndex() << kVexVVVVShift;
+ rmMem = static_cast<const X86Mem*>(o2);
+
+ goto _EmitXopM;
+ }
+ break;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Illegal]
+ // --------------------------------------------------------------------------
+
+_IllegalInst:
+ self->setError(kErrorIllegalInst);
+#ifdef ASMJIT_DEBUG
+ assertIllegal = true;
+#endif // ASMJIT_DEBUG
+ goto _EmitDone;
+
+_IllegalAddr:
+ self->setError(kErrorIllegalAddresing);
+#ifdef ASMJIT_DEBUG
+ assertIllegal = true;
+#endif // ASMJIT_DEBUG
+ goto _EmitDone;
+
+_IllegalDisp:
+ self->setError(kErrorIllegalDisplacement);
+#ifdef ASMJIT_DEBUG
+ assertIllegal = true;
+#endif // ASMJIT_DEBUG
+ goto _EmitDone;
+
+ // --------------------------------------------------------------------------
+ // [Emit - X86]
+ // --------------------------------------------------------------------------
+
+_EmitX86Op:
+ // Mandatory instruction prefix.
+ EMIT_PP(opCode);
+
+ // Rex prefix (64-bit only).
+ if (Arch == kArchX64 && opX) {
+ opX |= 0x40;
+ EMIT_BYTE(opX);
+ if (opX >= kRexForbidden)
+ goto _IllegalInst;
+ }
+
+ // Instruction opcodes.
+ EMIT_MM(opCode);
+ EMIT_OP(opCode);
+ goto _EmitDone;
+
+_EmitX86OpI:
+ // Mandatory instruction prefix.
+ EMIT_PP(opCode);
+
+ // Rex prefix (64-bit only).
+ if (Arch == kArchX64 && opX) {
+ opX |= 0x40;
+ EMIT_BYTE(opX);
+ if (opX >= kRexForbidden)
+ goto _IllegalInst;
+ }
+
+ // Instruction opcodes.
+ EMIT_MM(opCode);
+ EMIT_OP(opCode);
+ goto _EmitImm;
+
+_EmitX86R:
+ // Mandatory instruction prefix.
+ EMIT_PP(opCode);
+
+ // Rex prefix (64-bit only).
+ if (Arch == kArchX64) {
+ opX += static_cast<uint32_t>(opReg & 0x08) >> 1; // Rex.R (0x04).
+ opX += static_cast<uint32_t>(rmReg) >> 3; // Rex.B (0x01).
+
+ if (opX) {
+ opX |= 0x40;
+ EMIT_BYTE(opX);
+
+ if (opX >= kRexForbidden)
+ goto _IllegalInst;
+
+ opReg &= 0x7;
+ rmReg &= 0x7;
+ }
+ }
+
+ // Instruction opcodes.
+ EMIT_MM(opCode);
+ EMIT_OP(opCode);
+
+ // ModR.
+ EMIT_BYTE(x86EncodeMod(3, opReg, static_cast<uint32_t>(rmReg)));
+
+ if (imLen != 0)
+ goto _EmitImm;
+ else
+ goto _EmitDone;
+
+_EmitX86M:
+ ASMJIT_ASSERT(rmMem);
+ ASMJIT_ASSERT(rmMem->getOp() == kOperandTypeMem);
+
+ mBase = rmMem->getBase();
+ mIndex = rmMem->getIndex();
+
+ // Size override prefix.
+ if (rmMem->hasBaseOrIndex() && rmMem->getMemType() != kMemTypeLabel) {
+ if (Arch == kArchX86) {
+ if (!rmMem->hasGpdBase())
+ EMIT_BYTE(0x67);
+ }
+ else {
+ if (rmMem->hasGpdBase())
+ EMIT_BYTE(0x67);
+ }
+ }
+
+ // Segment override prefix.
+ if (rmMem->hasSegment()) {
+ EMIT_BYTE(x86SegmentPrefix[rmMem->getSegment()]);
+ }
+
+ // Mandatory instruction prefix.
+ EMIT_PP(opCode);
+
+ // Rex prefix (64-bit only).
+ if (Arch == kArchX64) {
+ opX += static_cast<uint32_t>(opReg & 8) >> 1; // Rex.R (0x04).
+ opX += static_cast<uint32_t>(mIndex - 8 < 8) << 1; // Rex.X (0x02).
+ opX += static_cast<uint32_t>(mBase - 8 < 8); // Rex.B (0x01).
+
+ if (opX) {
+ opX |= 0x40;
+ EMIT_BYTE(opX);
+
+ if (opX >= kRexForbidden)
+ goto _IllegalInst;
+
+ opReg &= 0x7;
+ }
+
+ mBase &= 0x7;
+ }
+
+ // Instruction opcodes.
+ EMIT_MM(opCode);
+ EMIT_OP(opCode);
+ // ... Fall through ...
+
+ // --------------------------------------------------------------------------
+ // [Emit - SIB]
+ // --------------------------------------------------------------------------
+
+_EmitSib:
+ dispOffset = rmMem->getDisplacement();
+ if (rmMem->isBaseIndexType()) {
+ if (mIndex >= kInvalidReg) {
+ if (mBase == kX86RegIndexSp) {
+ if (dispOffset == 0) {
+ // [Esp/Rsp/R12].
+ EMIT_BYTE(x86EncodeMod(0, opReg, 4));
+ EMIT_BYTE(x86EncodeSib(0, 4, 4));
+ }
+ else if (IntUtil::isInt8(dispOffset)) {
+ // [Esp/Rsp/R12 + Disp8].
+ EMIT_BYTE(x86EncodeMod(1, opReg, 4));
+ EMIT_BYTE(x86EncodeSib(0, 4, 4));
+ EMIT_BYTE(static_cast<int8_t>(dispOffset));
+ }
+ else {
+ // [Esp/Rsp/R12 + Disp32].
+ EMIT_BYTE(x86EncodeMod(2, opReg, 4));
+ EMIT_BYTE(x86EncodeSib(0, 4, 4));
+ EMIT_DWORD(static_cast<int32_t>(dispOffset));
+ }
+ }
+ else if (mBase != kX86RegIndexBp && dispOffset == 0) {
+ // [Base].
+ EMIT_BYTE(x86EncodeMod(0, opReg, mBase));
+ }
+ else if (IntUtil::isInt8(dispOffset)) {
+ // [Base + Disp8].
+ EMIT_BYTE(x86EncodeMod(1, opReg, mBase));
+ EMIT_BYTE(static_cast<int8_t>(dispOffset));
+ }
+ else {
+ // [Base + Disp32].
+ EMIT_BYTE(x86EncodeMod(2, opReg, mBase));
+ EMIT_DWORD(static_cast<int32_t>(dispOffset));
+ }
+ }
+ else {
+ uint32_t shift = rmMem->getShift();
+
+ // Esp/Rsp/R12 register can't be used as an index.
+ mIndex &= 0x7;
+ ASMJIT_ASSERT(mIndex != kX86RegIndexSp);
+
+ if (mBase != kX86RegIndexBp && dispOffset == 0) {
+ // [Base + Index * Scale].
+ EMIT_BYTE(x86EncodeMod(0, opReg, 4));
+ EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase));
+ }
+ else if (IntUtil::isInt8(dispOffset)) {
+ // [Base + Index * Scale + Disp8].
+ EMIT_BYTE(x86EncodeMod(1, opReg, 4));
+ EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase));
+ EMIT_BYTE(static_cast<int8_t>(dispOffset));
+ }
+ else {
+ // [Base + Index * Scale + Disp32].
+ EMIT_BYTE(x86EncodeMod(2, opReg, 4));
+ EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase));
+ EMIT_DWORD(static_cast<int32_t>(dispOffset));
+ }
+ }
+ }
+ else if (Arch == kArchX86) {
+ if (mIndex >= kInvalidReg) {
+ // [Disp32].
+ EMIT_BYTE(x86EncodeMod(0, opReg, 5));
+ }
+ else {
+ // [Index * Scale + Disp32].
+ uint32_t shift = rmMem->getShift();
+ ASMJIT_ASSERT(mIndex != kX86RegIndexSp);
+
+ EMIT_BYTE(x86EncodeMod(0, opReg, 4));
+ EMIT_BYTE(x86EncodeSib(shift, mIndex, 5));
+ }
+
+ if (rmMem->getMemType() == kMemTypeLabel) {
+ // Relative->Absolute [x86 mode].
+ label = self->getLabelData(rmMem->_vmem.base);
+ relocId = self->_relocList.getLength();
+
+ RelocData reloc;
+ reloc.type = kRelocRelToAbs;
+ reloc.size = 4;
+ reloc.from = static_cast<Ptr>(static_cast<uintptr_t>(cursor - self->_buffer));
+ reloc.data = static_cast<SignedPtr>(dispOffset);
+
+ if (self->_relocList.append(reloc) != kErrorOk)
+ return self->setError(kErrorNoHeapMemory);
+
+ if (label->offset != -1) {
+ // Bound label.
+ reloc.data += static_cast<SignedPtr>(label->offset);
+ EMIT_DWORD(0);
+ }
+ else {
+ // Non-bound label.
+ dispOffset = -4 - imLen;
+ dispSize = 4;
+ goto _EmitDisplacement;
+ }
+ }
+ else {
+ // [Disp32].
+ EMIT_DWORD(static_cast<int32_t>(dispOffset));
+ }
+ }
+ else /* if (Arch === kArchX64) */ {
+ if (rmMem->getMemType() == kMemTypeLabel) {
+ // [RIP + Disp32].
+ label = self->getLabelData(rmMem->_vmem.base);
+
+ // Indexing is invalid.
+ if (mIndex < kInvalidReg)
+ goto _IllegalDisp;
+
+ EMIT_BYTE(x86EncodeMod(0, opReg, 5));
+ dispOffset -= (4 + imLen);
+
+ if (label->offset != -1) {
+ // Bound label.
+ dispOffset += label->offset - static_cast<int32_t>(static_cast<intptr_t>(cursor - self->_buffer));
+ EMIT_DWORD(static_cast<int32_t>(dispOffset));
+ }
+ else {
+ // Non-bound label.
+ dispSize = 4;
+ relocId = -1;
+ goto _EmitDisplacement;
+ }
+ }
+ else {
+ EMIT_BYTE(x86EncodeMod(0, opReg, 4));
+ if (mIndex >= kInvalidReg) {
+ // [Disp32].
+ EMIT_BYTE(x86EncodeSib(0, 4, 5));
+ }
+ else {
+ // [Disp32 + Index * Scale].
+ mIndex &= 0x7;
+ ASMJIT_ASSERT(mIndex != kX86RegIndexSp);
+
+ uint32_t shift = rmMem->getShift();
+ EMIT_BYTE(x86EncodeSib(shift, mIndex, 5));
+ }
+
+ EMIT_DWORD(static_cast<int32_t>(dispOffset));
+ }
+ }
+
+ if (imLen == 0)
+ goto _EmitDone;
+
+ // --------------------------------------------------------------------------
+ // [Emit - Imm]
+ // --------------------------------------------------------------------------
+
+_EmitImm:
+ switch (imLen) {
+ case 1: EMIT_BYTE (imVal & 0x000000FF); break;
+ case 2: EMIT_WORD (imVal & 0x0000FFFF); break;
+ case 4: EMIT_DWORD(imVal & 0xFFFFFFFF); break;
+ case 8: EMIT_QWORD(imVal ); break;
+
+ default:
+ ASMJIT_ASSERT(!"Reached");
+ }
+ goto _EmitDone;
+
+ // --------------------------------------------------------------------------
+ // [Emit - Fpu]
+ // --------------------------------------------------------------------------
+
+_EmitFpuOp:
+ // Mandatory instruction prefix.
+ EMIT_PP(opCode);
+
+ // Instruction opcodes.
+ EMIT_OP(opCode >> 8);
+ EMIT_OP(opCode);
+ goto _EmitDone;
+
+ // --------------------------------------------------------------------------
+ // [Emit - Avx]
+ // --------------------------------------------------------------------------
+
+#define EMIT_AVX_M \
+ ASMJIT_ASSERT(rmMem); \
+ ASMJIT_ASSERT(rmMem->getOp() == kOperandTypeMem); \
+ \
+ if (rmMem->hasSegment()) { \
+ EMIT_BYTE(x86SegmentPrefix[rmMem->getSegment()]); \
+ } \
+ \
+ mBase = rmMem->getBase(); \
+ mIndex = rmMem->getIndex(); \
+ \
+ { \
+ uint32_t vex_XvvvvLpp; \
+ uint32_t vex_rxbmmmmm; \
+ \
+ vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; \
+ vex_XvvvvLpp += (opCode >> (kX86InstOpCode_PP_Shift)) & 0x03; \
+ vex_XvvvvLpp += (opX >> (kVexVVVVShift - 3)); \
+ vex_XvvvvLpp += (opX << 4) & 0x80; \
+ \
+ vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; \
+ vex_rxbmmmmm += static_cast<uint32_t>(mBase - 8 < 8) << 5; \
+ vex_rxbmmmmm += static_cast<uint32_t>(mIndex - 8 < 8) << 6; \
+ \
+ if (vex_rxbmmmmm != 0x01 || vex_XvvvvLpp >= 0x80 || (options & kX86InstOptionVex3) != 0) { \
+ vex_rxbmmmmm |= static_cast<uint32_t>(opReg << 4) & 0x80; \
+ vex_rxbmmmmm ^= 0xE0; \
+ vex_XvvvvLpp ^= 0x78; \
+ \
+ EMIT_BYTE(kVex3Byte); \
+ EMIT_BYTE(vex_rxbmmmmm); \
+ EMIT_BYTE(vex_XvvvvLpp); \
+ EMIT_OP(opCode); \
+ } \
+ else { \
+ vex_XvvvvLpp |= static_cast<uint32_t>(opReg << 4) & 0x80; \
+ vex_XvvvvLpp ^= 0xF8; \
+ \
+ EMIT_BYTE(kVex2Byte); \
+ EMIT_BYTE(vex_XvvvvLpp); \
+ EMIT_OP(opCode); \
+ } \
+ } \
+ \
+ mBase &= 0x7; \
+ opReg &= 0x7;
+
+_EmitAvxOp:
+ {
+ uint32_t vex_XvvvvLpp;
+
+ vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04;
+ vex_XvvvvLpp |= (opCode >> (kX86InstOpCode_PP_Shift));
+ vex_XvvvvLpp |= 0xF8;
+
+ // Encode 3-byte VEX prefix only if specified in options.
+ if ((options & kX86InstOptionVex3) != 0) {
+ uint32_t vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) | 0xE0;
+
+ EMIT_BYTE(kVex3Byte);
+ EMIT_OP(vex_rxbmmmmm);
+ EMIT_OP(vex_XvvvvLpp);
+ EMIT_OP(opCode);
+ }
+ else {
+ EMIT_BYTE(kVex2Byte);
+ EMIT_OP(vex_XvvvvLpp);
+ EMIT_OP(opCode);
+ }
+ }
+ goto _EmitDone;
+
+_EmitAvxR:
+ {
+ uint32_t vex_XvvvvLpp;
+ uint32_t vex_rxbmmmmm;
+
+ vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04;
+ vex_XvvvvLpp |= (opCode >> (kX86InstOpCode_PP_Shift));
+ vex_XvvvvLpp |= (opX >> (kVexVVVVShift - 3));
+ vex_XvvvvLpp |= (opX << 4) & 0x80;
+
+ vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F;
+ vex_rxbmmmmm |= (rmReg << 2) & 0x20;
+
+ if (vex_rxbmmmmm != 0x01 || vex_XvvvvLpp >= 0x80 || (options & kX86InstOptionVex3) != 0) {
+ vex_rxbmmmmm |= static_cast<uint32_t>(opReg & 0x08) << 4;
+ vex_rxbmmmmm ^= 0xE0;
+ vex_XvvvvLpp ^= 0x78;
+
+ EMIT_BYTE(kVex3Byte);
+ EMIT_OP(vex_rxbmmmmm);
+ EMIT_OP(vex_XvvvvLpp);
+ EMIT_OP(opCode);
+
+ rmReg &= 0x07;
+ }
+ else {
+ vex_XvvvvLpp += static_cast<uint32_t>(opReg & 0x08) << 4;
+ vex_XvvvvLpp ^= 0xF8;
+
+ EMIT_BYTE(kVex2Byte);
+ EMIT_OP(vex_XvvvvLpp);
+ EMIT_OP(opCode);
+ }
+ }
+
+ EMIT_BYTE(x86EncodeMod(3, opReg, static_cast<uint32_t>(rmReg)));
+
+ if (imLen == 0)
+ goto _EmitDone;
+
+ EMIT_BYTE(imVal & 0xFF);
+ goto _EmitDone;
+
+_EmitAvxM:
+ EMIT_AVX_M
+ goto _EmitSib;
+
+_EmitAvxV:
+ EMIT_AVX_M
+
+ if (mIndex >= kInvalidReg)
+ goto _IllegalInst;
+
+ if (Arch == kArchX64)
+ mIndex &= 0x7;
+
+ dispOffset = rmMem->getDisplacement();
+ if (rmMem->isBaseIndexType()) {
+ uint32_t shift = rmMem->getShift();
+
+ if (mBase != kX86RegIndexBp && dispOffset == 0) {
+ // [Base + Index * Scale].
+ EMIT_BYTE(x86EncodeMod(0, opReg, 4));
+ EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase));
+ }
+ else if (IntUtil::isInt8(dispOffset)) {
+ // [Base + Index * Scale + Disp8].
+ EMIT_BYTE(x86EncodeMod(1, opReg, 4));
+ EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase));
+ EMIT_BYTE(static_cast<int8_t>(dispOffset));
+ }
+ else {
+ // [Base + Index * Scale + Disp32].
+ EMIT_BYTE(x86EncodeMod(2, opReg, 4));
+ EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase));
+ EMIT_DWORD(static_cast<int32_t>(dispOffset));
+ }
+ }
+ else {
+ // [Index * Scale + Disp32].
+ uint32_t shift = rmMem->getShift();
+
+ EMIT_BYTE(x86EncodeMod(0, opReg, 4));
+ EMIT_BYTE(x86EncodeSib(shift, mIndex, 5));
+
+ if (rmMem->getMemType() == kMemTypeLabel) {
+ if (Arch == kArchX64)
+ goto _IllegalAddr;
+
+ // Relative->Absolute [x86 mode].
+ label = self->getLabelData(rmMem->_vmem.base);
+ relocId = self->_relocList.getLength();
+
+ RelocData reloc;
+ reloc.type = kRelocRelToAbs;
+ reloc.size = 4;
+ reloc.from = static_cast<Ptr>(static_cast<uintptr_t>(cursor - self->_buffer));
+ reloc.data = static_cast<SignedPtr>(dispOffset);
+
+ if (self->_relocList.append(reloc) != kErrorOk)
+ return self->setError(kErrorNoHeapMemory);
+
+ if (label->offset != -1) {
+ // Bound label.
+ reloc.data += static_cast<SignedPtr>(label->offset);
+ EMIT_DWORD(0);
+ }
+ else {
+ // Non-bound label.
+ dispOffset = -4 - imLen;
+ dispSize = 4;
+ goto _EmitDisplacement;
+ }
+ }
+ else {
+ // [Disp32].
+ EMIT_DWORD(static_cast<int32_t>(dispOffset));
+ }
+ }
+ goto _EmitDone;
+
+ // --------------------------------------------------------------------------
+ // [Xop]
+ // --------------------------------------------------------------------------
+
+#define EMIT_XOP_M \
+ ASMJIT_ASSERT(rmMem); \
+ ASMJIT_ASSERT(rmMem->getOp() == kOperandTypeMem); \
+ \
+ if (rmMem->hasSegment()) { \
+ EMIT_BYTE(x86SegmentPrefix[rmMem->getSegment()]); \
+ } \
+ \
+ mBase = rmMem->getBase(); \
+ mIndex = rmMem->getIndex(); \
+ \
+ { \
+ uint32_t vex_XvvvvLpp; \
+ uint32_t vex_rxbmmmmm; \
+ \
+ vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; \
+ vex_XvvvvLpp += (opCode >> (kX86InstOpCode_PP_Shift)) & 0x03; \
+ vex_XvvvvLpp += (opX >> (kVexVVVVShift - 3)); \
+ vex_XvvvvLpp += (opX << 4) & 0x80; \
+ \
+ vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; \
+ vex_rxbmmmmm += static_cast<uint32_t>(mBase - 8 < 8) << 5; \
+ vex_rxbmmmmm += static_cast<uint32_t>(mIndex - 8 < 8) << 6; \
+ \
+ vex_rxbmmmmm |= static_cast<uint32_t>(opReg << 4) & 0x80; \
+ vex_rxbmmmmm ^= 0xE0; \
+ vex_XvvvvLpp ^= 0x78; \
+ \
+ EMIT_BYTE(kXopByte); \
+ EMIT_BYTE(vex_rxbmmmmm); \
+ EMIT_BYTE(vex_XvvvvLpp); \
+ EMIT_OP(opCode); \
+ } \
+ \
+ mBase &= 0x7; \
+ opReg &= 0x7;
+
+_EmitXopR:
+ {
+ uint32_t xop_XvvvvLpp;
+ uint32_t xop_rxbmmmmm;
+
+ xop_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04;
+ xop_XvvvvLpp |= (opCode >> (kX86InstOpCode_PP_Shift));
+ xop_XvvvvLpp |= (opX >> (kVexVVVVShift - 3));
+ xop_XvvvvLpp |= (opX << 4) & 0x80;
+
+ xop_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F;
+ xop_rxbmmmmm |= (rmReg << 2) & 0x20;
+
+ xop_rxbmmmmm |= static_cast<uint32_t>(opReg & 0x08) << 4;
+ xop_rxbmmmmm ^= 0xE0;
+ xop_XvvvvLpp ^= 0x78;
+
+ EMIT_BYTE(kXopByte);
+ EMIT_OP(xop_rxbmmmmm);
+ EMIT_OP(xop_XvvvvLpp);
+ EMIT_OP(opCode);
+
+ rmReg &= 0x07;
+ }
+
+ EMIT_BYTE(x86EncodeMod(3, opReg, static_cast<uint32_t>(rmReg)));
+
+ if (imLen == 0)
+ goto _EmitDone;
+
+ EMIT_BYTE(imVal & 0xFF);
+ goto _EmitDone;
+
+_EmitXopM:
+ EMIT_XOP_M
+ goto _EmitSib;
+
+ // --------------------------------------------------------------------------
+ // [Emit - Jump/Call to an Immediate]
+ // --------------------------------------------------------------------------
+
+ // 64-bit mode requires a trampoline if a relative displacement doesn't fit
+ // into a 32-bit address. Old version of AsmJit used to emit jump to a section
+ // which contained another jump followed by an address (it worked well for
+ // both `jmp` and `call`), but it required to reserve 14-bytes for a possible
+ // trampoline.
+ //
+ // Instead of using 5-byte `jmp/call` and reserving 14 bytes required by the
+ // trampoline, it's better to use 6-byte `jmp/call` (prefixing it with REX
+ // prefix) and to patch the `jmp/call` instruction to read the address from
+ // a memory in case the trampoline is needed.
+ //
+_EmitJmpOrCallAbs:
+ {
+ RelocData rd;
+ rd.type = kRelocAbsToRel;
+ rd.size = 4;
+ rd.from = static_cast<intptr_t>(cursor - self->_buffer) + 1;
+ rd.data = static_cast<SignedPtr>(imVal);
+
+ uint32_t trampolineSize = 0;
+
+ if (Arch == kArchX64) {
+ Ptr baseAddress = self->getBaseAddress();
+ //Ptr diff = rd.data - (baseAddress + rd.from + 4);
+
+ // If the base address of the output is known, it's possible to determine
+ // the need for a trampoline here. This saves possible REX prefix in
+ // 64-bit mode and prevents reserving space needed for an absolute address.
+ if (baseAddress == kNoBaseAddress || !x64IsRelative(rd.data, baseAddress + rd.from + 4)) {
+ // Emit REX prefix so the instruction can be patched later on. The REX
+ // prefix does nothing if not patched after, but allows to patch the
+ // instruction in case where the trampoline is needed.
+ rd.type = kRelocTrampoline;
+ rd.from++;
+
+ EMIT_OP(0x40);
+ trampolineSize = 8;
+ }
+ }
+
+ // Both `jmp` and `call` instructions have a single-byte opcode and are
+ // followed by a 32-bit displacement.
+ EMIT_OP(opCode);
+ EMIT_DWORD(0);
+
+ if (self->_relocList.append(rd) != kErrorOk)
+ return self->setError(kErrorNoHeapMemory);
+
+ // Reserve space for a possible trampoline.
+ self->_trampolineSize += trampolineSize;
+ }
+ goto _EmitDone;
+
+ // --------------------------------------------------------------------------
+ // [Emit - Displacement]
+ // --------------------------------------------------------------------------
+
+_EmitDisplacement:
+ {
+ ASMJIT_ASSERT(label->offset == -1);
+ ASMJIT_ASSERT(dispSize == 1 || dispSize == 4);
+
+ // Chain with label.
+ LabelLink* link = self->_newLabelLink();
+ link->prev = label->links;
+ link->offset = static_cast<intptr_t>(cursor - self->_buffer);
+ link->displacement = dispOffset;
+ link->relocId = relocId;
+ label->links = link;
+
+ // Emit label size as dummy data.
+ if (dispSize == 1)
+ EMIT_BYTE(0x01);
+ else // if (dispSize == 4)
+ EMIT_DWORD(0x04040404);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Logging]
+ // --------------------------------------------------------------------------
+
+_EmitDone:
+#ifndef ASMJIT_DISABLE_LOGGER
+# ifdef ASMJIT_DEBUG
+ if (self->_logger || assertIllegal) {
+# else
+ if (self->_logger) {
+# endif // ASMJIT_DEBUG
+ StringBuilderT<512> sb;
+ uint32_t loggerOptions = 0;
+
+ if (self->_logger) {
+ sb.appendString(self->_logger->getIndentation());
+ loggerOptions = self->_logger->getOptions();
+ }
+
+ X86Assembler_dumpInstruction(sb, Arch, code, options, o0, o1, o2, o3, loggerOptions);
+
+ if ((loggerOptions & (1 << kLoggerOptionBinaryForm)) != 0)
+ X86Assembler_dumpComment(sb, sb.getLength(), self->_cursor, static_cast<intptr_t>(cursor - self->_cursor), dispSize, self->_comment);
+ else
+ X86Assembler_dumpComment(sb, sb.getLength(), nullptr, 0, 0, self->_comment);
+
+# ifdef ASMJIT_DEBUG
+ if (self->_logger)
+# endif // ASMJIT_DEBUG
+ self->_logger->logString(kLoggerStyleDefault, sb.getData(), sb.getLength());
+
+# ifdef ASMJIT_DEBUG
+ // Raise an assertion failure, because this situation shouldn't happen.
+ if (assertIllegal)
+ assertionFailed(sb.getData(), __FILE__, __LINE__);
+# endif // ASMJIT_DEBUG
+ }
+#else
+# ifdef ASMJIT_DEBUG
+ ASMJIT_ASSERT(!assertIllegal);
+# endif // ASMJIT_DEBUG
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ self->_comment = nullptr;
+ self->setCursor(cursor);
+
+ return kErrorOk;
+
+_GrowBuffer:
+ ASMJIT_PROPAGATE_ERROR(self->_grow(16));
+
+ cursor = self->getCursor();
+ goto _Prepare;
}
-X86Assembler::~X86Assembler()
-{
+Error X86Assembler::_emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) {
+#if defined(ASMJIT_BUILD_X86) && !defined(ASMJIT_BUILD_X64)
+ return X86Assembler_emit<kArchX86>(this, code, &o0, &o1, &o2, &o3);
+#elif !defined(ASMJIT_BUILD_X86) && defined(ASMJIT_BUILD_X64)
+ return X86Assembler_emit<kArchX64>(this, code, &o0, &o1, &o2, &o3);
+#else
+ if (_arch == kArchX86)
+ return X86Assembler_emit<kArchX86>(this, code, &o0, &o1, &o2, &o3);
+ else
+ return X86Assembler_emit<kArchX64>(this, code, &o0, &o1, &o2, &o3);
+#endif
}
-// ============================================================================
-// [AsmJit::X86Assembler - Buffer - Setters (X86-Extensions)]
-// ============================================================================
-
-void X86Assembler::setVarAt(size_t pos, sysint_t i, uint8_t isUnsigned, uint32_t size)
-{
- if (size == 1 && !isUnsigned)
- this->setByteAt(pos, static_cast<int8_t>(i));
- else if (size == 1 && isUnsigned)
- this->setByteAt(pos, static_cast<uint8_t>(i));
- else if (size == 2 && !isUnsigned)
- this->setWordAt(pos, static_cast<int16_t>(i));
- else if (size == 2 && isUnsigned)
- this->setWordAt(pos, static_cast<uint16_t>(i));
- else if (size == 4 && !isUnsigned)
- this->setDWordAt(pos, static_cast<int32_t>(i));
- else if (size == 4 && isUnsigned)
- this->setDWordAt(pos, static_cast<uint32_t>(i));
-#ifdef ASMJIT_X64
- else if (size == 8 && !isUnsigned)
- this->setQWordAt(pos, static_cast<int64_t>(i));
- else if (size == 8 && isUnsigned)
- this->setQWordAt(pos, static_cast<uint64_t>(i));
-#endif // ASMJIT_X64
- else
- ASMJIT_ASSERT(0);
-}
-
-// ============================================================================
-// [AsmJit::X86Assembler - Emit]
-// ============================================================================
-
-void X86Assembler::_emitModM(uint8_t opReg, const Mem &mem, sysint_t immSize)
-{
- ASMJIT_ASSERT(mem.getType() == kOperandMem);
-
- uint8_t baseReg = mem.getBase() & 0x7;
- uint8_t indexReg = mem.getIndex() & 0x7;
- sysint_t disp = mem.getDisplacement();
- uint32_t shift = mem.getShift();
-
- if (mem.getMemType() == kOperandMemNative)
- {
- // [base + displacemnt]
- if (!mem.hasIndex())
- {
- // ESP/RSP/R12 == 4
- if (baseReg == 4)
- {
- uint8_t mod = 0;
-
- if (disp)
- mod = IntUtil::isInt8(disp) ? 1 : 2;
-
- this->_emitMod(mod, opReg, 4);
- this->_emitSib(0, 4, 4);
-
- if (disp)
- {
- if (IntUtil::isInt8(disp))
- this->_emitByte(static_cast<int8_t>(disp));
- else
- this->_emitInt32(static_cast<int32_t>(disp));
- }
- }
- // EBP/RBP/R13 == 5
- else if (baseReg != 5 && !disp)
- this->_emitMod(0, opReg, baseReg);
- else if (IntUtil::isInt8(disp))
- {
- this->_emitMod(1, opReg, baseReg);
- this->_emitByte(static_cast<int8_t>(disp));
- }
- else
- {
- this->_emitMod(2, opReg, baseReg);
- this->_emitInt32(static_cast<int32_t>(disp));
- }
- }
- // [base + index * scale + displacemnt]
- else
- {
- //ASMJIT_ASSERT(indexReg != RID_ESP);
-
- // EBP/RBP/R13 == 5
- if (baseReg != 5 && !disp)
- {
- this->_emitMod(0, opReg, 4);
- this->_emitSib(shift, indexReg, baseReg);
- }
- else if (IntUtil::isInt8(disp))
- {
- this->_emitMod(1, opReg, 4);
- this->_emitSib(shift, indexReg, baseReg);
- this->_emitByte(static_cast<int8_t>(disp));
- }
- else
- {
- this->_emitMod(2, opReg, 4);
- this->_emitSib(shift, indexReg, baseReg);
- this->_emitInt32(static_cast<int32_t>(disp));
- }
- }
- }
- // Address | 32-bit mode | 64-bit mode
- // ------------------------------+-------------+---------------
- // [displacement] | ABSOLUTE | RELATIVE (RIP)
- // [index * scale + displacemnt] | ABSOLUTE | ABSOLUTE (ZERO EXTENDED)
- else
- {
- // - In 32-bit mode the absolute addressing model is used.
- // - In 64-bit mode the relative addressing model is used together with
- // the absolute addressing. Main problem is that if instruction
- // contains SIB then relative addressing (RIP) is not possible.
-
-#ifdef ASMJIT_X86
- if (mem.hasIndex())
- {
- // ASMJIT_ASSERT(mem.getMemIndex() != 4); // ESP/RSP == 4
- this->_emitMod(0, opReg, 4);
- this->_emitSib(shift, indexReg, 5);
- }
- else
- this->_emitMod(0, opReg, 5);
-
- // X86 uses absolute addressing model, all relative addresses will be
- // relocated to absolute ones.
- if (mem.getMemType() == kOperandMemLabel)
- {
- LabelData &l_data = this->_labels[mem._mem.base & kOperandIdValueMask];
- RelocData r_data;
- uint32_t relocId = this->_relocData.size();
-
- // Relative addressing will be relocated to absolute address.
- r_data.type = kRelocRelToAbs;
- r_data.size = 4;
- r_data.offset = this->getOffset();
- r_data.destination = disp;
-
- if (l_data.offset != -1)
- {
- // Bound label.
- r_data.destination += l_data.offset;
-
- // Add a dummy DWORD.
- this->_emitInt32(0);
- }
- else
- // Non-bound label.
- this->_emitDisplacement(l_data, -4 - immSize, 4)->relocId = relocId;
-
- this->_relocData.push_back(r_data);
- }
- else
- // Absolute address
- this->_emitInt32((int32_t)((uint8_t*)mem._mem.target + disp));
-#else
- // X64 uses relative addressing model
- if (mem.getMemType() == kOperandMemLabel)
- {
- LabelData &l_data = this->_labels[mem._mem.base & kOperandIdValueMask];
-
- if (mem.hasIndex())
- {
- // Indexing is not possible.
- this->setError(kErrorIllegalAddressing);
- return;
- }
-
- // Relative address (RIP +/- displacement).
- this->_emitMod(0, opReg, 5);
-
- disp -= 4 + immSize;
-
- if (l_data.offset != -1)
- {
- // Bound label.
- disp += getOffset() - l_data.offset;
-
- // Displacement is known.
- this->_emitInt32(static_cast<int32_t>(disp));
- }
- else
- // Non-bound label.
- this->_emitDisplacement(l_data, disp, 4);
- }
- else
- {
- // Absolute address (truncated to 32-bits), this kind of address requires
- // SIB byte (4).
- this->_emitMod(0, opReg, 4);
-
- if (mem.hasIndex())
- //ASMJIT_ASSERT(mem.getMemIndex() != 4); // ESP/RSP == 4
- this->_emitSib(shift, indexReg, 5);
- else
- this->_emitSib(0, 4, 5);
-
- // Truncate to 32-bits.
- sysuint_t target = (sysuint_t)((uint8_t*)mem._mem.target + disp);
-
- if (target > static_cast<sysuint_t>(0xFFFFFFFF))
- {
- if (this->_logger)
- this->_logger->logString("*** ASSEMBER WARNING - Absolute address truncated to 32-bits.\n");
- target &= 0xFFFFFFFF;
- }
-
- this->_emitInt32(static_cast<int32_t>(static_cast<uint32_t>(target)));
- }
-#endif // ASMJIT_X64
- }
-}
-
-void X86Assembler::_emitModRM(uint8_t opReg, const Operand &op, sysint_t immSize)
-{
- ASMJIT_ASSERT(op.getType() == kOperandReg || op.getType() == kOperandMem);
-
- if (op.getType() == kOperandReg)
- this->_emitModR(opReg, reinterpret_cast<const Reg &>(op).getRegCode());
- else
- this->_emitModM(opReg, reinterpret_cast<const Mem &>(op), immSize);
-}
-
-void X86Assembler::_emitSegmentPrefix(const Operand &rm)
-{
- static const uint8_t segmentCode[] =
- {
- 0x26, // ES
- 0x2E, // SS
- 0x36, // SS
- 0x3E, // DS
- 0x64, // FS
- 0x65 // GS
- };
-
- if (!rm.isMem())
- return;
-
- uint32_t seg = reinterpret_cast<const Mem &>(rm).getSegment();
- if (seg >= kX86RegNumSeg)
- return;
-
- this->_emitByte(segmentCode[seg]);
-}
-
-void X86Assembler::_emitX86Inl(uint32_t opCode, uint8_t i16bit, uint8_t rexw, uint8_t reg, bool forceRexPrefix)
-{
- // 16-bit prefix.
- if (i16bit)
- this->_emitByte(0x66);
-
- // Instruction prefix.
- if (opCode & 0xFF000000)
- this->_emitByte(static_cast<uint8_t>((opCode & 0xFF000000) >> 24));
-
- // REX prefix.
-#ifdef ASMJIT_X64
- this->_emitRexR(rexw, 0, reg, forceRexPrefix);
-#endif // ASMJIT_X64
-
- // Instruction opcodes.
- if (opCode & 0x00FF0000)
- this->_emitByte(static_cast<uint8_t>((opCode & 0x00FF0000) >> 16));
- if (opCode & 0x0000FF00)
- this->_emitByte(static_cast<uint8_t>((opCode & 0x0000FF00) >> 8));
- this->_emitByte(static_cast<uint8_t>(opCode & 0x000000FF) + (reg & 0x7));
-}
-
-void X86Assembler::_emitX86RM(uint32_t opCode, uint8_t i16bit, uint8_t rexw, uint8_t o, const Operand &op, sysint_t immSize, bool forceRexPrefix)
-{
- // 16-bit prefix.
- if (i16bit)
- this->_emitByte(0x66);
-
- // Segment prefix.
- this->_emitSegmentPrefix(op);
-
- // Instruction prefix.
- if (opCode & 0xFF000000)
- this->_emitByte(static_cast<uint8_t>((opCode & 0xFF000000) >> 24));
-
- // REX prefix.
-#ifdef ASMJIT_X64
- this->_emitRexRM(rexw, o, op, forceRexPrefix);
-#endif // ASMJIT_X64
-
- // Instruction opcodes.
- if (opCode & 0x00FF0000)
- this->_emitByte(static_cast<uint8_t>((opCode & 0x00FF0000) >> 16));
- if (opCode & 0x0000FF00)
- this->_emitByte(static_cast<uint8_t>((opCode & 0x0000FF00) >> 8));
- this->_emitByte(static_cast<uint8_t>(opCode & 0x000000FF));
-
- // Mod R/M.
- this->_emitModRM(o, op, immSize);
-}
-
-void X86Assembler::_emitFpu(uint32_t opCode)
-{
- this->_emitOpCode(opCode);
-}
-
-void X86Assembler::_emitFpuSTI(uint32_t opCode, uint32_t sti)
-{
- // Illegal stack offset.
- ASMJIT_ASSERT(0 <= sti && sti < 8);
- this->_emitOpCode(opCode + sti);
-}
-
-void X86Assembler::_emitFpuMEM(uint32_t opCode, uint8_t opReg, const Mem& mem)
-{
- // Segment prefix.
- this->_emitSegmentPrefix(mem);
-
- // Instruction prefix.
- if (opCode & 0xFF000000)
- this->_emitByte(static_cast<uint8_t>((opCode & 0xFF000000) >> 24));
-
- // REX prefix.
-#ifdef ASMJIT_X64
- this->_emitRexRM(0, opReg, mem, false);
-#endif // ASMJIT_X64
-
- // Instruction opcodes.
- if (opCode & 0x00FF0000)
- this->_emitByte(static_cast<uint8_t>((opCode & 0x00FF0000) >> 16));
- if (opCode & 0x0000FF00)
- this->_emitByte(static_cast<uint8_t>((opCode & 0x0000FF00) >> 8));
- this->_emitByte(static_cast<uint8_t>(opCode & 0x000000FF));
- this->_emitModM(opReg, mem, 0);
-}
-
-void X86Assembler::_emitMmu(uint32_t opCode, uint8_t rexw, uint8_t opReg, const Operand &src, sysint_t immSize)
-{
- // Segment prefix.
- this->_emitSegmentPrefix(src);
-
- // Instruction prefix.
- if (opCode & 0xFF000000)
- this->_emitByte(static_cast<uint8_t>((opCode & 0xFF000000) >> 24));
-
- // REX prefix.
-#ifdef ASMJIT_X64
- this->_emitRexRM(rexw, opReg, src, false);
-#endif // ASMJIT_X64
-
- // Instruction opcodes.
- if (opCode & 0x00FF0000)
- this->_emitByte(static_cast<uint8_t>((opCode & 0x00FF0000) >> 16));
-
- // No checking, MMX/SSE instructions have always two opcodes or more.
- this->_emitByte(static_cast<uint8_t>((opCode & 0x0000FF00) >> 8));
- this->_emitByte(static_cast<uint8_t>(opCode & 0x000000FF));
-
- if (src.isReg())
- this->_emitModR(opReg, reinterpret_cast<const Reg &>(src).getRegCode());
- else
- this->_emitModM(opReg, reinterpret_cast<const Mem &>(src), immSize);
-}
-
-X86Assembler::LabelLink *X86Assembler::_emitDisplacement(LabelData &l_data, sysint_t inlinedDisplacement, int size)
-{
- ASMJIT_ASSERT(l_data.offset == -1);
- ASMJIT_ASSERT(size == 1 || size == 4);
-
- // Chain with label.
- LabelLink *link = this->_newLabelLink();
- link->prev = l_data.links;
- link->offset = this->getOffset();
- link->displacement = inlinedDisplacement;
-
- l_data.links = link;
-
- // Emit label size as dummy data.
- if (size == 1)
- this->_emitByte(0x01);
- else // if (size == 4)
- this->_emitDWord(0x04040404);
-
- return link;
-}
-
-void X86Assembler::_emitJmpOrCallReloc(uint32_t instruction, void *target)
-{
- RelocData rd;
-
- rd.type = kRelocTrampoline;
-
-#ifdef ASMJIT_X64
- // If we are compiling in 64-bit mode, we can use trampoline if relative jump
- // is not possible.
- this->_trampolineSize += X64TrampolineWriter::kSizeTotal;
-#endif // ARCHITECTURE_SPECIFIC
-
- rd.size = 4;
- rd.offset = this->getOffset();
- rd.address = target;
-
- this->_relocData.push_back(rd);
-
- // Emit dummy 32-bit integer (will be overwritten by relocCode()).
- this->_emitInt32(0);
-}
-
-//! @internal
-//!
-//! @brief Get whether the extended register (additional eight registers
-//! introduced by 64-bit mode) is used.
-static inline bool X86Assembler_isExtRegisterUsed(const Operand &op)
-{
- // Hacky, but correct.
- // - If operand type is register then extended register is register with
- // index 8 and greater (8 to 15 inclusive).
- // - If operand type is memory operand then we need to take care about
- // label (in _mem.base) and kInvalidValue, we just decrement the value
- // by 8 and check if it's at interval 0 to 7 inclusive (if it's there
- // then it's extended register.
- return (op.isReg() && (op._reg.code & kRegIndexMask) >= 8U) || (op.isMem() && (((static_cast<uint32_t>(op._mem.base) - 8U) < 8U) || ((static_cast<uint32_t>(op._mem.index) - 8U) < 8U)));
-}
-
-// Logging helpers.
-static const char *AssemblerX86_operandSize[] =
-{
- nullptr,
- "byte ptr ",
- "word ptr ",
- nullptr,
- "dword ptr ",
- nullptr,
- nullptr,
- nullptr,
- "qword ptr ",
- nullptr,
- "tword ptr ",
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- "dqword ptr "
-};
-
-static const char X86Assembler_segmentName[] =
- "es:\0"
- "cs:\0"
- "ss:\0"
- "ds:\0"
- "fs:\0"
- "gs:\0"
- "\0\0\0\0";
-
-static char *X86Assembler_dumpInstructionName(char *buf, uint32_t code)
-{
- ASMJIT_ASSERT(code < _kX86InstCount);
- return StringUtil::copy(buf, x86InstInfo[code].getName());
-}
-
-char *X86Assembler_dumpRegister(char *buf, uint32_t type, uint32_t index)
-{
- // NE == Not-Encodable.
- const char reg8l[] = "al\0\0" "cl\0\0" "dl\0\0" "bl\0\0" "spl\0" "bpl\0" "sil\0" "dil\0" ;
- const char reg8h[] = "ah\0\0" "ch\0\0" "dh\0\0" "bh\0\0" "NE\0\0" "NE\0\0" "NE\0\0" "NE\0\0";
- const char reg16[] = "ax\0\0" "cx\0\0" "dx\0\0" "bx\0\0" "sp\0\0" "bp\0\0" "si\0\0" "di\0\0";
-
- switch (type)
- {
- case kX86RegTypeGpbLo:
- if (index < 8)
- return StringUtil::copy(buf, ®8l[index * 4]);
-
- *buf++ = 'r';
- goto _EmitID;
-
- case kX86RegTypeGpbHi:
- if (index < 4)
- return StringUtil::copy(buf, ®8h[index * 4]);
-
- _EmitNE:
- return StringUtil::copy(buf, "NE");
-
- case kX86RegTypeGpw:
- if (index < 8)
- return StringUtil::copy(buf, ®16[index * 4]);
-
- *buf++ = 'r';
- buf = StringUtil::utoa(buf, index);
- *buf++ = 'w';
- return buf;
-
- case kX86RegTypeGpd:
- if (index < 8)
- {
- *buf++ = 'e';
- return StringUtil::copy(buf, ®16[index * 4]);
- }
-
- *buf++ = 'r';
- buf = StringUtil::utoa(buf, index);
- *buf++ = 'd';
- return buf;
-
- case kX86RegTypeGpq:
- *buf++ = 'r';
-
- if (index < 8)
- return StringUtil::copy(buf, ®16[index * 4]);
-
- _EmitID:
- return StringUtil::utoa(buf, index);
-
- case kX86RegTypeX87:
- *buf++ = 's';
- *buf++ = 't';
- goto _EmitID;
-
- case kX86RegTypeMm:
- *buf++ = 'm';
- *buf++ = 'm';
- goto _EmitID;
-
- case kX86RegTypeXmm:
- *buf++ = 'x';
- *buf++ = 'm';
- *buf++ = 'm';
- goto _EmitID;
-
- case kX86RegTypeYmm:
- *buf++ = 'y';
- *buf++ = 'm';
- *buf++ = 'm';
- goto _EmitID;
-
- case kX86RegTypeSeg:
- if (index < kX86RegNumSeg)
- return StringUtil::copy(buf, &X86Assembler_segmentName[index * 4], 2);
-
- goto _EmitNE;
-
- default:
- return buf;
- }
-}
-
-char *X86Assembler_dumpOperand(char *buf, const Operand *op, uint32_t memRegType, uint32_t loggerFlags)
-{
- if (op->isReg())
- {
- const Reg ® = reinterpret_cast<const Reg &>(*op);
- return X86Assembler_dumpRegister(buf, reg.getRegType(), reg.getRegIndex());
- }
- else if (op->isMem())
- {
- const Mem &mem = reinterpret_cast<const Mem &>(*op);
- uint32_t seg = mem.getSegment();
-
- bool isAbsolute = false;
-
- if (op->getSize() <= 16)
- buf = StringUtil::copy(buf, AssemblerX86_operandSize[op->getSize()]);
-
- if (seg < kX86RegNumSeg)
- buf = StringUtil::copy(buf, &X86Assembler_segmentName[seg * 4]);
-
- *buf++ = '[';
-
- switch (mem.getMemType())
- {
- case kOperandMemNative:
- // [base + index << shift + displacement]
- buf = X86Assembler_dumpRegister(buf, memRegType, mem.getBase());
- break;
- case kOperandMemLabel:
- // [label + index << shift + displacement]
- buf += sprintf(buf, "L.%u", mem.getBase() & kOperandIdValueMask);
- break;
- case kOperandMemAbsolute:
- // [absolute]
- isAbsolute = true;
- buf = StringUtil::utoa(buf, reinterpret_cast<sysuint_t>(mem.getTarget()) + mem.getDisplacement(), 16);
- }
-
- if (mem.hasIndex())
- {
- buf = StringUtil::copy(buf, " + ");
- buf = X86Assembler_dumpRegister(buf, memRegType, mem.getIndex());
-
- if (mem.getShift())
- {
- buf = StringUtil::copy(buf, " * ");
- *buf++ = "1248"[mem.getShift() & 3];
- }
- }
-
- if (mem.getDisplacement() && !isAbsolute)
- {
- sysint_t d = mem.getDisplacement();
- uint32_t base = 10;
- char sign = '+';
-
- if (d < 0)
- {
- d = -d;
- sign = '-';
- }
-
- buf[0] = ' ';
- buf[1] = sign;
- buf[2] = ' ';
- buf += 3;
-
- if ((loggerFlags & kLoggerOutputHexDisplacement) && d > 9)
- {
- buf[0] = '0';
- buf[1] = 'x';
- buf += 2;
- base = 16;
- }
-
- buf = StringUtil::utoa(buf, static_cast<uintptr_t>(d), base);
- }
-
- *buf++ = ']';
- return buf;
- }
- else if (op->isImm())
- {
- const Imm &i = reinterpret_cast<const Imm &>(*op);
-
- sysuint_t value = i.getUValue();
- uint32_t base = 10;
-
- if ((loggerFlags & kLoggerOutputHexImmediate) && value > 9)
- base = 16;
-
- if (i.isUnsigned() || base == 16)
- return StringUtil::utoa(buf, value, base);
- else
- return StringUtil::itoa(buf, static_cast<sysint_t>(value), base);
- }
- else if (op->isLabel())
- return buf + sprintf(buf, "L.%u", op->getId() & kOperandIdValueMask);
- else
- return StringUtil::copy(buf, "None");
-}
-
-static char *X86Assembler_dumpInstruction(char *buf, uint32_t code, uint32_t emitOptions, const Operand *o0, const Operand *o1, const Operand *o2, uint32_t memRegType, uint32_t loggerFlags)
-{
- // Rex, lock, and short prefix.
- if (emitOptions & kX86EmitOptionRex)
- buf = StringUtil::copy(buf, "rex ", 4);
-
- if (emitOptions & kX86EmitOptionLock)
- buf = StringUtil::copy(buf, "lock ", 5);
-
- if (emitOptions & kX86EmitOptionShortJump)
- buf = StringUtil::copy(buf, "short ", 6);
-
- // Dump instruction name.
- buf = X86Assembler_dumpInstructionName(buf, code);
-
- // Dump operands.
- if (!o0->isNone())
- {
- *buf++ = ' ';
- buf = X86Assembler_dumpOperand(buf, o0, memRegType, loggerFlags);
- }
- if (!o1->isNone())
- {
- *buf++ = ',';
- *buf++ = ' ';
- buf = X86Assembler_dumpOperand(buf, o1, memRegType, loggerFlags);
- }
- if (!o2->isNone())
- {
- *buf++ = ',';
- *buf++ = ' ';
- buf = X86Assembler_dumpOperand(buf, o2, memRegType, loggerFlags);
- }
-
- return buf;
-}
-
-static char *X86Assembler_dumpComment(char *buf, size_t len, const uint8_t *binaryData, size_t binaryLen, const char *comment)
-{
- size_t currentLength = len;
- size_t commentLength = comment ? strnlen(comment, kMaxCommentLength) : 0;
-
- if (binaryLen || commentLength)
- {
- size_t align = 32;
- char sep = ';';
-
- for (size_t i = !binaryLen; i < 2; ++i)
- {
- char *bufBegin = buf;
-
- // Append align.
- if (currentLength < align)
- buf = StringUtil::fill(buf, ' ', align - currentLength);
-
- // Append separator.
- if (sep)
- {
- *buf++ = sep;
- *buf++ = ' ';
- }
-
- // Append binary data or comment.
- if (!i)
- {
- buf = StringUtil::hex(buf, binaryData, binaryLen);
- if (!commentLength)
- break;
- }
- else
- buf = StringUtil::copy(buf, comment, commentLength);
-
- currentLength += static_cast<size_t>(buf - bufBegin);
- align += 18;
- sep = '|';
- }
- }
-
- *buf++ = '\n';
- return buf;
-}
-
-static const _OpReg _patchedHiRegs[] =
-{
- // Operand |Size|Reserved0|Reserved1| OperandId | RegisterCode |
- // ----------+----+---------+---------+--------------+-----------------------+
- { kOperandReg, 1, {0 ,0 }, kInvalidValue, kX86RegTypeGpbLo | 4 },
- { kOperandReg, 1, {0 ,0 }, kInvalidValue, kX86RegTypeGpbLo | 5 },
- { kOperandReg, 1, {0 ,0 }, kInvalidValue, kX86RegTypeGpbLo | 6 },
- { kOperandReg, 1, {0 ,0 }, kInvalidValue, kX86RegTypeGpbLo | 7 }
-};
-
-void X86Assembler::_emitInstruction(uint32_t code)
-{
- this->_emitInstruction(code, &noOperand, &noOperand, &noOperand);
-}
-
-void X86Assembler::_emitInstruction(uint32_t code, const Operand *o0)
-{
- this->_emitInstruction(code, o0, &noOperand, &noOperand);
-}
-
-void X86Assembler::_emitInstruction(uint32_t code, const Operand *o0, const Operand *o1)
-{
- this->_emitInstruction(code, o0, o1, &noOperand);
-}
-
-void X86Assembler::_emitInstruction(uint32_t code, const Operand *o0, const Operand *o1, const Operand *o2)
-{
- ASMJIT_ASSERT(o0);
- ASMJIT_ASSERT(o1);
- ASMJIT_ASSERT(o2);
-
- const Operand *_loggerOperands[3];
-
- uint32_t bLoHiUsed = 0;
-#ifdef ASMJIT_X86
- uint32_t forceRexPrefix = false;
-#else
- uint32_t forceRexPrefix = this->_emitOptions & kX86EmitOptionRex;
-#endif
- uint32_t memRegType = kX86RegTypeGpz;
-
-#ifdef ASMJIT_DEBUG
- bool assertIllegal = false;
-#endif // ASMJIT_DEBUG
-
- const Imm *immOperand = nullptr;
- uint32_t immSize = 0;
-
-#define _FINISHED() \
- goto _End
-
-#define _FINISHED_IMMEDIATE(_Operand_, _Size_) \
- do \
- { \
- immOperand = reinterpret_cast<const Imm *>(_Operand_); \
- immSize = (_Size_); \
- goto _EmitImmediate; \
- } while (0)
-
- // Convert operands to kOperandNone if needed.
- if (o0->isReg())
- bLoHiUsed |= o0->_reg.code & (kX86RegTypeGpbLo | kX86RegTypeGpbHi);
- if (o1->isReg())
- bLoHiUsed |= o1->_reg.code & (kX86RegTypeGpbLo | kX86RegTypeGpbHi);
- if (o2->isReg())
- bLoHiUsed |= o2->_reg.code & (kX86RegTypeGpbLo | kX86RegTypeGpbHi);
-
- size_t beginOffset = this->getOffset();
- const X86InstInfo *id = &x86InstInfo[code];
-
- if (code >= _kX86InstCount)
- {
- this->setError(kErrorUnknownInstruction);
- goto _Cleanup;
- }
-
- // Check if register operand is BPL, SPL, SIL, DIL and do action that depends
- // to current mode:
- // - 64-bit: - Force REX prefix.
- //
- // Check if register operand is AH, BH, CH or DH and do action that depends
- // to current mode:
- // - 32-bit: - Patch operand index (index += 4), because we are using
- // different index what is used in opcode.
- // - 64-bit: - Check whether there is REX prefix and raise error if it is.
- // - Do the same as in 32-bit mode - patch register index.
- //
- // NOTE: This is a hit hacky, but I added this to older code-base and I have
- // no energy to rewrite it. Maybe in future all of this can be cleaned up!
- if (bLoHiUsed | forceRexPrefix)
- {
- _loggerOperands[0] = o0;
- _loggerOperands[1] = o1;
- _loggerOperands[2] = o2;
-
-#ifdef ASMJIT_X64
- // Check if there is register that makes this instruction un-encodable.
-
- forceRexPrefix |= static_cast<uint32_t>(X86Assembler_isExtRegisterUsed(*o0));
- forceRexPrefix |= static_cast<uint32_t>(X86Assembler_isExtRegisterUsed(*o1));
- forceRexPrefix |= static_cast<uint32_t>(X86Assembler_isExtRegisterUsed(*o2));
-
- if (o0->isRegType(kX86RegTypeGpbLo) && (o0->_reg.code & kRegIndexMask) >= 4)
- forceRexPrefix = true;
- else if (o1->isRegType(kX86RegTypeGpbLo) && (o1->_reg.code & kRegIndexMask) >= 4)
- forceRexPrefix = true;
- else if (o2->isRegType(kX86RegTypeGpbLo) && (o2->_reg.code & kRegIndexMask) >= 4)
- forceRexPrefix = true;
-
- if ((bLoHiUsed & kX86RegTypeGpbHi) && forceRexPrefix)
- goto _IllegalInstruction;
-#endif // ASMJIT_X64
-
- // Patch GPB.HI operand index.
- if (bLoHiUsed & kX86RegTypeGpbHi)
- {
- if (o0->isRegType(kX86RegTypeGpbHi))
- o0 = reinterpret_cast<const Operand *>(&_patchedHiRegs[o0->_reg.code & kRegIndexMask]);
- if (o1->isRegType(kX86RegTypeGpbHi))
- o1 = reinterpret_cast<const Operand *>(&_patchedHiRegs[o1->_reg.code & kRegIndexMask]);
- if (o2->isRegType(kX86RegTypeGpbHi))
- o2 = reinterpret_cast<const Operand *>(&_patchedHiRegs[o2->_reg.code & kRegIndexMask]);
- }
- }
-
- // Check for buffer space (and grow if needed).
- if (!this->canEmit())
- goto _Cleanup;
-
- if (this->_emitOptions & kX86EmitOptionLock)
- {
- if (!id->isLockable())
- goto _IllegalInstruction;
- this->_emitByte(0xF0);
- }
-
- switch (id->getGroup())
- {
- case kX86InstGroupNone:
- _FINISHED();
-
- case kX86InstGroupEmit:
- this->_emitOpCode(id->_opCode[0]);
- _FINISHED();
-
- case kX86InstGroupArith:
- {
- uint32_t opCode = id->_opCode[0];
- uint8_t opReg = static_cast<uint8_t>(id->_opCodeR);
-
- // Mem <- Reg
- if (o0->isMem() && o1->isReg())
- {
- this->_emitX86RM(opCode + (o1->getSize() != 1), o1->getSize() == 2, o1->getSize() == 8, reinterpret_cast<const GpReg &>(*o1).getRegCode(), reinterpret_cast<const Operand &>(*o0), 0, forceRexPrefix);
- _FINISHED();
- }
-
- // Reg <- Reg|Mem
- if (o0->isReg() && o1->isRegMem())
- {
- this->_emitX86RM(opCode + 2 + (o0->getSize() != 1), o0->getSize() == 2, o0->getSize() == 8, reinterpret_cast<const GpReg &>(*o0).getRegCode(), reinterpret_cast<const Operand &>(*o1), 0, forceRexPrefix);
- _FINISHED();
- }
-
- // Alternate Form - AL, AX, EAX, RAX.
- if (o0->isRegIndex(0) && o1->isImm())
- {
- if (o0->getSize() == 1 || !IntUtil::isInt8(static_cast<const Imm *>(o1)->getValue()))
- {
- if (o0->getSize() == 2)
- this->_emitByte(0x66); // 16-bit.
- else if (o0->getSize() == 8)
- this->_emitByte(0x48); // REX.W.
-
- this->_emitByte((opReg << 3) | (0x04 + (o0->getSize() != 1)));
- _FINISHED_IMMEDIATE(o1, IntUtil::_min<uint32_t>(o0->getSize(), 4));
- }
- }
-
- if (o0->isRegMem() && o1->isImm())
- {
- const Imm &imm = reinterpret_cast<const Imm &>(*o1);
- immSize = IntUtil::isInt8(imm.getValue()) ? 1 : IntUtil::_min(o0->getSize(), 4u);
-
- this->_emitX86RM(id->_opCode[1] + (o0->getSize() != 1 ? (immSize != 1 ? 1 : 3) : 0), o0->getSize() == 2, o0->getSize() == 8, opReg, reinterpret_cast<const Operand &>(*o0), immSize, forceRexPrefix);
- _FINISHED_IMMEDIATE(&imm, immSize);
- }
-
- break;
- }
-
- case kX86InstGroupBSwap:
- if (o0->isReg())
- {
- const GpReg &dst = reinterpret_cast<const GpReg &>(*o0);
-
-#ifdef ASMJIT_X64
- this->_emitRexR(dst.getRegType() == kX86RegTypeGpq, 1, dst.getRegCode(), forceRexPrefix);
-#endif // ASMJIT_X64
- this->_emitByte(0x0F);
- this->_emitModR(1, dst.getRegCode());
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupBTest:
- if (o0->isRegMem() && o1->isReg())
- {
- const Operand &dst = reinterpret_cast<const Operand &>(*o0);
- const GpReg &src = reinterpret_cast<const GpReg &>(*o1);
-
- this->_emitX86RM(id->_opCode[0], src.isRegType(kX86RegTypeGpw), src.isRegType(kX86RegTypeGpq), src.getRegCode(), dst, 0, forceRexPrefix);
- _FINISHED();
- }
-
- if (o0->isRegMem() && o1->isImm())
- {
- const Operand &dst = reinterpret_cast<const Operand &>(*o0);
-
- this->_emitX86RM(id->_opCode[1], dst.getSize() == 2, dst.getSize() == 8, static_cast<uint8_t>(id->_opCodeR), dst, 1, forceRexPrefix);
- _FINISHED_IMMEDIATE(o1, 1);
- }
-
- break;
-
- case kX86InstGroupCall:
- if (o0->isRegTypeMem(kX86RegTypeGpz))
- {
- const Operand &dst = reinterpret_cast<const Operand &>(*o0);
- this->_emitX86RM(0xFF, 0, 0, 2, dst, 0, forceRexPrefix);
- _FINISHED();
- }
-
- if (o0->isImm())
- {
- const Imm &imm = reinterpret_cast<const Imm &>(*o0);
- this->_emitByte(0xE8);
- this->_emitJmpOrCallReloc(kX86InstGroupCall, reinterpret_cast<void *>(imm.getValue()));
- _FINISHED();
- }
-
- if (o0->isLabel())
- {
- LabelData &l_data = this->_labels[reinterpret_cast<const Label *>(o0)->getId() & kOperandIdValueMask];
-
- if (l_data.offset != -1)
- {
- // Bound label.
- static const sysint_t rel32_size = 5;
- sysint_t offs = l_data.offset - this->getOffset();
-
- ASMJIT_ASSERT(offs <= 0);
-
- this->_emitByte(0xE8);
- this->_emitInt32(static_cast<int32_t>(offs - rel32_size));
- }
- else
- {
- // Non-bound label.
- this->_emitByte(0xE8);
- this->_emitDisplacement(l_data, -4, 4);
- }
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupCrc32:
- if (o0->isReg() && o1->isRegMem())
- {
- const GpReg &dst = reinterpret_cast<const GpReg &>(*o0);
- const Operand &src = reinterpret_cast<const Operand &>(*o1);
- ASMJIT_ASSERT(dst.getRegType() == kX86RegTypeGpd || dst.getRegType() == kX86RegTypeGpq);
-
- this->_emitX86RM(id->_opCode[0] + (src.getSize() != 1), src.getSize() == 2, dst.getRegType() == 8, dst.getRegCode(), src, 0, forceRexPrefix);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupEnter:
- if (o0->isImm() && o1->isImm())
- {
- this->_emitByte(0xC8);
- this->_emitWord(static_cast<uint16_t>(static_cast<uintptr_t>(reinterpret_cast<const Imm &>(*o2).getValue())));
- this->_emitByte(static_cast<uint8_t>(static_cast<uintptr_t>(reinterpret_cast<const Imm &>(*o1).getValue())));
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupIMul:
- // 1 operand
- if (o0->isRegMem() && o1->isNone() && o2->isNone())
- {
- const Operand &src = reinterpret_cast<const Operand &>(*o0);
- this->_emitX86RM(0xF6 + (src.getSize() != 1), src.getSize() == 2, src.getSize() == 8, 5, src, 0, forceRexPrefix);
- _FINISHED();
- }
- // 2 operands
- else if (o0->isReg() && !o1->isNone() && o2->isNone())
- {
- const GpReg &dst = reinterpret_cast<const GpReg &>(*o0);
- ASMJIT_ASSERT(!dst.isRegType(kX86RegTypeGpw));
-
- if (o1->isRegMem())
- {
- const Operand &src = reinterpret_cast<const Operand &>(*o1);
-
- this->_emitX86RM(0x0FAF, dst.isRegType(kX86RegTypeGpw), dst.isRegType(kX86RegTypeGpq), dst.getRegCode(), src, 0, forceRexPrefix);
- _FINISHED();
- }
- else if (o1->isImm())
- {
- const Imm &imm = reinterpret_cast<const Imm &>(*o1);
-
- if (IntUtil::isInt8(imm.getValue()))
- {
- this->_emitX86RM(0x6B, dst.isRegType(kX86RegTypeGpw), dst.isRegType(kX86RegTypeGpq), dst.getRegCode(), dst, 1, forceRexPrefix);
- _FINISHED_IMMEDIATE(&imm, 1);
- }
- else
- {
- immSize = dst.isRegType(kX86RegTypeGpw) ? 2 : 4;
- this->_emitX86RM(0x69, dst.isRegType(kX86RegTypeGpw), dst.isRegType(kX86RegTypeGpq), dst.getRegCode(), dst, immSize, forceRexPrefix);
- _FINISHED_IMMEDIATE(&imm, immSize);
- }
- }
- }
- // 3 operands
- else if (o0->isReg() && o1->isRegMem() && o2->isImm())
- {
- const GpReg &dst = reinterpret_cast<const GpReg &>(*o0);
- const Operand &src = reinterpret_cast<const Operand &>(*o1);
- const Imm &imm = reinterpret_cast<const Imm &>(*o2);
-
- if (IntUtil::isInt8(imm.getValue()))
- {
- this->_emitX86RM(0x6B, dst.isRegType(kX86RegTypeGpw), dst.isRegType(kX86RegTypeGpq), dst.getRegCode(), src, 1, forceRexPrefix);
- _FINISHED_IMMEDIATE(&imm, 1);
- }
- else
- {
- immSize = dst.isRegType(kX86RegTypeGpw) ? 2 : 4;
- this->_emitX86RM(0x69, dst.isRegType(kX86RegTypeGpw), dst.isRegType(kX86RegTypeGpq), dst.getRegCode(), src, immSize, forceRexPrefix);
- _FINISHED_IMMEDIATE(&imm, immSize);
- }
- }
-
- break;
-
- case kX86InstGroupIncDec:
- if (o0->isRegMem())
- {
- const Operand &dst = reinterpret_cast<const Operand &>(*o0);
-
- // INC [r16|r32] in 64-bit mode is not encodable.
-#ifdef ASMJIT_X86
- if (dst.isReg() && (dst.isRegType(kX86RegTypeGpw) || dst.isRegType(kX86RegTypeGpd)))
- {
- this->_emitX86Inl(id->_opCode[0], dst.isRegType(kX86RegTypeGpw), 0, reinterpret_cast<const Reg&>(dst).getRegCode(), false);
- _FINISHED();
- }
-#endif // ASMJIT_X86
-
- this->_emitX86RM(id->_opCode[1] + (dst.getSize() != 1), dst.getSize() == 2, dst.getSize() == 8, static_cast<uint8_t>(id->_opCodeR), dst, 0, forceRexPrefix);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupJcc:
- if (o0->isLabel())
- {
- LabelData &l_data = this->_labels[reinterpret_cast<const Label *>(o0)->getId() & kOperandIdValueMask];
-
- uint32_t hint = static_cast<uint32_t>(o1->isImm() ? reinterpret_cast<const Imm &>(*o1).getValue() : 0);
- bool isShortJump = !!(_emitOptions & kX86EmitOptionShortJump);
-
- // Emit jump hint if configured for that.
- if ((hint & (kCondHintLikely | kCondHintUnlikely)) && (this->_properties & (1 << kX86PropertyJumpHints)))
- {
- if (hint & kCondHintLikely)
- this->_emitByte(kX86CondPrefixLikely);
- else if (hint & kCondHintUnlikely)
- this->_emitByte(kX86CondPrefixUnlikely);
- }
-
- if (l_data.offset != -1)
- {
- // Bound label.
- static const sysint_t rel8_size = 2;
- static const sysint_t rel32_size = 6;
- sysint_t offs = l_data.offset - this->getOffset();
-
- ASMJIT_ASSERT(offs <= 0);
-
- if (IntUtil::isInt8(offs - rel8_size))
- {
- this->_emitByte(0x70 | static_cast<uint8_t>(id->_opCode[0]));
- this->_emitByte(static_cast<uint8_t>(static_cast<int8_t>(offs - rel8_size)));
-
- // Change the emit options so logger can log instruction correctly.
- this->_emitOptions |= kX86EmitOptionShortJump;
- }
- else
- {
- if (isShortJump && this->_logger)
- {
- this->_logger->logString("*** ASSEMBLER WARNING: Emitting long conditional jump, but short jump instruction forced!\n");
- this->_emitOptions &= ~kX86EmitOptionShortJump;
- }
-
- this->_emitByte(0x0F);
- this->_emitByte(0x80 | static_cast<uint8_t>(id->_opCode[0]));
- this->_emitInt32(static_cast<int32_t>(offs - rel32_size));
- }
- }
- else
- {
- // Non-bound label.
- if (isShortJump)
- {
- this->_emitByte(0x70 | static_cast<uint8_t>(id->_opCode[0]));
- this->_emitDisplacement(l_data, -1, 1);
- }
- else
- {
- this->_emitByte(0x0F);
- this->_emitByte(0x80 | static_cast<uint8_t>(id->_opCode[0]));
- this->_emitDisplacement(l_data, -4, 4);
- }
- }
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupJmp:
- if (o0->isRegMem())
- {
- const Operand &dst = reinterpret_cast<const Operand &>(*o0);
-
- this->_emitX86RM(0xFF, 0, 0, 4, dst, 0, forceRexPrefix);
- _FINISHED();
- }
-
- if (o0->isImm())
- {
- const Imm &imm = reinterpret_cast<const Imm &>(*o0);
- this->_emitByte(0xE9);
- this->_emitJmpOrCallReloc(kX86InstGroupJmp, reinterpret_cast<void *>(imm.getValue()));
- _FINISHED();
- }
-
- if (o0->isLabel())
- {
- LabelData &l_data = this->_labels[reinterpret_cast<const Label *>(o0)->getId() & kOperandIdValueMask];
- bool isShortJump = !!(this->_emitOptions & kX86EmitOptionShortJump);
-
- if (l_data.offset != -1)
- {
- // Bound label.
- static const sysint_t rel8_size = 2;
- static const sysint_t rel32_size = 5;
- sysint_t offs = l_data.offset - this->getOffset();
-
- if (IntUtil::isInt8(offs - rel8_size))
- {
- this->_emitByte(0xEB);
- this->_emitByte(static_cast<uint8_t>(static_cast<int8_t>(offs - rel8_size)));
-
- // Change the emit options so logger can log instruction correctly.
- this->_emitOptions |= kX86EmitOptionShortJump;
- }
- else
- {
- if (isShortJump && this->_logger)
- {
- this->_logger->logString("*** ASSEMBLER WARNING: Emitting long jump, but short jump instruction forced!\n");
- this->_emitOptions &= ~kX86EmitOptionShortJump;
- }
-
- this->_emitByte(0xE9);
- this->_emitInt32(static_cast<int32_t>(offs - rel32_size));
- }
- }
- else
- {
- // Non-bound label.
- if (isShortJump)
- {
- this->_emitByte(0xEB);
- this->_emitDisplacement(l_data, -1, 1);
- }
- else
- {
- this->_emitByte(0xE9);
- this->_emitDisplacement(l_data, -4, 4);
- }
- }
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupLea:
- if (o0->isReg() && o1->isMem())
- {
- const GpReg &dst = reinterpret_cast<const GpReg &>(*o0);
- const Mem &src = reinterpret_cast<const Mem &>(*o1);
-
- // Size override prefix support.
- if (src.getSizePrefix())
- {
- this->_emitByte(0x67);
-#ifdef ASMJIT_X86
- memRegType = kX86RegTypeGpw;
-#else
- memRegType = kX86RegTypeGpd;
-#endif
- }
-
- this->_emitX86RM(0x8D, dst.isRegType(kX86RegTypeGpw), dst.isRegType(kX86RegTypeGpq), dst.getRegCode(), src, 0, forceRexPrefix);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupMem:
- if (o0->isMem())
- {
- this->_emitX86RM(id->_opCode[0], 0, static_cast<uint8_t>(id->_opCode[1]), (uint8_t)id->_opCodeR, reinterpret_cast<const Mem &>(*o0), 0, forceRexPrefix);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupMov:
- {
- const Operand &dst = *o0;
- const Operand &src = *o1;
-
- switch ((dst.getType() << 4) | src.getType())
- {
- // Reg <- Reg/Mem
- case (kOperandReg << 4) | kOperandReg:
- // Reg <- Sreg
- if (src.isRegType(kX86RegTypeSeg))
- {
- ASMJIT_ASSERT(dst.isRegType(kX86RegTypeGpw) || dst.isRegType(kX86RegTypeGpd) || dst.isRegType(kX86RegTypeGpq));
-
- this->_emitX86RM(0x8C, dst.getSize() == 2, dst.getSize() == 8, reinterpret_cast<const SegmentReg &>(src).getRegCode(), reinterpret_cast<const Operand &>(dst), 0, forceRexPrefix);
- _FINISHED();
- }
-
- // Sreg <- Reg/Mem
- if (dst.isRegType(kX86RegTypeSeg))
- {
- ASMJIT_ASSERT(src.isRegType(kX86RegTypeGpw) || src.isRegType(kX86RegTypeGpd) || src.isRegType(kX86RegTypeGpq));
-
- _Emit_Mov_Sreg_RM:
- this->_emitX86RM(0x8E, src.getSize() == 2, src.getSize() == 8, reinterpret_cast<const SegmentReg &>(dst).getRegCode(), reinterpret_cast<const Operand &>(src), 0, forceRexPrefix);
- _FINISHED();
- }
-
- ASMJIT_ASSERT(src.isRegType(kX86RegTypeGpbLo) || src.isRegType(kX86RegTypeGpbHi) || src.isRegType(kX86RegTypeGpw) || src.isRegType(kX86RegTypeGpd) || src.isRegType(kX86RegTypeGpq));
- // ... fall through ...
- case (kOperandReg << 4) | kOperandMem:
- // Sreg <- Mem
- if (dst.isRegType(kX86RegTypeSeg))
- goto _Emit_Mov_Sreg_RM;
-
- ASMJIT_ASSERT(dst.isRegType(kX86RegTypeGpbLo) || dst.isRegType(kX86RegTypeGpbHi) || dst.isRegType(kX86RegTypeGpw) || dst.isRegType(kX86RegTypeGpd) || dst.isRegType(kX86RegTypeGpq));
-
- this->_emitX86RM(0x0000008A + (dst.getSize() != 1), dst.isRegType(kX86RegTypeGpw), dst.isRegType(kX86RegTypeGpq), reinterpret_cast<const GpReg &>(dst).getRegCode(),
- reinterpret_cast<const Operand &>(src), 0, forceRexPrefix);
- _FINISHED();
-
- // Reg <- Imm
- case (kOperandReg << 4) | kOperandImm:
- {
- const GpReg &dst = reinterpret_cast<const GpReg &>(*o0);
- const Imm &src = reinterpret_cast<const Imm &>(*o1);
-
- // In 64-bit mode the immediate can be 64-bits long if the
- // destination operand type is register (otherwise 32-bits).
- immSize = dst.getSize();
-
-#ifdef ASMJIT_X64
- // Optimize instruction size by using 32-bit immediate if value can
- // fit into it.
- if (immSize == 8 && IntUtil::isInt32(src.getValue()))
- {
- this->_emitX86RM(0xC7,
- 0, // 16BIT
- 1, // REX.W
- 0, // O
- dst, 0, forceRexPrefix);
- immSize = 4;
- }
- else
-#endif // ASMJIT_X64
- this->_emitX86Inl(dst.getSize() == 1 ? 0xB0 : 0xB8, dst.isRegType(kX86RegTypeGpw), dst.isRegType(kX86RegTypeGpq), dst.getRegCode(), forceRexPrefix);
-
- _FINISHED_IMMEDIATE(&src, immSize);
- }
-
- // Mem <- Reg/Sreg
- case (kOperandMem << 4) | kOperandReg:
- if (src.isRegType(kX86RegTypeSeg))
- {
- // Mem <- Sreg
- this->_emitX86RM(0x8C, dst.getSize() == 2, dst.getSize() == 8, reinterpret_cast<const SegmentReg &>(src).getRegCode(), reinterpret_cast<const Operand &>(dst), 0, forceRexPrefix);
- }
- else
- {
- // Mem <- Reg
- ASMJIT_ASSERT(src.isRegType(kX86RegTypeGpbLo) || src.isRegType(kX86RegTypeGpbHi) || src.isRegType(kX86RegTypeGpw) || src.isRegType(kX86RegTypeGpd) || src.isRegType(kX86RegTypeGpq));
-
- this->_emitX86RM(0x88 + (src.getSize() != 1), src.isRegType(kX86RegTypeGpw), src.isRegType(kX86RegTypeGpq), reinterpret_cast<const GpReg &>(src).getRegCode(),
- reinterpret_cast<const Operand &>(dst), 0, forceRexPrefix);
- }
-
- _FINISHED();
-
- // Mem <- Imm
- case (kOperandMem << 4) | kOperandImm:
- immSize = IntUtil::_min(dst.getSize(), 4u);
-
- this->_emitX86RM(0xC6 + (dst.getSize() != 1), dst.getSize() == 2, dst.getSize() == 8, 0, reinterpret_cast<const Operand &>(dst), immSize, forceRexPrefix);
- _FINISHED_IMMEDIATE(&src, immSize);
- }
-
- break;
- }
-
- case kX86InstGroupMovPtr:
- if ((o0->isReg() && o1->isImm()) || (o0->isImm() && o1->isReg()))
- {
- bool reverse = o1->getType() == kOperandReg;
- uint8_t opCode = !reverse ? 0xA0 : 0xA2;
- const GpReg ® = reinterpret_cast<const GpReg &>(!reverse ? *o0 : *o1);
- const Imm &imm = reinterpret_cast<const Imm &>(!reverse ? *o1 : *o0);
-
- if (reg.getRegIndex())
- goto _IllegalInstruction;
-
- if (reg.isRegType(kX86RegTypeGpw))
- this->_emitByte(0x66);
-#ifdef ASMJIT_X64
- this->_emitRexR(reg.getSize() == 8, 0, 0, forceRexPrefix);
-#endif // ASMJIT_X64
- this->_emitByte(opCode + (reg.getSize() != 1));
- _FINISHED_IMMEDIATE(&imm, sizeof(sysint_t));
- }
-
- break;
-
- case kX86InstGroupMovSxMovZx:
- if (o0->isReg() && o1->isRegMem())
- {
- const GpReg &dst = reinterpret_cast<const GpReg &>(*o0);
- const Operand &src = reinterpret_cast<const Operand &>(*o1);
-
- if (dst.getSize() == 1)
- goto _IllegalInstruction;
-
- if (src.getSize() != 1 && src.getSize() != 2)
- goto _IllegalInstruction;
-
- if (src.getSize() == 2 && dst.getSize() == 2)
- goto _IllegalInstruction;
-
- this->_emitX86RM(id->_opCode[0] + (src.getSize() != 1), dst.isRegType(kX86RegTypeGpw), dst.isRegType(kX86RegTypeGpq), dst.getRegCode(), src, 0, forceRexPrefix);
- _FINISHED();
- }
-
- break;
-
-#ifdef ASMJIT_X64
- case kX86InstGroupMovSxD:
- if (o0->isReg() && o1->isRegMem())
- {
- const GpReg &dst = reinterpret_cast<const GpReg &>(*o0);
- const Operand &src = reinterpret_cast<const Operand &>(*o1);
- this->_emitX86RM(0x00000063, 0, 1, dst.getRegCode(), src, 0, forceRexPrefix);
- _FINISHED();
- }
-
- break;
-#endif // ASMJIT_X64
-
- case kX86InstGroupPush:
- if (o0->isRegType(kX86RegTypeSeg))
- {
- static const uint32_t opcodeList[] =
- {
- 0x06, // ES.
- 0x0E, // CS.
- 0x16, // SS.
- 0x1E, // DS.
- 0x0FA0, // FS.
- 0x0FA8 // GS.
- };
-
- unsigned segment = reinterpret_cast<const SegmentReg *>(o0)->getRegIndex();
- ASMJIT_ASSERT(segment < kX86SegCount);
-
- unsigned opcode = opcodeList[segment];
-
- if (opcode > 0xFF)
- this->_emitByte(opcode >> 8);
- this->_emitByte(opcode & 0xFF);
-
- _FINISHED();
- }
-
- // This section is only for immediates, memory/register operands are handled in kX86InstGroupPop.
- if (o0->isImm())
- {
- const Imm &imm = reinterpret_cast<const Imm &>(*o0);
-
- if (IntUtil::isInt8(imm.getValue()))
- {
- this->_emitByte(0x6A);
- _FINISHED_IMMEDIATE(&imm, 1);
- }
- else
- {
- this->_emitByte(0x68);
- _FINISHED_IMMEDIATE(&imm, 4);
- }
- }
-
- // ... goto kX86InstGroupPop ...
-
- case kX86InstGroupPop:
- if (o0->isRegType(kX86RegTypeSeg))
- {
- static const uint32_t opcodeList[] =
- {
- 0x07, // ES.
- 0, // CS.
- 0x17, // SS.
- 0x1F, // DS.
- 0x0FA1, // FS.
- 0x0FA9 // GS.
- };
-
- unsigned segment = reinterpret_cast<const SegmentReg *>(o0)->getRegIndex();
- ASMJIT_ASSERT(segment < kX86SegCount);
-
- unsigned opcode = opcodeList[segment];
- ASMJIT_ASSERT(opcode);
-
- if (opcode > 0xFF)
- this->_emitByte(opcode >> 8);
- this->_emitByte(opcode & 0xFF);
-
- _FINISHED();
- }
-
- if (o0->isReg())
- {
- ASMJIT_ASSERT(o0->isRegType(kX86RegTypeGpw) || o0->isRegType(kX86RegTypeGpz));
- this->_emitX86Inl(id->_opCode[0], o0->isRegType(kX86RegTypeGpw), 0, reinterpret_cast<const GpReg &>(*o0).getRegCode(), forceRexPrefix);
- _FINISHED();
- }
-
- if (o0->isMem())
- {
- this->_emitX86RM(id->_opCode[1], o0->getSize() == 2, 0, static_cast<uint8_t>(id->_opCodeR), reinterpret_cast<const Operand &>(*o0), 0, forceRexPrefix);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupRegRm:
- if (o0->isReg() && o1->isRegMem())
- {
- const GpReg &dst = reinterpret_cast<const GpReg &>(*o0);
- const Operand &src = reinterpret_cast<const Operand &>(*o1);
- ASMJIT_ASSERT(dst.getSize() != 1);
-
- this->_emitX86RM(id->_opCode[0], dst.getRegType() == kX86RegTypeGpw, dst.getRegType() == kX86RegTypeGpq, dst.getRegCode(), src, 0, forceRexPrefix);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupRm:
- if (o0->isRegMem())
- {
- const Operand &op = reinterpret_cast<const Operand &>(*o0);
- this->_emitX86RM(id->_opCode[0] + (op.getSize() != 1), op.getSize() == 2, op.getSize() == 8, static_cast<uint8_t>(id->_opCodeR), op, 0, forceRexPrefix);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupRmByte:
- if (o0->isRegMem())
- {
- const Operand &op = reinterpret_cast<const Operand &>(*o0);
-
- // Only BYTE register or BYTE/TYPELESS memory location can be used.
- ASMJIT_ASSERT(op.getSize() <= 1);
-
- this->_emitX86RM(id->_opCode[0], false, false, 0, op, 0, forceRexPrefix);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupRmReg:
- if (o0->isRegMem() && o1->isReg())
- {
- const Operand &dst = reinterpret_cast<const Operand &>(*o0);
- const GpReg &src = reinterpret_cast<const GpReg &>(*o1);
- this->_emitX86RM(id->_opCode[0] + (src.getSize() != 1), src.getRegType() == kX86RegTypeGpw, src.getRegType() == kX86RegTypeGpq, src.getRegCode(), dst, 0, forceRexPrefix);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupRep:
- {
- uint32_t opCode = id->_opCode[0];
- uint32_t opSize = id->_opCode[1];
-
- // Emit REP prefix (1 BYTE).
- this->_emitByte(opCode >> 24);
-
- if (opSize != 1)
- ++opCode; // D, Q and W form.
- if (opSize == 2)
- this->_emitByte(0x66); // 16-bit prefix.
-#ifdef ASMJIT_X64
- else if (opSize == 8)
- this->_emitByte(0x48); // REX.W prefix.
-#endif // ASMJIT_X64
-
- // Emit opcode (1 BYTE).
- this->_emitByte(opCode & 0xFF);
- _FINISHED();
- }
-
- case kX86InstGroupRet:
- if (o0->isNone())
- {
- this->_emitByte(0xC3);
- _FINISHED();
- }
- else if (o0->isImm())
- {
- const Imm &imm = reinterpret_cast<const Imm &>(*o0);
- ASMJIT_ASSERT(IntUtil::isUInt16(imm.getValue()));
-
- if (!imm.getValue())
- {
- this->_emitByte(0xC3);
- _FINISHED();
- }
- else
- {
- this->_emitByte(0xC2);
- _FINISHED_IMMEDIATE(&imm, 2);
- }
- }
-
- break;
-
- case kX86InstGroupRot:
- if (o0->isRegMem() && (o1->isRegCode(kX86RegCl) || o1->isImm()))
- {
- // generate opcode. For these operations is base 0xC0 or 0xD0.
- bool useImm8 = o1->isImm() && reinterpret_cast<const Imm &>(*o1).getValue() != 1;
- uint32_t opCode = useImm8 ? 0xC0 : 0xD0;
-
- // size and operand type modifies the opcode
- if (o0->getSize() != 1)
- opCode |= 0x01;
- if (o1->getType() == kOperandReg)
- opCode |= 0x02;
-
- this->_emitX86RM(opCode, o0->getSize() == 2, o0->getSize() == 8, static_cast<uint8_t>(id->_opCodeR), reinterpret_cast<const Operand &>(*o0), useImm8 ? 1 : 0, forceRexPrefix);
-
- if (useImm8)
- _FINISHED_IMMEDIATE(o1, 1);
- else
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupShldShrd:
- if (o0->isRegMem() && o1->isReg() && (o2->isImm() || (o2->isReg() && o2->isRegCode(kX86RegCl))))
- {
- const Operand &dst = reinterpret_cast<const Operand &>(*o0);
- const GpReg &src1 = reinterpret_cast<const GpReg &>(*o1);
- const Operand &src2 = reinterpret_cast<const Operand &>(*o2);
-
- ASMJIT_ASSERT(dst.getSize() == src1.getSize());
-
- this->_emitX86RM(id->_opCode[0] + src2.isReg(), src1.isRegType(kX86RegTypeGpw), src1.isRegType(kX86RegTypeGpq), src1.getRegCode(), dst, src2.isImm() ? 1 : 0, forceRexPrefix);
- if (src2.isImm())
- _FINISHED_IMMEDIATE(&src2, 1);
- else
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupTest:
- if (o0->isRegMem() && o1->isReg())
- {
- ASMJIT_ASSERT(o0->getSize() == o1->getSize());
- this->_emitX86RM(0x84 + (o1->getSize() != 1), o1->getSize() == 2, o1->getSize() == 8, reinterpret_cast<const Reg &>(*o1).getRegCode(), reinterpret_cast<const Operand &>(*o0), 0, forceRexPrefix);
- _FINISHED();
- }
-
- // Alternate Form - AL, AX, EAX, RAX.
- if (o0->isRegIndex(0) && o1->isImm())
- {
- immSize = IntUtil::_min(o0->getSize(), 4u);
-
- if (o0->getSize() == 2)
- this->_emitByte(0x66); // 16-bit.
-#ifdef ASMJIT_X64
- this->_emitRexRM(o0->getSize() == 8, 0, reinterpret_cast<const Operand &>(*o0), forceRexPrefix);
-#endif // ASMJIT_X64
- this->_emitByte(0xA8 + (o0->getSize() != 1));
- _FINISHED_IMMEDIATE(o1, immSize);
- }
-
- if (o0->isRegMem() && o1->isImm())
- {
- immSize = IntUtil::_min(o0->getSize(), 4u);
-
- if (o0->getSize() == 2)
- this->_emitByte(0x66); // 16-bit.
- this->_emitSegmentPrefix(reinterpret_cast<const Operand &>(*o0)); // Segment prefix.
-#ifdef ASMJIT_X64
- this->_emitRexRM(o0->getSize() == 8, 0, reinterpret_cast<const Operand &>(*o0), forceRexPrefix);
-#endif // ASMJIT_X64
- this->_emitByte(0xF6 + (o0->getSize() != 1));
- this->_emitModRM(0, reinterpret_cast<const Operand &>(*o0), immSize);
- _FINISHED_IMMEDIATE(o1, immSize);
- }
-
- break;
-
- case kX86InstGroupXchg:
- if (o0->isRegMem() && o1->isReg())
- {
- const Operand &dst = reinterpret_cast<const Operand &>(*o0);
- const GpReg &src = reinterpret_cast<const GpReg &>(*o1);
-
- if (src.isRegType(kX86RegTypeGpw))
- this->_emitByte(0x66); // 16-bit.
- this->_emitSegmentPrefix(dst); // segment prefix
-#ifdef ASMJIT_X64
- this->_emitRexRM(src.isRegType(kX86RegTypeGpq), src.getRegCode(), dst, forceRexPrefix);
-#endif // ASMJIT_X64
-
- // Special opcode for index 0 registers (AX, EAX, RAX vs register).
- if ((dst.getType() == kOperandReg && dst.getSize() > 1) && (!reinterpret_cast<const GpReg &>(dst).getRegCode() || !reinterpret_cast<const GpReg &>(src).getRegCode()))
- {
- uint8_t index = reinterpret_cast<const GpReg &>(dst).getRegCode() | src.getRegCode();
- this->_emitByte(0x90 + index);
- _FINISHED();
- }
-
- this->_emitByte(0x86 + (src.getSize() != 1));
- this->_emitModRM(src.getRegCode(), dst, 0);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupMovBE:
- if (o0->isReg() && o1->isMem())
- {
- this->_emitX86RM(0x000F38F0, o0->isRegType(kX86RegTypeGpw), o0->isRegType(kX86RegTypeGpq), reinterpret_cast<const GpReg &>(*o0).getRegCode(), reinterpret_cast<const Mem &>(*o1), 0, forceRexPrefix);
- _FINISHED();
- }
-
- if (o0->isMem() && o1->isReg())
- {
- this->_emitX86RM(0x000F38F1, o1->isRegType(kX86RegTypeGpw), o1->isRegType(kX86RegTypeGpq), reinterpret_cast<const GpReg &>(*o1).getRegCode(), reinterpret_cast<const Mem &>(*o0), 0, forceRexPrefix);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupX87StM:
- if (o0->isRegType(kX86RegTypeX87))
- {
- uint8_t i1 = reinterpret_cast<const X87Reg &>(*o0).getRegIndex();
- uint8_t i2 = 0;
-
- if (code != kX86InstFCom && code != kX86InstFComP)
- {
- if (!o1->isRegType(kX86RegTypeX87))
- goto _IllegalInstruction;
- i2 = reinterpret_cast<const X87Reg &>(*o1).getRegIndex();
- }
- else if (i1 && i2)
- goto _IllegalInstruction;
-
- this->_emitByte(!i1 ? ((id->_opCode[0] & 0xFF000000) >> 24) : ((id->_opCode[0] & 0x00FF0000) >> 16));
- this->_emitByte(!i1 ? ((id->_opCode[0] & 0x0000FF00) >> 8) + i2 : (id->_opCode[0] & 0x000000FF) + i1);
- _FINISHED();
- }
-
- if (o0->isMem() && (o0->getSize() == 4 || o0->getSize() == 8) && o1->isNone())
- {
- const Mem &m = reinterpret_cast<const Mem &>(*o0);
-
- // Segment prefix.
- this->_emitSegmentPrefix(m);
-
- this->_emitByte(o0->getSize() == 4 ? ((id->_opCode[0] & 0xFF000000) >> 24) : ((id->_opCode[0] & 0x00FF0000) >> 16));
- this->_emitModM(static_cast<uint8_t>(id->_opCodeR), m, 0);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupX87StI:
- if (o0->isRegType(kX86RegTypeX87))
- {
- uint8_t i = reinterpret_cast<const X87Reg &>(*o0).getRegIndex();
- this->_emitByte(static_cast<uint8_t>((id->_opCode[0] & 0x0000FF00) >> 8));
- this->_emitByte(static_cast<uint8_t>((id->_opCode[0] & 0x000000FF) + i));
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupX87Status:
- if (o0->isReg() && reinterpret_cast<const Reg &>(*o0).getRegType() <= kX86RegTypeGpq && !reinterpret_cast<const Reg &>(*o0).getRegIndex())
- {
- this->_emitOpCode(id->_opCode[1]);
- _FINISHED();
- }
-
- if (o0->isMem())
- {
- this->_emitX86RM(id->_opCode[0], 0, 0, static_cast<uint8_t>(id->_opCodeR), reinterpret_cast<const Mem &>(*o0), 0, forceRexPrefix);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupX87FldFst:
- if (o0->isRegType(kX86RegTypeX87))
- {
- this->_emitByte(static_cast<uint8_t>((id->_opCode[1] & 0xFF000000) >> 24));
- this->_emitByte(static_cast<uint8_t>((id->_opCode[1] & 0x00FF0000) >> 16) + reinterpret_cast<const X87Reg &>(*o0).getRegIndex());
- _FINISHED();
- }
-
- // ... fall through to kX86InstGroupX87Mem ...
-
- case kX86InstGroupX87Mem:
- {
- if (!o0->isMem())
- goto _IllegalInstruction;
- const Mem &m = reinterpret_cast<const Mem &>(*o0);
-
- uint8_t opCode = 0x00, mod = 0;
-
- if (o0->getSize() == 2 && (id->_opFlags[0] & kX86InstOpStM2))
- {
- opCode = static_cast<uint8_t>((id->_opCode[0] & 0xFF000000) >> 24);
- mod = static_cast<uint8_t>(id->_opCodeR);
- }
- if (o0->getSize() == 4 && (id->_opFlags[0] & kX86InstOpStM4))
- {
- opCode = static_cast<uint8_t>((id->_opCode[0] & 0x00FF0000) >> 16);
- mod = static_cast<uint8_t>(id->_opCodeR);
- }
- if (o0->getSize() == 8 && (id->_opFlags[0] & kX86InstOpStM8))
- {
- opCode = static_cast<uint8_t>((id->_opCode[0] & 0x0000FF00) >> 8);
- mod = static_cast<uint8_t>(id->_opCode[0] & 0x000000FF);
- }
-
- if (opCode)
- {
- this->_emitSegmentPrefix(m);
- this->_emitByte(opCode);
- this->_emitModM(mod, m, 0);
- _FINISHED();
- }
-
- break;
- }
-
- case kX86InstGroupMmuMov:
- {
- ASMJIT_ASSERT(id->_opFlags[0]);
- ASMJIT_ASSERT(id->_opFlags[1]);
-
- // Check parameters (X)MM|GP32_64 <- (X)MM|GP32_64|Mem|Imm
- if ((o0->isMem() && !(id->_opFlags[0] & kX86InstOpMem)) || (o0->isRegType(kX86RegTypeMm) && !(id->_opFlags[0] & kX86InstOpMm)) || (o0->isRegType(kX86RegTypeXmm) && !(id->_opFlags[0] & kX86InstOpXmm)) ||
- (o0->isRegType(kX86RegTypeGpd) && !(id->_opFlags[0] & kX86InstOpGd)) || (o0->isRegType(kX86RegTypeGpq) && !(id->_opFlags[0] & kX86InstOpGq)) ||
- (o1->isRegType(kX86RegTypeMm) && !(id->_opFlags[1] & kX86InstOpMm)) || (o1->isRegType(kX86RegTypeXmm) && !(id->_opFlags[1] & kX86InstOpXmm)) ||
- (o1->isRegType(kX86RegTypeGpd) && !(id->_opFlags[1] & kX86InstOpGd)) || (o1->isRegType(kX86RegTypeGpq) && !(id->_opFlags[1] & kX86InstOpGq)) ||
- (o1->isMem() && !(id->_opFlags[1] & kX86InstOpMem)))
- goto _IllegalInstruction;
-
- // Illegal.
- if (o0->isMem() && o1->isMem())
- goto _IllegalInstruction;
-
- uint8_t rexw = ((id->_opFlags[0] | id->_opFlags[1]) & kX86InstOpNoRex) ? 0 : o0->isRegType(kX86RegTypeGpq) | o1->isRegType(kX86RegTypeGpq);
-
- // (X)MM|Reg <- (X)MM|Reg
- if (o0->isReg() && o1->isReg())
- {
- this->_emitMmu(id->_opCode[0], rexw, reinterpret_cast<const Reg &>(*o0).getRegCode(), reinterpret_cast<const Reg &>(*o1), 0);
- _FINISHED();
- }
-
- // (X)MM|Reg <- Mem
- if (o0->isReg() && o1->isMem())
- {
- this->_emitMmu(id->_opCode[0], rexw, reinterpret_cast<const Reg &>(*o0).getRegCode(), reinterpret_cast<const Mem &>(*o1), 0);
- _FINISHED();
- }
-
- // Mem <- (X)MM|Reg
- if (o0->isMem() && o1->isReg())
- {
- this->_emitMmu(id->_opCode[1], rexw, reinterpret_cast<const Reg &>(*o1).getRegCode(), reinterpret_cast<const Mem &>(*o0), 0);
- _FINISHED();
- }
-
- break;
- }
-
- case kX86InstGroupMmuMovD:
- if ((o0->isRegType(kX86RegTypeMm) || o0->isRegType(kX86RegTypeXmm)) && (o1->isRegType(kX86RegTypeGpd) || o1->isMem()))
- {
- this->_emitMmu(o0->isRegType(kX86RegTypeXmm) ? 0x66000F6E : 0x00000F6E, 0, reinterpret_cast<const Reg &>(*o0).getRegCode(), reinterpret_cast<const Operand &>(*o1), 0);
- _FINISHED();
- }
-
- if ((o0->isRegType(kX86RegTypeGpd) || o0->isMem()) && (o1->isRegType(kX86RegTypeMm) || o1->isRegType(kX86RegTypeXmm)))
- {
- this->_emitMmu(o1->isRegType(kX86RegTypeXmm) ? 0x66000F7E : 0x00000F7E, 0, reinterpret_cast<const Reg &>(*o1).getRegCode(), reinterpret_cast<const Operand &>(*o0), 0);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupMmuMovQ:
- if (o0->isRegType(kX86RegTypeMm) && o1->isRegType(kX86RegTypeMm))
- {
- this->_emitMmu(0x00000F6F, 0, reinterpret_cast<const MmReg &>(*o0).getRegCode(), reinterpret_cast<const MmReg &>(*o1), 0);
- _FINISHED();
- }
-
- if (o0->isRegType(kX86RegTypeXmm) && o1->isRegType(kX86RegTypeXmm))
- {
- this->_emitMmu(0xF3000F7E, 0, reinterpret_cast<const XmmReg &>(*o0).getRegCode(), reinterpret_cast<const XmmReg &>(*o1), 0);
- _FINISHED();
- }
-
- // Convenience - movdq2q
- if (o0->isRegType(kX86RegTypeMm) && o1->isRegType(kX86RegTypeXmm))
- {
- this->_emitMmu(0xF2000FD6, 0, reinterpret_cast<const MmReg &>(*o0).getRegCode(), reinterpret_cast<const XmmReg &>(*o1), 0);
- _FINISHED();
- }
-
- // Convenience - movq2dq
- if (o0->isRegType(kX86RegTypeXmm) && o1->isRegType(kX86RegTypeMm))
- {
- this->_emitMmu(0xF3000FD6, 0, reinterpret_cast<const XmmReg &>(*o0).getRegCode(), reinterpret_cast<const MmReg &>(*o1), 0);
- _FINISHED();
- }
-
- if (o0->isRegType(kX86RegTypeMm) && o1->isMem())
- {
- this->_emitMmu(0x00000F6F, 0, reinterpret_cast<const MmReg &>(*o0).getRegCode(), reinterpret_cast<const Mem &>(*o1), 0);
- _FINISHED();
- }
-
- if (o0->isRegType(kX86RegTypeXmm) && o1->isMem())
- {
- this->_emitMmu(0xF3000F7E, 0, reinterpret_cast<const XmmReg &>(*o0).getRegCode(), reinterpret_cast<const Mem &>(*o1), 0);
- _FINISHED();
- }
-
- if (o0->isMem() && o1->isRegType(kX86RegTypeMm))
- {
- this->_emitMmu(0x00000F7F, 0, reinterpret_cast<const MmReg &>(*o1).getRegCode(), reinterpret_cast<const Mem &>(*o0), 0);
- _FINISHED();
- }
-
- if (o0->isMem() && o1->isRegType(kX86RegTypeXmm))
- {
- this->_emitMmu(0x66000FD6, 0, reinterpret_cast<const XmmReg &>(*o1).getRegCode(), reinterpret_cast<const Mem &>(*o0), 0);
- _FINISHED();
- }
-
-#ifdef ASMJIT_X64
- if ((o0->isRegType(kX86RegTypeMm) || o0->isRegType(kX86RegTypeXmm)) && (o1->isRegType(kX86RegTypeGpq) || o1->isMem()))
- {
- this->_emitMmu(o0->isRegType(kX86RegTypeXmm) ? 0x66000F6E : 0x00000F6E, 1, reinterpret_cast<const Reg &>(*o0).getRegCode(), reinterpret_cast<const Operand &>(*o1), 0);
- _FINISHED();
- }
-
- if ((o0->isRegType(kX86RegTypeGpq) || o0->isMem()) && (o1->isRegType(kX86RegTypeMm) || o1->isRegType(kX86RegTypeXmm)))
- {
- this->_emitMmu(o1->isRegType(kX86RegTypeXmm) ? 0x66000F7E : 0x00000F7E, 1, reinterpret_cast<const Reg &>(*o1).getRegCode(), reinterpret_cast<const Operand &>(*o0), 0);
- _FINISHED();
- }
-#endif // ASMJIT_X64
-
- break;
-
- case kX86InstGroupMmuExtract:
- {
- if (!(o0->isRegMem() && (o1->isRegType(kX86RegTypeXmm) || (code == kX86InstPExtrW && o1->isRegType(kX86RegTypeMm))) && o2->isImm()))
- goto _IllegalInstruction;
-
- uint32_t opCode = id->_opCode[0];
- uint8_t isGpdGpq = o0->isRegType(kX86RegTypeGpd) | o0->isRegType(kX86RegTypeGpq);
-
- if (code == kX86InstPExtrB && (o0->getSize() && o0->getSize() != 1) && !isGpdGpq)
- goto _IllegalInstruction;
- if (code == kX86InstPExtrW && (o0->getSize() && o0->getSize() != 2) && !isGpdGpq)
- goto _IllegalInstruction;
- if (code == kX86InstPExtrD && (o0->getSize() && o0->getSize() != 4) && !isGpdGpq)
- goto _IllegalInstruction;
- if (code == kX86InstPExtrQ && (o0->getSize() && o0->getSize() != 8) && !isGpdGpq)
- goto _IllegalInstruction;
-
- if (o1->isRegType(kX86RegTypeXmm))
- opCode |= 0x66000000;
-
- if (o0->isReg())
- {
- this->_emitMmu(opCode, id->_opCodeR | static_cast<uint8_t>(o0->isRegType(kX86RegTypeGpq)), reinterpret_cast<const Reg &>(*o1).getRegCode(), reinterpret_cast<const Reg &>(*o0), 1);
- _FINISHED_IMMEDIATE(o2, 1);
- }
-
- if (o0->isMem())
- {
- this->_emitMmu(opCode, static_cast<uint8_t>(id->_opCodeR), reinterpret_cast<const Reg &>(*o1).getRegCode(), reinterpret_cast<const Mem &>(*o0), 1);
- _FINISHED_IMMEDIATE(o2, 1);
- }
-
- break;
- }
-
- case kX86InstGroupMmuPrefetch:
- if (o0->isMem() && o1->isImm())
- {
- const Mem &mem = reinterpret_cast<const Mem &>(*o0);
- const Imm &hint = reinterpret_cast<const Imm &>(*o1);
-
- this->_emitMmu(0x00000F18, 0, static_cast<uint8_t>(hint.getValue()), mem, 0);
- _FINISHED();
- }
-
- break;
-
- case kX86InstGroupMmuRmI:
- {
- ASMJIT_ASSERT(id->_opFlags[0]);
- ASMJIT_ASSERT(id->_opFlags[1]);
-
- // Check parameters (X)MM|GP32_64 <- (X)MM|GP32_64|Mem|Imm
- if (!o0->isReg() || (o0->isRegType(kX86RegTypeMm) && !(id->_opFlags[0] & kX86InstOpMm)) || (o0->isRegType(kX86RegTypeXmm) && !(id->_opFlags[0] & kX86InstOpXmm)) ||
- (o0->isRegType(kX86RegTypeGpd) && !(id->_opFlags[0] & kX86InstOpGd)) || (o0->isRegType(kX86RegTypeGpq) && !(id->_opFlags[0] & kX86InstOpGq)) ||
- (o1->isRegType(kX86RegTypeMm) && !(id->_opFlags[1] & kX86InstOpMm)) || (o1->isRegType(kX86RegTypeXmm) && !(id->_opFlags[1] & kX86InstOpXmm)) ||
- (o1->isRegType(kX86RegTypeGpd) && !(id->_opFlags[1] & kX86InstOpGd)) || (o1->isRegType(kX86RegTypeGpq) && !(id->_opFlags[1] & kX86InstOpGq)) ||
- (o1->isMem() && !(id->_opFlags[1] & kX86InstOpMem)) || (o1->isImm() && !(id->_opFlags[1] & kX86InstOpImm)))
- goto _IllegalInstruction;
-
- uint32_t prefix = ((id->_opFlags[0] & kX86InstOpMmXmm) == kX86InstOpMmXmm && o0->isRegType(kX86RegTypeXmm)) ||
- ((id->_opFlags[1] & kX86InstOpMmXmm) == kX86InstOpMmXmm && o1->isRegType(kX86RegTypeXmm)) ? 0x66000000 : 0x00000000;
-
- uint8_t rexw = ((id->_opFlags[0] | id->_opFlags[1]) & kX86InstOpNoRex) ? 0 : o0->isRegType(kX86RegTypeGpq) | o1->isRegType(kX86RegTypeGpq);
-
- // (X)MM <- (X)MM (opcode0)
- if (o1->isReg())
- {
- if (!(id->_opFlags[1] & (kX86InstOpMmXmm | kX86InstOpGqd)))
- goto _IllegalInstruction;
- this->_emitMmu(id->_opCode[0] | prefix, rexw, reinterpret_cast<const Reg &>(*o0).getRegCode(), reinterpret_cast<const Reg &>(*o1), 0);
- _FINISHED();
- }
- // (X)MM <- Mem (opcode0)
- if (o1->isMem())
- {
- if (!(id->_opFlags[1] & kX86InstOpMem))
- goto _IllegalInstruction;
- this->_emitMmu(id->_opCode[0] | prefix, rexw, reinterpret_cast<const Reg &>(*o0).getRegCode(), reinterpret_cast<const Mem &>(*o1), 0);
- _FINISHED();
- }
- // (X)MM <- Imm (opcode1+opcodeR)
- if (o1->isImm())
- {
- if (!(id->_opFlags[1] & kX86InstOpImm))
- goto _IllegalInstruction;
- this->_emitMmu(id->_opCode[1] | prefix, rexw, static_cast<uint8_t>(id->_opCodeR), reinterpret_cast<const Reg &>(*o0), 1);
- _FINISHED_IMMEDIATE(o1, 1);
- }
-
- break;
- }
-
- case kX86InstGroupMmuRmImm8:
- {
- ASMJIT_ASSERT(id->_opFlags[0]);
- ASMJIT_ASSERT(id->_opFlags[1]);
-
- // Check parameters (X)MM|GP32_64 <- (X)MM|GP32_64|Mem|Imm
- if (!o0->isReg() || (o0->isRegType(kX86RegTypeMm ) && !(id->_opFlags[0] & kX86InstOpMm)) || (o0->isRegType(kX86RegTypeXmm) && !(id->_opFlags[0] & kX86InstOpXmm)) ||
- (o0->isRegType(kX86RegTypeGpd) && !(id->_opFlags[0] & kX86InstOpGd)) || (o0->isRegType(kX86RegTypeGpq) && !(id->_opFlags[0] & kX86InstOpGq)) ||
- (o1->isRegType(kX86RegTypeMm) && !(id->_opFlags[1] & kX86InstOpMm)) || (o1->isRegType(kX86RegTypeXmm) && !(id->_opFlags[1] & kX86InstOpXmm)) ||
- (o1->isRegType(kX86RegTypeGpd) && !(id->_opFlags[1] & kX86InstOpGd)) || (o1->isRegType(kX86RegTypeGpq) && !(id->_opFlags[1] & kX86InstOpGq)) ||
- (o1->isMem() && !(id->_opFlags[1] & kX86InstOpMem)) || !o2->isImm())
- goto _IllegalInstruction;
-
- uint32_t prefix = ((id->_opFlags[0] & kX86InstOpMmXmm) == kX86InstOpMmXmm && o0->isRegType(kX86RegTypeXmm)) ||
- ((id->_opFlags[1] & kX86InstOpMmXmm) == kX86InstOpMmXmm && o1->isRegType(kX86RegTypeXmm)) ? 0x66000000 : 0x00000000;
-
- uint8_t rexw = ((id->_opFlags[0]|id->_opFlags[1]) & kX86InstOpNoRex) ? 0 : o0->isRegType(kX86RegTypeGpq) | o1->isRegType(kX86RegTypeGpq);
-
- // (X)MM <- (X)MM (opcode0)
- if (o1->isReg())
- {
- if (!(id->_opFlags[1] & (kX86InstOpMmXmm | kX86InstOpGqd)))
- goto _IllegalInstruction;
- this->_emitMmu(id->_opCode[0] | prefix, rexw, reinterpret_cast<const Reg &>(*o0).getRegCode(), reinterpret_cast<const Reg &>(*o1), 1);
- _FINISHED_IMMEDIATE(o2, 1);
- }
- // (X)MM <- Mem (opcode0)
- if (o1->isMem())
- {
- if (!(id->_opFlags[1] & kX86InstOpMem))
- goto _IllegalInstruction;
- this->_emitMmu(id->_opCode[0] | prefix, rexw, reinterpret_cast<const Reg &>(*o0).getRegCode(), reinterpret_cast<const Mem &>(*o1), 1);
- _FINISHED_IMMEDIATE(o2, 1);
- }
-
- break;
- }
-
- case kX86InstGroupMmuRm3dNow:
- if (o0->isRegType(kX86RegTypeMm) && (o1->isRegType(kX86RegTypeMm) || o1->isMem()))
- {
- this->_emitMmu(id->_opCode[0], 0, reinterpret_cast<const Reg &>(*o0).getRegCode(), reinterpret_cast<const Mem &>(*o1), 1);
- this->_emitByte(static_cast<uint8_t>(id->_opCode[1]));
- _FINISHED();
- }
-
- break;
- }
-
-_IllegalInstruction:
- // Set an error. If we run in release mode assertion will be not used, so we
- // must inform about invalid state.
- this->setError(kErrorIllegalInstruction);
-
-#ifdef ASMJIT_DEBUG
- assertIllegal = true;
-#endif // ASMJIT_DEBUG
- goto _End;
-
-_EmitImmediate:
- sysint_t value = immOperand->getValue();
- switch (immSize)
- {
- case 1:
- this->_emitByte(static_cast<uint8_t>(static_cast<sysuint_t>(value)));
- break;
- case 2:
- this->_emitWord(static_cast<uint16_t>(static_cast<sysuint_t>(value)));
- break;
- case 4:
- this->_emitDWord(static_cast<uint32_t>(static_cast<sysuint_t>(value)));
- break;
-#ifdef ASMJIT_X64
- case 8:
- this->_emitQWord(static_cast<uint64_t>(static_cast<sysuint_t>(value)));
- break;
-#endif // ASMJIT_X64
- default:
- ASMJIT_ASSERT(0);
- }
-
-_End:
- if (this->_logger
-#ifdef ASMJIT_DEBUG
- || assertIllegal
-#endif // ASMJIT_DEBUG
- )
- {
- char bufStorage[512];
- char *buf = bufStorage;
-
- // Detect truncated operand.
- Imm immTemporary(0);
- uint32_t loggerFlags = 0;
-
- // Use the original operands, because BYTE some of them were replaced.
- if (bLoHiUsed)
- {
- o0 = _loggerOperands[0];
- o1 = _loggerOperands[1];
- o2 = _loggerOperands[2];
- }
-
- if (immOperand)
- {
- sysint_t value = immOperand->getValue();
- bool isUnsigned = immOperand->isUnsigned();
-
- switch (immSize)
- {
- case 1:
- if (isUnsigned && !IntUtil::isUInt8(value))
- {
- immTemporary.setValue(static_cast<uint8_t>(static_cast<sysuint_t>(value)), true);
- break;
- }
- if (!isUnsigned && !IntUtil::isInt8(value))
- {
- immTemporary.setValue(static_cast<uint8_t>(static_cast<sysuint_t>(value)), false);
- break;
- }
- break;
- case 2:
- if (isUnsigned && !IntUtil::isUInt16(value))
- {
- immTemporary.setValue(static_cast<uint16_t>(static_cast<sysuint_t>(value)), true);
- break;
- }
- if (!isUnsigned && !IntUtil::isInt16(value))
- {
- immTemporary.setValue(static_cast<uint16_t>(static_cast<sysuint_t>(value)), false);
- break;
- }
- break;
- case 4:
- if (isUnsigned && !IntUtil::isUInt32(value))
- {
- immTemporary.setValue(static_cast<uint32_t>(static_cast<sysuint_t>(value)), true);
- break;
- }
- if (!isUnsigned && !IntUtil::isInt32(value))
- {
- immTemporary.setValue(static_cast<uint32_t>(static_cast<sysuint_t>(value)), false);
- break;
- }
- break;
- }
-
- if (immTemporary.getValue())
- {
- if (o0 == immOperand)
- o0 = &immTemporary;
- if (o1 == immOperand)
- o1 = &immTemporary;
- if (o2 == immOperand)
- o2 = &immTemporary;
- }
- }
-
- if (this->_logger)
- {
- buf = StringUtil::copy(buf, this->_logger->getInstructionPrefix());
- loggerFlags = this->_logger->getFlags();
- }
-
- buf = X86Assembler_dumpInstruction(buf, code, this->_emitOptions, o0, o1, o2, memRegType, loggerFlags);
-
- if (loggerFlags & kLoggerOutputBinary)
- buf = X86Assembler_dumpComment(buf, static_cast<size_t>(buf - bufStorage), this->getCode() + beginOffset, this->getOffset() - beginOffset, this->_inlineComment);
- else
- buf = X86Assembler_dumpComment(buf, static_cast<size_t>(buf - bufStorage), nullptr, 0, this->_inlineComment);
-
- // We don't need to NULL terminate the resulting string.
-#ifdef ASMJIT_DEBUG
- if (this->_logger)
-#endif // ASMJIT_DEBUG
- this->_logger->logString(bufStorage, static_cast<size_t>(buf - bufStorage));
-
-#ifdef ASMJIT_DEBUG
- if (assertIllegal)
- {
- // Here we need to NULL terminate.
- buf[0] = '\0';
-
- // Raise an assertion failure, because this situation shouldn't happen.
- assertionFailure(__FILE__, __LINE__, bufStorage);
- }
-#endif // ASMJIT_DEBUG
- }
-
-_Cleanup:
- this->_inlineComment = nullptr;
- this->_emitOptions = 0;
-}
-
-void X86Assembler::_emitJcc(uint32_t code, const Label *label, uint32_t hint)
-{
- if (hint == kCondHintNone)
- this->_emitInstruction(code, label);
- else
- {
- Imm imm(hint);
- this->_emitInstruction(code, label, &imm);
- }
-}
-
-// ============================================================================
-// [AsmJit::Assembler - Relocation helpers]
-// ============================================================================
-
-size_t X86Assembler::relocCode(void *_dst, sysuint_t addressBase) const
-{
- // Copy code to virtual memory (this is a given _dst pointer).
- uint8_t *dst = reinterpret_cast<uint8_t *>(_dst);
-
- size_t coff = this->_buffer.getOffset();
-
- // We are copying the exact size of the generated code. Extra code for trampolines
- // is generated on-the-fly by relocator (this code doesn't exist at the moment).
- memcpy(dst, this->_buffer.getData(), coff);
-
-#ifdef ASMJIT_X64
- // Trampoline pointer.
- uint8_t *tramp = dst + coff;
-#endif // ASMJIT_X64
-
- // Relocate all recorded locations.
- size_t i;
- size_t len = this->_relocData.size();
-
- for (i = 0; i < len; ++i)
- {
- const RelocData &r = this->_relocData[i];
- sysint_t val = 0;
-
-#ifdef ASMJIT_X64
- // Whether to use trampoline, can be only used if relocation type is
- // kRelocAbsToRel.
- bool useTrampoline = false;
-#endif // ASMJIT_X64
-
- // Be sure that reloc data structure is correct.
- //ASMJIT_ASSERT((size_t)(r.offset + r.size) <= csize);
-
- switch (r.type)
- {
- case kRelocAbsToAbs:
- val = reinterpret_cast<sysint_t>(r.address);
- break;
-
- case kRelocRelToAbs:
- val = static_cast<sysint_t>(addressBase + r.destination);
- break;
-
- case kRelocAbsToRel:
- case kRelocTrampoline:
- val = static_cast<sysint_t>(reinterpret_cast<sysuint_t>(r.address) - (addressBase + static_cast<sysuint_t>(r.offset) + 4));
-
-#ifdef ASMJIT_X64
- if (r.type == kRelocTrampoline && !IntUtil::isInt32(val))
- {
- val = static_cast<sysint_t>(reinterpret_cast<sysuint_t>(tramp) - (reinterpret_cast<sysuint_t>(_dst) + static_cast<sysuint_t>(r.offset) + 4));
- useTrampoline = true;
- }
-#endif // ASMJIT_X64
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
-
- switch (r.size)
- {
- case 4:
- *reinterpret_cast<int32_t *>(dst + r.offset) = static_cast<int32_t>(val);
- break;
-
- case 8:
- *reinterpret_cast<int64_t *>(dst + r.offset) = static_cast<int64_t>(val);
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
-
-#ifdef ASMJIT_X64
- if (useTrampoline)
- {
- if (this->getLogger())
- this->getLogger()->logFormat("; Trampoline from %p -> %p\n", reinterpret_cast<int8_t *>(addressBase) + r.offset, r.address);
-
- X64TrampolineWriter::writeTrampoline(tramp, reinterpret_cast<uint64_t>(r.address));
- tramp += X64TrampolineWriter::kSizeTotal;
- }
-#endif // ASMJIT_X64
- }
-
-#ifdef ASMJIT_X64
- return static_cast<size_t>(tramp - dst);
-#else
- return coff;
-#endif // ASMJIT_X64
-}
-
-// ============================================================================
-// [AsmJit::Assembler - EmbedLabel]
-// ============================================================================
-
-void X86Assembler::embedLabel(const Label &label)
-{
- ASMJIT_ASSERT(label.getId() != kInvalidValue);
- if (!this->canEmit())
- return;
-
- LabelData &l_data = this->_labels[label.getId() & kOperandIdValueMask];
- RelocData r_data;
-
- if (this->_logger)
- this->_logger->logFormat(sizeof(sysint_t) == 4 ? ".dd L.%u\n" : ".dq L.%u\n", static_cast<uint32_t>(label.getId()) & kOperandIdValueMask);
-
- r_data.type = kRelocRelToAbs;
- r_data.size = sizeof(sysint_t);
- r_data.offset = this->getOffset();
- r_data.destination = 0;
-
- if (l_data.offset != -1)
- // Bound label.
- r_data.destination = l_data.offset;
- else
- {
- // Non-bound label. Need to chain.
- LabelLink *link = this->_newLabelLink();
-
- link->prev = l_data.links;
- link->offset = this->getOffset();
- link->displacement = 0;
- link->relocId = this->_relocData.size();
-
- l_data.links = link;
- }
-
- this->_relocData.push_back(r_data);
-
- // Emit dummy intptr_t (4 or 8 bytes that depends on address size).
- this->_emitIntPtrT(0);
-}
-
-// ============================================================================
-// [AsmJit::Assembler - Align]
-// ============================================================================
-
-void X86Assembler::align(uint32_t m)
-{
- if (!this->canEmit())
- return;
-
- if (this->_logger)
- this->_logger->logFormat("%s.align %u\n", this->_logger->getInstructionPrefix(), static_cast<unsigned>(m));
-
- if (!m)
- return;
-
- if (m > 64)
- {
- ASMJIT_ASSERT(0);
- return;
- }
-
- sysint_t i = m - (this->getOffset() % m);
- if (static_cast<uint32_t>(i) == m)
- return;
-
- if (this->_properties & (1 << kX86PropertyOptimizedAlign))
- {
- const X86CpuInfo *ci = X86CpuInfo::getGlobal();
-
- // NOPs optimized for Intel:
- // Intel 64 and IA-32 Architectures Software Developer's Manual
- // - Volume 2B
- // - Instruction Set Reference N-Z
- // - NOP
-
- // NOPs optimized for AMD:
- // Software Optimization Guide for AMD Family 10h Processors (Quad-Core)
- // - 4.13 - Code Padding with Operand-Size Override and Multibyte NOP
-
- // Intel and AMD.
- static const uint8_t nop1[] = { 0x90 };
- static const uint8_t nop2[] = { 0x66, 0x90 };
- static const uint8_t nop3[] = { 0x0F, 0x1F, 0x00 };
- static const uint8_t nop4[] = { 0x0F, 0x1F, 0x40, 0x00 };
- static const uint8_t nop5[] = { 0x0F, 0x1F, 0x44, 0x00, 0x00 };
- static const uint8_t nop6[] = { 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00 };
- static const uint8_t nop7[] = { 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00 };
- static const uint8_t nop8[] = { 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const uint8_t nop9[] = { 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
- // AMD.
- static const uint8_t nop10[] = { 0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const uint8_t nop11[] = { 0x66, 0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
- const uint8_t *p;
- sysint_t n;
-
- if (ci->getVendorId() == kCpuIntel && ((ci->getFamily() & 0x0F) == 6 || (ci->getFamily() & 0x0F) == 15))
- {
- do
- {
- switch (i)
- {
- case 1:
- p = nop1;
- n = 1;
- break;
- case 2:
- p = nop2;
- n = 2;
- break;
- case 3:
- p = nop3;
- n = 3;
- break;
- case 4:
- p = nop4;
- n = 4;
- break;
- case 5:
- p = nop5;
- n = 5;
- break;
- case 6:
- p = nop6;
- n = 6;
- break;
- case 7:
- p = nop7;
- n = 7;
- break;
- case 8:
- p = nop8;
- n = 8;
- break;
- default:
- p = nop9;
- n = 9;
- }
-
- i -= n;
- do
- {
- this->_emitByte(*p++);
- } while (--n);
- } while (i);
-
- return;
- }
-
- if (ci->getVendorId() == kCpuAmd && ci->getFamily() >= 0x0F)
- {
- do
- {
- switch (i)
- {
- case 1:
- p = nop1;
- n = 1;
- break;
- case 2:
- p = nop2;
- n = 2;
- break;
- case 3:
- p = nop3;
- n = 3;
- break;
- case 4:
- p = nop4;
- n = 4;
- break;
- case 5:
- p = nop5;
- n = 5;
- break;
- case 6:
- p = nop6; n = 6;
- break;
- case 7:
- p = nop7;
- n = 7;
- break;
- case 8:
- p = nop8;
- n = 8;
- break;
- case 9:
- p = nop9;
- n = 9;
- break;
- case 10:
- p = nop10;
- n = 10;
- break;
- default:
- p = nop11;
- n = 11;
- }
-
- i -= n;
- do
- {
- this->_emitByte(*p++);
- } while (--n);
- } while (i);
-
- return;
- }
-#ifdef ASMJIT_X86
- // Legacy NOPs, 0x90 with 0x66 prefix.
- do
- {
- switch (i)
- {
- default:
- this->_emitByte(0x66);
- --i;
- case 3:
- this->_emitByte(0x66);
- --i;
- case 2:
- this->_emitByte(0x66);
- --i;
- case 1:
- this->_emitByte(0x90);
- --i;
- }
- } while(i);
-#endif
- }
-
- // Legacy NOPs, only 0x90. In 64-bit mode, we can't use 0x66 prefix.
- do
- {
- this->_emitByte(0x90);
- } while (--i);
-}
-
-// ============================================================================
-// [AsmJit::Assembler - Label]
-// ============================================================================
-
-Label X86Assembler::newLabel()
-{
- Label label;
- label._base.id = static_cast<uint32_t>(this->_labels.size()) | kOperandIdTypeLabel;
-
- LabelData l_data;
- l_data.offset = -1;
- l_data.links = nullptr;
- this->_labels.push_back(l_data);
-
- return label;
-}
-
-void X86Assembler::registerLabels(size_t count)
-{
- // Duplicated newLabel() code, but we are not creating Label instances.
- LabelData l_data;
- l_data.offset = -1;
- l_data.links = nullptr;
-
- for (size_t i = 0; i < count; ++i)
- this->_labels.push_back(l_data);
-}
-
-void X86Assembler::bind(const Label &label)
-{
- // Only labels created by newLabel() can be used by Assembler.
- ASMJIT_ASSERT(label.getId() != kInvalidValue);
- // Never go out of bounds.
- ASMJIT_ASSERT((label.getId() & kOperandIdValueMask) < this->_labels.size());
-
- // Get label data based on label id.
- LabelData &l_data = this->_labels[label.getId() & kOperandIdValueMask];
-
- // Label can be bound only once.
- ASMJIT_ASSERT(l_data.offset == -1);
-
- // Log.
- if (this->_logger)
- this->_logger->logFormat("L.%u:\n", static_cast<uint32_t>(label.getId()) & kOperandIdValueMask);
-
- sysint_t pos = this->getOffset();
-
- LabelLink *link = l_data.links;
- LabelLink *prev = nullptr;
-
- while (link)
- {
- sysint_t offset = link->offset;
-
- if (link->relocId != -1)
- // If linked label points to RelocData then instead of writing relative
- // displacement to assembler stream, we will write it to RelocData.
- this->_relocData[link->relocId].destination += pos;
- else
- {
- // Not using relocId, this means that we overwriting real displacement
- // in assembler stream.
- int32_t patchedValue = static_cast<int32_t>(pos - offset + link->displacement);
- uint32_t size = this->getByteAt(offset);
-
- // Only these size specifiers are allowed.
- ASMJIT_ASSERT(size == 1 || size == 4);
-
- if (size == 4)
- this->setInt32At(offset, patchedValue);
- else // if (size == 1)
- {
- if (IntUtil::isInt8(patchedValue))
- this->setByteAt(offset, static_cast<uint8_t>(static_cast<int8_t>(patchedValue)));
- else
- // Fatal error.
- this->setError(kErrorIllegalShortJump);
- }
- }
-
- prev = link->prev;
- link = prev;
- }
-
- // Chain unused links.
- link = l_data.links;
- if (link)
- {
- if (!prev)
- prev = link;
-
- prev->prev = this->_unusedLinks;
- this->_unusedLinks = link;
- }
-
- // Unlink label if it was linked.
- l_data.offset = pos;
- l_data.links = nullptr;
-}
-
-// ============================================================================
-// [AsmJit::Assembler - Make]
-// ============================================================================
-
-void *X86Assembler::make()
-{
- // Do nothing on error state or when no instruction was emitted.
- if (this->_error || !this->getCodeSize())
- return nullptr;
-
- void *p;
- this->_error = this->_context->generate(&p, this);
- return p;
-}
-
-} // AsmJit namespace
+} // asmjit namespace
// [Api-End]
-#include "../core/apiend.h"
-
+#include "../apiend.h"
+
+// [Guard]
+#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64
+
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86assembler.h
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86assembler.h
@@ -1,65 +1,98 @@
// [AsmJit]
-// Complete JIT Assembler for C++ Language.
+// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
-// Zlib - See COPYING file in this package.
+// Zlib - See LICENSE.md file in the package.
#pragma once
// [Dependencies - AsmJit]
-#include "../core/assembler.h"
-
-#include "../x86/x86defs.h"
+#include "../base/assembler.h"
+#include "../x86/x86inst.h"
#include "../x86/x86operand.h"
-#include "../x86/x86util.h"
// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_X86
-//! @{
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_x86_general
+//! \{
// ============================================================================
-// [AsmJit::X86Assembler]
+// [asmjit::X86Assembler]
// ============================================================================
-//! @brief X86Assembler - low level x86/x64 code generation.
+// \internal
+#define ASMJIT_X86_EMIT_OPTIONS(_Class_) \
+ /*! Force short form of jmp/jcc instruction. */ \
+ ASMJIT_INLINE _Class_& short_() { \
+ _instOptions |= kInstOptionShortForm; \
+ return *this; \
+ } \
+ \
+ /*! Force long form of jmp/jcc instruction. */ \
+ ASMJIT_INLINE _Class_& long_() { \
+ _instOptions |= kInstOptionLongForm; \
+ return *this; \
+ } \
+ \
+ /*! Condition is likely to be taken (has only benefit on P4). */ \
+ ASMJIT_INLINE _Class_& taken() { \
+ _instOptions |= kInstOptionTaken; \
+ return *this; \
+ } \
+ \
+ /*! Condition is unlikely to be taken (has only benefit on P4). */ \
+ ASMJIT_INLINE _Class_& notTaken() { \
+ _instOptions |= kInstOptionNotTaken; \
+ return *this; \
+ } \
+ \
+ /*! Use LOCK prefix. */ \
+ ASMJIT_INLINE _Class_& lock() { \
+ _instOptions |= kX86InstOptionLock; \
+ return *this; \
+ } \
+ \
+ /*! Force REX prefix. */ \
+ ASMJIT_INLINE _Class_& rex() { \
+ _instOptions |= kX86InstOptionRex; \
+ return *this; \
+ } \
+ \
+ /*! Force 3-byte VEX prefix. */ \
+ ASMJIT_INLINE _Class_& vex3() { \
+ _instOptions |= kX86InstOptionVex3; \
+ return *this; \
+ }
+
+//! X86/X64 assembler.
//!
-//! @ref X86Assembler is the main class in AsmJit for generating low level
-//! x86/x64 binary stream. It creates internal buffer where opcodes are stored
-//! and contains methods that mimics x86/x64 assembler instructions. Code
-//! generation should be safe, because basic type-checks are done by the C++
-//! compiler. It's nearly impossible to create invalid instruction (for example
-//! <code>mov [eax], [eax]</code> that will not be detected at compile time by
-//! C++ compiler.
+//! Assembler is the main class in AsmJit that can encode instructions and their
+//! operands to a binary stream runnable by CPU. It creates internal buffer
+//! where the encodes instructions are stored and it contains intrinsics that
+//! can be used to emit the code in a convenent way. Code generation is in
+//! general safe, because the intrinsics uses method overloading so even the
+//! code is emitted it can be checked by a C++ compiler. It's nearly impossible
+//! to create invalid instruction, for example `mov [eax], [eax]`, because such
+//! overload doesn't exist.
//!
-//! Each call to assembler intrinsics directly emits instruction to internal
-//! binary stream. Instruction emitting also contains runtime checks so it
-//! should be impossible to create an instruction that is not valid (except
-//! there is bug in AsmJit).
+//! Each call to an assembler intrinsic function emits instruction directly
+//! to the binary stream. There are also runtime checks that prevent invalid
+//! code to be emitted. It will assert in debug mode and put the `Assembler`
+//! instance to an error state in production mode.
//!
-//! @ref X86Assembler contains internal buffer where all emitted instructions
-//! are stored. Look at @ref Buffer for an implementation. To generate and
-//! allocate memory for function use @ref X86Assembler::make() method that will
-//! allocate memory using the provided memory manager (see @ref MemoryManager)
-//! and relocates the output code to the provided address. If you want to create
-//! your function manually, you should look at @ref VirtualMemory interface and
-//! use @ref X86Assembler::relocCode() method to relocate emitted code into
-//! provided memory location. You can also take the emitted buffer by @ref
-//! X86Assembler::take() to do something else with it. If you take buffer, you
-//! must free it manually by using @ref ASMJIT_FREE() macro.
+//! Code Generation
+//! ---------------
//!
-//! @section AsmJit_Assembler_CodeGeneration Code Generation
-//!
-//! To generate code is only needed to create instance of @c AsmJit::Assembler
+//! To generate code is only needed to create instance of `Assembler`
//! and to use intrinsics. See example how to do that:
//!
-//! @code
-//! // Use AsmJit namespace.
-//! using namespace AsmJit;
+//! ~~~
+//! // Use asmjit namespace.
+//! using namespace asmjit;
+//! using namespace asmjit::host;
//!
//! // Create Assembler instance.
//! Assembler a;
@@ -69,7 +102,7 @@
//! a.mov(ebp, esp);
//!
//! // Mov 1024 to EAX, EAX is also return value.
-//! a.mov(eax, imm(1024));
+//! a.mov(eax, 1024);
//!
//! // Epilog.
//! a.mov(esp, ebp);
@@ -77,161 +110,139 @@
//!
//! // Return.
//! 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 an
-//! immediate value. Use @c AsmJit::uimm() to create unsigned immediate value.
+//! are in `asmjit` namespace, so it's very comfortable to use it (look at
+//! first line). There is also used method `imm()` to create an immediate value.
+//! Use `imm_u()` to create unsigned immediate value.
//!
-//! There is also possibility to use memory addresses and immediates. To build
-//! memory address use @c ptr(), @c byte_ptr(), @c word_ptr(), @c dword_ptr()
-//! or other friend methods. In most cases you needs only @c ptr() method, but
-//! there are instructions where you must specify address size,
+//! There is also possibility to use memory addresses and immediates. Use
+//! `ptr()`, `byte_ptr()`, `word_ptr()`, `dword_ptr()` and similar functions to
+//! build a memory address operand. In most cases `ptr()` is enough, because an
+//! information related to the operand size is needed only in rare cases, that
+//! is an instruction without having any register operands, such as `inc [mem]`.
//!
-//! for example (a is @c AsmJit::Assembler instance):
+//! for example, `a` is `x86::Assembler` instance:
//!
-//! @code
-//! a.mov(ptr(eax), imm(0)); // mov ptr [eax], 0
-//! a.mov(ptr(eax), edx); // mov ptr [eax], edx
-//! @endcode
+//! ~~~
+//! a.mov(ptr(eax), 0); // mov ptr [eax], 0
+//! a.mov(ptr(eax), edx); // mov ptr [eax], edx
+//! ~~~
//!
//! But it's also possible to create complex addresses:
//!
-//! @code
+//! ~~~
//! // eax + ecx*x addresses
-//! a.mov(ptr(eax, ecx, kScaleNone), imm(0)); // mov ptr [eax + ecx], 0
-//! a.mov(ptr(eax, ecx, kScale2Times), imm(0)); // mov ptr [eax + ecx * 2], 0
-//! a.mov(ptr(eax, ecx, kScale4Times), imm(0)); // mov ptr [eax + ecx * 4], 0
-//! a.mov(ptr(eax, ecx, kScale8Times), imm(0)); // mov ptr [eax + ecx * 8], 0
+//! a.mov(ptr(eax, ecx, 0), 0); // mov ptr [eax + ecx], 0
+//! a.mov(ptr(eax, ecx, 1), 0); // mov ptr [eax + ecx * 2], 0
+//! a.mov(ptr(eax, ecx, 2), 0); // mov ptr [eax + ecx * 4], 0
+//! a.mov(ptr(eax, ecx, 3), 0); // mov ptr [eax + ecx * 8], 0
//! // eax + ecx*x + disp addresses
-//! a.mov(ptr(eax, ecx, kScaleNone, 4), imm(0)); // mov ptr [eax + ecx + 4], 0
-//! a.mov(ptr(eax, ecx, kScale2Times, 8), imm(0)); // mov ptr [eax + ecx * 2 + 8], 0
-//! a.mov(ptr(eax, ecx, kScale4Times, 12), imm(0)); // mov ptr [eax + ecx * 4 + 12], 0
-//! a.mov(ptr(eax, ecx, kScale8Times, 16), imm(0)); // mov ptr [eax + ecx * 8 + 16], 0
-//! @endcode
+//! a.mov(ptr(eax, ecx, 0, 4), 0); // mov ptr [eax + ecx + 4], 0
+//! a.mov(ptr(eax, ecx, 1, 8), 0); // mov ptr [eax + ecx * 2 + 8], 0
+//! a.mov(ptr(eax, ecx, 2, 12), 0); // mov ptr [eax + ecx * 4 + 12], 0
+//! a.mov(ptr(eax, ecx, 3, 16), 0); // mov ptr [eax + ecx * 8 + 16], 0
+//! ~~~
//!
-//! 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 <code>a.inc(ptr(eax))</code> 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:
+//! All addresses shown are using `ptr()` to make memory operand. Some assembler
+//! instructions (single operand ones) needs to have specified memory operand
+//! size. For example `a.inc(ptr(eax))` can't be called, because the meaning is
+//! ambiguous, see the code below.
//!
-//! @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
+//! ~~~
+//! // [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].
+//! ~~~
//!
-//! @section AsmJit_Assembler_CallingJitCode Calling JIT Code
+//! Calling JIT Code
+//! ----------------
//!
//! While you are over from emitting instructions, you can make your function
-//! using @c AsmJit::Assembler::make() method. This method will use memory
+//! by using `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 overridden 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 getCodeSize() or @c getOffset()
-//! 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.
+//! You can get size of generated code by `getCodeSize()` or `getOffset()`
+//! methods. These methods returns you code size or more precisely the current
+//! code offset in bytes. The `takeCode()` function can be used to take the
+//! internal buffer and reset the code generator, but the buffer taken has to
+//! be freed manually in such case.
//!
-//! See next example how to allocate memory where you can execute code created
-//! by @c AsmJit::Assembler:
+//! Machine code can be executed only in memory that is marked executable. This
+//! mark is usually not set for memory returned by a C/C++ `malloc` function.
+//! The `VMem::alloc()` function can be used allocate a memory where the code can
+//! be executed or more preferably `VMemMgr` which has interface
+//! similar to `malloc/free` and can allocate chunks of various sizes.
//!
-//! @code
-//! using namespace AsmJit;
+//! The next example shows how to allocate memory where the code can be executed:
//!
-//! Assembler a;
+//! ~~~
+//! using namespace asmjit;
//!
-//! // ... your code generation
+//! JitRuntime runtime;
+//! Assembler a(&runtime);
//!
-//! // your function prototype
-//! typedef void (*MyFn)();
+//! // ... Your code generation ...
+//!
+//! // The function prototype
+//! typedef void (*MyFunc)();
//!
//! // make your function
-//! MyFn fn = asmjit_cast<MyFn>(a.make());
+//! MyFunc func = asmjit_cast<MyFunc>(a.make());
//!
//! // call your function
-//! fn();
+//! func();
//!
//! // If you don't need your function again, free it.
-//! MemoryManager::getGlobal()->free(fn);
-//! @endcode
+//! runtime.release(func);
+//! ~~~
//!
-//! There is also low level alternative how to allocate virtual memory and
-//! relocate code to it:
+//! This was a very primitive showing how the generated code can be executed.
+//! In production noone will probably generate a function that is only called
+//! once and nobody will probably free the function right after it was executed.
+//! The code just shows the proper way of code generation and cleanup.
//!
-//! @code
-//! using namespace AsmJit;
-//!
-//! Assembler a;
-//! // Your code generation ...
-//!
-//! // Your function prototype.
-//! typedef void (*MyFn)();
-//!
-//! // Alloc memory for your function.
-//! MyFn fn = asmjit_cast<MyFn>(
-//! MemoryManager::getGlobal()->alloc(a.getCodeSize());
-//!
-//! // Relocate the code (will make the function).
-//! a.relocCode(fn);
-//!
-//! // Call the generated function.
-//! fn();
-//!
-//! // If you don't need your function anymore, it should be freed.
-//! MemoryManager::getGlobal()->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.
-//!
-//! @section AsmJit_Assembler_Labels Labels
+//! 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.
+//! code with labels. Labels are fully supported and you can call `jmp` or
+//! `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.
+//! offset, use `CodeGen::bind()` method.
//!
//! See next example that contains complete code that creates simple memory
-//! copy function (in DWORD entities).
+//! copy function (in DWord entities).
//!
-//! @code
+//! ~~~
//! // Example: Usage of Label (32-bit code).
//! //
-//! // Create simple DWORD memory copy function:
+//! // Create simple DWord memory copy function:
//! // ASMJIT_STDCALL void copy32(uint32_t* dst, const uint32_t* src, size_t count);
-//! using namespace AsmJit;
+//! using namespace asmjit;
//!
//! // Assembler instance.
-//! Assembler a;
+//! JitRuntime runtime;
+//! Assembler a(&runtime);
//!
//! // Constants.
//! const int arg_offset = 8; // Arguments offset (STDCALL EBP).
//! const int arg_size = 12; // Arguments size.
//!
//! // Labels.
-//! Label L_Loop = a.newLabel();
+//! Label L_Loop(a);
//!
//! // Prolog.
//! a.push(ebp);
@@ -267,16 +278,17 @@
//!
//! // 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
+//! look at `Compiler` class that is designed for higher level code
//! generation.
//!
-//! @section AsmJit_Assembler_AdvancedCodeGeneration Advanced Code Generation
+//! Advanced Code Generation
+//! ------------------------
//!
-//! This section describes some advanced generation features of @c Assembler
+//! This section describes some advanced generation features of `Assembler`
//! class which can be simply overlooked. The first thing that is very likely
//! needed is generic register support. In previous example the named registers
//! were used. AsmJit contains functions which can convert register index into
@@ -284,5156 +296,6221 @@
//!
//! Let's define function which can be used to generate some abstract code:
//!
-//! @code
+//! ~~~
//! // Simple function that generates dword copy.
-//! void genCopyDWord(
-//! Assembler& a,
-//! const GpReg& dst, const GpReg& src, const GpReg& tmp)
-//! {
+//! void genCopyDWord(Assembler& a, const X86GpReg& dst, const X86GpReg& src, const X86GpReg& tmp) {
//! a.mov(tmp, dword_ptr(src));
//! a.mov(dword_ptr(dst), tmp);
//! }
-//! @endcode
+//! ~~~
//!
-//! This function can be called like <code>genCopyDWord(a, edi, esi, ebx)</code>
-//! or by using existing @ref GpReg instances. This abstraction allows to join
-//! more code sections together without rewriting each to use specific registers.
-//! You need to take care only about implicit registers which may be used by
+//! This function can be called like `genCopyDWord(a, edi, esi, ebx)` or by
+//! using existing `X86GpReg` instances. This abstraction allows to join more
+//! code sections together without rewriting each to use specific registers.
+//! You need to take care only about implicit registers which may be used by
//! several instructions (like mul, imul, div, idiv, shifting, etc...).
//!
//! Next, more advanced, but often needed technique is that you can build your
-//! own registers allocator. X86 architecture contains 8 general purpose registers,
-//! 8 MMX (MM) registers and 8 SSE (XMM) registers. The X64 (AMD64) architecture
-//! extends count of general purpose registers and SSE2 registers to 16. Use the
-//! @c kX86RegNumBase constant to get count of GP or XMM registers or @c kX86RegNumGp,
-//! @c kX86RegNumMm and @c kX86RegNumXmm constants individually.
+//! own registers allocator. X86 architecture contains 8 general purpose
+//! registers, 8 Mm registers and 8 Xmm/Ymm/Zmm registers. X64 architecture
+//! extends the count of Gp registers and Xmm/Ymm/Zmm registers to 16 or 32
+//! when AVX512 is available.
//!
-//! To build register from index (value from 0 inclusive to kRegNumXXX
-//! exclusive) use @ref gpd(), @ref gpq() or @ref gpz() functions. To create
-//! a 8 or 16-bit register use @ref gpw(), @ref gpb_lo() or @ref gpb_hi().
-//! To create other registers there are similar methods like @ref mm(), @ref xmm()
-//! and @ref st().
+//! To create a general purpose register operand from register index use
+//! `gpb_lo()`, `gpb_hi()`, `gpw()`, `gpd()`, `gpq()`. To create registers of
+//! other types there are functions `fp()`, `mm()`, `xmm()`, `ymm()` and `zmm()`
+//! available.
//!
-//! So our function call to genCopyDWord can be also used like this:
-//!
-//! @code
-//! genCopyDWord(a, gpd(kX86RegIndexEdi), gpd(kX86RegIndexEsi), gpd(kX86RegIndexEbx));
-//! @endcode
-//!
-//! kX86RegIndexXXX are constants defined by @ref kX86RegIndex enum. You can use your
-//! own register allocator (or register slot manager) to alloc / free registers
-//! so kX86RegIndexXXX values can be replaced by your variables (0 to kRegNumXXX-1).
-//!
-//! @sa @ref X86Compiler.
-struct X86Assembler : public Assembler
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- ASMJIT_API X86Assembler(Context *context = JitContext::getGlobal());
- ASMJIT_API virtual ~X86Assembler();
-
- // --------------------------------------------------------------------------
- // [Buffer - Setters (X86-Extensions)]
- // --------------------------------------------------------------------------
-
- //! @brief Set custom variable @a i at position @a pos.
- //!
- //! @note This function is used to patch existing code.
- ASMJIT_API void setVarAt(size_t pos, sysint_t i, uint8_t isUnsigned, uint32_t size);
-
- // --------------------------------------------------------------------------
- // [Emit]
- //
- // These functions are not protected against buffer overrun. Each place of
- // code which calls these functions ensures that there is some space using
- // canEmit() method. Emitters are internally protected in AsmJit::Buffer,
- // but only in debug builds.
- // --------------------------------------------------------------------------
-
- //! @brief Emit single @a opCode without operands.
- void _emitOpCode(uint32_t opCode)
- {
- // Instruction prefix.
- if (opCode & 0xFF000000)
- _emitByte(static_cast<uint8_t>((opCode >> 24) & 0xFF));
-
- // Instruction opcodes.
- if (opCode & 0x00FF0000)
- _emitByte(static_cast<uint8_t>((opCode >> 16) & 0xFF));
- if (opCode & 0x0000FF00)
- _emitByte(static_cast<uint8_t>((opCode >> 8) & 0xFF));
-
- // Last opcode is always emitted (can be also 0x00).
- _emitByte(static_cast<uint8_t>(opCode & 0xFF));
- }
-
- //! @brief Emit MODR/M byte.
- void _emitMod(uint8_t m, uint8_t o, uint8_t r) { this->_emitByte(((m & 0x03) << 6) | ((o & 0x07) << 3) | (r & 0x07)); }
-
- //! @brief Emit SIB byte.
- void _emitSib(uint8_t s, uint8_t i, uint8_t b) { this->_emitByte(((s & 0x03) << 6) | ((i & 0x07) << 3) | (b & 0x07)); }
-
- //! @brief Emit REX prefix (64-bit mode only).
- void _emitRexR(uint8_t w, uint8_t opReg, uint8_t regCode, bool forceRexPrefix)
- {
-#ifdef ASMJIT_X64
- // w - Default operand size(0=Default, 1=64-bit).
- // 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).
- uint32_t rex = static_cast<uint32_t>(!!forceRexPrefix) << 6; // Rex prefix code.
- rex += static_cast<uint32_t>(w) << 3; // Rex.W (w << 3).
- rex += (static_cast<uint32_t>(opReg) & 0x08) >> 1; // Rex.R (r << 2).
- rex += (static_cast<uint32_t>(regCode) & 0x08) >> 3; // Rex.B (b << 0).
-
- if (rex)
- this->_emitByte(static_cast<uint8_t>(rex | 0x40));
-#else
- ASMJIT_UNUSED(w);
- ASMJIT_UNUSED(opReg);
- ASMJIT_UNUSED(regCode);
- ASMJIT_UNUSED(forceRexPrefix);
-#endif // ASMJIT_X64
- }
-
- //! @brief Emit REX prefix (64-bit mode only).
- void _emitRexRM(uint8_t w, uint8_t opReg, const Operand &rm, bool forceRexPrefix)
- {
-#ifdef ASMJIT_X64
- // w - Default operand size(0=Default, 1=64-bit).
- // 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).
- uint32_t rex = static_cast<uint32_t>(!!forceRexPrefix) << 6; // Rex prefix code.
- rex += static_cast<uint32_t>(w) << 3; // Rex.W (w << 3).
- rex += (static_cast<uint32_t>(opReg) & 0x08) >> 1; // Rex.R (r << 2).
-
- uint32_t b = 0;
- uint32_t x = 0;
-
- if (rm.isReg())
- b = !!(static_cast<const Reg &>(rm).getRegCode() & 0x08);
- else if (rm.isMem())
- {
- b = !!(static_cast<const Mem &>(rm).getBase() & 0x8) && static_cast<const Mem &>(rm).getBase() != kInvalidValue;
- x = !!(static_cast<const Mem &>(rm).getIndex() & 0x8) && static_cast<const Mem &>(rm).getIndex() != kInvalidValue;
- }
-
- rex += x << 1; // Rex.R (x << 1).
- rex += b; // Rex.B (b << 0).
-
- if (rex)
- this->_emitByte(static_cast<uint8_t>(rex | 0x40));
-#else
- ASMJIT_UNUSED(w);
- ASMJIT_UNUSED(opReg);
- ASMJIT_UNUSED(rm);
-#endif // ASMJIT_X64
- }
-
- //! @brief Emit Register / Register - calls _emitMod(3, opReg, r)
- void _emitModR(uint8_t opReg, uint8_t r) { this->_emitMod(3, opReg, r); }
-
- //! @brief Emit Register / Register - calls _emitMod(3, opReg, r.code())
- void _emitModR(uint8_t opReg, const Reg &r) { this->_emitMod(3, opReg, r.getRegCode()); }
-
- //! @brief Emit register / memory address combination to buffer.
- //!
- //! This method can hangle addresses from simple to complex ones with
- //! index and displacement.
- ASMJIT_API void _emitModM(uint8_t opReg, const Mem &mem, sysint_t immSize);
-
- //! @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.
- ASMJIT_API void _emitModRM(uint8_t opReg, const Operand &op, sysint_t immSize);
-
- //! @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.
- ASMJIT_API void _emitSegmentPrefix(const Operand &rm);
-
- //! @brief Emit instruction where register is inlined to opcode.
- ASMJIT_API void _emitX86Inl(uint32_t opCode, uint8_t i16bit, uint8_t rexw, uint8_t reg, bool forceRexPrefix);
-
- //! @brief Emit instruction with reg/memory operand.
- ASMJIT_API void _emitX86RM(uint32_t opCode, uint8_t i16bit, uint8_t rexw, uint8_t o, const Operand &op, sysint_t immSize, bool forceRexPrefix);
-
- //! @brief Emit FPU instruction with no operands.
- ASMJIT_API void _emitFpu(uint32_t opCode);
-
- //! @brief Emit FPU instruction with one operand @a sti (index of FPU register).
- ASMJIT_API void _emitFpuSTI(uint32_t opCode, uint32_t sti);
-
- //! @brief Emit FPU instruction with one operand @a opReg and memory operand @a mem.
- ASMJIT_API void _emitFpuMEM(uint32_t opCode, uint8_t opReg, const Mem &mem);
-
- //! @brief Emit MMX/SSE instruction.
- ASMJIT_API void _emitMmu(uint32_t opCode, uint8_t rexw, uint8_t opReg, const Operand& src, sysint_t immSize);
-
- //! @brief Emit displacement.
- ASMJIT_API LabelLink *_emitDisplacement(LabelData &l_data, sysint_t inlinedDisplacement, int size);
-
- //! @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.
- ASMJIT_API void _emitJmpOrCallReloc(uint32_t instruction, void *target);
-
- // Helpers to decrease binary code size. These four emit methods are just
- // helpers thats used by assembler. They call emitX86() adding NULLs
- // to first, second and third operand, if needed.
-
- //! @brief Emit X86/FPU or MM/XMM instruction.
- ASMJIT_API void _emitInstruction(uint32_t code);
-
- //! @brief Emit X86/FPU or MM/XMM instruction.
- ASMJIT_API void _emitInstruction(uint32_t code, const Operand *o0);
-
- //! @brief Emit X86/FPU or MM/XMM instruction.
- ASMJIT_API void _emitInstruction(uint32_t code, const Operand *o0, const Operand *o1);
-
- //! @brief Emit X86/FPU or MM/XMM 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.
- ASMJIT_API void _emitInstruction(uint32_t code, const Operand *o0, const Operand *o1, const Operand *o2);
-
- //! @brief Private method for emitting jcc.
- ASMJIT_API void _emitJcc(uint32_t code, const Label *label, uint32_t hint);
-
- //! @brief Private method for emitting short jcc.
- void _emitShortJcc(uint32_t code, const Label *label, uint32_t hint)
- {
- this->_emitOptions |= kX86EmitOptionShortJump;
- this->_emitJcc(code, label, hint);
- }
-
- // --------------------------------------------------------------------------
- // [EmbedLabel]
- // --------------------------------------------------------------------------
-
- //! @brief Embed absolute label pointer (4 or 8 bytes).
- ASMJIT_API void embedLabel(const Label &label);
-
- // --------------------------------------------------------------------------
- // [Align]
- // --------------------------------------------------------------------------
-
- //! @brief Align target buffer to @a m bytes.
- //!
- //! Typical usage of this is to align labels at start of the inner loops.
- //!
- //! Inserts @c nop() instructions or CPU optimized NOPs.
- ASMJIT_API void align(uint32_t m);
-
- // --------------------------------------------------------------------------
- // [Label]
- // --------------------------------------------------------------------------
-
- //! @brief Create and return new label.
- ASMJIT_API Label newLabel();
-
- //! @brief Register labels (used by @c Compiler).
- ASMJIT_API void registerLabels(size_t count);
-
- //! @brief Bind label to the current offset.
- //!
- //! @note Label can be bound only once!
- ASMJIT_API void bind(const Label &label);
-
- // --------------------------------------------------------------------------
- // [Reloc]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual size_t relocCode(void *dst, sysuint_t addressBase) const;
-
- // --------------------------------------------------------------------------
- // [Make]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void *make();
+//! \sa X86Compiler.
+struct ASMJIT_VCLASS X86Assembler : public Assembler {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API X86Assembler(Runtime* runtime, uint32_t arch
+#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
+ = kArchHost
+#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64
+ );
+ ASMJIT_API virtual ~X86Assembler();
+
+ // --------------------------------------------------------------------------
+ // [Arch]
+ // --------------------------------------------------------------------------
+
+ //! Get count of registers of the current architecture.
+ ASMJIT_INLINE const X86RegCount& getRegCount() const {
+ return _regCount;
+ }
+
+ //! Get Gpd or Gpq register depending on the current architecture.
+ ASMJIT_INLINE X86GpReg gpz(uint32_t index) const {
+ return X86GpReg(zax, index);
+ }
+
+ //! Create an architecture dependent intptr_t memory operand.
+ ASMJIT_INLINE X86Mem intptr_ptr(const X86GpReg& base, int32_t disp = 0) const {
+ return x86::ptr(base, disp, _regSize);
+ }
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) const {
+ return x86::ptr(base, index, shift, disp, _regSize);
+ }
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, int32_t disp = 0) const {
+ return x86::ptr(label, disp, _regSize);
+ }
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0) const {
+ return x86::ptr(label, index, shift, disp, _regSize);
+ }
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, int32_t disp = 0) const {
+ return x86::ptr_abs(pAbs, disp, _regSize);
+ }
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, const X86GpReg& index, uint32_t shift, int32_t disp = 0) const {
+ return x86::ptr_abs(pAbs, index, shift, disp, _regSize);
+ }
+
+ ASMJIT_API Error setArch(uint32_t arch);
// --------------------------------------------------------------------------
// [Embed]
// --------------------------------------------------------------------------
- //! @brief Add 8-bit integer data to the instuction stream.
- void db(uint8_t x) { embed(&x, 1); }
- //! @brief Add 16-bit integer data to the instuction stream.
- void dw(uint16_t x) { embed(&x, 2); }
- //! @brief Add 32-bit integer data to the instuction stream.
- void dd(uint32_t x) { embed(&x, 4); }
- //! @brief Add 64-bit integer data to the instuction stream.
- void dq(uint64_t x) { embed(&x, 8); }
-
- //! @brief Add 8-bit integer data to the instuction stream.
- void dint8(int8_t x) { embed(&x, sizeof(int8_t)); }
- //! @brief Add 8-bit integer data to the instuction stream.
- void duint8(uint8_t x) { embed(&x, sizeof(uint8_t)); }
-
- //! @brief Add 16-bit integer data to the instuction stream.
- void dint16(int16_t x) { embed(&x, sizeof(int16_t)); }
- //! @brief Add 16-bit integer data to the instuction stream.
- void duint16(uint16_t x) { embed(&x, sizeof(uint16_t)); }
-
- //! @brief Add 32-bit integer data to the instuction stream.
- void dint32(int32_t x) { embed(&x, sizeof(int32_t)); }
- //! @brief Add 32-bit integer data to the instuction stream.
- void duint32(uint32_t x) { embed(&x, sizeof(uint32_t)); }
-
- //! @brief Add 64-bit integer data to the instuction stream.
- void dint64(int64_t x) { embed(&x, sizeof(int64_t)); }
- //! @brief Add 64-bit integer data to the instuction stream.
- void duint64(uint64_t x) { embed(&x, sizeof(uint64_t)); }
-
- //! @brief Add system-integer data to the instuction stream.
- void dintptr(intptr_t x) { embed(&x, sizeof(intptr_t)); }
- //! @brief Add system-integer data to the instuction stream.
- void duintptr(uintptr_t x) { embed(&x, sizeof(uintptr_t)); }
-
- //! @brief Add float data to the instuction stream.
- void dfloat(float x) { embed(&x, sizeof(float)); }
- //! @brief Add double data to the instuction stream.
- void ddouble(double x) { embed(&x, sizeof(double)); }
-
- //! @brief Add pointer data to the instuction stream.
- void dptr(void* x) { embed(&x, sizeof(void*)); }
-
- //! @brief Add MM data to the instuction stream.
- void dmm(const MmData& x) { embed(&x, sizeof(MmData)); }
- //! @brief Add XMM data to the instuction stream.
- void dxmm(const XmmData& x) { embed(&x, sizeof(XmmData)); }
-
- //! @brief Add data to the instuction stream.
- void data(const void* data, size_t size) { embed(data, size); }
-
- //! @brief Add data in a given structure instance to the instuction stream.
+ //! Add 8-bit integer data to the instruction stream.
+ ASMJIT_INLINE void db(uint8_t x) { embed(&x, 1); }
+ //! Add 16-bit integer data to the instruction stream.
+ ASMJIT_INLINE void dw(uint16_t x) { embed(&x, 2); }
+ //! Add 32-bit integer data to the instruction stream.
+ ASMJIT_INLINE void dd(uint32_t x) { embed(&x, 4); }
+ //! Add 64-bit integer data to the instruction stream.
+ ASMJIT_INLINE void dq(uint64_t x) { embed(&x, 8); }
+
+ //! Add 8-bit integer data to the instruction stream.
+ ASMJIT_INLINE void dint8(int8_t x) { embed(&x, sizeof(int8_t)); }
+ //! Add 8-bit integer data to the instruction stream.
+ ASMJIT_INLINE void duint8(uint8_t x) { embed(&x, sizeof(uint8_t)); }
+
+ //! Add 16-bit integer data to the instruction stream.
+ ASMJIT_INLINE void dint16(int16_t x) { embed(&x, sizeof(int16_t)); }
+ //! Add 16-bit integer data to the instruction stream.
+ ASMJIT_INLINE void duint16(uint16_t x) { embed(&x, sizeof(uint16_t)); }
+
+ //! Add 32-bit integer data to the instruction stream.
+ ASMJIT_INLINE void dint32(int32_t x) { embed(&x, sizeof(int32_t)); }
+ //! Add 32-bit integer data to the instruction stream.
+ ASMJIT_INLINE void duint32(uint32_t x) { embed(&x, sizeof(uint32_t)); }
+
+ //! Add 64-bit integer data to the instruction stream.
+ ASMJIT_INLINE void dint64(int64_t x) { embed(&x, sizeof(int64_t)); }
+ //! Add 64-bit integer data to the instruction stream.
+ ASMJIT_INLINE void duint64(uint64_t x) { embed(&x, sizeof(uint64_t)); }
+
+ //! Add float data to the instruction stream.
+ ASMJIT_INLINE void dfloat(float x) { embed(&x, sizeof(float)); }
+ //! Add double data to the instruction stream.
+ ASMJIT_INLINE void ddouble(double x) { embed(&x, sizeof(double)); }
+
+ //! Add Mm data to the instruction stream.
+ ASMJIT_INLINE void dmm(const Vec64& x) { embed(&x, sizeof(Vec64)); }
+ //! Add Xmm data to the instruction stream.
+ ASMJIT_INLINE void dxmm(const Vec128& x) { embed(&x, sizeof(Vec128)); }
+ //! Add Ymm data to the instruction stream.
+ ASMJIT_INLINE void dymm(const Vec256& x) { embed(&x, sizeof(Vec256)); }
+
+ //! Add data in a given structure instance to the instruction stream.
template<typename T>
- void dstruct(const T& x) { embed(&x, sizeof(T)); }
+ ASMJIT_INLINE void dstruct(const T& x) { embed(&x, static_cast<uint32_t>(sizeof(T))); }
+
+ //! Embed absolute label pointer (4 or 8 bytes).
+ ASMJIT_API Error embedLabel(const Label& op);
// --------------------------------------------------------------------------
- // [X86 Instructions]
+ // [Align]
// --------------------------------------------------------------------------
- //! @brief Add with Carry.
- void adc(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstAdc, &dst, &src); }
- //! @brief Add with Carry.
- void adc(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstAdc, &dst, &src); }
- //! @brief Add with Carry.
- void adc(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstAdc, &dst, &src); }
- //! @brief Add with Carry.
- void adc(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstAdc, &dst, &src); }
- //! @brief Add with Carry.
- void adc(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstAdc, &dst, &src); }
-
- //! @brief Add.
- void add(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstAdd, &dst, &src); }
- //! @brief Add.
- void add(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstAdd, &dst, &src); }
- //! @brief Add.
- void add(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstAdd, &dst, &src); }
- //! @brief Add.
- void add(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstAdd, &dst, &src); }
- //! @brief Add.
- void add(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstAdd, &dst, &src); }
-
- //! @brief Logical And.
- void and_(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstAnd, &dst, &src); }
- //! @brief Logical And.
- void and_(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstAnd, &dst, &src); }
- //! @brief Logical And.
- void and_(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstAnd, &dst, &src); }
- //! @brief Logical And.
- void and_(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstAnd, &dst, &src); }
- //! @brief Logical And.
- void and_(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstAnd, &dst, &src); }
-
- //! @brief Bit Scan Forward.
- void bsf(const GpReg& dst, const GpReg& src)
- {
- ASMJIT_ASSERT(!dst.isGpb());
- _emitInstruction(kX86InstBsf, &dst, &src);
+ ASMJIT_API virtual Error align(uint32_t mode, uint32_t offset);
+
+ // --------------------------------------------------------------------------
+ // [Reloc]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual size_t _relocCode(void* dst, Ptr baseAddress) const;
+
+ // --------------------------------------------------------------------------
+ // [Emit]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual Error _emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3);
+
+ // -------------------------------------------------------------------------
+ // [Options]
+ // -------------------------------------------------------------------------
+
+ ASMJIT_X86_EMIT_OPTIONS(X86Assembler)
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Count of registers depending on the current architecture.
+ X86RegCount _regCount;
+
+ //! EAX or RAX register depending on the current architecture.
+ X86GpReg zax;
+ //! ECX or RCX register depending on the current architecture.
+ X86GpReg zcx;
+ //! EDX or RDX register depending on the current architecture.
+ X86GpReg zdx;
+ //! EBX or RBX register depending on the current architecture.
+ X86GpReg zbx;
+ //! ESP or RSP register depending on the current architecture.
+ X86GpReg zsp;
+ //! EBP or RBP register depending on the current architecture.
+ X86GpReg zbp;
+ //! ESI or RSI register depending on the current architecture.
+ X86GpReg zsi;
+ //! EDI or RDI register depending on the current architecture.
+ X86GpReg zdi;
+
+ // --------------------------------------------------------------------------
+ // [Base Instructions]
+ // --------------------------------------------------------------------------
+
+#define INST_0x(_Inst_, _Code_) \
+ ASMJIT_INLINE Error _Inst_() { \
+ return emit(_Code_); \
}
- //! @brief Bit Scan Forward.
- void bsf(const GpReg& dst, const Mem& src)
- {
- ASMJIT_ASSERT(!dst.isGpb());
- _emitInstruction(kX86InstBsf, &dst, &src);
+
+#define INST_1x(_Inst_, _Code_, _Op0_) \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0) { \
+ return emit(_Code_, o0); \
}
- //! @brief Bit Scan Reverse.
- void bsr(const GpReg& dst, const GpReg& src)
- {
- ASMJIT_ASSERT(!dst.isGpb());
- _emitInstruction(kX86InstBsr, &dst, &src);
+#define INST_1x_(_Inst_, _Code_, _Op0_, _Cond_) \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0) { \
+ ASMJIT_ASSERT(_Cond_); \
+ return emit(_Code_, o0); \
}
- //! @brief Bit Scan Reverse.
- void bsr(const GpReg& dst, const Mem& src)
- {
- ASMJIT_ASSERT(!dst.isGpb());
- _emitInstruction(kX86InstBsr, &dst, &src);
+
+#define INST_1i(_Inst_, _Code_, _Op0_) \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0) { \
+ return emit(_Code_, o0); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(int o0) { \
+ return emit(_Code_, o0); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(unsigned int o0) { \
+ return emit(_Code_, static_cast<uint64_t>(o0)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(int64_t o0) { \
+ return emit(_Code_, static_cast<uint64_t>(o0)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(uint64_t o0) { \
+ return emit(_Code_, o0); \
}
- //! @brief Byte swap (32-bit or 64-bit registers only) (i486).
- void bswap(const GpReg& dst)
- {
- ASMJIT_ASSERT(dst.getRegType() == kX86RegTypeGpd || dst.getRegType() == kX86RegTypeGpq);
- _emitInstruction(kX86InstBSwap, &dst);
+#define INST_1cc(_Inst_, _Code_, _Translate_, _Op0_) \
+ ASMJIT_INLINE Error _Inst_(uint32_t cc, const _Op0_& o0) { \
+ return emit(_Translate_(cc), o0); \
+ } \
+ \
+ ASMJIT_INLINE Error _Inst_##a(const _Op0_& o0) { return emit(_Code_##a, o0); } \
+ ASMJIT_INLINE Error _Inst_##ae(const _Op0_& o0) { return emit(_Code_##ae, o0); } \
+ ASMJIT_INLINE Error _Inst_##b(const _Op0_& o0) { return emit(_Code_##b, o0); } \
+ ASMJIT_INLINE Error _Inst_##be(const _Op0_& o0) { return emit(_Code_##be, o0); } \
+ ASMJIT_INLINE Error _Inst_##c(const _Op0_& o0) { return emit(_Code_##c, o0); } \
+ ASMJIT_INLINE Error _Inst_##e(const _Op0_& o0) { return emit(_Code_##e, o0); } \
+ ASMJIT_INLINE Error _Inst_##g(const _Op0_& o0) { return emit(_Code_##g, o0); } \
+ ASMJIT_INLINE Error _Inst_##ge(const _Op0_& o0) { return emit(_Code_##ge, o0); } \
+ ASMJIT_INLINE Error _Inst_##l(const _Op0_& o0) { return emit(_Code_##l, o0); } \
+ ASMJIT_INLINE Error _Inst_##le(const _Op0_& o0) { return emit(_Code_##le, o0); } \
+ ASMJIT_INLINE Error _Inst_##na(const _Op0_& o0) { return emit(_Code_##na, o0); } \
+ ASMJIT_INLINE Error _Inst_##nae(const _Op0_& o0) { return emit(_Code_##nae, o0); } \
+ ASMJIT_INLINE Error _Inst_##nb(const _Op0_& o0) { return emit(_Code_##nb, o0); } \
+ ASMJIT_INLINE Error _Inst_##nbe(const _Op0_& o0) { return emit(_Code_##nbe, o0); } \
+ ASMJIT_INLINE Error _Inst_##nc(const _Op0_& o0) { return emit(_Code_##nc, o0); } \
+ ASMJIT_INLINE Error _Inst_##ne(const _Op0_& o0) { return emit(_Code_##ne, o0); } \
+ ASMJIT_INLINE Error _Inst_##ng(const _Op0_& o0) { return emit(_Code_##ng, o0); } \
+ ASMJIT_INLINE Error _Inst_##nge(const _Op0_& o0) { return emit(_Code_##nge, o0); } \
+ ASMJIT_INLINE Error _Inst_##nl(const _Op0_& o0) { return emit(_Code_##nl, o0); } \
+ ASMJIT_INLINE Error _Inst_##nle(const _Op0_& o0) { return emit(_Code_##nle, o0); } \
+ ASMJIT_INLINE Error _Inst_##no(const _Op0_& o0) { return emit(_Code_##no, o0); } \
+ ASMJIT_INLINE Error _Inst_##np(const _Op0_& o0) { return emit(_Code_##np, o0); } \
+ ASMJIT_INLINE Error _Inst_##ns(const _Op0_& o0) { return emit(_Code_##ns, o0); } \
+ ASMJIT_INLINE Error _Inst_##nz(const _Op0_& o0) { return emit(_Code_##nz, o0); } \
+ ASMJIT_INLINE Error _Inst_##o(const _Op0_& o0) { return emit(_Code_##o, o0); } \
+ ASMJIT_INLINE Error _Inst_##p(const _Op0_& o0) { return emit(_Code_##p, o0); } \
+ ASMJIT_INLINE Error _Inst_##pe(const _Op0_& o0) { return emit(_Code_##pe, o0); } \
+ ASMJIT_INLINE Error _Inst_##po(const _Op0_& o0) { return emit(_Code_##po, o0); } \
+ ASMJIT_INLINE Error _Inst_##s(const _Op0_& o0) { return emit(_Code_##s, o0); } \
+ ASMJIT_INLINE Error _Inst_##z(const _Op0_& o0) { return emit(_Code_##z, o0); }
+
+#define INST_2x(_Inst_, _Code_, _Op0_, _Op1_) \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1) { \
+ return emit(_Code_, o0, o1); \
}
- //! @brief Bit test.
- void bt(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstBt, &dst, &src); }
- //! @brief Bit test.
- void bt(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstBt, &dst, &src); }
- //! @brief Bit test.
- void bt(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstBt, &dst, &src); }
- //! @brief Bit test.
- void bt(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstBt, &dst, &src); }
-
- //! @brief Bit test and complement.
- void btc(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstBtc, &dst, &src); }
- //! @brief Bit test and complement.
- void btc(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstBtc, &dst, &src); }
- //! @brief Bit test and complement.
- void btc(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstBtc, &dst, &src); }
- //! @brief Bit test and complement.
- void btc(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstBtc, &dst, &src); }
-
- //! @brief Bit test and reset.
- void btr(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstBtr, &dst, &src); }
- //! @brief Bit test and reset.
- void btr(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstBtr, &dst, &src); }
- //! @brief Bit test and reset.
- void btr(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstBtr, &dst, &src); }
- //! @brief Bit test and reset.
- void btr(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstBtr, &dst, &src); }
-
- //! @brief Bit test and set.
- void bts(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstBts, &dst, &src); }
- //! @brief Bit test and set.
- void bts(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstBts, &dst, &src); }
- //! @brief Bit test and set.
- void bts(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstBts, &dst, &src); }
- //! @brief Bit test and set.
- void bts(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstBts, &dst, &src); }
-
- //! @brief Call Procedure.
- void call(const GpReg& dst)
- {
- ASMJIT_ASSERT(dst.isRegType(kX86RegTypeGpz));
- _emitInstruction(kX86InstCall, &dst);
+#define INST_2x_(_Inst_, _Code_, _Op0_, _Op1_, _Cond_) \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1) { \
+ ASMJIT_ASSERT(_Cond_); \
+ return emit(_Code_, o0, o1); \
}
- //! @brief Call Procedure.
- void call(const Mem& dst)
- { _emitInstruction(kX86InstCall, &dst); }
- //! @brief Call Procedure.
- void call(const Imm& dst)
- { _emitInstruction(kX86InstCall, &dst); }
- //! @brief Call Procedure.
- //! @overload
- void call(void* dst)
- {
- Imm imm((sysint_t)dst);
- _emitInstruction(kX86InstCall, &imm);
+
+#define INST_2i(_Inst_, _Code_, _Op0_, _Op1_) \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1) { \
+ return emit(_Code_, o0, o1); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int o1) { \
+ return emit(_Code_, o0, o1); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, unsigned int o1) { \
+ return emit(_Code_, o0, static_cast<uint64_t>(o1)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int64_t o1) { \
+ return emit(_Code_, o0, static_cast<uint64_t>(o1)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, uint64_t o1) { \
+ return emit(_Code_, o0, o1); \
}
- //! @brief Call Procedure.
- void call(const Label& label)
- { _emitInstruction(kX86InstCall, &label); }
-
- //! @brief Convert Byte to Word (Sign Extend).
+#define INST_2cc(_Inst_, _Code_, _Translate_, _Op0_, _Op1_) \
+ ASMJIT_INLINE Error _Inst_(uint32_t cc, const _Op0_& o0, const _Op1_& o1) { \
+ return emit(_Translate_(cc), o0, o1); \
+ } \
+ \
+ ASMJIT_INLINE Error _Inst_##a(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##a, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##ae(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ae, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##b(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##b, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##be(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##be, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##c(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##c, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##e(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##e, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##g(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##g, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##ge(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ge, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##l(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##l, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##le(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##le, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##na(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##na, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##nae(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nae, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##nb(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nb, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##nbe(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nbe, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##nc(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nc, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##ne(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ne, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##ng(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ng, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##nge(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nge, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##nl(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nl, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##nle(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nle, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##no(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##no, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##np(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##np, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##ns(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ns, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##nz(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nz, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##o(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##o, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##p(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##p, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##pe(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##pe, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##po(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##po, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##s(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##s, o0, o1); } \
+ ASMJIT_INLINE Error _Inst_##z(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##z, o0, o1); }
+
+#define INST_3x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \
+ return emit(_Code_, o0, o1, o2); \
+ }
+
+#define INST_3x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Cond_) \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \
+ ASMJIT_ASSERT(_Cond_); \
+ return emit(_Code_, o0, o1, o2); \
+ }
+
+#define INST_3i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \
+ return emit(_Code_, o0, o1, o2); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int o2) { \
+ return emit(_Code_, o0, o1, o2); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, unsigned int o2) { \
+ return emit(_Code_, o0, o1, static_cast<uint64_t>(o2)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int64_t o2) { \
+ return emit(_Code_, o0, o1, static_cast<uint64_t>(o2)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, uint64_t o2) { \
+ return emit(_Code_, o0, o1, o2); \
+ }
+
+#define INST_4x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_) \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \
+ return emit(_Code_, o0, o1, o2, o3); \
+ }
+
+#define INST_4x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_, _Cond_) \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \
+ ASMJIT_ASSERT(_Cond_); \
+ return emit(_Code_, o0, o1, o2, o3); \
+ }
+
+#define INST_4i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_) \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \
+ return emit(_Code_, o0, o1, o2, o3); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int o3) { \
+ return emit(_Code_, o0, o1, o2, o3); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, unsigned int o3) { \
+ return emit(_Code_, o0, o1, o2, static_cast<uint64_t>(o3)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int64_t o3) { \
+ return emit(_Code_, o0, o1, o2, static_cast<uint64_t>(o3)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, uint64_t o3) { \
+ return emit(_Code_, o0, o1, o2, o3); \
+ }
+
+ //! Add with Carry.
+ INST_2x(adc, kX86InstIdAdc, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(adc, kX86InstIdAdc, X86GpReg, X86Mem)
+ //! \overload
+ INST_2i(adc, kX86InstIdAdc, X86GpReg, Imm)
+ //! \overload
+ INST_2x(adc, kX86InstIdAdc, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(adc, kX86InstIdAdc, X86Mem, Imm)
+
+ //! Add.
+ INST_2x(add, kX86InstIdAdd, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(add, kX86InstIdAdd, X86GpReg, X86Mem)
+ //! \overload
+ INST_2i(add, kX86InstIdAdd, X86GpReg, Imm)
+ //! \overload
+ INST_2x(add, kX86InstIdAdd, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(add, kX86InstIdAdd, X86Mem, Imm)
+
+ //! And.
+ INST_2x(and_, kX86InstIdAnd, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(and_, kX86InstIdAnd, X86GpReg, X86Mem)
+ //! \overload
+ INST_2i(and_, kX86InstIdAnd, X86GpReg, Imm)
+ //! \overload
+ INST_2x(and_, kX86InstIdAnd, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(and_, kX86InstIdAnd, X86Mem, Imm)
+
+ //! Bit scan forward.
+ INST_2x_(bsf, kX86InstIdBsf, X86GpReg, X86GpReg, !o0.isGpb())
+ //! \overload
+ INST_2x_(bsf, kX86InstIdBsf, X86GpReg, X86Mem, !o0.isGpb())
+
+ //! Bit scan reverse.
+ INST_2x_(bsr, kX86InstIdBsr, X86GpReg, X86GpReg, !o0.isGpb())
+ //! \overload
+ INST_2x_(bsr, kX86InstIdBsr, X86GpReg, X86Mem, !o0.isGpb())
+
+ //! Byte swap (32-bit or 64-bit registers only) (i486).
+ INST_1x_(bswap, kX86InstIdBswap, X86GpReg, o0.getSize() >= 4)
+
+ //! Bit test.
+ INST_2x(bt, kX86InstIdBt, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2i(bt, kX86InstIdBt, X86GpReg, Imm)
+ //! \overload
+ INST_2x(bt, kX86InstIdBt, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(bt, kX86InstIdBt, X86Mem, Imm)
+
+ //! Bit test and complement.
+ INST_2x(btc, kX86InstIdBtc, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2i(btc, kX86InstIdBtc, X86GpReg, Imm)
+ //! \overload
+ INST_2x(btc, kX86InstIdBtc, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(btc, kX86InstIdBtc, X86Mem, Imm)
+
+ //! Bit test and reset.
+ INST_2x(btr, kX86InstIdBtr, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2i(btr, kX86InstIdBtr, X86GpReg, Imm)
+ //! \overload
+ INST_2x(btr, kX86InstIdBtr, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(btr, kX86InstIdBtr, X86Mem, Imm)
+
+ //! Bit test and set.
+ INST_2x(bts, kX86InstIdBts, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2i(bts, kX86InstIdBts, X86GpReg, Imm)
+ //! \overload
+ INST_2x(bts, kX86InstIdBts, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(bts, kX86InstIdBts, X86Mem, Imm)
+
+ //! Call.
+ INST_1x(call, kX86InstIdCall, X86GpReg)
+ //! \overload
+ INST_1x(call, kX86InstIdCall, X86Mem)
+ //! \overload
+ INST_1x(call, kX86InstIdCall, Label)
+ //! \overload
+ INST_1x(call, kX86InstIdCall, Imm)
+ //! \overload
+ ASMJIT_INLINE Error call(Ptr o0) { return call(Imm(o0)); }
+
+ //! Clear carry flag.
+ INST_0x(clc, kX86InstIdClc)
+ //! Clear direction flag.
+ INST_0x(cld, kX86InstIdCld)
+ //! Complement carry flag.
+ INST_0x(cmc, kX86InstIdCmc)
+
+ //! Convert BYTE to WORD (AX <- Sign Extend AL).
+ INST_0x(cbw, kX86InstIdCbw)
+ //! Convert DWORD to QWORD (EDX:EAX <- Sign Extend EAX).
+ INST_0x(cdq, kX86InstIdCdq)
+ //! Convert DWORD to QWORD (RAX <- Sign Extend EAX) (X64 Only).
+ INST_0x(cdqe, kX86InstIdCdqe)
+ //! Convert QWORD to OWORD (RDX:RAX <- Sign Extend RAX) (X64 Only).
+ INST_0x(cqo, kX86InstIdCqo)
+ //! Convert WORD to DWORD (DX:AX <- Sign Extend AX).
+ INST_0x(cwd, kX86InstIdCwd)
+ //! Convert WORD to DWORD (EAX <- Sign Extend AX).
+ INST_0x(cwde, kX86InstIdCwde)
+
+ //! Conditional move.
+ INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpReg, X86GpReg)
+ //! Conditional move.
+ INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpReg, X86Mem)
+
+ //! Compare two operands.
+ INST_2x(cmp, kX86InstIdCmp, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(cmp, kX86InstIdCmp, X86GpReg, X86Mem)
+ //! \overload
+ INST_2i(cmp, kX86InstIdCmp, X86GpReg, Imm)
+ //! \overload
+ INST_2x(cmp, kX86InstIdCmp, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(cmp, kX86InstIdCmp, X86Mem, Imm)
+
+ //! Compare BYTE in ES:[EDI/RDI] and DS:[ESI/RSI].
+ INST_0x(cmpsb, kX86InstIdCmpsB)
+ //! Compare DWORD in ES:[EDI/RDI] and DS:[ESI/RSI].
+ INST_0x(cmpsd, kX86InstIdCmpsD)
+ //! Compare QWORD in ES:[RDI] and DS:[RDI] (X64 Only).
+ INST_0x(cmpsq, kX86InstIdCmpsQ)
+ //! Compare WORD in ES:[EDI/RDI] and DS:[ESI/RSI].
+ INST_0x(cmpsw, kX86InstIdCmpsW)
+
+ //! Compare and exchange (i486).
+ INST_2x(cmpxchg, kX86InstIdCmpxchg, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(cmpxchg, kX86InstIdCmpxchg, X86Mem, X86GpReg)
+
+ //! Compare and exchange 128-bit value in RDX:RAX with the memory operand (X64 Only).
+ INST_1x(cmpxchg16b, kX86InstIdCmpxchg16b, X86Mem)
+ //! Compare and exchange 64-bit value in EDX:EAX with the memory operand (Pentium).
+ INST_1x(cmpxchg8b, kX86InstIdCmpxchg8b, X86Mem)
+
+ //! CPU identification (i486).
+ INST_0x(cpuid, kX86InstIdCpuid)
+
+ //! Accumulate crc32 value (polynomial 0x11EDC6F41) (SSE4.2).
+ INST_2x_(crc32, kX86InstIdCrc32, X86GpReg, X86GpReg, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq))
+ //! \overload
+ INST_2x_(crc32, kX86InstIdCrc32, X86GpReg, X86Mem, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq))
+
+ //! Decimal adjust AL after addition (X86 Only).
+ INST_0x(daa, kX86InstIdDaa)
+ //! Decimal adjust AL after subtraction (X86 Only).
+ INST_0x(das, kX86InstIdDas)
+
+ //! Decrement by 1.
+ INST_1x(dec, kX86InstIdDec, X86GpReg)
+ //! \overload
+ INST_1x(dec, kX86InstIdDec, X86Mem)
+
+ //! Unsigned divide (xDX:xAX <- xDX:xAX / o0).
+ INST_1x(div, kX86InstIdDiv, X86GpReg)
+ //! \overload
+ INST_1x(div, kX86InstIdDiv, X86Mem)
+
+ //! Make stack frame for procedure parameters.
+ INST_2x(enter, kX86InstIdEnter, Imm, Imm)
+
+ //! Signed divide (xDX:xAX <- xDX:xAX / op).
+ INST_1x(idiv, kX86InstIdIdiv, X86GpReg)
+ //! \overload
+ INST_1x(idiv, kX86InstIdIdiv, X86Mem)
+
+ //! Signed multiply (xDX:xAX <- xAX * o0).
+ INST_1x(imul, kX86InstIdImul, X86GpReg)
+ //! \overload
+ INST_1x(imul, kX86InstIdImul, X86Mem)
+
+ //! Signed multiply.
+ INST_2x(imul, kX86InstIdImul, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(imul, kX86InstIdImul, X86GpReg, X86Mem)
+ //! \overload
+ INST_2i(imul, kX86InstIdImul, X86GpReg, Imm)
+
+ //! Signed multiply.
+ INST_3i(imul, kX86InstIdImul, X86GpReg, X86GpReg, Imm)
+ //! \overload
+ INST_3i(imul, kX86InstIdImul, X86GpReg, X86Mem, Imm)
+
+ //! Increment by 1.
+ INST_1x(inc, kX86InstIdInc, X86GpReg)
+ //! \overload
+ INST_1x(inc, kX86InstIdInc, X86Mem)
+
+ //! Interrupt.
+ INST_1i(int_, kX86InstIdInt, Imm)
+ //! Interrupt 3 - trap to debugger.
+ ASMJIT_INLINE Error int3() { return int_(3); }
+
+ //! Jump to `label` if condition `cc` is met.
+ INST_1cc(j, kX86InstIdJ, X86Util::condToJcc, Label)
+
+ //! Short jump if CX/ECX/RCX is zero.
+ INST_2x_(jecxz, kX86InstIdJecxz, X86GpReg, Label, o0.getRegIndex() == kX86RegIndexCx)
+
+ //! Jump.
+ INST_1x(jmp, kX86InstIdJmp, X86GpReg)
+ //! \overload
+ INST_1x(jmp, kX86InstIdJmp, X86Mem)
+ //! \overload
+ INST_1x(jmp, kX86InstIdJmp, Label)
+ //! \overload
+ INST_1x(jmp, kX86InstIdJmp, Imm)
+ //! \overload
+ ASMJIT_INLINE Error jmp(Ptr dst) { return jmp(Imm(dst)); }
+
+ //! Load AH from flags.
+ INST_0x(lahf, kX86InstIdLahf)
+
+ //! Load effective address
+ INST_2x(lea, kX86InstIdLea, X86GpReg, X86Mem)
+
+ //! High level procedure exit.
+ INST_0x(leave, kX86InstIdLeave)
+
+ //! Load BYTE from DS:[ESI/RSI] to AL.
+ INST_0x(lodsb, kX86InstIdLodsB)
+ //! Load DWORD from DS:[ESI/RSI] to EAX.
+ INST_0x(lodsd, kX86InstIdLodsD)
+ //! Load QWORD from DS:[RDI] to RAX (X64 Only).
+ INST_0x(lodsq, kX86InstIdLodsQ)
+ //! Load WORD from DS:[ESI/RSI] to AX.
+ INST_0x(lodsw, kX86InstIdLodsW)
+
+ //! Move.
+ INST_2x(mov, kX86InstIdMov, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(mov, kX86InstIdMov, X86GpReg, X86Mem)
+ //! \overload
+ INST_2i(mov, kX86InstIdMov, X86GpReg, Imm)
+ //! \overload
+ INST_2x(mov, kX86InstIdMov, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(mov, kX86InstIdMov, X86Mem, Imm)
+
+ //! Move from segment register.
+ INST_2x(mov, kX86InstIdMov, X86GpReg, X86SegReg)
+ //! \overload
+ INST_2x(mov, kX86InstIdMov, X86Mem, X86SegReg)
+ //! Move to segment register.
+ INST_2x(mov, kX86InstIdMov, X86SegReg, X86GpReg)
+ //! \overload
+ INST_2x(mov, kX86InstIdMov, X86SegReg, X86Mem)
+
+ //! Move (AL|AX|EAX|RAX <- absolute address in immediate).
+ INST_2x_(mov_ptr, kX86InstIdMovPtr, X86GpReg, Imm, o0.getRegIndex() == 0);
+ //! \overload
+ ASMJIT_INLINE Error mov_ptr(const X86GpReg& o0, Ptr o1) {
+ ASMJIT_ASSERT(o0.getRegIndex() == 0);
+ return emit(kX86InstIdMovPtr, o0, Imm(o1));
+ }
+
+ //! Move (absolute address in immediate <- AL|AX|EAX|RAX).
+ INST_2x_(mov_ptr, kX86InstIdMovPtr, Imm, X86GpReg, o1.getRegIndex() == 0);
+ //! \overload
+ ASMJIT_INLINE Error mov_ptr(Ptr o0, const X86GpReg& o1) {
+ ASMJIT_ASSERT(o1.getRegIndex() == 0);
+ return emit(kX86InstIdMovPtr, Imm(o0), o1);
+ }
+
+ //! Move data after dwapping bytes (SSE3 - Atom).
+ INST_2x_(movbe, kX86InstIdMovbe, X86GpReg, X86Mem, !o0.isGpb());
+ //! \overload
+ INST_2x_(movbe, kX86InstIdMovbe, X86Mem, X86GpReg, !o1.isGpb());
+
+ //! Move BYTE from DS:[ESI/RSI] to ES:[EDI/RDI].
+ INST_0x(movsb, kX86InstIdMovsB)
+ //! Move DWORD from DS:[ESI/RSI] to ES:[EDI/RDI].
+ INST_0x(movsd, kX86InstIdMovsD)
+ //! Move QWORD from DS:[RSI] to ES:[RDI] (X64 Only).
+ INST_0x(movsq, kX86InstIdMovsQ)
+ //! Move WORD from DS:[ESI/RSI] to ES:[EDI/RDI].
+ INST_0x(movsw, kX86InstIdMovsW)
+
+ //! Move with sign-extension.
+ INST_2x(movsx, kX86InstIdMovsx, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(movsx, kX86InstIdMovsx, X86GpReg, X86Mem)
+
+ //! Move DWORD to QWORD with sign-extension (X64 Only).
+ INST_2x(movsxd, kX86InstIdMovsxd, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(movsxd, kX86InstIdMovsxd, X86GpReg, X86Mem)
+
+ //! Move with zero-extension.
+ INST_2x(movzx, kX86InstIdMovzx, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(movzx, kX86InstIdMovzx, X86GpReg, X86Mem)
+
+ //! Unsigned multiply (xDX:xAX <- xAX * o0).
+ INST_1x(mul, kX86InstIdMul, X86GpReg)
+ //! \overload
+ INST_1x(mul, kX86InstIdMul, X86Mem)
+
+ //! Two's complement negation.
+ INST_1x(neg, kX86InstIdNeg, X86GpReg)
+ //! \overload
+ INST_1x(neg, kX86InstIdNeg, X86Mem)
+
+ //! No operation.
+ INST_0x(nop, kX86InstIdNop)
+
+ //! One's complement negation.
+ INST_1x(not_, kX86InstIdNot, X86GpReg)
+ //! \overload
+ INST_1x(not_, kX86InstIdNot, X86Mem)
+
+ //! Or.
+ INST_2x(or_, kX86InstIdOr, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(or_, kX86InstIdOr, X86GpReg, X86Mem)
+ //! \overload
+ INST_2i(or_, kX86InstIdOr, X86GpReg, Imm)
+ //! \overload
+ INST_2x(or_, kX86InstIdOr, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(or_, kX86InstIdOr, X86Mem, Imm)
+
+ //! Pop a value from the stack.
+ INST_1x_(pop, kX86InstIdPop, X86GpReg, o0.getSize() == 2 || o0.getSize() == _regSize)
+ //! \overload
+ INST_1x_(pop, kX86InstIdPop, X86Mem, o0.getSize() == 2 || o0.getSize() == _regSize)
+
+ //! Pop a segment register from the stack.
//!
- //! AX <- Sign Extend AL
- void cbw()
- { _emitInstruction(kX86InstCbw); }
-
- //! @brief Convert Word to DWord (Sign Extend).
+ //! \note There is no instruction to pop a cs segment register.
+ INST_1x_(pop, kX86InstIdPop, X86SegReg, o0.getRegIndex() != kX86SegCs);
+
+ //! Pop all Gp registers - EDI|ESI|EBP|Ign|EBX|EDX|ECX|EAX (X86 Only).
+ INST_0x(popa, kX86InstIdPopa)
+
+ //! Pop stack into EFLAGS register (32-bit or 64-bit).
+ INST_0x(popf, kX86InstIdPopf)
+
+ //! Return the count of number of bits set to 1 (SSE4.2).
+ INST_2x_(popcnt, kX86InstIdPopcnt, X86GpReg, X86GpReg, !o0.isGpb() && o0.getRegType() == o1.getRegType())
+ //! \overload
+ INST_2x_(popcnt, kX86InstIdPopcnt, X86GpReg, X86Mem, !o0.isGpb())
+
+ //! Push WORD or DWORD/QWORD on the stack.
+ INST_1x_(push, kX86InstIdPush, X86GpReg, o0.getSize() == 2 || o0.getSize() == _regSize)
+ //! Push WORD or DWORD/QWORD on the stack.
+ INST_1x_(push, kX86InstIdPush, X86Mem, o0.getSize() == 2 || o0.getSize() == _regSize)
+ //! Push segment register on the stack.
+ INST_1x(push, kX86InstIdPush, X86SegReg)
+ //! Push WORD or DWORD/QWORD on the stack.
+ INST_1i(push, kX86InstIdPush, Imm)
+
+ //! Push all Gp registers - EAX|ECX|EDX|EBX|ESP|EBP|ESI|EDI (X86 Only).
+ INST_0x(pusha, kX86InstIdPusha)
+
+ //! Push EFLAGS register (32-bit or 64-bit) on the stack.
+ INST_0x(pushf, kX86InstIdPushf)
+
+ //! Rotate bits left.
//!
- //! DX:AX <- Sign Extend AX
- void cwd()
- { _emitInstruction(kX86InstCwd); }
-
- //! @brief Convert Word to DWord (Sign Extend).
+ //! \note `o1` register can be only `cl`.
+ INST_2x(rcl, kX86InstIdRcl, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(rcl, kX86InstIdRcl, X86Mem, X86GpReg)
+ //! Rotate bits left.
+ INST_2i(rcl, kX86InstIdRcl, X86GpReg, Imm)
+ //! \overload
+ INST_2i(rcl, kX86InstIdRcl, X86Mem, Imm)
+
+ //! Rotate bits right.
//!
- //! EAX <- Sign Extend AX
- void cwde()
- { _emitInstruction(kX86InstCwde); }
-
- //! @brief Convert DWord to QWord (Sign Extend).
+ //! \note `o1` register can be only `cl`.
+ INST_2x(rcr, kX86InstIdRcr, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(rcr, kX86InstIdRcr, X86Mem, X86GpReg)
+ //! Rotate bits right.
+ INST_2i(rcr, kX86InstIdRcr, X86GpReg, Imm)
+ //! \overload
+ INST_2i(rcr, kX86InstIdRcr, X86Mem, Imm)
+
+ //! Read time-stamp counter (Pentium).
+ INST_0x(rdtsc, kX86InstIdRdtsc)
+ //! Read time-stamp counter and processor id (Pentium).
+ INST_0x(rdtscp, kX86InstIdRdtscp)
+
+ //! Repeated load ECX/RCX BYTEs from DS:[ESI/RSI] to AL.
+ INST_0x(rep_lodsb, kX86InstIdRepLodsB)
+ //! Repeated load ECX/RCX DWORDs from DS:[ESI/RSI] to EAX.
+ INST_0x(rep_lodsd, kX86InstIdRepLodsD)
+ //! Repeated load ECX/RCX QWORDs from DS:[RDI] to RAX (X64 Only).
+ INST_0x(rep_lodsq, kX86InstIdRepLodsQ)
+ //! Repeated load ECX/RCX WORDs from DS:[ESI/RSI] to AX.
+ INST_0x(rep_lodsw, kX86InstIdRepLodsW)
+
+ //! Repeated move ECX/RCX BYTEs from DS:[ESI/RSI] to ES:[EDI/RDI].
+ INST_0x(rep_movsb, kX86InstIdRepMovsB)
+ //! Repeated move ECX/RCX DWORDs from DS:[ESI/RSI] to ES:[EDI/RDI].
+ INST_0x(rep_movsd, kX86InstIdRepMovsD)
+ //! Repeated move ECX/RCX QWORDs from DS:[RSI] to ES:[RDI] (X64 Only).
+ INST_0x(rep_movsq, kX86InstIdRepMovsQ)
+ //! Repeated move ECX/RCX WORDs from DS:[ESI/RSI] to ES:[EDI/RDI].
+ INST_0x(rep_movsw, kX86InstIdRepMovsW)
+
+ //! Repeated fill ECX/RCX BYTEs at ES:[EDI/RDI] with AL.
+ INST_0x(rep_stosb, kX86InstIdRepStosB)
+ //! Repeated fill ECX/RCX DWORDs at ES:[EDI/RDI] with EAX.
+ INST_0x(rep_stosd, kX86InstIdRepStosD)
+ //! Repeated fill ECX/RCX QWORDs at ES:[RDI] with RAX (X64 Only).
+ INST_0x(rep_stosq, kX86InstIdRepStosQ)
+ //! Repeated fill ECX/RCX WORDs at ES:[EDI/RDI] with AX.
+ INST_0x(rep_stosw, kX86InstIdRepStosW)
+
+ //! Repeated find non-AL BYTEs in ES:[EDI/RDI] and DS:[ESI/RSI].
+ INST_0x(repe_cmpsb, kX86InstIdRepeCmpsB)
+ //! Repeated find non-EAX DWORDs in ES:[EDI/RDI] and DS:[ESI/RSI].
+ INST_0x(repe_cmpsd, kX86InstIdRepeCmpsD)
+ //! Repeated find non-RAX QWORDs in ES:[RDI] and DS:[RDI] (X64 Only).
+ INST_0x(repe_cmpsq, kX86InstIdRepeCmpsQ)
+ //! Repeated find non-AX WORDs in ES:[EDI/RDI] and DS:[ESI/RSI].
+ INST_0x(repe_cmpsw, kX86InstIdRepeCmpsW)
+
+ //! Repeated find non-AL BYTE starting at ES:[EDI/RDI].
+ INST_0x(repe_scasb, kX86InstIdRepeScasB)
+ //! Repeated find non-EAX DWORD starting at ES:[EDI/RDI].
+ INST_0x(repe_scasd, kX86InstIdRepeScasD)
+ //! Repeated find non-RAX QWORD starting at ES:[RDI] (X64 Only).
+ INST_0x(repe_scasq, kX86InstIdRepeScasQ)
+ //! Repeated find non-AX WORD starting at ES:[EDI/RDI].
+ INST_0x(repe_scasw, kX86InstIdRepeScasW)
+
+ //! Repeated find AL BYTEs in ES:[EDI/RDI] and DS:[ESI/RSI].
+ INST_0x(repne_cmpsb, kX86InstIdRepneCmpsB)
+ //! Repeated find EAX DWORDs in ES:[EDI/RDI] and DS:[ESI/RSI].
+ INST_0x(repne_cmpsd, kX86InstIdRepneCmpsD)
+ //! Repeated find RAX QWORDs in ES:[RDI] and DS:[RDI] (X64 Only).
+ INST_0x(repne_cmpsq, kX86InstIdRepneCmpsQ)
+ //! Repeated find AX WORDs in ES:[EDI/RDI] and DS:[ESI/RSI].
+ INST_0x(repne_cmpsw, kX86InstIdRepneCmpsW)
+
+ //! Repeated find AL BYTEs starting at ES:[EDI/RDI].
+ INST_0x(repne_scasb, kX86InstIdRepneScasB)
+ //! Repeated find EAX DWORDs starting at ES:[EDI/RDI].
+ INST_0x(repne_scasd, kX86InstIdRepneScasD)
+ //! Repeated find RAX QWORDs starting at ES:[RDI] (X64 Only).
+ INST_0x(repne_scasq, kX86InstIdRepneScasQ)
+ //! Repeated find AX WORDs starting at ES:[EDI/RDI].
+ INST_0x(repne_scasw, kX86InstIdRepneScasW)
+
+ //! Return.
+ INST_0x(ret, kX86InstIdRet)
+ //! \overload
+ INST_1i(ret, kX86InstIdRet, Imm)
+
+ //! Rotate bits left.
//!
- //! EDX:EAX <- Sign Extend EAX
- void cdq()
- { _emitInstruction(kX86InstCdq); }
-
-#if defined(ASMJIT_X64)
- //! @brief Convert DWord to QWord (Sign Extend).
+ //! \note `o1` register can be only `cl`.
+ INST_2x(rol, kX86InstIdRol, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(rol, kX86InstIdRol, X86Mem, X86GpReg)
+ //! Rotate bits left.
+ INST_2i(rol, kX86InstIdRol, X86GpReg, Imm)
+ //! \overload
+ INST_2i(rol, kX86InstIdRol, X86Mem, Imm)
+
+ //! Rotate bits right.
//!
- //! RAX <- Sign Extend EAX
- void cdqe()
- { _emitInstruction(kX86InstCdqe); }
-#endif // ASMJIT_X64
-
- //! @brief Clear Carry flag
+ //! \note `o1` register can be only `cl`.
+ INST_2x(ror, kX86InstIdRor, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(ror, kX86InstIdRor, X86Mem, X86GpReg)
+ //! Rotate bits right.
+ INST_2i(ror, kX86InstIdRor, X86GpReg, Imm)
+ //! \overload
+ INST_2i(ror, kX86InstIdRor, X86Mem, Imm)
+
+ //! Store AH into flags.
+ INST_0x(sahf, kX86InstIdSahf)
+
+ //! Integer subtraction with borrow.
+ INST_2x(sbb, kX86InstIdSbb, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(sbb, kX86InstIdSbb, X86GpReg, X86Mem)
+ //! \overload
+ INST_2i(sbb, kX86InstIdSbb, X86GpReg, Imm)
+ //! \overload
+ INST_2x(sbb, kX86InstIdSbb, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(sbb, kX86InstIdSbb, X86Mem, Imm)
+
+ //! Shift bits left.
//!
- //! This instruction clears the CF flag in the EFLAGS register.
- void clc()
- { _emitInstruction(kX86InstClc); }
-
- //! @brief Clear Direction flag
+ //! \note `o1` register can be only `cl`.
+ INST_2x(sal, kX86InstIdSal, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(sal, kX86InstIdSal, X86Mem, X86GpReg)
+ //! Shift bits left.
+ INST_2i(sal, kX86InstIdSal, X86GpReg, Imm)
+ //! \overload
+ INST_2i(sal, kX86InstIdSal, X86Mem, Imm)
+
+ //! Shift bits right.
//!
- //! This instruction clears the DF flag in the EFLAGS register.
- void cld()
- { _emitInstruction(kX86InstCld); }
-
- //! @brief Complement Carry Flag.
+ //! \note `o1` register can be only `cl`.
+ INST_2x(sar, kX86InstIdSar, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(sar, kX86InstIdSar, X86Mem, X86GpReg)
+ //! Shift bits right.
+ INST_2i(sar, kX86InstIdSar, X86GpReg, Imm)
+ //! \overload
+ INST_2i(sar, kX86InstIdSar, X86Mem, Imm)
+
+ //! Find non-AL BYTE starting at ES:[EDI/RDI].
+ INST_0x(scasb, kX86InstIdScasB)
+ //! Find non-EAX DWORD starting at ES:[EDI/RDI].
+ INST_0x(scasd, kX86InstIdScasD)
+ //! Find non-rax QWORD starting at ES:[RDI] (X64 Only).
+ INST_0x(scasq, kX86InstIdScasQ)
+ //! Find non-AX WORD starting at ES:[EDI/RDI].
+ INST_0x(scasw, kX86InstIdScasW)
+
+ //! Set byte on condition.
+ INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86GpReg)
+ //! Set byte on condition.
+ INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86Mem)
+
+ //! Shift bits left.
//!
- //! This instruction complements the CF flag in the EFLAGS register.
- //! (CF = NOT CF)
- void cmc()
- { _emitInstruction(kX86InstCmc); }
-
- //! @brief Conditional Move.
- void cmov(kX86Cond cc, const GpReg& dst, const GpReg& src)
- { _emitInstruction(X86Util::getCMovccInstFromCond(cc), &dst, &src); }
-
- //! @brief Conditional Move.
- void cmov(kX86Cond cc, const GpReg& dst, const Mem& src)
- { _emitInstruction(X86Util::getCMovccInstFromCond(cc), &dst, &src); }
-
- //! @brief Conditional Move.
- void cmova (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovA , &dst, &src); }
- //! @brief Conditional Move.
- void cmova (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovA , &dst, &src); }
- //! @brief Conditional Move.
- void cmovae (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovAE , &dst, &src); }
- //! @brief Conditional Move.
- void cmovae (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovAE , &dst, &src); }
- //! @brief Conditional Move.
- void cmovb (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovB , &dst, &src); }
- //! @brief Conditional Move.
- void cmovb (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovB , &dst, &src); }
- //! @brief Conditional Move.
- void cmovbe (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovBE , &dst, &src); }
- //! @brief Conditional Move.
- void cmovbe (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovBE , &dst, &src); }
- //! @brief Conditional Move.
- void cmovc (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovC , &dst, &src); }
- //! @brief Conditional Move.
- void cmovc (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovC , &dst, &src); }
- //! @brief Conditional Move.
- void cmove (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovE , &dst, &src); }
- //! @brief Conditional Move.
- void cmove (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovE , &dst, &src); }
- //! @brief Conditional Move.
- void cmovg (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovG , &dst, &src); }
- //! @brief Conditional Move.
- void cmovg (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovG , &dst, &src); }
- //! @brief Conditional Move.
- void cmovge (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovGE , &dst, &src); }
- //! @brief Conditional Move.
- void cmovge (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovGE , &dst, &src); }
- //! @brief Conditional Move.
- void cmovl (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovL , &dst, &src); }
- //! @brief Conditional Move.
- void cmovl (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovL , &dst, &src); }
- //! @brief Conditional Move.
- void cmovle (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovLE , &dst, &src); }
- //! @brief Conditional Move.
- void cmovle (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovLE , &dst, &src); }
- //! @brief Conditional Move.
- void cmovna (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNA , &dst, &src); }
- //! @brief Conditional Move.
- void cmovna (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNA , &dst, &src); }
- //! @brief Conditional Move.
- void cmovnae(const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNAE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnae(const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNAE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnb (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNB , &dst, &src); }
- //! @brief Conditional Move.
- void cmovnb (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNB , &dst, &src); }
- //! @brief Conditional Move.
- void cmovnbe(const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNBE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnbe(const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNBE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnc (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNC , &dst, &src); }
- //! @brief Conditional Move.
- void cmovnc (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNC , &dst, &src); }
- //! @brief Conditional Move.
- void cmovne (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNE , &dst, &src); }
- //! @brief Conditional Move.
- void cmovne (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNE , &dst, &src); }
- //! @brief Conditional Move.
- void cmovng (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNG , &dst, &src); }
- //! @brief Conditional Move.
- void cmovng (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNG , &dst, &src); }
- //! @brief Conditional Move.
- void cmovnge(const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNGE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnge(const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNGE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnl (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNL , &dst, &src); }
- //! @brief Conditional Move.
- void cmovnl (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNL , &dst, &src); }
- //! @brief Conditional Move.
- void cmovnle(const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNLE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnle(const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNLE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovno (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNO , &dst, &src); }
- //! @brief Conditional Move.
- void cmovno (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNO , &dst, &src); }
- //! @brief Conditional Move.
- void cmovnp (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNP , &dst, &src); }
- //! @brief Conditional Move.
- void cmovnp (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNP , &dst, &src); }
- //! @brief Conditional Move.
- void cmovns (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNS , &dst, &src); }
- //! @brief Conditional Move.
- void cmovns (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNS , &dst, &src); }
- //! @brief Conditional Move.
- void cmovnz (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovNZ , &dst, &src); }
- //! @brief Conditional Move.
- void cmovnz (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovNZ , &dst, &src); }
- //! @brief Conditional Move.
- void cmovo (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovO , &dst, &src); }
- //! @brief Conditional Move.
- void cmovo (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovO , &dst, &src); }
- //! @brief Conditional Move.
- void cmovp (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovP , &dst, &src); }
- //! @brief Conditional Move.
- void cmovp (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovP , &dst, &src); }
- //! @brief Conditional Move.
- void cmovpe (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovPE , &dst, &src); }
- //! @brief Conditional Move.
- void cmovpe (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovPE , &dst, &src); }
- //! @brief Conditional Move.
- void cmovpo (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovPO , &dst, &src); }
- //! @brief Conditional Move.
- void cmovpo (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovPO , &dst, &src); }
- //! @brief Conditional Move.
- void cmovs (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovS , &dst, &src); }
- //! @brief Conditional Move.
- void cmovs (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovS , &dst, &src); }
- //! @brief Conditional Move.
- void cmovz (const GpReg& dst, const GpReg& src) { _emitInstruction(kX86InstCMovZ , &dst, &src); }
- //! @brief Conditional Move.
- void cmovz (const GpReg& dst, const Mem& src) { _emitInstruction(kX86InstCMovZ , &dst, &src); }
-
- //! @brief Compare Two Operands.
- void cmp(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstCmp, &dst, &src); }
- //! @brief Compare Two Operands.
- void cmp(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCmp, &dst, &src); }
- //! @brief Compare Two Operands.
- void cmp(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstCmp, &dst, &src); }
- //! @brief Compare Two Operands.
- void cmp(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstCmp, &dst, &src); }
- //! @brief Compare Two Operands.
- void cmp(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstCmp, &dst, &src); }
-
- //! @brief Compare and Exchange (i486).
- void cmpxchg(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstCmpXCHG, &dst, &src); }
- //! @brief Compare and Exchange (i486).
- void cmpxchg(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstCmpXCHG, &dst, &src); }
-
- //! @brief Compares the 64-bit value in EDX:EAX with the memory operand (Pentium).
+ //! \note `o1` register can be only `cl`.
+ INST_2x(shl, kX86InstIdShl, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(shl, kX86InstIdShl, X86Mem, X86GpReg)
+ //! Shift bits left.
+ INST_2i(shl, kX86InstIdShl, X86GpReg, Imm)
+ //! \overload
+ INST_2i(shl, kX86InstIdShl, X86Mem, Imm)
+
+ //! Shift bits right.
//!
- //! 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.
- void cmpxchg8b(const Mem& dst)
- { _emitInstruction(kX86InstCmpXCHG8B, &dst); }
-
-#if defined(ASMJIT_X64)
- //! @brief Compares the 128-bit value in RDX:RAX with the memory operand (X64).
+ //! \note `o1` register can be only `cl`.
+ INST_2x(shr, kX86InstIdShr, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(shr, kX86InstIdShr, X86Mem, X86GpReg)
+ //! Shift bits right.
+ INST_2i(shr, kX86InstIdShr, X86GpReg, Imm)
+ //! \overload
+ INST_2i(shr, kX86InstIdShr, X86Mem, Imm)
+
+ //! Double precision shift left.
//!
- //! 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.
- void cmpxchg16b(const Mem& dst)
- { _emitInstruction(kX86InstCmpXCHG16B, &dst); }
-#endif // ASMJIT_X64
-
- //! @brief CPU Identification (i486).
- void cpuid()
- { _emitInstruction(kX86InstCpuId); }
-
-#if defined(ASMJIT_X64)
- //! @brief Convert QWord to DQWord (Sign Extend).
+ //! \note `o2` register can be only `cl` register.
+ INST_3x(shld, kX86InstIdShld, X86GpReg, X86GpReg, X86GpReg)
+ //! \overload
+ INST_3x(shld, kX86InstIdShld, X86Mem, X86GpReg, X86GpReg)
+ //! Double precision shift left.
+ INST_3i(shld, kX86InstIdShld, X86GpReg, X86GpReg, Imm)
+ //! \overload
+ INST_3i(shld, kX86InstIdShld, X86Mem, X86GpReg, Imm)
+
+ //! Double precision shift right.
//!
- //! RDX:RAX <- Sign Extend RAX
- void cqo()
- { _emitInstruction(kX86InstCqo); }
-#endif // ASMJIT_X64
-
-#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.
- void daa()
- { _emitInstruction(kX86InstDaa); }
-#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.
- void das()
- { _emitInstruction(kX86InstDas); }
-#endif // ASMJIT_X86
-
- //! @brief Decrement by 1.
- //! @note This instruction can be slower than sub(dst, 1)
- void dec(const GpReg& dst)
- { _emitInstruction(kX86InstDec, &dst); }
- //! @brief Decrement by 1.
- //! @note This instruction can be slower than sub(dst, 1)
- void dec(const Mem& dst)
- { _emitInstruction(kX86InstDec, &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.
- void div(const GpReg& src)
- { _emitInstruction(kX86InstDiv, &src); }
- //! @brief Unsigned divide.
- //! @overload
- void div(const Mem& src)
- { _emitInstruction(kX86InstDiv, &src); }
-
- //! @brief Make Stack Frame for Procedure Parameters.
- void enter(const Imm& imm16, const Imm& imm8)
- { _emitInstruction(kX86InstEnter, &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.
- void idiv(const GpReg& src)
- { _emitInstruction(kX86InstIDiv, &src); }
- //! @brief Signed divide.
- //! @overload
- void idiv(const Mem& src)
- { _emitInstruction(kX86InstIDiv, &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.
- void imul(const GpReg& src)
- { _emitInstruction(kX86InstIMul, &src); }
- //! @overload
- void imul(const Mem& src)
- { _emitInstruction(kX86InstIMul, &src); }
-
- //! @brief Signed multiply.
- //!
- //! Destination operand (the first operand) is multiplied by the source
- //! operand (second operand). The destination operand is a general-purpose
- //! 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.
- void imul(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstIMul, &dst, &src); }
- //! @brief Signed multiply.
- //! @overload
- void imul(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstIMul, &dst, &src); }
- //! @brief Signed multiply.
- //! @overload
- void imul(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstIMul, &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).
- void imul(const GpReg& dst, const GpReg& src, const Imm& imm)
- { _emitInstruction(kX86InstIMul, &dst, &src, &imm); }
- //! @overload
- void imul(const GpReg& dst, const Mem& src, const Imm& imm)
- { _emitInstruction(kX86InstIMul, &dst, &src, &imm); }
-
- //! @brief Increment by 1.
- //! @note This instruction can be slower than add(dst, 1)
- void inc(const GpReg& dst)
- { _emitInstruction(kX86InstInc, &dst); }
- //! @brief Increment by 1.
- //! @note This instruction can be slower than add(dst, 1)
- void inc(const Mem& dst)
- { _emitInstruction(kX86InstInc, &dst); }
-
- //! @brief Interrupt 3 - trap to debugger.
- void int3()
- { _emitInstruction(kX86InstInt3); }
-
- //! @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.
- void j(kX86Cond cc, const Label& label, uint32_t hint = kCondHintNone)
- {
- _emitJcc(X86Util::getJccInstFromCond(cc), &label, hint);
- }
-
- //! @brief Jump to label @a label if condition is met.
- void ja (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJA , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jae (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJAE , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jb (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJB , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jbe (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJBE , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jc (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJC , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void je (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJE , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jg (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJG , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jge (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJGE , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jl (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJL , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jle (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJLE , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jna (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNA , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnae(const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNAE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnb (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNB , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnbe(const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNBE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnc (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNC , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jne (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNE , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jng (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNG , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnge(const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNGE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnl (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNL , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnle(const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNLE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jno (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNO , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnp (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNP , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jns (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNS , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnz (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJNZ , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jo (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJO , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jp (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJP , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jpe (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJPE , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jpo (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJPO , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void js (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJS , &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jz (const Label& label, uint32_t hint = kCondHintNone) { _emitJcc(kX86InstJZ , &label, hint); }
-
- //! @brief Short jump to label @a label if condition @a cc is met.
- //! @sa j()
- void short_j(kX86Cond cc, const Label& label, uint32_t hint = kCondHintNone)
- {
- _emitOptions |= kX86EmitOptionShortJump;
- j(cc, label, hint);
- }
-
- //! @brief Short jump to label @a label if condition is met.
- void short_ja (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJA , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jae (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJAE , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jb (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJB , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jbe (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJBE , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jc (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJC , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_je (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJE , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jg (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJG , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jge (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJGE , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jl (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJL , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jle (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJLE , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jna (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNA , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jnae(const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNAE, &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jnb (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNB , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jnbe(const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNBE, &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jnc (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNC , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jne (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNE , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jng (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNG , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jnge(const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNGE, &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jnl (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNL , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jnle(const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNLE, &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jno (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNO , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jnp (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNP , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jns (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNS , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jnz (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJNZ , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jo (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJO , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jp (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJP , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jpe (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJPE , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jpo (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJPO , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_js (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJS , &label, hint); }
- //! @brief Short jump to label @a label if condition is met.
- void short_jz (const Label& label, uint32_t hint = kCondHintNone) { _emitShortJcc(kX86InstJZ , &label, hint); }
-
- //! @brief Jump.
- //! @overload
- void jmp(const GpReg& dst)
- { _emitInstruction(kX86InstJmp, &dst); }
- //! @brief Jump.
- //! @overload
- void jmp(const Mem& dst)
- { _emitInstruction(kX86InstJmp, &dst); }
- //! @brief Jump.
- //! @overload
- void jmp(const Imm& dst)
- { _emitInstruction(kX86InstJmp, &dst); }
-
- //! @brief Jump.
- //! @overload
- void jmp(void* dst)
- {
- Imm imm((sysint_t)dst);
- _emitInstruction(kX86InstJmp, &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.
- void jmp(const Label& label)
- { _emitInstruction(kX86InstJmp, &label); }
-
- //! @brief Short jump.
- //! @sa jmp()
- void short_jmp(const Label& label)
- {
- _emitOptions |= kX86EmitOptionShortJump;
- _emitInstruction(kX86InstJmp, &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.
- void lea(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstLea, &dst, &src); }
-
- //! @brief High Level Procedure Exit.
- void leave()
- { _emitInstruction(kX86InstLeave); }
-
- //! @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.
- void mov(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstMov, &dst, &src); }
- //! @brief Move.
- //! @overload
- void mov(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMov, &dst, &src); }
- //! @brief Move.
- //! @overload
- void mov(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstMov, &dst, &src); }
- //! @brief Move.
- //! @overload
- void mov(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstMov, &dst, &src); }
- //! @brief Move.
- //! @overload
- void mov(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move from segment register.
- //! @overload.
- void mov(const GpReg& dst, const SegmentReg& src)
- { _emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move from segment register.
- //! @overload.
- void mov(const Mem& dst, const SegmentReg& src)
- { _emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move to segment register.
- //! @overload.
- void mov(const SegmentReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move to segment register.
- //! @overload.
- void mov(const SegmentReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move byte, word, dword or qword from absolute address @a src to
- //! AL, AX, EAX or RAX register.
- void mov_ptr(const GpReg& dst, void* src)
- {
- ASMJIT_ASSERT(!dst.getRegIndex());
- Imm imm((sysint_t)src);
- _emitInstruction(kX86InstMovPtr, &dst, &imm);
- }
-
- //! @brief Move byte, word, dword or qword from AL, AX, EAX or RAX register
- //! to absolute address @a dst.
- void mov_ptr(void* dst, const GpReg& src)
- {
- ASMJIT_ASSERT(!src.getRegIndex());
- Imm imm((sysint_t)dst);
- _emitInstruction(kX86InstMovPtr, &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 GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstMovSX, &dst, &src); }
- //! @brief Move with Sign-Extension.
- //! @overload
- void movsx(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovSX, &dst, &src); }
-
-#if defined(ASMJIT_X64)
- //! @brief Move DWord to QWord with sign-extension.
- void movsxd(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstMovSXD, &dst, &src); }
- //! @brief Move DWord to QWord with sign-extension.
- //! @overload
- void movsxd(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovSXD, &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.
- void movzx(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstMovZX, &dst, &src); }
- //! @brief Move with Zero-Extend.
- //! @brief Overload
- void movzx(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovZX, &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.
- void mul(const GpReg& src)
- { _emitInstruction(kX86InstMul, &src); }
- //! @brief Unsigned multiply.
- //! @overload
- void mul(const Mem& src)
- { _emitInstruction(kX86InstMul, &src); }
-
- //! @brief Two's Complement Negation.
- void neg(const GpReg& dst)
- { _emitInstruction(kX86InstNeg, &dst); }
- //! @brief Two's Complement Negation.
- void neg(const Mem& dst)
- { _emitInstruction(kX86InstNeg, &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.
- void nop()
- { _emitInstruction(kX86InstNop); }
-
- //! @brief One's Complement Negation.
- void not_(const GpReg& dst)
- { _emitInstruction(kX86InstNot, &dst); }
- //! @brief One's Complement Negation.
- void not_(const Mem& dst)
- { _emitInstruction(kX86InstNot, &dst); }
-
- //! @brief Logical Inclusive OR.
- void or_(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstOr, &dst, &src); }
- //! @brief Logical Inclusive OR.
- void or_(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstOr, &dst, &src); }
- //! @brief Logical Inclusive OR.
- void or_(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstOr, &dst, &src); }
- //! @brief Logical Inclusive OR.
- void or_(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstOr, &dst, &src); }
- //! @brief Logical Inclusive OR.
- void or_(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstOr, &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.
- void pop(const GpReg& dst)
- {
- ASMJIT_ASSERT(dst.isRegType(kX86RegTypeGpw) || dst.isRegType(kX86RegTypeGpz));
- _emitInstruction(kX86InstPop, &dst);
- }
- //! @brief Pop a Segment Register from the Stack.
- //!
- //! @note There is no instruction to pop a cs segment register.
- void pop(const SegmentReg& dst)
- {
- ASMJIT_ASSERT(dst.getRegIndex() != kX86SegCs);
- _emitInstruction(kX86InstPop, &dst);
- }
-
- void pop(const Mem& dst)
- {
- ASMJIT_ASSERT(dst.getSize() == 2 || dst.getSize() == sizeof(sysint_t));
- _emitInstruction(kX86InstPop, &dst);
- }
-
-#if defined(ASMJIT_X86)
- //! @brief Pop All General-Purpose Registers.
- //!
- //! Pop EDI, ESI, EBP, EBX, EDX, ECX, and EAX.
- void popad()
- { _emitInstruction(kX86InstPopAD); }
-#endif // ASMJIT_X86
-
- //! @brief Pop Stack into EFLAGS Register (32-bit or 64-bit).
- void popf()
- {
-#if defined(ASMJIT_X86)
- popfd();
-#else
- popfq();
-#endif
- }
-
-#if defined(ASMJIT_X86)
- //! @brief Pop Stack into EFLAGS Register (32-bit).
- void popfd() { _emitInstruction(kX86InstPopFD); }
-#else
- //! @brief Pop Stack into EFLAGS Register (64-bit).
- void popfq() { _emitInstruction(kX86InstPopFQ); }
-#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.
- void push(const GpReg& src)
- {
- ASMJIT_ASSERT(src.isRegType(kX86RegTypeGpw) || src.isRegType(kX86RegTypeGpz));
- _emitInstruction(kX86InstPush, &src);
- }
- //! @brief Push Segment Register Onto the Stack.
- void push(const SegmentReg& src)
- { _emitInstruction(kX86InstPush, &src); }
- //! @brief Push WORD/DWORD/QWORD Onto the Stack.
- void push(const Mem& src)
- {
- ASMJIT_ASSERT(src.getSize() == 2 || src.getSize() == sizeof(sysint_t));
- _emitInstruction(kX86InstPush, &src);
- }
- //! @brief Push WORD/DWORD/QWORD Onto the Stack.
- void push(const Imm& src)
- { _emitInstruction(kX86InstPush, &src); }
-
-#if defined(ASMJIT_X86)
- //! @brief Push All General-Purpose Registers.
- //!
- //! Push EAX, ECX, EDX, EBX, original ESP, EBP, ESI, and EDI.
- void pushad()
- { _emitInstruction(kX86InstPushAD); }
-#endif // ASMJIT_X86
-
- //! @brief Push EFLAGS Register (32-bit or 64-bit) onto the Stack.
- void pushf()
- {
-#if defined(ASMJIT_X86)
- pushfd();
-#else
- pushfq();
-#endif
- }
-
-#if defined(ASMJIT_X86)
- //! @brief Push EFLAGS Register (32-bit) onto the Stack.
- void pushfd() { _emitInstruction(kX86InstPushFD); }
-#else
- //! @brief Push EFLAGS Register (64-bit) onto the Stack.
- void pushfq() { _emitInstruction(kX86InstPushFQ); }
-#endif // ASMJIT_X86
-
- //! @brief Rotate Bits Left.
- //! @note @a src register can be only @c cl.
- void rcl(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstRcl, &dst, &src); }
- //! @brief Rotate Bits Left.
- void rcl(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstRcl, &dst, &src); }
- //! @brief Rotate Bits Left.
- //! @note @a src register can be only @c cl.
- void rcl(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstRcl, &dst, &src); }
- //! @brief Rotate Bits Left.
- void rcl(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstRcl, &dst, &src); }
-
- //! @brief Rotate Bits Right.
- //! @note @a src register can be only @c cl.
- void rcr(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstRcr, &dst, &src); }
- //! @brief Rotate Bits Right.
- void rcr(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstRcr, &dst, &src); }
- //! @brief Rotate Bits Right.
- //! @note @a src register can be only @c cl.
- void rcr(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstRcr, &dst, &src); }
- //! @brief Rotate Bits Right.
- void rcr(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstRcr, &dst, &src); }
-
- //! @brief Read Time-Stamp Counter (Pentium).
- void rdtsc()
- { _emitInstruction(kX86InstRdtsc); }
-
- //! @brief Read Time-Stamp Counter and Processor ID (New).
- void rdtscp()
- { _emitInstruction(kX86InstRdtscP); }
-
- //! @brief Load ECX/RCX BYTEs from DS:[ESI/RSI] to AL.
- void rep_lodsb()
- { _emitInstruction(kX86InstRepLodSB); }
-
- //! @brief Load ECX/RCX DWORDs from DS:[ESI/RSI] to EAX.
- void rep_lodsd()
- { _emitInstruction(kX86InstRepLodSD); }
-
-#if defined(ASMJIT_X64)
- //! @brief Load ECX/RCX QWORDs from DS:[ESI/RSI] to RAX.
- void rep_lodsq()
- { _emitInstruction(kX86InstRepLodSQ); }
-#endif // ASMJIT_X64
-
- //! @brief Load ECX/RCX WORDs from DS:[ESI/RSI] to AX.
- void rep_lodsw()
- { _emitInstruction(kX86InstRepLodSW); }
-
- //! @brief Move ECX/RCX BYTEs from DS:[ESI/RSI] to ES:[EDI/RDI].
- void rep_movsb()
- { _emitInstruction(kX86InstRepMovSB); }
-
- //! @brief Move ECX/RCX DWORDs from DS:[ESI/RSI] to ES:[EDI/RDI].
- void rep_movsd()
- { _emitInstruction(kX86InstRepMovSD); }
-
-#if defined(ASMJIT_X64)
- //! @brief Move ECX/RCX QWORDs from DS:[ESI/RSI] to ES:[EDI/RDI].
- void rep_movsq()
- { _emitInstruction(kX86InstRepMovSQ); }
-#endif // ASMJIT_X64
-
- //! @brief Move ECX/RCX WORDs from DS:[ESI/RSI] to ES:[EDI/RDI].
- void rep_movsw()
- { _emitInstruction(kX86InstRepMovSW); }
-
- //! @brief Fill ECX/RCX BYTEs at ES:[EDI/RDI] with AL.
- void rep_stosb()
- { _emitInstruction(kX86InstRepStoSB); }
-
- //! @brief Fill ECX/RCX DWORDs at ES:[EDI/RDI] with EAX.
- void rep_stosd()
- { _emitInstruction(kX86InstRepStoSD); }
-
-#if defined(ASMJIT_X64)
- //! @brief Fill ECX/RCX QWORDs at ES:[EDI/RDI] with RAX.
- void rep_stosq()
- { _emitInstruction(kX86InstRepStoSQ); }
-#endif // ASMJIT_X64
-
- //! @brief Fill ECX/RCX WORDs at ES:[EDI/RDI] with AX.
- void rep_stosw()
- { _emitInstruction(kX86InstRepStoSW); }
-
- //! @brief Repeated find nonmatching BYTEs in ES:[EDI/RDI] and DS:[ESI/RDI].
- void repe_cmpsb()
- { _emitInstruction(kX86InstRepECmpSB); }
-
- //! @brief Repeated find nonmatching DWORDs in ES:[EDI/RDI] and DS:[ESI/RDI].
- void repe_cmpsd()
- { _emitInstruction(kX86InstRepECmpSD); }
-
-#if defined(ASMJIT_X64)
- //! @brief Repeated find nonmatching QWORDs in ES:[EDI/RDI] and DS:[ESI/RDI].
- void repe_cmpsq()
- { _emitInstruction(kX86InstRepECmpSQ); }
-#endif // ASMJIT_X64
-
- //! @brief Repeated find nonmatching WORDs in ES:[EDI/RDI] and DS:[ESI/RDI].
- void repe_cmpsw()
- { _emitInstruction(kX86InstRepECmpSW); }
-
- //! @brief Find non-AL BYTE starting at ES:[EDI/RDI].
- void repe_scasb()
- { _emitInstruction(kX86InstRepEScaSB); }
-
- //! @brief Find non-EAX DWORD starting at ES:[EDI/RDI].
- void repe_scasd()
- { _emitInstruction(kX86InstRepEScaSD); }
-
-#if defined(ASMJIT_X64)
- //! @brief Find non-RAX QWORD starting at ES:[EDI/RDI].
- void repe_scasq()
- { _emitInstruction(kX86InstRepEScaSQ); }
-#endif // ASMJIT_X64
-
- //! @brief Find non-AX WORD starting at ES:[EDI/RDI].
- void repe_scasw()
- { _emitInstruction(kX86InstRepEScaSW); }
-
- //! @brief Repeated find nonmatching BYTEs in ES:[EDI/RDI] and DS:[ESI/RDI].
- void repne_cmpsb()
- { _emitInstruction(kX86InstRepNECmpSB); }
-
- //! @brief Repeated find nonmatching DWORDs in ES:[EDI/RDI] and DS:[ESI/RDI].
- void repne_cmpsd()
- { _emitInstruction(kX86InstRepNECmpSD); }
-
-#if defined(ASMJIT_X64)
- //! @brief Repeated find nonmatching QWORDs in ES:[EDI/RDI] and DS:[ESI/RDI].
- void repne_cmpsq()
- { _emitInstruction(kX86InstRepNECmpSQ); }
-#endif // ASMJIT_X64
-
- //! @brief Repeated find nonmatching WORDs in ES:[EDI/RDI] and DS:[ESI/RDI].
- void repne_cmpsw()
- { _emitInstruction(kX86InstRepNECmpSW); }
-
- //! @brief Find AL, starting at ES:[EDI/RDI].
- void repne_scasb()
- { _emitInstruction(kX86InstRepNEScaSB); }
-
- //! @brief Find EAX, starting at ES:[EDI/RDI].
- void repne_scasd()
- { _emitInstruction(kX86InstRepNEScaSD); }
-
-#if defined(ASMJIT_X64)
- //! @brief Find RAX, starting at ES:[EDI/RDI].
- void repne_scasq()
- { _emitInstruction(kX86InstRepNEScaSQ); }
-#endif // ASMJIT_X64
-
- //! @brief Find AX, starting at ES:[EDI/RDI].
- void repne_scasw()
- { _emitInstruction(kX86InstRepNEScaSW); }
-
- //! @brief Return from Procedure.
- void ret()
- { _emitInstruction(kX86InstRet); }
-
- //! @brief Return from Procedure.
- void ret(const Imm& imm16)
- { _emitInstruction(kX86InstRet, &imm16); }
-
- //! @brief Rotate Bits Left.
- //! @note @a src register can be only @c cl.
- void rol(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstRol, &dst, &src); }
- //! @brief Rotate Bits Left.
- void rol(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstRol, &dst, &src); }
- //! @brief Rotate Bits Left.
- //! @note @a src register can be only @c cl.
- void rol(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstRol, &dst, &src); }
- //! @brief Rotate Bits Left.
- void rol(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstRol, &dst, &src); }
-
- //! @brief Rotate Bits Right.
- //! @note @a src register can be only @c cl.
- void ror(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstRor, &dst, &src); }
- //! @brief Rotate Bits Right.
- void ror(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstRor, &dst, &src); }
- //! @brief Rotate Bits Right.
- //! @note @a src register can be only @c cl.
- void ror(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstRor, &dst, &src); }
- //! @brief Rotate Bits Right.
- void ror(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstRor, &dst, &src); }
-
-#if defined(ASMJIT_X86)
- //! @brief Store AH into Flags.
- void sahf()
- { _emitInstruction(kX86InstSahf); }
-#endif // ASMJIT_X86
-
- //! @brief Integer subtraction with borrow.
- void sbb(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstSbb, &dst, &src); }
- //! @brief Integer subtraction with borrow.
- void sbb(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstSbb, &dst, &src); }
- //! @brief Integer subtraction with borrow.
- void sbb(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstSbb, &dst, &src); }
- //! @brief Integer subtraction with borrow.
- void sbb(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstSbb, &dst, &src); }
- //! @brief Integer subtraction with borrow.
- void sbb(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstSbb, &dst, &src); }
-
- //! @brief Shift Bits Left.
- //! @note @a src register can be only @c cl.
- void sal(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstSal, &dst, &src); }
- //! @brief Shift Bits Left.
- void sal(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstSal, &dst, &src); }
- //! @brief Shift Bits Left.
- //! @note @a src register can be only @c cl.
- void sal(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstSal, &dst, &src); }
- //! @brief Shift Bits Left.
- void sal(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstSal, &dst, &src); }
-
- //! @brief Shift Bits Right.
- //! @note @a src register can be only @c cl.
- void sar(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstSar, &dst, &src); }
- //! @brief Shift Bits Right.
- void sar(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstSar, &dst, &src); }
- //! @brief Shift Bits Right.
- //! @note @a src register can be only @c cl.
- void sar(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstSar, &dst, &src); }
- //! @brief Shift Bits Right.
- void sar(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstSar, &dst, &src); }
-
- //! @brief Set Byte on Condition.
- void set(kX86Cond cc, const GpReg& dst)
- {
- ASMJIT_ASSERT(dst.getSize() == 1);
- _emitInstruction(X86Util::getSetccInstFromCond(cc), &dst);
- }
-
- //! @brief Set Byte on Condition.
- void set(kX86Cond cc, const Mem& dst)
- {
- ASMJIT_ASSERT(dst.getSize() <= 1);
- _emitInstruction(X86Util::getSetccInstFromCond(cc), &dst);
- }
-
- //! @brief Set Byte on Condition.
- void seta (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetA , &dst); }
- //! @brief Set Byte on Condition.
- void seta (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetA , &dst); }
- //! @brief Set Byte on Condition.
- void setae (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetAE , &dst); }
- //! @brief Set Byte on Condition.
- void setae (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetAE , &dst); }
- //! @brief Set Byte on Condition.
- void setb (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetB , &dst); }
- //! @brief Set Byte on Condition.
- void setb (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetB , &dst); }
- //! @brief Set Byte on Condition.
- void setbe (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetBE , &dst); }
- //! @brief Set Byte on Condition.
- void setbe (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetBE , &dst); }
- //! @brief Set Byte on Condition.
- void setc (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetC , &dst); }
- //! @brief Set Byte on Condition.
- void setc (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetC , &dst); }
- //! @brief Set Byte on Condition.
- void sete (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetE , &dst); }
- //! @brief Set Byte on Condition.
- void sete (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetE , &dst); }
- //! @brief Set Byte on Condition.
- void setg (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetG , &dst); }
- //! @brief Set Byte on Condition.
- void setg (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetG , &dst); }
- //! @brief Set Byte on Condition.
- void setge (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetGE , &dst); }
- //! @brief Set Byte on Condition.
- void setge (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetGE , &dst); }
- //! @brief Set Byte on Condition.
- void setl (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetL , &dst); }
- //! @brief Set Byte on Condition.
- void setl (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetL , &dst); }
- //! @brief Set Byte on Condition.
- void setle (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetLE , &dst); }
- //! @brief Set Byte on Condition.
- void setle (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetLE , &dst); }
- //! @brief Set Byte on Condition.
- void setna (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNA , &dst); }
- //! @brief Set Byte on Condition.
- void setna (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNA , &dst); }
- //! @brief Set Byte on Condition.
- void setnae(const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNAE, &dst); }
- //! @brief Set Byte on Condition.
- void setnae(const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNAE, &dst); }
- //! @brief Set Byte on Condition.
- void setnb (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNB , &dst); }
- //! @brief Set Byte on Condition.
- void setnb (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNB , &dst); }
- //! @brief Set Byte on Condition.
- void setnbe(const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNBE, &dst); }
- //! @brief Set Byte on Condition.
- void setnbe(const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNBE, &dst); }
- //! @brief Set Byte on Condition.
- void setnc (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNC , &dst); }
- //! @brief Set Byte on Condition.
- void setnc (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNC , &dst); }
- //! @brief Set Byte on Condition.
- void setne (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNE , &dst); }
- //! @brief Set Byte on Condition.
- void setne (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNE , &dst); }
- //! @brief Set Byte on Condition.
- void setng (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNG , &dst); }
- //! @brief Set Byte on Condition.
- void setng (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNG , &dst); }
- //! @brief Set Byte on Condition.
- void setnge(const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNGE, &dst); }
- //! @brief Set Byte on Condition.
- void setnge(const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNGE, &dst); }
- //! @brief Set Byte on Condition.
- void setnl (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNL , &dst); }
- //! @brief Set Byte on Condition.
- void setnl (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNL , &dst); }
- //! @brief Set Byte on Condition.
- void setnle(const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNLE, &dst); }
- //! @brief Set Byte on Condition.
- void setnle(const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNLE, &dst); }
- //! @brief Set Byte on Condition.
- void setno (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNO , &dst); }
- //! @brief Set Byte on Condition.
- void setno (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNO , &dst); }
- //! @brief Set Byte on Condition.
- void setnp (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNP , &dst); }
- //! @brief Set Byte on Condition.
- void setnp (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNP , &dst); }
- //! @brief Set Byte on Condition.
- void setns (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNS , &dst); }
- //! @brief Set Byte on Condition.
- void setns (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNS , &dst); }
- //! @brief Set Byte on Condition.
- void setnz (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetNZ , &dst); }
- //! @brief Set Byte on Condition.
- void setnz (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetNZ , &dst); }
- //! @brief Set Byte on Condition.
- void seto (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetO , &dst); }
- //! @brief Set Byte on Condition.
- void seto (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetO , &dst); }
- //! @brief Set Byte on Condition.
- void setp (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetP , &dst); }
- //! @brief Set Byte on Condition.
- void setp (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetP , &dst); }
- //! @brief Set Byte on Condition.
- void setpe (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetPE , &dst); }
- //! @brief Set Byte on Condition.
- void setpe (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetPE , &dst); }
- //! @brief Set Byte on Condition.
- void setpo (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetPO , &dst); }
- //! @brief Set Byte on Condition.
- void setpo (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetPO , &dst); }
- //! @brief Set Byte on Condition.
- void sets (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetS , &dst); }
- //! @brief Set Byte on Condition.
- void sets (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetS , &dst); }
- //! @brief Set Byte on Condition.
- void setz (const GpReg& dst) { ASMJIT_ASSERT(dst.getSize() == 1); _emitInstruction(kX86InstSetZ , &dst); }
- //! @brief Set Byte on Condition.
- void setz (const Mem& dst) { ASMJIT_ASSERT(dst.getSize() <= 1); _emitInstruction(kX86InstSetZ , &dst); }
-
- //! @brief Shift Bits Left.
- //! @note @a src register can be only @c cl.
- void shl(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstShl, &dst, &src); }
- //! @brief Shift Bits Left.
- void shl(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstShl, &dst, &src); }
- //! @brief Shift Bits Left.
- //! @note @a src register can be only @c cl.
- void shl(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstShl, &dst, &src); }
- //! @brief Shift Bits Left.
- void shl(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstShl, &dst, &src); }
-
- //! @brief Shift Bits Right.
- //! @note @a src register can be only @c cl.
- void shr(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstShr, &dst, &src); }
- //! @brief Shift Bits Right.
- void shr(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstShr, &dst, &src); }
- //! @brief Shift Bits Right.
- //! @note @a src register can be only @c cl.
- void shr(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstShr, &dst, &src); }
- //! @brief Shift Bits Right.
- void shr(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstShr, &dst, &src); }
-
- //! @brief Double Precision Shift Left.
- //! @note src2 register can be only @c cl register.
- void shld(const GpReg& dst, const GpReg& src1, const GpReg& src2)
- { _emitInstruction(kX86InstShld, &dst, &src1, &src2); }
- //! @brief Double Precision Shift Left.
- void shld(const GpReg& dst, const GpReg& src1, const Imm& src2)
- { _emitInstruction(kX86InstShld, &dst, &src1, &src2); }
- //! @brief Double Precision Shift Left.
- //! @note src2 register can be only @c cl register.
- void shld(const Mem& dst, const GpReg& src1, const GpReg& src2)
- { _emitInstruction(kX86InstShld, &dst, &src1, &src2); }
- //! @brief Double Precision Shift Left.
- void shld(const Mem& dst, const GpReg& src1, const Imm& src2)
- { _emitInstruction(kX86InstShld, &dst, &src1, &src2); }
-
- //! @brief Double Precision Shift Right.
- //! @note src2 register can be only @c cl register.
- void shrd(const GpReg& dst, const GpReg& src1, const GpReg& src2)
- { _emitInstruction(kX86InstShrd, &dst, &src1, &src2); }
- //! @brief Double Precision Shift Right.
- void shrd(const GpReg& dst, const GpReg& src1, const Imm& src2)
- { _emitInstruction(kX86InstShrd, &dst, &src1, &src2); }
- //! @brief Double Precision Shift Right.
- //! @note src2 register can be only @c cl register.
- void shrd(const Mem& dst, const GpReg& src1, const GpReg& src2)
- { _emitInstruction(kX86InstShrd, &dst, &src1, &src2); }
- //! @brief Double Precision Shift Right.
- void shrd(const Mem& dst, const GpReg& src1, const Imm& src2)
- { _emitInstruction(kX86InstShrd, &dst, &src1, &src2); }
-
- //! @brief Set Carry Flag to 1.
- void stc()
- { _emitInstruction(kX86InstStc); }
-
- //! @brief Set Direction Flag to 1.
- void std()
- { _emitInstruction(kX86InstStd); }
-
- //! @brief Subtract.
- void sub(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstSub, &dst, &src); }
- //! @brief Subtract.
- void sub(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstSub, &dst, &src); }
- //! @brief Subtract.
- void sub(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstSub, &dst, &src); }
- //! @brief Subtract.
- void sub(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstSub, &dst, &src); }
- //! @brief Subtract.
- void sub(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstSub, &dst, &src); }
-
- //! @brief Logical Compare.
- void test(const GpReg& op1, const GpReg& op2)
- { _emitInstruction(kX86InstTest, &op1, &op2); }
- //! @brief Logical Compare.
- void test(const GpReg& op1, const Imm& op2)
- { _emitInstruction(kX86InstTest, &op1, &op2); }
- //! @brief Logical Compare.
- void test(const Mem& op1, const GpReg& op2)
- { _emitInstruction(kX86InstTest, &op1, &op2); }
- //! @brief Logical Compare.
- void test(const Mem& op1, const Imm& op2)
- { _emitInstruction(kX86InstTest, &op1, &op2); }
-
- //! @brief Undefined instruction - Raise invalid opcode exception.
- void ud2()
- { _emitInstruction(kX86InstUd2); }
-
- //! @brief Exchange and Add.
- void xadd(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstXadd, &dst, &src); }
- //! @brief Exchange and Add.
- void xadd(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstXadd, &dst, &src); }
-
- //! @brief Exchange Register/Memory with Register.
- void xchg(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstXchg, &dst, &src); }
- //! @brief Exchange Register/Memory with Register.
- void xchg(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstXchg, &dst, &src); }
- //! @brief Exchange Register/Memory with Register.
- void xchg(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstXchg, &src, &dst); }
-
- //! @brief Exchange Register/Memory with Register.
- void xor_(const GpReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstXor, &dst, &src); }
- //! @brief Exchange Register/Memory with Register.
- void xor_(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstXor, &dst, &src); }
- //! @brief Exchange Register/Memory with Register.
- void xor_(const GpReg& dst, const Imm& src)
- { _emitInstruction(kX86InstXor, &dst, &src); }
- //! @brief Exchange Register/Memory with Register.
- void xor_(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstXor, &dst, &src); }
- //! @brief Exchange Register/Memory with Register.
- void xor_(const Mem& dst, const Imm& src)
- { _emitInstruction(kX86InstXor, &dst, &src); }
+ //! \note `o2` register can be only `cl` register.
+ INST_3x(shrd, kX86InstIdShrd, X86GpReg, X86GpReg, X86GpReg)
+ //! \overload
+ INST_3x(shrd, kX86InstIdShrd, X86Mem, X86GpReg, X86GpReg)
+ //! Double precision shift right.
+ INST_3i(shrd, kX86InstIdShrd, X86GpReg, X86GpReg, Imm)
+ //! \overload
+ INST_3i(shrd, kX86InstIdShrd, X86Mem, X86GpReg, Imm)
+
+ //! Set carry flag to 1.
+ INST_0x(stc, kX86InstIdStc)
+ //! Set direction flag to 1.
+ INST_0x(std, kX86InstIdStd)
+
+ //! Fill BYTE at ES:[EDI/RDI] with AL.
+ INST_0x(stosb, kX86InstIdStosB)
+ //! Fill DWORD at ES:[EDI/RDI] with EAX.
+ INST_0x(stosd, kX86InstIdStosD)
+ //! Fill QWORD at ES:[RDI] with RAX (X64 Only).
+ INST_0x(stosq, kX86InstIdStosQ)
+ //! Fill WORD at ES:[EDI/RDI] with AX.
+ INST_0x(stosw, kX86InstIdStosW)
+
+ //! Subtract.
+ INST_2x(sub, kX86InstIdSub, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(sub, kX86InstIdSub, X86GpReg, X86Mem)
+ //! \overload
+ INST_2i(sub, kX86InstIdSub, X86GpReg, Imm)
+ //! \overload
+ INST_2x(sub, kX86InstIdSub, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(sub, kX86InstIdSub, X86Mem, Imm)
+
+ //! Logical compare.
+ INST_2x(test, kX86InstIdTest, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2i(test, kX86InstIdTest, X86GpReg, Imm)
+ //! \overload
+ INST_2x(test, kX86InstIdTest, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(test, kX86InstIdTest, X86Mem, Imm)
+
+ //! Undefined instruction - Raise #UD exception.
+ INST_0x(ud2, kX86InstIdUd2)
+
+ //! Exchange and Add.
+ INST_2x(xadd, kX86InstIdXadd, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(xadd, kX86InstIdXadd, X86Mem, X86GpReg)
+
+ //! Exchange register/memory with register.
+ INST_2x(xchg, kX86InstIdXchg, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(xchg, kX86InstIdXchg, X86Mem, X86GpReg)
+ //! \overload
+ INST_2x(xchg, kX86InstIdXchg, X86GpReg, X86Mem)
+
+ //! Xor.
+ INST_2x(xor_, kX86InstIdXor, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(xor_, kX86InstIdXor, X86GpReg, X86Mem)
+ //! \overload
+ INST_2i(xor_, kX86InstIdXor, X86GpReg, Imm)
+ //! \overload
+ INST_2x(xor_, kX86InstIdXor, X86Mem, X86GpReg)
+ //! \overload
+ INST_2i(xor_, kX86InstIdXor, X86Mem, Imm)
// --------------------------------------------------------------------------
- // [X87 Instructions (FPU)]
+ // [Fpu]
// --------------------------------------------------------------------------
- //! @brief Compute 2^x - 1 (FPU).
- void f2xm1()
- { _emitInstruction(kX86InstF2XM1); }
-
- //! @brief Absolute Value of st(0) (FPU).
- void fabs()
- { _emitInstruction(kX86InstFAbs); }
-
- //! @brief Add @a src to @a dst and store result in @a dst (FPU).
- //!
- //! @note One of dst or src must be st(0).
- void fadd(const X87Reg& dst, const X87Reg& src)
- {
- ASMJIT_ASSERT(!dst.getRegIndex() || !src.getRegIndex());
- _emitInstruction(kX86InstFAdd, &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.
- void fadd(const Mem& src)
- { _emitInstruction(kX86InstFAdd, &src); }
-
- //! @brief Add st(0) to @a dst and POP register stack (FPU).
- void faddp(const X87Reg& dst = st(1))
- { _emitInstruction(kX86InstFAddP, &dst); }
-
- //! @brief Load Binary Coded Decimal (FPU).
- void fbld(const Mem& src)
- { _emitInstruction(kX86InstFBLd, &src); }
-
- //! @brief Store BCD Integer and Pop (FPU).
- void fbstp(const Mem& dst)
- { _emitInstruction(kX86InstFBStP, &dst); }
-
- //! @brief Change st(0) Sign (FPU).
- void fchs()
- { _emitInstruction(kX86InstFCHS); }
-
- //! @brief Clear Exceptions (FPU).
- //!
- //! Clear floating-point exception flags after 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 checks
- //! for and handles any pending unmasked floating-point exceptions before
- //! clearing the exception flags.
- void fclex()
- { _emitInstruction(kX86InstFClex); }
-
- //! @brief FP Conditional Move (FPU).
- void fcmovb(const X87Reg& src)
- { _emitInstruction(kX86InstFCMovB, &src); }
- //! @brief FP Conditional Move (FPU).
- void fcmovbe(const X87Reg& src)
- { _emitInstruction(kX86InstFCMovBE, &src); }
- //! @brief FP Conditional Move (FPU).
- void fcmove(const X87Reg& src)
- { _emitInstruction(kX86InstFCMovE, &src); }
- //! @brief FP Conditional Move (FPU).
- void fcmovnb(const X87Reg& src)
- { _emitInstruction(kX86InstFCMovNB, &src); }
- //! @brief FP Conditional Move (FPU).
- void fcmovnbe(const X87Reg& src)
- { _emitInstruction(kX86InstFCMovNBE, &src); }
- //! @brief FP Conditional Move (FPU).
- void fcmovne(const X87Reg& src)
- { _emitInstruction(kX86InstFCMovNE, &src); }
- //! @brief FP Conditional Move (FPU).
- void fcmovnu(const X87Reg& src)
- { _emitInstruction(kX86InstFCMovNU, &src); }
- //! @brief FP Conditional Move (FPU).
- void fcmovu(const X87Reg& src)
- { _emitInstruction(kX86InstFCMovU, &src); }
-
- //! @brief Compare st(0) with @a reg (FPU).
- void fcom(const X87Reg& reg = st(1))
- { _emitInstruction(kX86InstFCom, ®); }
- //! @brief Compare st(0) with 4-byte or 8-byte FP at @a src (FPU).
- void fcom(const Mem& src)
- { _emitInstruction(kX86InstFCom, &src); }
-
- //! @brief Compare st(0) with @a reg and pop the stack (FPU).
- void fcomp(const X87Reg& reg = st(1))
- { _emitInstruction(kX86InstFComP, ®); }
- //! @brief Compare st(0) with 4-byte or 8-byte FP at @a adr and pop the
- //! stack (FPU).
- void fcomp(const Mem& mem)
- { _emitInstruction(kX86InstFComP, &mem); }
-
- //! @brief Compare st(0) with st(1) and pop register stack twice (FPU).
- void fcompp()
- { _emitInstruction(kX86InstFComPP); }
-
- //! @brief Compare st(0) and @a reg and Set EFLAGS (FPU).
- void fcomi(const X87Reg& reg)
- { _emitInstruction(kX86InstFComI, ®); }
-
- //! @brief Compare st(0) and @a reg and Set EFLAGS and pop the stack (FPU).
- void fcomip(const X87Reg& reg)
- { _emitInstruction(kX86InstFComIP, ®); }
-
- //! @brief Cosine (FPU).
- //!
- //! This instruction calculates the cosine of the source operand in
- //! register st(0) and stores the result in st(0).
- void fcos()
- { _emitInstruction(kX86InstFCos); }
-
- //! @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.
- void fdecstp()
- { _emitInstruction(kX86InstFDecStP); }
-
- //! @brief Divide @a dst by @a src (FPU).
- //!
- //! @note One of @a dst or @a src register must be st(0).
- void fdiv(const X87Reg& dst, const X87Reg& src)
- {
- ASMJIT_ASSERT(!dst.getRegIndex() || !src.getRegIndex());
- _emitInstruction(kX86InstFDiv, &dst, &src);
- }
- //! @brief Divide st(0) by 32-bit or 64-bit FP value (FPU).
- void fdiv(const Mem& src)
- { _emitInstruction(kX86InstFDiv, &src); }
-
- //! @brief Divide @a reg by st(0) (FPU).
- void fdivp(const X87Reg& reg = st(1))
- { _emitInstruction(kX86InstFDivP, ®); }
-
- //! @brief Reverse Divide @a dst by @a src (FPU).
- //!
- //! @note One of @a dst or @a src register must be st(0).
- void fdivr(const X87Reg& dst, const X87Reg& src)
- {
- ASMJIT_ASSERT(!dst.getRegIndex() || !src.getRegIndex());
- _emitInstruction(kX86InstFDivR, &dst, &src);
- }
- //! @brief Reverse Divide st(0) by 32-bit or 64-bit FP value (FPU).
- void fdivr(const Mem& src)
- { _emitInstruction(kX86InstFDivR, &src); }
-
- //! @brief Reverse Divide @a reg by st(0) (FPU).
- void fdivrp(const X87Reg& reg = st(1))
- { _emitInstruction(kX86InstFDivRP, ®); }
-
- //! @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.
- void ffree(const X87Reg& reg)
- { _emitInstruction(kX86InstFFree, ®); }
-
- //! @brief Add 16-bit or 32-bit integer to st(0) (FPU).
- void fiadd(const Mem& src)
- {
- ASMJIT_ASSERT(src.getSize() == 2 || src.getSize() == 4);
- _emitInstruction(kX86InstFIAdd, &src);
- }
-
- //! @brief Compare st(0) with 16-bit or 32-bit Integer (FPU).
- void ficom(const Mem& src)
- {
- ASMJIT_ASSERT(src.getSize() == 2 || src.getSize() == 4);
- _emitInstruction(kX86InstFICom, &src);
- }
-
- //! @brief Compare st(0) with 16-bit or 32-bit Integer and pop the stack (FPU).
- void ficomp(const Mem& src)
- {
- ASMJIT_ASSERT(src.getSize() == 2 || src.getSize() == 4);
- _emitInstruction(kX86InstFIComP, &src);
- }
-
- //! @brief Divide st(0) by 32-bit or 16-bit integer (@a src) (FPU).
- void fidiv(const Mem& src)
- {
- ASMJIT_ASSERT(src.getSize() == 2 || src.getSize() == 4);
- _emitInstruction(kX86InstFIDiv, &src);
- }
-
- //! @brief Reverse Divide st(0) by 32-bit or 16-bit integer (@a src) (FPU).
- void fidivr(const Mem& src)
- {
- ASMJIT_ASSERT(src.getSize() == 2 || src.getSize() == 4);
- _emitInstruction(kX86InstFIDivR, &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.
- void fild(const Mem& src)
- {
- ASMJIT_ASSERT(src.getSize() == 2 || src.getSize() == 4 || src.getSize() == 8);
- _emitInstruction(kX86InstFILd, &src);
- }
-
- //! @brief Multiply st(0) by 16-bit or 32-bit integer and store it
- //! to st(0) (FPU).
- void fimul(const Mem& src)
- {
- ASMJIT_ASSERT(src.getSize() == 2 || src.getSize() == 4);
- _emitInstruction(kX86InstFIMul, &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.
- void fincstp()
- { _emitInstruction(kX86InstFIncStP); }
-
- //! @brief Initialize Floating-Point Unit (FPU).
- //!
- //! Initialize FPU after checking for pending unmasked floating-point
- //! exceptions.
- void finit()
- { _emitInstruction(kX86InstFInit); }
-
- //! @brief Subtract 16-bit or 32-bit integer from st(0) and store result to
- //! st(0) (FPU).
- void fisub(const Mem& src)
- {
- ASMJIT_ASSERT(src.getSize() == 2 || src.getSize() == 4);
- _emitInstruction(kX86InstFISub, &src);
- }
-
- //! @brief Reverse Subtract 16-bit or 32-bit integer from st(0) and
- //! store result to st(0) (FPU).
- void fisubr(const Mem& src)
- {
- ASMJIT_ASSERT(src.getSize() == 2 || src.getSize() == 4);
- _emitInstruction(kX86InstFISubR, &src);
- }
-
- //! @brief Initialize Floating-Point Unit (FPU).
- //!
- //! Initialize FPU without checking for pending unmasked floating-point
- //! exceptions.
- void fninit()
- { _emitInstruction(kX86InstFNInit); }
-
- //! @brief Store st(0) as 16-bit or 32-bit Integer to @a dst (FPU).
- void fist(const Mem& dst)
- {
- ASMJIT_ASSERT(dst.getSize() == 2 || dst.getSize() == 4);
- _emitInstruction(kX86InstFISt, &dst);
- }
-
- //! @brief Store st(0) as 16-bit, 32-bit or 64-bit Integer to @a dst and pop
- //! stack (FPU).
- void fistp(const Mem& dst)
- {
- ASMJIT_ASSERT(dst.getSize() == 2 || dst.getSize() == 4 || dst.getSize() == 8);
- _emitInstruction(kX86InstFIStP, &dst);
- }
-
- //! @brief Push 32-bit, 64-bit or 80-bit Floating Point Value onto the FPU
- //! register stack (FPU).
- void fld(const Mem& src)
- {
- ASMJIT_ASSERT(src.getSize() == 4 || src.getSize() == 8 || src.getSize() == 10);
- _emitInstruction(kX86InstFLd, &src);
- }
-
- //! @brief Push @a reg onto the FPU register stack (FPU).
- void fld(const X87Reg& reg)
- { _emitInstruction(kX86InstFLd, ®); }
-
- //! @brief Push +1.0 onto the FPU register stack (FPU).
- void fld1()
- { _emitInstruction(kX86InstFLd1); }
-
- //! @brief Push log2(10) onto the FPU register stack (FPU).
- void fldl2t()
- { _emitInstruction(kX86InstFLdL2T); }
-
- //! @brief Push log2(e) onto the FPU register stack (FPU).
- void fldl2e()
- { _emitInstruction(kX86InstFLdL2E); }
-
- //! @brief Push pi onto the FPU register stack (FPU).
- void fldpi()
- { _emitInstruction(kX86InstFLdPi); }
-
- //! @brief Push log10(2) onto the FPU register stack (FPU).
- void fldlg2()
- { _emitInstruction(kX86InstFLdLg2); }
-
- //! @brief Push ln(2) onto the FPU register stack (FPU).
- void fldln2()
- { _emitInstruction(kX86InstFLdLn2); }
-
- //! @brief Push +0.0 onto the FPU register stack (FPU).
- void fldz()
- { _emitInstruction(kX86InstFLdZ); }
-
- //! @brief Load x87 FPU Control Word (2 bytes) (FPU).
- void fldcw(const Mem& src)
- { _emitInstruction(kX86InstFLdCw, &src); }
-
- //! @brief Load x87 FPU Environment (14 or 28 bytes) (FPU).
- void fldenv(const Mem& src)
- { _emitInstruction(kX86InstFLdEnv, &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).
- void fmul(const X87Reg& dst, const X87Reg& src)
- {
- ASMJIT_ASSERT(!dst.getRegIndex() || !src.getRegIndex());
- _emitInstruction(kX86InstFMul, &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.
- void fmul(const Mem& src)
- { _emitInstruction(kX86InstFMul, &src); }
-
- //! @brief Multiply st(0) by @a dst and POP register stack (FPU).
- void fmulp(const X87Reg& dst = st(1))
- { _emitInstruction(kX86InstFMulP, &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.
- void fnclex()
- { _emitInstruction(kX86InstFNClex); }
-
- //! @brief No Operation (FPU).
- void fnop()
- { _emitInstruction(kX86InstFNop); }
-
- //! @brief Save FPU State (FPU).
- //!
- //! Store FPU environment to m94byte or m108byte without
- //! checking for pending unmasked FP exceptions.
- //! Then re-initialize the FPU.
- void fnsave(const Mem& dst)
- { _emitInstruction(kX86InstFNSave, &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.
- void fnstenv(const Mem& dst)
- { _emitInstruction(kX86InstFNStEnv, &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.
- void fnstcw(const Mem& dst)
- { _emitInstruction(kX86InstFNStCw, &dst); }
-
- //! @brief Store x87 FPU Status Word (2 Bytes) (FPU).
- void fnstsw(const GpReg& dst)
- {
- ASMJIT_ASSERT(dst.isRegCode(kX86RegAx));
- _emitInstruction(kX86InstFNStSw, &dst);
- }
- //! @brief Store x87 FPU Status Word (2 Bytes) (FPU).
- void fnstsw(const Mem& dst)
- { _emitInstruction(kX86InstFNStSw, &dst); }
-
- //! @brief Partial Arctangent (FPU).
- //!
- //! Replace st(1) with arctan(st(1)/st(0)) and pop the register stack.
- void fpatan()
- { _emitInstruction(kX86InstFPAtan); }
-
- //! @brief Partial Remainder (FPU).
- //!
- //! Replace st(0) with the remainder obtained from dividing st(0) by st(1).
- void fprem()
- { _emitInstruction(kX86InstFPRem); }
-
- //! @brief Partial Remainder (FPU).
- //!
- //! Replace st(0) with the IEEE remainder obtained from dividing st(0) by
- //! st(1).
- void fprem1()
- { _emitInstruction(kX86InstFPRem1); }
-
- //! @brief Partial Tangent (FPU).
- //!
- //! Replace st(0) with its tangent and push 1 onto the FPU stack.
- void fptan()
- { _emitInstruction(kX86InstFPTan); }
-
- //! @brief Round to Integer (FPU).
- //!
- //! Rount st(0) to an Integer.
- void frndint()
- { _emitInstruction(kX86InstFRndInt); }
-
- //! @brief Restore FPU State (FPU).
- //!
- //! Load FPU state from src (94 or 108 bytes).
- void frstor(const Mem& src)
- { _emitInstruction(kX86InstFRstor, &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.
- void fsave(const Mem& dst)
- { _emitInstruction(kX86InstFSave, &dst); }
-
- //! @brief Scale (FPU).
- //!
- //! Scale st(0) by st(1).
- void fscale()
- { _emitInstruction(kX86InstFScale); }
-
- //! @brief Sine (FPU).
- //!
- //! This instruction calculates the sine of the source operand in
- //! register st(0) and stores the result in st(0).
- void fsin()
- { _emitInstruction(kX86InstFSin); }
-
- //! @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.
- void fsincos()
- { _emitInstruction(kX86InstFSinCos); }
-
- //! @brief Square Root (FPU).
- //!
- //! Calculates square root of st(0) and stores the result in st(0).
- void fsqrt()
- { _emitInstruction(kX86InstFSqrt); }
-
- //! @brief Store Floating Point Value (FPU).
- //!
- //! Store st(0) as 32-bit or 64-bit floating point value to @a dst.
- void fst(const Mem& dst)
- {
- ASMJIT_ASSERT(dst.getSize() == 4 || dst.getSize() == 8);
- _emitInstruction(kX86InstFSt, &dst);
- }
-
- //! @brief Store Floating Point Value (FPU).
- //!
- //! Store st(0) to @a reg.
- void fst(const X87Reg& reg)
- { _emitInstruction(kX86InstFSt, ®); }
-
- //! @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.
- void fstp(const Mem& dst)
- {
- ASMJIT_ASSERT(dst.getSize() == 4 || dst.getSize() == 8 || dst.getSize() == 10);
- _emitInstruction(kX86InstFStP, &dst);
- }
-
- //! @brief Store Floating Point Value and Pop Register Stack (FPU).
- //!
- //! Store st(0) to @a reg and pop register stack.
- void fstp(const X87Reg& reg)
- { _emitInstruction(kX86InstFStP, ®); }
-
- //! @brief Store x87 FPU Control Word (FPU).
- //!
- //! Store FPU control word to @a dst (2 Bytes) after checking for pending
- //! unmasked floating-point exceptions.
- void fstcw(const Mem& dst)
- { _emitInstruction(kX86InstFStCw, &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.
- void fstenv(const Mem& dst)
- { _emitInstruction(kX86InstFStEnv, &dst); }
-
- //! @brief Store x87 FPU Status Word (2 Bytes) (FPU).
- void fstsw(const GpReg& dst)
- {
- ASMJIT_ASSERT(dst.isRegCode(kX86RegAx));
- _emitInstruction(kX86InstFStSw, &dst);
- }
- //! @brief Store x87 FPU Status Word (2 Bytes) (FPU).
- void fstsw(const Mem& dst)
- { _emitInstruction(kX86InstFStSw, &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).
- void fsub(const X87Reg& dst, const X87Reg& src)
- {
- ASMJIT_ASSERT(!dst.getRegIndex() || !src.getRegIndex());
- _emitInstruction(kX86InstFSub, &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.
- void fsub(const Mem& src)
- {
- ASMJIT_ASSERT(src.getSize() == 4 || src.getSize() == 8);
- _emitInstruction(kX86InstFSub, &src);
- }
-
- //! @brief Subtract st(0) from @a dst and POP register stack (FPU).
- void fsubp(const X87Reg& dst = st(1))
- { _emitInstruction(kX86InstFSubP, &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).
- void fsubr(const X87Reg& dst, const X87Reg& src)
- {
- ASMJIT_ASSERT(!dst.getRegIndex() || !src.getRegIndex());
- _emitInstruction(kX86InstFSubR, &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.
- void fsubr(const Mem& src)
- {
- ASMJIT_ASSERT(src.getSize() == 4 || src.getSize() == 8);
- _emitInstruction(kX86InstFSubR, &src);
- }
-
- //! @brief Reverse Subtract st(0) from @a dst and POP register stack (FPU).
- void fsubrp(const X87Reg& dst = st(1))
- { _emitInstruction(kX86InstFSubRP, &dst); }
-
- //! @brief Floating point test - Compare st(0) with 0.0. (FPU).
- void ftst()
- { _emitInstruction(kX86InstFTst); }
-
- //! @brief Unordered Compare st(0) with @a reg (FPU).
- void fucom(const X87Reg& reg = st(1))
- { _emitInstruction(kX86InstFUCom, ®); }
-
- //! @brief Unordered Compare st(0) and @a reg, check for ordered values
- //! and Set EFLAGS (FPU).
- void fucomi(const X87Reg& reg)
- { _emitInstruction(kX86InstFUComI, ®); }
-
- //! @brief UnorderedCompare st(0) and @a reg, Check for ordered values
- //! and Set EFLAGS and pop the stack (FPU).
- void fucomip(const X87Reg& reg = st(1))
- { _emitInstruction(kX86InstFUComIP, ®); }
-
- //! @brief Unordered Compare st(0) with @a reg and pop register stack (FPU).
- void fucomp(const X87Reg& reg = st(1))
- { _emitInstruction(kX86InstFUComP, ®); }
-
- //! @brief Unordered compare st(0) with st(1) and pop register stack twice
- //! (FPU).
- void fucompp()
- { _emitInstruction(kX86InstFUComPP); }
-
- void fwait()
- { _emitInstruction(kX86InstFWait); }
-
- //! @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.
- void fxam()
- { _emitInstruction(kX86InstFXam); }
-
- //! @brief Exchange Register Contents (FPU).
- //!
- //! Exchange content of st(0) with @a reg.
- void fxch(const X87Reg& reg = st(1))
- { _emitInstruction(kX86InstFXch, ®); }
-
- //! @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).
- void fxrstor(const Mem& src)
- { _emitInstruction(kX86InstFXRstor, &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).
- void fxsave(const Mem& dst)
- { _emitInstruction(kX86InstFXSave, &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.
- void fxtract()
- { _emitInstruction(kX86InstFXtract); }
-
- //! @brief Compute y * log2(x).
- //!
- //! Replace st(1) with (st(1) * log2st(0)) and pop the register stack.
- void fyl2x()
- { _emitInstruction(kX86InstFYL2X); }
-
- //! @brief Compute y * log_2(x+1).
- //!
- //! Replace st(1) with (st(1) * (log2st(0) + 1.0)) and pop the register stack.
- void fyl2xp1()
- { _emitInstruction(kX86InstFYL2XP1); }
+ //! Compute 2^x - 1 (FPU).
+ INST_0x(f2xm1, kX86InstIdF2xm1)
+ //! Absolute value of fp0 (FPU).
+ INST_0x(fabs, kX86InstIdFabs)
+
+ //! Add `o1` to `o0` (one has to be `fp0`) and store result in `o0` (FPU).
+ INST_2x_(fadd, kX86InstIdFadd, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0)
+ //! Add 4-byte or 8-byte FP `o0` to fp0 and store result in fp0 (FPU).
+ INST_1x(fadd, kX86InstIdFadd, X86Mem)
+ //! Add fp0 to `o0` and pop the FPU stack (FPU).
+ INST_1x(faddp, kX86InstIdFaddp, X86FpReg)
+ //! \overload
+ INST_0x(faddp, kX86InstIdFaddp)
+
+ //! Load binary coded decimal (FPU).
+ INST_1x(fbld, kX86InstIdFbld, X86Mem)
+ //! Store BCD integer and Pop (FPU).
+ INST_1x(fbstp, kX86InstIdFbstp, X86Mem)
+ //! Change fp0 sign (FPU).
+ INST_0x(fchs, kX86InstIdFchs)
+ //! Clear exceptions (FPU).
+ INST_0x(fclex, kX86InstIdFclex)
+
+ //! Conditional move (FPU).
+ INST_1x(fcmovb, kX86InstIdFcmovb, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmovbe, kX86InstIdFcmovbe, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmove, kX86InstIdFcmove, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmovnb, kX86InstIdFcmovnb, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmovnbe, kX86InstIdFcmovnbe, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmovne, kX86InstIdFcmovne, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmovnu, kX86InstIdFcmovnu, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmovu, kX86InstIdFcmovu, X86FpReg)
+
+ //! Compare fp0 with `o0` (FPU).
+ INST_1x(fcom, kX86InstIdFcom, X86FpReg)
+ //! Compare fp0 with fp1 (FPU).
+ INST_0x(fcom, kX86InstIdFcom)
+ //! Compare fp0 with 4-byte or 8-byte FP at `src` (FPU).
+ INST_1x(fcom, kX86InstIdFcom, X86Mem)
+ //! Compare fp0 with `o0` and pop the FPU stack (FPU).
+ INST_1x(fcomp, kX86InstIdFcomp, X86FpReg)
+ //! Compare fp0 with fp1 and pop the FPU stack (FPU).
+ INST_0x(fcomp, kX86InstIdFcomp)
+ //! Compare fp0 with 4-byte or 8-byte FP at `adr` and pop the FPU stack (FPU).
+ INST_1x(fcomp, kX86InstIdFcomp, X86Mem)
+ //! Compare fp0 with fp1 and pop the FPU stack twice (FPU).
+ INST_0x(fcompp, kX86InstIdFcompp)
+ //! Compare fp0 and `o0` and Set EFLAGS (FPU).
+ INST_1x(fcomi, kX86InstIdFcomi, X86FpReg)
+ //! Compare fp0 and `o0` and Set EFLAGS and pop the FPU stack (FPU).
+ INST_1x(fcomip, kX86InstIdFcomip, X86FpReg)
+
+ //! Calculate cosine of fp0 and store result in fp0 (FPU).
+ INST_0x(fcos, kX86InstIdFcos)
+ //! Decrement FPU stack-top pointer (FPU).
+ INST_0x(fdecstp, kX86InstIdFdecstp)
+
+ //! Divide `o0` by `o1` (one has to be `fp0`) (FPU).
+ INST_2x_(fdiv, kX86InstIdFdiv, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0)
+ //! Divide fp0 by 32-bit or 64-bit FP value (FPU).
+ INST_1x(fdiv, kX86InstIdFdiv, X86Mem)
+ //! Divide `o0` by fp0 (FPU).
+ INST_1x(fdivp, kX86InstIdFdivp, X86FpReg)
+ //! \overload
+ INST_0x(fdivp, kX86InstIdFdivp)
+
+ //! Reverse divide `o0` by `o1` (one has to be `fp0`) (FPU).
+ INST_2x_(fdivr, kX86InstIdFdivr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0)
+ //! Reverse divide fp0 by 32-bit or 64-bit FP value (FPU).
+ INST_1x(fdivr, kX86InstIdFdivr, X86Mem)
+ //! Reverse divide `o0` by fp0 (FPU).
+ INST_1x(fdivrp, kX86InstIdFdivrp, X86FpReg)
+ //! \overload
+ INST_0x(fdivrp, kX86InstIdFdivrp)
+
+ //! Free FP register (FPU).
+ INST_1x(ffree, kX86InstIdFfree, X86FpReg)
+
+ //! Add 16-bit or 32-bit integer to fp0 (FPU).
+ INST_1x_(fiadd, kX86InstIdFiadd, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+ //! Compare fp0 with 16-bit or 32-bit Integer (FPU).
+ INST_1x_(ficom, kX86InstIdFicom, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+ //! Compare fp0 with 16-bit or 32-bit Integer and pop the FPU stack (FPU).
+ INST_1x_(ficomp, kX86InstIdFicomp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+ //! Divide fp0 by 32-bit or 16-bit integer (`src`) (FPU).
+ INST_1x_(fidiv, kX86InstIdFidiv, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+ //! Reverse divide fp0 by 32-bit or 16-bit integer (`src`) (FPU).
+ INST_1x_(fidivr, kX86InstIdFidivr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+
+ //! Load 16-bit, 32-bit or 64-bit Integer and push it to the FPU stack (FPU).
+ INST_1x_(fild, kX86InstIdFild, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8)
+ //! Multiply fp0 by 16-bit or 32-bit integer and store it to fp0 (FPU).
+ INST_1x_(fimul, kX86InstIdFimul, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+
+ //! Increment FPU stack-top pointer (FPU).
+ INST_0x(fincstp, kX86InstIdFincstp)
+ //! Initialize FPU (FPU).
+ INST_0x(finit, kX86InstIdFinit)
+
+ //! Subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU).
+ INST_1x_(fisub, kX86InstIdFisub, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+ //! Reverse subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU).
+ INST_1x_(fisubr, kX86InstIdFisubr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+
+ //! Initialize FPU without checking for pending unmasked exceptions (FPU).
+ INST_0x(fninit, kX86InstIdFninit)
+
+ //! Store fp0 as 16-bit or 32-bit Integer to `o0` (FPU).
+ INST_1x_(fist, kX86InstIdFist, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+ //! Store fp0 as 16-bit, 32-bit or 64-bit Integer to `o0` and pop the FPU stack (FPU).
+ INST_1x_(fistp, kX86InstIdFistp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8)
+ //! Push 32-bit, 64-bit or 80-bit floating point value on the FPU stack (FPU).
+ INST_1x_(fld, kX86InstIdFld, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10)
+ //! Push `o0` on the FPU stack (FPU).
+ INST_1x(fld, kX86InstIdFld, X86FpReg)
+
+ //! Push +1.0 on the FPU stack (FPU).
+ INST_0x(fld1, kX86InstIdFld1)
+ //! Push log2(10) on the FPU stack (FPU).
+ INST_0x(fldl2t, kX86InstIdFldl2t)
+ //! Push log2(e) on the FPU stack (FPU).
+ INST_0x(fldl2e, kX86InstIdFldl2e)
+ //! Push pi on the FPU stack (FPU).
+ INST_0x(fldpi, kX86InstIdFldpi)
+ //! Push log10(2) on the FPU stack (FPU).
+ INST_0x(fldlg2, kX86InstIdFldlg2)
+ //! Push ln(2) on the FPU stack (FPU).
+ INST_0x(fldln2, kX86InstIdFldln2)
+ //! Push +0.0 on the FPU stack (FPU).
+ INST_0x(fldz, kX86InstIdFldz)
+
+ //! Load x87 FPU control word (2 bytes) (FPU).
+ INST_1x(fldcw, kX86InstIdFldcw, X86Mem)
+ //! Load x87 FPU environment (14 or 28 bytes) (FPU).
+ INST_1x(fldenv, kX86InstIdFldenv, X86Mem)
+
+ //! Multiply `o0` by `o1` (one has to be `fp0`) and store result in `o0` (FPU).
+ INST_2x_(fmul, kX86InstIdFmul, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0)
+ //! Multiply fp0 by 32-bit or 64-bit `o0` and store result in fp0 (FPU).
+ INST_1x(fmul, kX86InstIdFmul, X86Mem)
+ //! Multiply fp0 by `o0` and pop the FPU stack (FPU).
+ INST_1x(fmulp, kX86InstIdFmulp, X86FpReg)
+ //! \overload
+ INST_0x(fmulp, kX86InstIdFmulp)
+
+ //! Clear exceptions (FPU).
+ INST_0x(fnclex, kX86InstIdFnclex)
+ //! No operation (FPU).
+ INST_0x(fnop, kX86InstIdFnop)
+ //! Save FPU state (FPU).
+ INST_1x(fnsave, kX86InstIdFnsave, X86Mem)
+ //! Store x87 FPU environment (FPU).
+ INST_1x(fnstenv, kX86InstIdFnstenv, X86Mem)
+ //! Store x87 FPU control word (FPU).
+ INST_1x(fnstcw, kX86InstIdFnstcw, X86Mem)
+
+ //! Store x87 FPU status word to `o0` (AX) (FPU).
+ INST_1x_(fnstsw, kX86InstIdFnstsw, X86GpReg, o0.isRegCode(kX86RegTypeGpw, kX86RegIndexAx))
+ //! Store x87 FPU status word to `o0` (2 bytes) (FPU).
+ INST_1x(fnstsw, kX86InstIdFnstsw, X86Mem)
+
+ //! Arctan(`fp1` / `fp0`) and pop the FPU stack (FPU).
+ INST_0x(fpatan, kX86InstIdFpatan)
+ //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU).
+ INST_0x(fprem, kX86InstIdFprem)
+ //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU).
+ INST_0x(fprem1, kX86InstIdFprem1)
+ //! Arctan(`fp0`) and pop the FPU stack (FPU).
+ INST_0x(fptan, kX86InstIdFptan)
+ //! Round `fp0` to Integer (FPU).
+ INST_0x(frndint, kX86InstIdFrndint)
+
+ //! Restore FPU state from `o0` (94 or 108 bytes) (FPU).
+ INST_1x(frstor, kX86InstIdFrstor, X86Mem)
+ //! Save FPU state to `o0` (94 or 108 bytes) (FPU).
+ INST_1x(fsave, kX86InstIdFsave, X86Mem)
+
+ //! Scale `fp0` by `fp1` (FPU).
+ INST_0x(fscale, kX86InstIdFscale)
+ //! Sine of `fp0` and store result in `fp0` (FPU).
+ INST_0x(fsin, kX86InstIdFsin)
+ //! Sine and cosine of `fp0`, store sine in `fp0` and push cosine on the FPU stack (FPU).
+ INST_0x(fsincos, kX86InstIdFsincos)
+ //! Square root of `fp0` and store it in `fp0` (FPU).
+ INST_0x(fsqrt, kX86InstIdFsqrt)
+
+ //! Store floating point value to 32-bit or 64-bit memory location (FPU).
+ INST_1x_(fst, kX86InstIdFst, X86Mem, o0.getSize() == 4 || o0.getSize() == 8)
+ //! Store floating point value to `o0` (FPU).
+ INST_1x(fst, kX86InstIdFst, X86FpReg)
+ //! Store floating point value to 32-bit or 64-bit memory location and pop the FPU stack (FPU).
+ INST_1x_(fstp, kX86InstIdFstp, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10)
+ //! Store floating point value to `o0` and pop the FPU stack (FPU).
+ INST_1x(fstp, kX86InstIdFstp, X86FpReg)
+
+ //! Store x87 FPU control word to `o0` (2 bytes) (FPU).
+ INST_1x(fstcw, kX86InstIdFstcw, X86Mem)
+ //! Store x87 FPU environment to `o0` (14 or 28 bytes) (FPU).
+ INST_1x(fstenv, kX86InstIdFstenv, X86Mem)
+ //! Store x87 FPU status word to AX (FPU).
+ INST_1x_(fstsw, kX86InstIdFstsw, X86GpReg, o0.getRegIndex() == kX86RegIndexAx)
+ //! Store x87 FPU status word (2 bytes) (FPU).
+ INST_1x(fstsw, kX86InstIdFstsw, X86Mem)
+
+ //! Subtract `o0` from `o0` (one has to be `fp0`) and store result in `o0` (FPU).
+ INST_2x_(fsub, kX86InstIdFsub, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0)
+ //! Subtract 32-bit or 64-bit `o0` from fp0 and store result in fp0 (FPU).
+ INST_1x_(fsub, kX86InstIdFsub, X86Mem, o0.getSize() == 4 || o0.getSize() == 8)
+ //! Subtract fp0 from `o0` and pop FPU stack (FPU).
+ INST_1x(fsubp, kX86InstIdFsubp, X86FpReg)
+ //! \overload
+ INST_0x(fsubp, kX86InstIdFsubp)
+
+ //! Reverse subtract `o1` from `o0` (one has to be `fp0`) and store result in `o0` (FPU).
+ INST_2x_(fsubr, kX86InstIdFsubr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0)
+ //! Reverse subtract 32-bit or 64-bit `o0` from `fp0` and store result in `fp0` (FPU).
+ INST_1x_(fsubr, kX86InstIdFsubr, X86Mem, o0.getSize() == 4 || o0.getSize() == 8)
+ //! Reverse subtract `fp0` from `o0` and pop FPU stack (FPU).
+ INST_1x(fsubrp, kX86InstIdFsubrp, X86FpReg)
+ //! \overload
+ INST_0x(fsubrp, kX86InstIdFsubrp)
+
+ //! Floating point test - Compare `fp0` with 0.0. (FPU).
+ INST_0x(ftst, kX86InstIdFtst)
+
+ //! Unordered compare `fp0` with `o0` (FPU).
+ INST_1x(fucom, kX86InstIdFucom, X86FpReg)
+ //! Unordered compare `fp0` with `fp1` (FPU).
+ INST_0x(fucom, kX86InstIdFucom)
+ //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS (FPU).
+ INST_1x(fucomi, kX86InstIdFucomi, X86FpReg)
+ //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS and pop the FPU stack (FPU).
+ INST_1x(fucomip, kX86InstIdFucomip, X86FpReg)
+ //! Unordered compare `fp0` with `o0` and pop the FPU stack (FPU).
+ INST_1x(fucomp, kX86InstIdFucomp, X86FpReg)
+ //! Unordered compare `fp0` with `fp1` and pop the FPU stack (FPU).
+ INST_0x(fucomp, kX86InstIdFucomp)
+ //! Unordered compare `fp0` with `fp1` and pop the FPU stack twice (FPU).
+ INST_0x(fucompp, kX86InstIdFucompp)
+
+ INST_0x(fwait, kX86InstIdFwait)
+
+ //! Examine fp0 (FPU).
+ INST_0x(fxam, kX86InstIdFxam)
+ //! Exchange content of fp0 with `o0` (FPU).
+ INST_1x(fxch, kX86InstIdFxch, X86FpReg)
+
+ //! Restore FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE).
+ INST_1x(fxrstor, kX86InstIdFxrstor, X86Mem)
+ //! Store FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE).
+ INST_1x(fxsave, kX86InstIdFxsave, X86Mem)
+ //! Extract exponent and store to `fp0` and push significand on the FPU stack (FPU).
+ INST_0x(fxtract, kX86InstIdFxtract)
+
+ //! Compute `fp1 * log2(fp0)`, pop the FPU stack and store result in `fp0` (FPU).
+ INST_0x(fyl2x, kX86InstIdFyl2x)
+ //! Compute `fp1 * log2(fp0 + 1)`, pop the FPU stack and store result in `fp0` (FPU).
+ INST_0x(fyl2xp1, kX86InstIdFyl2xp1)
// --------------------------------------------------------------------------
// [MMX]
// --------------------------------------------------------------------------
- //! @brief Empty MMX state.
- void emms()
- { _emitInstruction(kX86InstEmms); }
-
- //! @brief Move DWord (MMX).
- void movd(const Mem& dst, const MmReg& src)
- { _emitInstruction(kX86InstMovD, &dst, &src); }
- //! @brief Move DWord (MMX).
- void movd(const GpReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstMovD, &dst, &src); }
- //! @brief Move DWord (MMX).
- void movd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovD, &dst, &src); }
- //! @brief Move DWord (MMX).
- void movd(const MmReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstMovD, &dst, &src); }
-
- //! @brief Move QWord (MMX).
- void movq(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstMovQ, &dst, &src); }
- //! @brief Move QWord (MMX).
- void movq(const Mem& dst, const MmReg& src)
- { _emitInstruction(kX86InstMovQ, &dst, &src); }
-#if defined(ASMJIT_X64)
- //! @brief Move QWord (MMX).
- void movq(const GpReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstMovQ, &dst, &src); }
-#endif
- //! @brief Move QWord (MMX).
- void movq(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovQ, &dst, &src); }
-#if defined(ASMJIT_X64)
- //! @brief Move QWord (MMX).
- void movq(const MmReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstMovQ, &dst, &src); }
-#endif
-
- //! @brief Pack with Signed Saturation (MMX).
- void packsswb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPackSSWB, &dst, &src); }
- //! @brief Pack with Signed Saturation (MMX).
- void packsswb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPackSSWB, &dst, &src); }
-
- //! @brief Pack with Signed Saturation (MMX).
- void packssdw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPackSSDW, &dst, &src); }
- //! @brief Pack with Signed Saturation (MMX).
- void packssdw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPackSSDW, &dst, &src); }
-
- //! @brief Pack with Unsigned Saturation (MMX).
- void packuswb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPackUSWB, &dst, &src); }
- //! @brief Pack with Unsigned Saturation (MMX).
- void packuswb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPackUSWB, &dst, &src); }
-
- //! @brief Packed BYTE Add (MMX).
- void paddb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAddB, &dst, &src); }
- //! @brief Packed BYTE Add (MMX).
- void paddb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddB, &dst, &src); }
-
- //! @brief Packed WORD Add (MMX).
- void paddw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAddW, &dst, &src); }
- //! @brief Packed WORD Add (MMX).
- void paddw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddW, &dst, &src); }
-
- //! @brief Packed DWORD Add (MMX).
- void paddd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAddD, &dst, &src); }
- //! @brief Packed DWORD Add (MMX).
- void paddd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddD, &dst, &src); }
-
- //! @brief Packed Add with Saturation (MMX).
- void paddsb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAddSB, &dst, &src); }
- //! @brief Packed Add with Saturation (MMX).
- void paddsb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddSB, &dst, &src); }
-
- //! @brief Packed Add with Saturation (MMX).
- void paddsw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAddSW, &dst, &src); }
- //! @brief Packed Add with Saturation (MMX).
- void paddsw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddSW, &dst, &src); }
-
- //! @brief Packed Add Unsigned with Saturation (MMX).
- void paddusb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAddUSB, &dst, &src); }
- //! @brief Packed Add Unsigned with Saturation (MMX).
- void paddusb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddUSB, &dst, &src); }
-
- //! @brief Packed Add Unsigned with Saturation (MMX).
- void paddusw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAddUSW, &dst, &src); }
- //! @brief Packed Add Unsigned with Saturation (MMX).
- void paddusw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddUSW, &dst, &src); }
-
- //! @brief Logical AND (MMX).
- void pand(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAnd, &dst, &src); }
- //! @brief Logical AND (MMX).
- void pand(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAnd, &dst, &src); }
-
- //! @brief Logical AND Not (MMX).
- void pandn(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAndN, &dst, &src); }
- //! @brief Logical AND Not (MMX).
- void pandn(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAndN, &dst, &src); }
-
- //! @brief Packed Compare for Equal (BYTES) (MMX).
- void pcmpeqb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPCmpEqB, &dst, &src); }
- //! @brief Packed Compare for Equal (BYTES) (MMX).
- void pcmpeqb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpEqB, &dst, &src); }
-
- //! @brief Packed Compare for Equal (WORDS) (MMX).
- void pcmpeqw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPCmpEqW, &dst, &src); }
- //! @brief Packed Compare for Equal (WORDS) (MMX).
- void pcmpeqw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpEqW, &dst, &src); }
-
- //! @brief Packed Compare for Equal (DWORDS) (MMX).
- void pcmpeqd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPCmpEqD, &dst, &src); }
- //! @brief Packed Compare for Equal (DWORDS) (MMX).
- void pcmpeqd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpEqD, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (BYTES) (MMX).
- void pcmpgtb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPCmpGtB, &dst, &src); }
- //! @brief Packed Compare for Greater Than (BYTES) (MMX).
- void pcmpgtb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpGtB, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (WORDS) (MMX).
- void pcmpgtw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPCmpGtW, &dst, &src); }
- //! @brief Packed Compare for Greater Than (WORDS) (MMX).
- void pcmpgtw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpGtW, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (DWORDS) (MMX).
- void pcmpgtd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPCmpGtD, &dst, &src); }
- //! @brief Packed Compare for Greater Than (DWORDS) (MMX).
- void pcmpgtd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpGtD, &dst, &src); }
-
- //! @brief Packed Multiply High (MMX).
- void pmulhw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPMulHW, &dst, &src); }
- //! @brief Packed Multiply High (MMX).
- void pmulhw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMulHW, &dst, &src); }
-
- //! @brief Packed Multiply Low (MMX).
- void pmullw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPMulLW, &dst, &src); }
- //! @brief Packed Multiply Low (MMX).
- void pmullw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMulLW, &dst, &src); }
-
- //! @brief Bitwise Logical OR (MMX).
- void por(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPOr, &dst, &src); }
- //! @brief Bitwise Logical OR (MMX).
- void por(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPOr, &dst, &src); }
-
- //! @brief Packed Multiply and Add (MMX).
- void pmaddwd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPMAddWD, &dst, &src); }
- //! @brief Packed Multiply and Add (MMX).
- void pmaddwd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMAddWD, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (MMX).
- void pslld(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSllD, &dst, &src); }
- //! @brief Packed Shift Left Logical (MMX).
- void pslld(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSllD, &dst, &src); }
- //! @brief Packed Shift Left Logical (MMX).
- void pslld(const MmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSllD, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (MMX).
- void psllq(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSllQ, &dst, &src); }
- //! @brief Packed Shift Left Logical (MMX).
- void psllq(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSllQ, &dst, &src); }
- //! @brief Packed Shift Left Logical (MMX).
- void psllq(const MmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSllQ, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (MMX).
- void psllw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSllW, &dst, &src); }
- //! @brief Packed Shift Left Logical (MMX).
- void psllw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSllW, &dst, &src); }
- //! @brief Packed Shift Left Logical (MMX).
- void psllw(const MmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSllW, &dst, &src); }
-
- //! @brief Packed Shift Right Arithmetic (MMX).
- void psrad(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSraD, &dst, &src); }
- //! @brief Packed Shift Right Arithmetic (MMX).
- void psrad(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSraD, &dst, &src); }
- //! @brief Packed Shift Right Arithmetic (MMX).
- void psrad(const MmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSraD, &dst, &src); }
-
- //! @brief Packed Shift Right Arithmetic (MMX).
- void psraw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSraW, &dst, &src); }
- //! @brief Packed Shift Right Arithmetic (MMX).
- void psraw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSraW, &dst, &src); }
- //! @brief Packed Shift Right Arithmetic (MMX).
- void psraw(const MmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSraW, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (MMX).
- void psrld(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSrlD, &dst, &src); }
- //! @brief Packed Shift Right Logical (MMX).
- void psrld(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSrlD, &dst, &src); }
- //! @brief Packed Shift Right Logical (MMX).
- void psrld(const MmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSrlD, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (MMX).
- void psrlq(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSrlQ, &dst, &src); }
- //! @brief Packed Shift Right Logical (MMX).
- void psrlq(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSrlQ, &dst, &src); }
- //! @brief Packed Shift Right Logical (MMX).
- void psrlq(const MmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSrlQ, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (MMX).
- void psrlw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSrlW, &dst, &src); }
- //! @brief Packed Shift Right Logical (MMX).
- void psrlw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSrlW, &dst, &src); }
- //! @brief Packed Shift Right Logical (MMX).
- void psrlw(const MmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSrlW, &dst, &src); }
-
- //! @brief Packed Subtract (MMX).
- void psubb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSubB, &dst, &src); }
- //! @brief Packed Subtract (MMX).
- void psubb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubB, &dst, &src); }
-
- //! @brief Packed Subtract (MMX).
- void psubw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSubW, &dst, &src); }
- //! @brief Packed Subtract (MMX).
- void psubw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubW, &dst, &src); }
-
- //! @brief Packed Subtract (MMX).
- void psubd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSubD, &dst, &src); }
- //! @brief Packed Subtract (MMX).
- void psubd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubD, &dst, &src); }
-
- //! @brief Packed Subtract with Saturation (MMX).
- void psubsb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSubSB, &dst, &src); }
- //! @brief Packed Subtract with Saturation (MMX).
- void psubsb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubSB, &dst, &src); }
-
- //! @brief Packed Subtract with Saturation (MMX).
- void psubsw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSubSW, &dst, &src); }
- //! @brief Packed Subtract with Saturation (MMX).
- void psubsw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubSW, &dst, &src); }
-
- //! @brief Packed Subtract with Unsigned Saturation (MMX).
- void psubusb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSubUSB, &dst, &src); }
- //! @brief Packed Subtract with Unsigned Saturation (MMX).
- void psubusb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubUSB, &dst, &src); }
-
- //! @brief Packed Subtract with Unsigned Saturation (MMX).
- void psubusw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSubUSW, &dst, &src); }
- //! @brief Packed Subtract with Unsigned Saturation (MMX).
- void psubusw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubUSW, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpckhbw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPunpckHBW, &dst, &src); }
- //! @brief Unpack High Packed Data (MMX).
- void punpckhbw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckHBW, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpckhwd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPunpckHWD, &dst, &src); }
- //! @brief Unpack High Packed Data (MMX).
- void punpckhwd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckHWD, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpckhdq(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPunpckHDQ, &dst, &src); }
- //! @brief Unpack High Packed Data (MMX).
- void punpckhdq(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckHDQ, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpcklbw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPunpckLBW, &dst, &src); }
- //! @brief Unpack High Packed Data (MMX).
- void punpcklbw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckLBW, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpcklwd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPunpckLWD, &dst, &src); }
- //! @brief Unpack High Packed Data (MMX).
- void punpcklwd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckLWD, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpckldq(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPunpckLDQ, &dst, &src); }
- //! @brief Unpack High Packed Data (MMX).
- void punpckldq(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckLDQ, &dst, &src); }
-
- //! @brief Bitwise Exclusive OR (MMX).
- void pxor(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPXor, &dst, &src); }
- //! @brief Bitwise Exclusive OR (MMX).
- void pxor(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPXor, &dst, &src); }
+ //! Move DWORD (MMX).
+ INST_2x(movd, kX86InstIdMovd, X86Mem, X86MmReg)
+ //! \overload
+ INST_2x(movd, kX86InstIdMovd, X86GpReg, X86MmReg)
+ //! \overload
+ INST_2x(movd, kX86InstIdMovd, X86MmReg, X86Mem)
+ //! \overload
+ INST_2x(movd, kX86InstIdMovd, X86MmReg, X86GpReg)
+
+ //! Move QWORD (MMX).
+ INST_2x(movq, kX86InstIdMovq, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(movq, kX86InstIdMovq, X86Mem, X86MmReg)
+ //! \overload
+ INST_2x(movq, kX86InstIdMovq, X86MmReg, X86Mem)
+
+ //! Move QWORD (X64 Only).
+ INST_2x(movq, kX86InstIdMovq, X86GpReg, X86MmReg)
+ //! \overload
+ INST_2x(movq, kX86InstIdMovq, X86MmReg, X86GpReg)
+
+ //! Pack DWORDs to WORDs with signed saturation (MMX).
+ INST_2x(packssdw, kX86InstIdPackssdw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(packssdw, kX86InstIdPackssdw, X86MmReg, X86Mem)
+
+ //! Pack WORDs to BYTEs with signed saturation (MMX).
+ INST_2x(packsswb, kX86InstIdPacksswb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(packsswb, kX86InstIdPacksswb, X86MmReg, X86Mem)
+
+ //! Pack WORDs to BYTEs with unsigned saturation (MMX).
+ INST_2x(packuswb, kX86InstIdPackuswb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(packuswb, kX86InstIdPackuswb, X86MmReg, X86Mem)
+
+ //! Packed BYTE add (MMX).
+ INST_2x(paddb, kX86InstIdPaddb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(paddb, kX86InstIdPaddb, X86MmReg, X86Mem)
+
+ //! Packed DWORD add (MMX).
+ INST_2x(paddd, kX86InstIdPaddd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(paddd, kX86InstIdPaddd, X86MmReg, X86Mem)
+
+ //! Packed BYTE add with saturation (MMX).
+ INST_2x(paddsb, kX86InstIdPaddsb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(paddsb, kX86InstIdPaddsb, X86MmReg, X86Mem)
+
+ //! Packed WORD add with saturation (MMX).
+ INST_2x(paddsw, kX86InstIdPaddsw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(paddsw, kX86InstIdPaddsw, X86MmReg, X86Mem)
+
+ //! Packed BYTE add with unsigned saturation (MMX).
+ INST_2x(paddusb, kX86InstIdPaddusb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(paddusb, kX86InstIdPaddusb, X86MmReg, X86Mem)
+
+ //! Packed WORD add with unsigned saturation (MMX).
+ INST_2x(paddusw, kX86InstIdPaddusw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(paddusw, kX86InstIdPaddusw, X86MmReg, X86Mem)
+
+ //! Packed WORD add (MMX).
+ INST_2x(paddw, kX86InstIdPaddw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(paddw, kX86InstIdPaddw, X86MmReg, X86Mem)
+
+ //! Packed bitwise and (MMX).
+ INST_2x(pand, kX86InstIdPand, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pand, kX86InstIdPand, X86MmReg, X86Mem)
+
+ //! Packed bitwise and-not (MMX).
+ INST_2x(pandn, kX86InstIdPandn, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pandn, kX86InstIdPandn, X86MmReg, X86Mem)
+
+ //! Packed BYTEs compare for equality (MMX).
+ INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmReg, X86Mem)
+
+ //! Packed DWORDs compare for equality (MMX).
+ INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmReg, X86Mem)
+
+ //! Packed WORDs compare for equality (MMX).
+ INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmReg, X86Mem)
+
+ //! Packed BYTEs compare if greater than (MMX).
+ INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmReg, X86Mem)
+
+ //! Packed DWORDs compare if greater than (MMX).
+ INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmReg, X86Mem)
+
+ //! Packed WORDs compare if greater than (MMX).
+ INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmReg, X86Mem)
+
+ //! Packed WORDs multiply high (MMX).
+ INST_2x(pmulhw, kX86InstIdPmulhw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pmulhw, kX86InstIdPmulhw, X86MmReg, X86Mem)
+
+ //! Packed WORDs multiply low (MMX).
+ INST_2x(pmullw, kX86InstIdPmullw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pmullw, kX86InstIdPmullw, X86MmReg, X86Mem)
+
+ //! Pakced bitwise or (MMX).
+ INST_2x(por, kX86InstIdPor, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(por, kX86InstIdPor, X86MmReg, X86Mem)
+
+ //! Packed WORD multiply and add to packed DWORD (MMX).
+ INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmReg, X86Mem)
+
+ //! Packed DWORD shift left logical (MMX).
+ INST_2x(pslld, kX86InstIdPslld, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pslld, kX86InstIdPslld, X86MmReg, X86Mem)
+ //! \overload
+ INST_2i(pslld, kX86InstIdPslld, X86MmReg, Imm)
+
+ //! Packed QWORD shift left logical (MMX).
+ INST_2x(psllq, kX86InstIdPsllq, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psllq, kX86InstIdPsllq, X86MmReg, X86Mem)
+ //! \overload
+ INST_2i(psllq, kX86InstIdPsllq, X86MmReg, Imm)
+
+ //! Packed WORD shift left logical (MMX).
+ INST_2x(psllw, kX86InstIdPsllw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psllw, kX86InstIdPsllw, X86MmReg, X86Mem)
+ //! \overload
+ INST_2i(psllw, kX86InstIdPsllw, X86MmReg, Imm)
+
+ //! Packed DWORD shift right arithmetic (MMX).
+ INST_2x(psrad, kX86InstIdPsrad, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psrad, kX86InstIdPsrad, X86MmReg, X86Mem)
+ //! \overload
+ INST_2i(psrad, kX86InstIdPsrad, X86MmReg, Imm)
+
+ //! Packed WORD shift right arithmetic (MMX).
+ INST_2x(psraw, kX86InstIdPsraw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psraw, kX86InstIdPsraw, X86MmReg, X86Mem)
+ //! \overload
+ INST_2i(psraw, kX86InstIdPsraw, X86MmReg, Imm)
+
+ //! Packed DWORD shift right logical (MMX).
+ INST_2x(psrld, kX86InstIdPsrld, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psrld, kX86InstIdPsrld, X86MmReg, X86Mem)
+ //! \overload
+ INST_2i(psrld, kX86InstIdPsrld, X86MmReg, Imm)
+
+ //! Packed QWORD shift right logical (MMX).
+ INST_2x(psrlq, kX86InstIdPsrlq, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psrlq, kX86InstIdPsrlq, X86MmReg, X86Mem)
+ //! \overload
+ INST_2i(psrlq, kX86InstIdPsrlq, X86MmReg, Imm)
+
+ //! Packed WORD shift right logical (MMX).
+ INST_2x(psrlw, kX86InstIdPsrlw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psrlw, kX86InstIdPsrlw, X86MmReg, X86Mem)
+ //! \overload
+ INST_2i(psrlw, kX86InstIdPsrlw, X86MmReg, Imm)
+
+ //! Packed BYTE subtract (MMX).
+ INST_2x(psubb, kX86InstIdPsubb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psubb, kX86InstIdPsubb, X86MmReg, X86Mem)
+
+ //! Packed DWORD subtract (MMX).
+ INST_2x(psubd, kX86InstIdPsubd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psubd, kX86InstIdPsubd, X86MmReg, X86Mem)
+
+ //! Packed BYTE subtract with saturation (MMX).
+ INST_2x(psubsb, kX86InstIdPsubsb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psubsb, kX86InstIdPsubsb, X86MmReg, X86Mem)
+
+ //! Packed WORD subtract with saturation (MMX).
+ INST_2x(psubsw, kX86InstIdPsubsw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psubsw, kX86InstIdPsubsw, X86MmReg, X86Mem)
+
+ //! Packed BYTE subtract with unsigned saturation (MMX).
+ INST_2x(psubusb, kX86InstIdPsubusb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psubusb, kX86InstIdPsubusb, X86MmReg, X86Mem)
+
+ //! Packed WORD subtract with unsigned saturation (MMX).
+ INST_2x(psubusw, kX86InstIdPsubusw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psubusw, kX86InstIdPsubusw, X86MmReg, X86Mem)
+
+ //! Packed WORD subtract (MMX).
+ INST_2x(psubw, kX86InstIdPsubw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psubw, kX86InstIdPsubw, X86MmReg, X86Mem)
+
+ //! Unpack high packed BYTEs to WORDs (MMX).
+ INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmReg, X86Mem)
+
+ //! Unpack high packed DWORDs to QWORDs (MMX).
+ INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmReg, X86Mem)
+
+ //! Unpack high packed WORDs to DWORDs (MMX).
+ INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmReg, X86Mem)
+
+ //! Unpack low packed BYTEs to WORDs (MMX).
+ INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmReg, X86Mem)
+
+ //! Unpack low packed DWORDs to QWORDs (MMX).
+ INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmReg, X86Mem)
+
+ //! Unpack low packed WORDs to DWORDs (MMX).
+ INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmReg, X86Mem)
+
+ //! Packed bitwise xor (MMX).
+ INST_2x(pxor, kX86InstIdPxor, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pxor, kX86InstIdPxor, X86MmReg, X86Mem)
+
+ //! Empty MMX state.
+ INST_0x(emms, kX86InstIdEmms)
// -------------------------------------------------------------------------
// [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() ).
- void femms()
- { _emitInstruction(kX86InstFEmms); }
-
- //! @brief Packed SP-FP to Integer Convert (3dNow!).
- void pf2id(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPF2ID, &dst, &src); }
- //! @brief Packed SP-FP to Integer Convert (3dNow!).
- void pf2id(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPF2ID, &dst, &src); }
-
- //! @brief Packed SP-FP to Integer Word Convert (3dNow!).
- void pf2iw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPF2IW, &dst, &src); }
- //! @brief Packed SP-FP to Integer Word Convert (3dNow!).
- void pf2iw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPF2IW, &dst, &src); }
-
- //! @brief Packed SP-FP Accumulate (3dNow!).
- void pfacc(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFAcc, &dst, &src); }
- //! @brief Packed SP-FP Accumulate (3dNow!).
- void pfacc(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFAcc, &dst, &src); }
-
- //! @brief Packed SP-FP Addition (3dNow!).
- void pfadd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFAdd, &dst, &src); }
- //! @brief Packed SP-FP Addition (3dNow!).
- void pfadd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFAdd, &dst, &src); }
-
- //! @brief Packed SP-FP Compare - dst == src (3dNow!).
- void pfcmpeq(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFCmpEQ, &dst, &src); }
- //! @brief Packed SP-FP Compare - dst == src (3dNow!).
- void pfcmpeq(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFCmpEQ, &dst, &src); }
-
- //! @brief Packed SP-FP Compare - dst >= src (3dNow!).
- void pfcmpge(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFCmpGE, &dst, &src); }
- //! @brief Packed SP-FP Compare - dst >= src (3dNow!).
- void pfcmpge(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFCmpGE, &dst, &src); }
-
- //! @brief Packed SP-FP Compare - dst > src (3dNow!).
- void pfcmpgt(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFCmpGT, &dst, &src); }
- //! @brief Packed SP-FP Compare - dst > src (3dNow!).
- void pfcmpgt(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFCmpGT, &dst, &src); }
-
- //! @brief Packed SP-FP Maximum (3dNow!).
- void pfmax(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFMax, &dst, &src); }
- //! @brief Packed SP-FP Maximum (3dNow!).
- void pfmax(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFMax, &dst, &src); }
-
- //! @brief Packed SP-FP Minimum (3dNow!).
- void pfmin(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFMin, &dst, &src); }
- //! @brief Packed SP-FP Minimum (3dNow!).
- void pfmin(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFMin, &dst, &src); }
-
- //! @brief Packed SP-FP Multiply (3dNow!).
- void pfmul(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFMul, &dst, &src); }
- //! @brief Packed SP-FP Multiply (3dNow!).
- void pfmul(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFMul, &dst, &src); }
-
- //! @brief Packed SP-FP Negative Accumulate (3dNow!).
- void pfnacc(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFNAcc, &dst, &src); }
- //! @brief Packed SP-FP Negative Accumulate (3dNow!).
- void pfnacc(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFNAcc, &dst, &src); }
-
- //! @brief Packed SP-FP Mixed Accumulate (3dNow!).
- void pfpnacc(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFPNAcc, &dst, &src); }
- //! @brief Packed SP-FP Mixed Accumulate (3dNow!).
- void pfpnacc(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFPNAcc, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal Approximation (3dNow!).
- void pfrcp(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFRcp, &dst, &src); }
- //! @brief Packed SP-FP Reciprocal Approximation (3dNow!).
- void pfrcp(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFRcp, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal, First Iteration Step (3dNow!).
- void pfrcpit1(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFRcpIt1, &dst, &src); }
- //! @brief Packed SP-FP Reciprocal, First Iteration Step (3dNow!).
- void pfrcpit1(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFRcpIt1, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal, Second Iteration Step (3dNow!).
- void pfrcpit2(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFRcpIt2, &dst, &src); }
- //! @brief Packed SP-FP Reciprocal, Second Iteration Step (3dNow!).
- void pfrcpit2(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFRcpIt2, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal Square Root, First Iteration Step (3dNow!).
- void pfrsqit1(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFRSqIt1, &dst, &src); }
- //! @brief Packed SP-FP Reciprocal Square Root, First Iteration Step (3dNow!).
- void pfrsqit1(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFRSqIt1, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal Square Root Approximation (3dNow!).
- void pfrsqrt(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFRSqrt, &dst, &src); }
- //! @brief Packed SP-FP Reciprocal Square Root Approximation (3dNow!).
- void pfrsqrt(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFRSqrt, &dst, &src); }
-
- //! @brief Packed SP-FP Subtract (3dNow!).
- void pfsub(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFSub, &dst, &src); }
- //! @brief Packed SP-FP Subtract (3dNow!).
- void pfsub(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFSub, &dst, &src); }
-
- //! @brief Packed SP-FP Reverse Subtract (3dNow!).
- void pfsubr(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPFSubR, &dst, &src); }
- //! @brief Packed SP-FP Reverse Subtract (3dNow!).
- void pfsubr(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPFSubR, &dst, &src); }
-
- //! @brief Packed DWords to SP-FP (3dNow!).
- void pi2fd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPI2FD, &dst, &src); }
- //! @brief Packed DWords to SP-FP (3dNow!).
- void pi2fd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPI2FD, &dst, &src); }
-
- //! @brief Packed Words to SP-FP (3dNow!).
- void pi2fw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPI2FW, &dst, &src); }
- //! @brief Packed Words to SP-FP (3dNow!).
- void pi2fw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPI2FW, &dst, &src); }
-
- //! @brief Packed swap DWord (3dNow!)
- void pswapd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSwapD, &dst, &src); }
- //! @brief Packed swap DWord (3dNow!)
- void pswapd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSwapD, &dst, &src); }
+ //! Packed SP-FP to DWORD convert (3dNow!).
+ INST_2x(pf2id, kX86InstIdPf2id, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pf2id, kX86InstIdPf2id, X86MmReg, X86Mem)
+
+ //! Packed SP-FP to WORD convert (3dNow!).
+ INST_2x(pf2iw, kX86InstIdPf2iw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pf2iw, kX86InstIdPf2iw, X86MmReg, X86Mem)
+
+ //! Packed SP-FP accumulate (3dNow!).
+ INST_2x(pfacc, kX86InstIdPfacc, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfacc, kX86InstIdPfacc, X86MmReg, X86Mem)
+
+ //! Packed SP-FP addition (3dNow!).
+ INST_2x(pfadd, kX86InstIdPfadd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfadd, kX86InstIdPfadd, X86MmReg, X86Mem)
+
+ //! Packed SP-FP compare - dst == src (3dNow!).
+ INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmReg, X86Mem)
+
+ //! Packed SP-FP compare - dst >= src (3dNow!).
+ INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmReg, X86Mem)
+
+ //! Packed SP-FP compare - dst > src (3dNow!).
+ INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmReg, X86Mem)
+
+ //! Packed SP-FP maximum (3dNow!).
+ INST_2x(pfmax, kX86InstIdPfmax, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfmax, kX86InstIdPfmax, X86MmReg, X86Mem)
+
+ //! Packed SP-FP minimum (3dNow!).
+ INST_2x(pfmin, kX86InstIdPfmin, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfmin, kX86InstIdPfmin, X86MmReg, X86Mem)
+
+ //! Packed SP-FP multiply (3dNow!).
+ INST_2x(pfmul, kX86InstIdPfmul, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfmul, kX86InstIdPfmul, X86MmReg, X86Mem)
+
+ //! Packed SP-FP negative accumulate (3dNow!).
+ INST_2x(pfnacc, kX86InstIdPfnacc, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfnacc, kX86InstIdPfnacc, X86MmReg, X86Mem)
+
+ //! Packed SP-FP mixed accumulate (3dNow!).
+ INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmReg, X86Mem)
+
+ //! Packed SP-FP reciprocal Approximation (3dNow!).
+ INST_2x(pfrcp, kX86InstIdPfrcp, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfrcp, kX86InstIdPfrcp, X86MmReg, X86Mem)
+
+ //! Packed SP-FP reciprocal, first iteration step (3dNow!).
+ INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmReg, X86Mem)
+
+ //! Packed SP-FP reciprocal, second iteration step (3dNow!).
+ INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmReg, X86Mem)
+
+ //! Packed SP-FP reciprocal square root, first iteration step (3dNow!).
+ INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmReg, X86Mem)
+
+ //! Packed SP-FP reciprocal square root approximation (3dNow!).
+ INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmReg, X86Mem)
+
+ //! Packed SP-FP subtract (3dNow!).
+ INST_2x(pfsub, kX86InstIdPfsub, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfsub, kX86InstIdPfsub, X86MmReg, X86Mem)
+
+ //! Packed SP-FP reverse subtract (3dNow!).
+ INST_2x(pfsubr, kX86InstIdPfsubr, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pfsubr, kX86InstIdPfsubr, X86MmReg, X86Mem)
+
+ //! Packed DWORDs to SP-FP (3dNow!).
+ INST_2x(pi2fd, kX86InstIdPi2fd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pi2fd, kX86InstIdPi2fd, X86MmReg, X86Mem)
+
+ //! Packed WORDs to SP-FP (3dNow!).
+ INST_2x(pi2fw, kX86InstIdPi2fw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pi2fw, kX86InstIdPi2fw, X86MmReg, X86Mem)
+
+ //! Packed swap DWORDs (3dNow!)
+ INST_2x(pswapd, kX86InstIdPswapd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pswapd, kX86InstIdPswapd, X86MmReg, X86Mem)
+
+ //! Prefetch (3dNow!).
+ INST_1x(prefetch3dnow, kX86InstIdPrefetch3dNow, X86Mem)
+
+ //! Prefetch and set cache to modified (3dNow!).
+ INST_1x(prefetchw3dnow, kX86InstIdPrefetchw3dNow, X86Mem)
+
+ //! Faster EMMS (3dNow!).
+ INST_0x(femms, kX86InstIdFemms)
// --------------------------------------------------------------------------
// [SSE]
// --------------------------------------------------------------------------
- //! @brief Packed SP-FP Add (SSE).
- void addps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstAddPS, &dst, &src); }
- //! @brief Packed SP-FP Add (SSE).
- void addps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstAddPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Add (SSE).
- void addss(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstAddSS, &dst, &src); }
- //! @brief Scalar SP-FP Add (SSE).
- void addss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstAddSS, &dst, &src); }
-
- //! @brief Bit-wise Logical And Not For SP-FP (SSE).
- void andnps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstAndnPS, &dst, &src); }
- //! @brief Bit-wise Logical And Not For SP-FP (SSE).
- void andnps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstAndnPS, &dst, &src); }
-
- //! @brief Bit-wise Logical And For SP-FP (SSE).
- void andps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstAndPS, &dst, &src); }
- //! @brief Bit-wise Logical And For SP-FP (SSE).
- void andps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstAndPS, &dst, &src); }
-
- //! @brief Packed SP-FP Compare (SSE).
- void cmpps(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstCmpPS, &dst, &src, &imm8); }
- //! @brief Packed SP-FP Compare (SSE).
- void cmpps(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstCmpPS, &dst, &src, &imm8); }
-
- //! @brief Compare Scalar SP-FP Values (SSE).
- void cmpss(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstCmpSS, &dst, &src, &imm8); }
- //! @brief Compare Scalar SP-FP Values (SSE).
- void cmpss(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstCmpSS, &dst, &src, &imm8); }
-
- //! @brief Scalar Ordered SP-FP Compare and Set EFLAGS (SSE).
- void comiss(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstComISS, &dst, &src); }
- //! @brief Scalar Ordered SP-FP Compare and Set EFLAGS (SSE).
- void comiss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstComISS, &dst, &src); }
-
- //! @brief Packed Signed INT32 to Packed SP-FP Conversion (SSE).
- void cvtpi2ps(const XmmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstCvtPI2PS, &dst, &src); }
- //! @brief Packed Signed INT32 to Packed SP-FP Conversion (SSE).
- void cvtpi2ps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtPI2PS, &dst, &src); }
-
- //! @brief Packed SP-FP to Packed INT32 Conversion (SSE).
- void cvtps2pi(const MmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvtPS2PI, &dst, &src); }
- //! @brief Packed SP-FP to Packed INT32 Conversion (SSE).
- void cvtps2pi(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtPS2PI, &dst, &src); }
-
- //! @brief Scalar Signed INT32 to SP-FP Conversion (SSE).
- void cvtsi2ss(const XmmReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstCvtSI2SS, &dst, &src); }
- //! @brief Scalar Signed INT32 to SP-FP Conversion (SSE).
- void cvtsi2ss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtSI2SS, &dst, &src); }
-
- //! @brief Scalar SP-FP to Signed INT32 Conversion (SSE).
- void cvtss2si(const GpReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvtSS2SI, &dst, &src); }
- //! @brief Scalar SP-FP to Signed INT32 Conversion (SSE).
- void cvtss2si(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtSS2SI, &dst, &src); }
-
- //! @brief Packed SP-FP to Packed INT32 Conversion (truncate) (SSE).
- void cvttps2pi(const MmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvttPS2PI, &dst, &src); }
- //! @brief Packed SP-FP to Packed INT32 Conversion (truncate) (SSE).
- void cvttps2pi(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvttPS2PI, &dst, &src); }
-
- //! @brief Scalar SP-FP to Signed INT32 Conversion (truncate) (SSE).
- void cvttss2si(const GpReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvttSS2SI, &dst, &src); }
- //! @brief Scalar SP-FP to Signed INT32 Conversion (truncate) (SSE).
- void cvttss2si(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvttSS2SI, &dst, &src); }
-
- //! @brief Packed SP-FP Divide (SSE).
- void divps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstDivPS, &dst, &src); }
- //! @brief Packed SP-FP Divide (SSE).
- void divps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstDivPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Divide (SSE).
- void divss(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstDivSS, &dst, &src); }
- //! @brief Scalar SP-FP Divide (SSE).
- void divss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstDivSS, &dst, &src); }
-
- //! @brief Load Streaming SIMD Extension Control/Status (SSE).
- void ldmxcsr(const Mem& src)
- { _emitInstruction(kX86InstLdMXCSR, &src); }
-
- //! @brief Byte Mask Write (SSE).
- //!
- //! @note The default memory location is specified by DS:EDI.
- void maskmovq(const MmReg& data, const MmReg& mask)
- { _emitInstruction(kX86InstMaskMovQ, &data, &mask); }
-
- //! @brief Packed SP-FP Maximum (SSE).
- void maxps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMaxPS, &dst, &src); }
- //! @brief Packed SP-FP Maximum (SSE).
- void maxps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMaxPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Maximum (SSE).
- void maxss(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMaxSS, &dst, &src); }
- //! @brief Scalar SP-FP Maximum (SSE).
- void maxss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMaxSS, &dst, &src); }
-
- //! @brief Packed SP-FP Minimum (SSE).
- void minps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMinPS, &dst, &src); }
- //! @brief Packed SP-FP Minimum (SSE).
- void minps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMinPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Minimum (SSE).
- void minss(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMinSS, &dst, &src); }
- //! @brief Scalar SP-FP Minimum (SSE).
- void minss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMinSS, &dst, &src); }
-
- //! @brief Move Aligned Packed SP-FP Values (SSE).
- void movaps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovAPS, &dst, &src); }
- //! @brief Move Aligned Packed SP-FP Values (SSE).
- void movaps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovAPS, &dst, &src); }
-
- //! @brief Move Aligned Packed SP-FP Values (SSE).
- void movaps(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovAPS, &dst, &src); }
-
- //! @brief Move DWord.
- void movd(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovD, &dst, &src); }
- //! @brief Move DWord.
- void movd(const GpReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovD, &dst, &src); }
- //! @brief Move DWord.
- void movd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovD, &dst, &src); }
- //! @brief Move DWord.
- void movd(const XmmReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstMovD, &dst, &src); }
-
- //! @brief Move QWord (SSE).
- void movq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovQ, &dst, &src); }
- //! @brief Move QWord (SSE).
- void movq(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovQ, &dst, &src); }
-#if defined(ASMJIT_X64)
- //! @brief Move QWord (SSE).
- void movq(const GpReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovQ, &dst, &src); }
-#endif // ASMJIT_X64
- //! @brief Move QWord (SSE).
- void movq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovQ, &dst, &src); }
-#if defined(ASMJIT_X64)
- //! @brief Move QWord (SSE).
- void movq(const XmmReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstMovQ, &dst, &src); }
-#endif // ASMJIT_X64
-
- //! @brief Move 64 Bits Non Temporal (SSE).
- void movntq(const Mem& dst, const MmReg& src)
- { _emitInstruction(kX86InstMovNTQ, &dst, &src); }
-
- //! @brief High to Low Packed SP-FP (SSE).
- void movhlps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovHLPS, &dst, &src); }
-
- //! @brief Move High Packed SP-FP (SSE).
- void movhps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovHPS, &dst, &src); }
-
- //! @brief Move High Packed SP-FP (SSE).
- void movhps(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovHPS, &dst, &src); }
-
- //! @brief Move Low to High Packed SP-FP (SSE).
- void movlhps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovLHPS, &dst, &src); }
-
- //! @brief Move Low Packed SP-FP (SSE).
- void movlps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovLPS, &dst, &src); }
-
- //! @brief Move Low Packed SP-FP (SSE).
- void movlps(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovLPS, &dst, &src); }
-
- //! @brief Move Aligned Four Packed SP-FP Non Temporal (SSE).
- void movntps(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovNTPS, &dst, &src); }
-
- //! @brief Move Scalar SP-FP (SSE).
- void movss(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovSS, &dst, &src); }
-
- //! @brief Move Scalar SP-FP (SSE).
- void movss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovSS, &dst, &src); }
-
- //! @brief Move Scalar SP-FP (SSE).
- void movss(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovSS, &dst, &src); }
-
- //! @brief Move Unaligned Packed SP-FP Values (SSE).
- void movups(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovUPS, &dst, &src); }
- //! @brief Move Unaligned Packed SP-FP Values (SSE).
- void movups(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovUPS, &dst, &src); }
-
- //! @brief Move Unaligned Packed SP-FP Values (SSE).
- void movups(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovUPS, &dst, &src); }
-
- //! @brief Packed SP-FP Multiply (SSE).
- void mulps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMulPS, &dst, &src); }
- //! @brief Packed SP-FP Multiply (SSE).
- void mulps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMulPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Multiply (SSE).
- void mulss(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMulSS, &dst, &src); }
- //! @brief Scalar SP-FP Multiply (SSE).
- void mulss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMulSS, &dst, &src); }
-
- //! @brief Bit-wise Logical OR for SP-FP Data (SSE).
- void orps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstOrPS, &dst, &src); }
- //! @brief Bit-wise Logical OR for SP-FP Data (SSE).
- void orps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstOrPS, &dst, &src); }
-
- //! @brief Packed Average (SSE).
- void pavgb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAvgB, &dst, &src); }
- //! @brief Packed Average (SSE).
- void pavgb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAvgB, &dst, &src); }
-
- //! @brief Packed Average (SSE).
- void pavgw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAvgW, &dst, &src); }
- //! @brief Packed Average (SSE).
- void pavgw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAvgW, &dst, &src); }
-
- //! @brief Extract Word (SSE).
- void pextrw(const GpReg& dst, const MmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPExtrW, &dst, &src, &imm8); }
-
- //! @brief Insert Word (SSE).
- void pinsrw(const MmReg& dst, const GpReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPInsRW, &dst, &src, &imm8); }
- //! @brief Insert Word (SSE).
- void pinsrw(const MmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPInsRW, &dst, &src, &imm8); }
-
- //! @brief Packed Signed Integer Word Maximum (SSE).
- void pmaxsw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPMaxSW, &dst, &src); }
- //! @brief Packed Signed Integer Word Maximum (SSE).
- void pmaxsw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMaxSW, &dst, &src); }
-
- //! @brief Packed Unsigned Integer Byte Maximum (SSE).
- void pmaxub(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPMaxUB, &dst, &src); }
- //! @brief Packed Unsigned Integer Byte Maximum (SSE).
- void pmaxub(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMaxUB, &dst, &src); }
-
- //! @brief Packed Signed Integer Word Minimum (SSE).
- void pminsw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPMinSW, &dst, &src); }
- //! @brief Packed Signed Integer Word Minimum (SSE).
- void pminsw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMinSW, &dst, &src); }
-
- //! @brief Packed Unsigned Integer Byte Minimum (SSE).
- void pminub(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPMinUB, &dst, &src); }
- //! @brief Packed Unsigned Integer Byte Minimum (SSE).
- void pminub(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMinUB, &dst, &src); }
-
- //! @brief Move Byte Mask To Integer (SSE).
- void pmovmskb(const GpReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPMovMskB, &dst, &src); }
-
- //! @brief Packed Multiply High Unsigned (SSE).
- void pmulhuw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPMulHUW, &dst, &src); }
- //! @brief Packed Multiply High Unsigned (SSE).
- void pmulhuw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMulHUW, &dst, &src); }
-
- //! @brief Packed Sum of Absolute Differences (SSE).
- void psadbw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSADBW, &dst, &src); }
- //! @brief Packed Sum of Absolute Differences (SSE).
- void psadbw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSADBW, &dst, &src); }
-
- //! @brief Packed Shuffle word (SSE).
- void pshufw(const MmReg& dst, const MmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPShufW, &dst, &src, &imm8); }
- //! @brief Packed Shuffle word (SSE).
- void pshufw(const MmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPShufW, &dst, &src, &imm8); }
-
- //! @brief Packed SP-FP Reciprocal (SSE).
- void rcpps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstRcpPS, &dst, &src); }
- //! @brief Packed SP-FP Reciprocal (SSE).
- void rcpps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstRcpPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Reciprocal (SSE).
- void rcpss(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstRcpSS, &dst, &src); }
- //! @brief Scalar SP-FP Reciprocal (SSE).
- void rcpss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstRcpSS, &dst, &src); }
-
- //! @brief Prefetch (SSE).
- void prefetch(const Mem& mem, const Imm& hint)
- { _emitInstruction(kX86InstPrefetch, &mem, &hint); }
-
- //! @brief Compute Sum of Absolute Differences (SSE).
- void psadbw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSADBW, &dst, &src); }
- //! @brief Compute Sum of Absolute Differences (SSE).
- void psadbw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSADBW, &dst, &src); }
-
- //! @brief Packed SP-FP Square Root Reciprocal (SSE).
- void rsqrtps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstSqrtPS, &dst, &src); }
- //! @brief Packed SP-FP Square Root Reciprocal (SSE).
- void rsqrtps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstSqrtPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Square Root Reciprocal (SSE).
- void rsqrtss(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstSqrtSS, &dst, &src); }
- //! @brief Scalar SP-FP Square Root Reciprocal (SSE).
- void rsqrtss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstSqrtSS, &dst, &src); }
-
- //! @brief Store fence (SSE).
- void sfence()
- { _emitInstruction(kX86InstSFence); }
-
- //! @brief Shuffle SP-FP (SSE).
- void shufps(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstShufPS, &dst, &src, &imm8); }
- //! @brief Shuffle SP-FP (SSE).
- void shufps(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstShufPS, &dst, &src, &imm8); }
-
- //! @brief Packed SP-FP Square Root (SSE).
- void sqrtps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstSqrtPS, &dst, &src); }
- //! @brief Packed SP-FP Square Root (SSE).
- void sqrtps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstSqrtPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Square Root (SSE).
- void sqrtss(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstSqrtSS, &dst, &src); }
- //! @brief Scalar SP-FP Square Root (SSE).
- void sqrtss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstSqrtSS, &dst, &src); }
-
- //! @brief Store Streaming SIMD Extension Control/Status (SSE).
- void stmxcsr(const Mem& dst)
- { _emitInstruction(kX86InstStMXCSR, &dst); }
-
- //! @brief Packed SP-FP Subtract (SSE).
- void subps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstSubPS, &dst, &src); }
- //! @brief Packed SP-FP Subtract (SSE).
- void subps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstSubPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Subtract (SSE).
- void subss(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstSubSS, &dst, &src); }
- //! @brief Scalar SP-FP Subtract (SSE).
- void subss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstSubSS, &dst, &src); }
-
- //! @brief Unordered Scalar SP-FP compare and set EFLAGS (SSE).
- void ucomiss(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstUComISS, &dst, &src); }
- //! @brief Unordered Scalar SP-FP compare and set EFLAGS (SSE).
- void ucomiss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstUComISS, &dst, &src); }
-
- //! @brief Unpack High Packed SP-FP Data (SSE).
- void unpckhps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstUnpckHPS, &dst, &src); }
- //! @brief Unpack High Packed SP-FP Data (SSE).
- void unpckhps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstUnpckHPS, &dst, &src); }
-
- //! @brief Unpack Low Packed SP-FP Data (SSE).
- void unpcklps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstUnpckLPS, &dst, &src); }
- //! @brief Unpack Low Packed SP-FP Data (SSE).
- void unpcklps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstUnpckLPS, &dst, &src); }
-
- //! @brief Bit-wise Logical Xor for SP-FP Data (SSE).
- void xorps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstXorPS, &dst, &src); }
- //! @brief Bit-wise Logical Xor for SP-FP Data (SSE).
- void xorps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstXorPS, &dst, &src); }
+ //! Packed SP-FP add (SSE).
+ INST_2x(addps, kX86InstIdAddps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(addps, kX86InstIdAddps, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP add (SSE).
+ INST_2x(addss, kX86InstIdAddss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(addss, kX86InstIdAddss, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP bitwise and-not (SSE).
+ INST_2x(andnps, kX86InstIdAndnps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(andnps, kX86InstIdAndnps, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP bitwise and (SSE).
+ INST_2x(andps, kX86InstIdAndps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(andps, kX86InstIdAndps, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP compare (SSE).
+ INST_3i(cmpps, kX86InstIdCmpps, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(cmpps, kX86InstIdCmpps, X86XmmReg, X86Mem, Imm)
+
+ //! Compare scalar SP-FP (SSE).
+ INST_3i(cmpss, kX86InstIdCmpss, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(cmpss, kX86InstIdCmpss, X86XmmReg, X86Mem, Imm)
+
+ //! Scalar ordered SP-FP compare and set EFLAGS (SSE).
+ INST_2x(comiss, kX86InstIdComiss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(comiss, kX86InstIdComiss, X86XmmReg, X86Mem)
+
+ //! Packed signed INT32 to packed SP-FP conversion (SSE).
+ INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmReg, X86MmReg)
+ //! \overload
+ INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP to packed INT32 conversion (SSE).
+ INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmReg, X86Mem)
+
+ //! Convert scalar INT32 to SP-FP (SSE).
+ INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmReg, X86GpReg)
+ //! \overload
+ INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmReg, X86Mem)
+
+ //! Convert scalar SP-FP to INT32 (SSE).
+ INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpReg, X86Mem)
+
+ //! Convert with truncation packed SP-FP to packed INT32 (SSE).
+ INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmReg, X86Mem)
+
+ //! Convert with truncation scalar SP-FP to INT32 (SSE).
+ INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpReg, X86Mem)
+
+ //! Packed SP-FP divide (SSE).
+ INST_2x(divps, kX86InstIdDivps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(divps, kX86InstIdDivps, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP divide (SSE).
+ INST_2x(divss, kX86InstIdDivss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(divss, kX86InstIdDivss, X86XmmReg, X86Mem)
+
+ //! Load streaming SIMD extension control/status (SSE).
+ INST_1x(ldmxcsr, kX86InstIdLdmxcsr, X86Mem)
+
+ //! Byte mask write to DS:EDI/RDI (SSE).
+ INST_2x(maskmovq, kX86InstIdMaskmovq, X86MmReg, X86MmReg)
+
+ //! Packed SP-FP maximum (SSE).
+ INST_2x(maxps, kX86InstIdMaxps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(maxps, kX86InstIdMaxps, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP maximum (SSE).
+ INST_2x(maxss, kX86InstIdMaxss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(maxss, kX86InstIdMaxss, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP minimum (SSE).
+ INST_2x(minps, kX86InstIdMinps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(minps, kX86InstIdMinps, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP minimum (SSE).
+ INST_2x(minss, kX86InstIdMinss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(minss, kX86InstIdMinss, X86XmmReg, X86Mem)
+
+ //! Move aligned packed SP-FP (SSE).
+ INST_2x(movaps, kX86InstIdMovaps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(movaps, kX86InstIdMovaps, X86XmmReg, X86Mem)
+ //! Move aligned packed SP-FP (SSE).
+ INST_2x(movaps, kX86InstIdMovaps, X86Mem, X86XmmReg)
+
+ //! Move DWORD.
+ INST_2x(movd, kX86InstIdMovd, X86Mem, X86XmmReg)
+ //! \overload
+ INST_2x(movd, kX86InstIdMovd, X86GpReg, X86XmmReg)
+ //! \overload
+ INST_2x(movd, kX86InstIdMovd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(movd, kX86InstIdMovd, X86XmmReg, X86GpReg)
+
+ //! Move QWORD (SSE).
+ INST_2x(movq, kX86InstIdMovq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(movq, kX86InstIdMovq, X86Mem, X86XmmReg)
+ //! \overload
+ INST_2x(movq, kX86InstIdMovq, X86XmmReg, X86Mem)
+
+ //! Move QWORD (X64 Only).
+ INST_2x(movq, kX86InstIdMovq, X86GpReg, X86XmmReg)
+ //! \overload
+ INST_2x(movq, kX86InstIdMovq, X86XmmReg, X86GpReg)
+
+ //! Move QWORD using NT hint (SSE).
+ INST_2x(movntq, kX86InstIdMovntq, X86Mem, X86MmReg)
+
+ //! Move high to low packed SP-FP (SSE).
+ INST_2x(movhlps, kX86InstIdMovhlps, X86XmmReg, X86XmmReg)
+
+ //! Move high packed SP-FP (SSE).
+ INST_2x(movhps, kX86InstIdMovhps, X86XmmReg, X86Mem)
+ //! Move high packed SP-FP (SSE).
+ INST_2x(movhps, kX86InstIdMovhps, X86Mem, X86XmmReg)
+
+ //! Move low to high packed SP-FP (SSE).
+ INST_2x(movlhps, kX86InstIdMovlhps, X86XmmReg, X86XmmReg)
+
+ //! Move low packed SP-FP (SSE).
+ INST_2x(movlps, kX86InstIdMovlps, X86XmmReg, X86Mem)
+ //! Move low packed SP-FP (SSE).
+ INST_2x(movlps, kX86InstIdMovlps, X86Mem, X86XmmReg)
+
+ //! Move aligned packed SP-FP using NT hint (SSE).
+ INST_2x(movntps, kX86InstIdMovntps, X86Mem, X86XmmReg)
+
+ //! Move scalar SP-FP (SSE).
+ INST_2x(movss, kX86InstIdMovss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(movss, kX86InstIdMovss, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(movss, kX86InstIdMovss, X86Mem, X86XmmReg)
+
+ //! Move unaligned packed SP-FP (SSE).
+ INST_2x(movups, kX86InstIdMovups, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(movups, kX86InstIdMovups, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(movups, kX86InstIdMovups, X86Mem, X86XmmReg)
+
+ //! Packed SP-FP multiply (SSE).
+ INST_2x(mulps, kX86InstIdMulps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(mulps, kX86InstIdMulps, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP multiply (SSE).
+ INST_2x(mulss, kX86InstIdMulss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(mulss, kX86InstIdMulss, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP bitwise or (SSE).
+ INST_2x(orps, kX86InstIdOrps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(orps, kX86InstIdOrps, X86XmmReg, X86Mem)
+
+ //! Packed BYTE average (SSE).
+ INST_2x(pavgb, kX86InstIdPavgb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pavgb, kX86InstIdPavgb, X86MmReg, X86Mem)
+
+ //! Packed WORD average (SSE).
+ INST_2x(pavgw, kX86InstIdPavgw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pavgw, kX86InstIdPavgw, X86MmReg, X86Mem)
+
+ //! Extract WORD based on selector (SSE).
+ INST_3i(pextrw, kX86InstIdPextrw, X86GpReg, X86MmReg, Imm)
+
+ //! Insert WORD based on selector (SSE).
+ INST_3i(pinsrw, kX86InstIdPinsrw, X86MmReg, X86GpReg, Imm)
+ //! \overload
+ INST_3i(pinsrw, kX86InstIdPinsrw, X86MmReg, X86Mem, Imm)
+
+ //! Packed WORD maximum (SSE).
+ INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmReg, X86Mem)
+
+ //! Packed BYTE unsigned maximum (SSE).
+ INST_2x(pmaxub, kX86InstIdPmaxub, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pmaxub, kX86InstIdPmaxub, X86MmReg, X86Mem)
+
+ //! Packed WORD minimum (SSE).
+ INST_2x(pminsw, kX86InstIdPminsw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pminsw, kX86InstIdPminsw, X86MmReg, X86Mem)
+
+ //! Packed BYTE unsigned minimum (SSE).
+ INST_2x(pminub, kX86InstIdPminub, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pminub, kX86InstIdPminub, X86MmReg, X86Mem)
+
+ //! Move Byte mask to integer (SSE).
+ INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpReg, X86MmReg)
+
+ //! Packed WORD unsigned multiply high (SSE).
+ INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmReg, X86Mem)
+
+ //! Packed WORD sum of absolute differences (SSE).
+ INST_2x(psadbw, kX86InstIdPsadbw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psadbw, kX86InstIdPsadbw, X86MmReg, X86Mem)
+
+ //! Packed WORD shuffle (SSE).
+ INST_3i(pshufw, kX86InstIdPshufw, X86MmReg, X86MmReg, Imm)
+ //! \overload
+ INST_3i(pshufw, kX86InstIdPshufw, X86MmReg, X86Mem, Imm)
+
+ //! Packed SP-FP reciprocal (SSE).
+ INST_2x(rcpps, kX86InstIdRcpps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(rcpps, kX86InstIdRcpps, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP reciprocal (SSE).
+ INST_2x(rcpss, kX86InstIdRcpss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(rcpss, kX86InstIdRcpss, X86XmmReg, X86Mem)
+
+ //! Prefetch (SSE).
+ INST_2i(prefetch, kX86InstIdPrefetch, X86Mem, Imm)
+
+ //! Packed WORD sum of absolute differences (SSE).
+ INST_2x(psadbw, kX86InstIdPsadbw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psadbw, kX86InstIdPsadbw, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP square root reciprocal (SSE).
+ INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP square root reciprocal (SSE).
+ INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmReg, X86Mem)
+
+ //! Store fence (SSE).
+ INST_0x(sfence, kX86InstIdSfence)
+
+ //! Shuffle SP-FP (SSE).
+ INST_3i(shufps, kX86InstIdShufps, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(shufps, kX86InstIdShufps, X86XmmReg, X86Mem, Imm)
+
+ //! Packed SP-FP square root (SSE).
+ INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP square root (SSE).
+ INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmReg, X86Mem)
+
+ //! Store streaming SIMD extension control/status (SSE).
+ INST_1x(stmxcsr, kX86InstIdStmxcsr, X86Mem)
+
+ //! Packed SP-FP subtract (SSE).
+ INST_2x(subps, kX86InstIdSubps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(subps, kX86InstIdSubps, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP subtract (SSE).
+ INST_2x(subss, kX86InstIdSubss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(subss, kX86InstIdSubss, X86XmmReg, X86Mem)
+
+ //! Unordered scalar SP-FP compare and set EFLAGS (SSE).
+ INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmReg, X86Mem)
+
+ //! Unpack high packed SP-FP data (SSE).
+ INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmReg, X86Mem)
+
+ //! Unpack low packed SP-FP data (SSE).
+ INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP bitwise xor (SSE).
+ INST_2x(xorps, kX86InstIdXorps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(xorps, kX86InstIdXorps, X86XmmReg, X86Mem)
// --------------------------------------------------------------------------
// [SSE2]
// --------------------------------------------------------------------------
- //! @brief Packed DP-FP Add (SSE2).
- void addpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstAddPD, &dst, &src); }
- //! @brief Packed DP-FP Add (SSE2).
- void addpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstAddPD, &dst, &src); }
-
- //! @brief Scalar DP-FP Add (SSE2).
- void addsd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstAddSD, &dst, &src); }
- //! @brief Scalar DP-FP Add (SSE2).
- void addsd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstAddSD, &dst, &src); }
-
- //! @brief Bit-wise Logical And Not For DP-FP (SSE2).
- void andnpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstAndnPD, &dst, &src); }
- //! @brief Bit-wise Logical And Not For DP-FP (SSE2).
- void andnpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstAndnPD, &dst, &src); }
-
- //! @brief Bit-wise Logical And For DP-FP (SSE2).
- void andpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstAndPD, &dst, &src); }
- //! @brief Bit-wise Logical And For DP-FP (SSE2).
- void andpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstAndPD, &dst, &src); }
-
- //! @brief Flush Cache Line (SSE2).
- void clflush(const Mem& mem)
- { _emitInstruction(kX86InstClFlush, &mem); }
-
- //! @brief Packed DP-FP Compare (SSE2).
- void cmppd(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstCmpPD, &dst, &src, &imm8); }
- //! @brief Packed DP-FP Compare (SSE2).
- void cmppd(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstCmpPD, &dst, &src, &imm8); }
-
- //! @brief Compare Scalar SP-FP Values (SSE2).
- void cmpsd(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstCmpSD, &dst, &src, &imm8); }
- //! @brief Compare Scalar SP-FP Values (SSE2).
- void cmpsd(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstCmpSD, &dst, &src, &imm8); }
-
- //! @brief Scalar Ordered DP-FP Compare and Set EFLAGS (SSE2).
- void comisd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstComISD, &dst, &src); }
- //! @brief Scalar Ordered DP-FP Compare and Set EFLAGS (SSE2).
- void comisd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstComISD, &dst, &src); }
-
- //! @brief Convert Packed Dword Integers to Packed DP-FP Values (SSE2).
- void cvtdq2pd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvtDQ2PD, &dst, &src); }
- //! @brief Convert Packed Dword Integers to Packed DP-FP Values (SSE2).
- void cvtdq2pd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtDQ2PD, &dst, &src); }
-
- //! @brief Convert Packed Dword Integers to Packed SP-FP Values (SSE2).
- void cvtdq2ps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvtDQ2PS, &dst, &src); }
- //! @brief Convert Packed Dword Integers to Packed SP-FP Values (SSE2).
- void cvtdq2ps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtDQ2PS, &dst, &src); }
-
- //! @brief Convert Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvtpd2dq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvtPD2DQ, &dst, &src); }
- //! @brief Convert Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvtpd2dq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtPD2DQ, &dst, &src); }
-
- //! @brief Convert Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvtpd2pi(const MmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvtPD2PI, &dst, &src); }
- //! @brief Convert Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvtpd2pi(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtPD2PI, &dst, &src); }
-
- //! @brief Convert Packed DP-FP Values to Packed SP-FP Values (SSE2).
- void cvtpd2ps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvtPD2PS, &dst, &src); }
- //! @brief Convert Packed DP-FP Values to Packed SP-FP Values (SSE2).
- void cvtpd2ps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtPD2PS, &dst, &src); }
-
- //! @brief Convert Packed Dword Integers to Packed DP-FP Values (SSE2).
- void cvtpi2pd(const XmmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstCvtPI2PD, &dst, &src); }
- //! @brief Convert Packed Dword Integers to Packed DP-FP Values (SSE2).
- void cvtpi2pd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtPI2PD, &dst, &src); }
-
- //! @brief Convert Packed SP-FP Values to Packed Dword Integers (SSE2).
- void cvtps2dq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvtPS2DQ, &dst, &src); }
- //! @brief Convert Packed SP-FP Values to Packed Dword Integers (SSE2).
- void cvtps2dq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtPS2DQ, &dst, &src); }
-
- //! @brief Convert Packed SP-FP Values to Packed DP-FP Values (SSE2).
- void cvtps2pd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvtPS2PD, &dst, &src); }
- //! @brief Convert Packed SP-FP Values to Packed DP-FP Values (SSE2).
- void cvtps2pd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtPS2PD, &dst, &src); }
-
- //! @brief Convert Scalar DP-FP Value to Dword Integer (SSE2).
- void cvtsd2si(const GpReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvtSD2SI, &dst, &src); }
- //! @brief Convert Scalar DP-FP Value to Dword Integer (SSE2).
- void cvtsd2si(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtSD2SI, &dst, &src); }
-
- //! @brief Convert Scalar DP-FP Value to Scalar SP-FP Value (SSE2).
- void cvtsd2ss(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvtSD2SS, &dst, &src); }
- //! @brief Convert Scalar DP-FP Value to Scalar SP-FP Value (SSE2).
- void cvtsd2ss(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtSD2SS, &dst, &src); }
-
- //! @brief Convert Dword Integer to Scalar DP-FP Value (SSE2).
- void cvtsi2sd(const XmmReg& dst, const GpReg& src)
- { _emitInstruction(kX86InstCvtSI2SD, &dst, &src); }
- //! @brief Convert Dword Integer to Scalar DP-FP Value (SSE2).
- void cvtsi2sd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtSI2SD, &dst, &src); }
-
- //! @brief Convert Scalar SP-FP Value to Scalar DP-FP Value (SSE2).
- void cvtss2sd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvtSS2SD, &dst, &src); }
- //! @brief Convert Scalar SP-FP Value to Scalar DP-FP Value (SSE2).
- void cvtss2sd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvtSS2SD, &dst, &src); }
-
- //! @brief Convert with Truncation Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvttpd2pi(const MmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvttPD2PI, &dst, &src); }
- //! @brief Convert with Truncation Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvttpd2pi(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvttPD2PI, &dst, &src); }
-
- //! @brief Convert with Truncation Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvttpd2dq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvttPD2DQ, &dst, &src); }
- //! @brief Convert with Truncation Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvttpd2dq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvttPD2DQ, &dst, &src); }
-
- //! @brief Convert with Truncation Packed SP-FP Values to Packed Dword Integers (SSE2).
- void cvttps2dq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvttPS2DQ, &dst, &src); }
- //! @brief Convert with Truncation Packed SP-FP Values to Packed Dword Integers (SSE2).
- void cvttps2dq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvttPS2DQ, &dst, &src); }
-
- //! @brief Convert with Truncation Scalar DP-FP Value to Signed Dword Integer (SSE2).
- void cvttsd2si(const GpReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstCvttSD2SI, &dst, &src); }
- //! @brief Convert with Truncation Scalar DP-FP Value to Signed Dword Integer (SSE2).
- void cvttsd2si(const GpReg& dst, const Mem& src)
- { _emitInstruction(kX86InstCvttSD2SI, &dst, &src); }
-
- //! @brief Packed DP-FP Divide (SSE2).
- void divpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstDivPD, &dst, &src); }
- //! @brief Packed DP-FP Divide (SSE2).
- void divpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstDivPD, &dst, &src); }
-
- //! @brief Scalar DP-FP Divide (SSE2).
- void divsd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstDivSD, &dst, &src); }
- //! @brief Scalar DP-FP Divide (SSE2).
- void divsd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstDivSD, &dst, &src); }
-
- //! @brief Load Fence (SSE2).
- void lfence()
- { _emitInstruction(kX86InstLFence); }
-
- //! @brief Store Selected Bytes of Double Quadword (SSE2).
- //!
- //! @note Target is DS:EDI.
- void maskmovdqu(const XmmReg& src, const XmmReg& mask)
- { _emitInstruction(kX86InstMaskMovDQU, &src, &mask); }
-
- //! @brief Return Maximum Packed Double-Precision FP Values (SSE2).
- void maxpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMaxPD, &dst, &src); }
- //! @brief Return Maximum Packed Double-Precision FP Values (SSE2).
- void maxpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMaxPD, &dst, &src); }
-
- //! @brief Return Maximum Scalar Double-Precision FP Value (SSE2).
- void maxsd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMaxSD, &dst, &src); }
- //! @brief Return Maximum Scalar Double-Precision FP Value (SSE2).
- void maxsd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMaxSD, &dst, &src); }
-
- //! @brief Memory Fence (SSE2).
- void mfence()
- { _emitInstruction(kX86InstMFence); }
-
- //! @brief Return Minimum Packed DP-FP Values (SSE2).
- void minpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMinPD, &dst, &src); }
- //! @brief Return Minimum Packed DP-FP Values (SSE2).
- void minpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMinPD, &dst, &src); }
-
- //! @brief Return Minimum Scalar DP-FP Value (SSE2).
- void minsd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMinSD, &dst, &src); }
- //! @brief Return Minimum Scalar DP-FP Value (SSE2).
- void minsd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMinSD, &dst, &src); }
-
- //! @brief Move Aligned DQWord (SSE2).
- void movdqa(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovDQA, &dst, &src); }
- //! @brief Move Aligned DQWord (SSE2).
- void movdqa(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovDQA, &dst, &src); }
-
- //! @brief Move Aligned DQWord (SSE2).
- void movdqa(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovDQA, &dst, &src); }
-
- //! @brief Move Unaligned Double Quadword (SSE2).
- void movdqu(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovDQU, &dst, &src); }
- //! @brief Move Unaligned Double Quadword (SSE2).
- void movdqu(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovDQU, &dst, &src); }
-
- //! @brief Move Unaligned Double Quadword (SSE2).
- void movdqu(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovDQU, &dst, &src); }
-
- //! @brief Extract Packed SP-FP Sign Mask (SSE2).
- void movmskps(const GpReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovMskPS, &dst, &src); }
-
- //! @brief Extract Packed DP-FP Sign Mask (SSE2).
- void movmskpd(const GpReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovMskPD, &dst, &src); }
-
- //! @brief Move Scalar Double-Precision FP Value (SSE2).
- void movsd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovSD, &dst, &src); }
- //! @brief Move Scalar Double-Precision FP Value (SSE2).
- void movsd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovSD, &dst, &src); }
-
- //! @brief Move Scalar Double-Precision FP Value (SSE2).
- void movsd(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovSD, &dst, &src); }
-
- //! @brief Move Aligned Packed Double-Precision FP Values (SSE2).
- void movapd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovAPD, &dst, &src); }
-
- //! @brief Move Aligned Packed Double-Precision FP Values (SSE2).
- void movapd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovAPD, &dst, &src); }
-
- //! @brief Move Aligned Packed Double-Precision FP Values (SSE2).
- void movapd(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovAPD, &dst, &src); }
-
- //! @brief Move Quadword from XMM to MMX Technology Register (SSE2).
- void movdq2q(const MmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovDQ2Q, &dst, &src); }
-
- //! @brief Move Quadword from MMX Technology to XMM Register (SSE2).
- void movq2dq(const XmmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstMovQ2DQ, &dst, &src); }
-
- //! @brief Move High Packed Double-Precision FP Value (SSE2).
- void movhpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovHPD, &dst, &src); }
-
- //! @brief Move High Packed Double-Precision FP Value (SSE2).
- void movhpd(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovHPD, &dst, &src); }
-
- //! @brief Move Low Packed Double-Precision FP Value (SSE2).
- void movlpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovLPD, &dst, &src); }
-
- //! @brief Move Low Packed Double-Precision FP Value (SSE2).
- void movlpd(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovLPD, &dst, &src); }
-
- //! @brief Store Double Quadword Using Non-Temporal Hint (SSE2).
- void movntdq(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovNTDQ, &dst, &src); }
-
- //! @brief Store Store DWORD Using Non-Temporal Hint (SSE2).
- void movnti(const Mem& dst, const GpReg& src)
- { _emitInstruction(kX86InstMovNTI, &dst, &src); }
-
- //! @brief Store Packed Double-Precision FP Values Using Non-Temporal Hint (SSE2).
- void movntpd(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovNTPD, &dst, &src); }
-
- //! @brief Move Unaligned Packed Double-Precision FP Values (SSE2).
- void movupd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovUPD, &dst, &src); }
-
- //! @brief Move Unaligned Packed Double-Precision FP Values (SSE2).
- void movupd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovUPD, &dst, &src); }
-
- //! @brief Move Unaligned Packed Double-Precision FP Values (SSE2).
- void movupd(const Mem& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovUPD, &dst, &src); }
-
- //! @brief Packed DP-FP Multiply (SSE2).
- void mulpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMulPD, &dst, &src); }
- //! @brief Packed DP-FP Multiply (SSE2).
- void mulpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMulPD, &dst, &src); }
-
- //! @brief Scalar DP-FP Multiply (SSE2).
- void mulsd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMulSD, &dst, &src); }
- //! @brief Scalar DP-FP Multiply (SSE2).
- void mulsd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMulSD, &dst, &src); }
-
- //! @brief Bit-wise Logical OR for DP-FP Data (SSE2).
- void orpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstOrPD, &dst, &src); }
- //! @brief Bit-wise Logical OR for DP-FP Data (SSE2).
- void orpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstOrPD, &dst, &src); }
-
- //! @brief Pack with Signed Saturation (SSE2).
- void packsswb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPackSSWB, &dst, &src); }
- //! @brief Pack with Signed Saturation (SSE2).
- void packsswb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPackSSWB, &dst, &src); }
-
- //! @brief Pack with Signed Saturation (SSE2).
- void packssdw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPackSSDW, &dst, &src); }
- //! @brief Pack with Signed Saturation (SSE2).
- void packssdw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPackSSDW, &dst, &src); }
-
- //! @brief Pack with Unsigned Saturation (SSE2).
- void packuswb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPackUSWB, &dst, &src); }
- //! @brief Pack with Unsigned Saturation (SSE2).
- void packuswb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPackUSWB, &dst, &src); }
-
- //! @brief Packed BYTE Add (SSE2).
- void paddb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAddB, &dst, &src); }
- //! @brief Packed BYTE Add (SSE2).
- void paddb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddB, &dst, &src); }
-
- //! @brief Packed WORD Add (SSE2).
- void paddw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAddW, &dst, &src); }
- //! @brief Packed WORD Add (SSE2).
- void paddw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddW, &dst, &src); }
-
- //! @brief Packed DWORD Add (SSE2).
- void paddd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAddD, &dst, &src); }
- //! @brief Packed DWORD Add (SSE2).
- void paddd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddD, &dst, &src); }
-
- //! @brief Packed QWORD Add (SSE2).
- void paddq(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAddQ, &dst, &src); }
- //! @brief Packed QWORD Add (SSE2).
- void paddq(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddQ, &dst, &src); }
-
- //! @brief Packed QWORD Add (SSE2).
- void paddq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAddQ, &dst, &src); }
- //! @brief Packed QWORD Add (SSE2).
- void paddq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddQ, &dst, &src); }
-
- //! @brief Packed Add with Saturation (SSE2).
- void paddsb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAddSB, &dst, &src); }
- //! @brief Packed Add with Saturation (SSE2).
- void paddsb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddSB, &dst, &src); }
-
- //! @brief Packed Add with Saturation (SSE2).
- void paddsw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAddSW, &dst, &src); }
- //! @brief Packed Add with Saturation (SSE2).
- void paddsw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddSW, &dst, &src); }
-
- //! @brief Packed Add Unsigned with Saturation (SSE2).
- void paddusb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAddUSB, &dst, &src); }
- //! @brief Packed Add Unsigned with Saturation (SSE2).
- void paddusb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddUSB, &dst, &src); }
-
- //! @brief Packed Add Unsigned with Saturation (SSE2).
- void paddusw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAddUSW, &dst, &src); }
- //! @brief Packed Add Unsigned with Saturation (SSE2).
- void paddusw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAddUSW, &dst, &src); }
-
- //! @brief Logical AND (SSE2).
- void pand(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAnd, &dst, &src); }
- //! @brief Logical AND (SSE2).
- void pand(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAnd, &dst, &src); }
-
- //! @brief Logical AND Not (SSE2).
- void pandn(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAndN, &dst, &src); }
- //! @brief Logical AND Not (SSE2).
- void pandn(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAndN, &dst, &src); }
-
- //! @brief Spin Loop Hint (SSE2).
- void pause()
- { _emitInstruction(kX86InstPause); }
-
- //! @brief Packed Average (SSE2).
- void pavgb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAvgB, &dst, &src); }
- //! @brief Packed Average (SSE2).
- void pavgb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAvgB, &dst, &src); }
-
- //! @brief Packed Average (SSE2).
- void pavgw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAvgW, &dst, &src); }
- //! @brief Packed Average (SSE2).
- void pavgw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAvgW, &dst, &src); }
-
- //! @brief Packed Compare for Equal (BYTES) (SSE2).
- void pcmpeqb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPCmpEqB, &dst, &src); }
- //! @brief Packed Compare for Equal (BYTES) (SSE2).
- void pcmpeqb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpEqB, &dst, &src); }
-
- //! @brief Packed Compare for Equal (WORDS) (SSE2).
- void pcmpeqw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPCmpEqW, &dst, &src); }
- //! @brief Packed Compare for Equal (WORDS) (SSE2).
- void pcmpeqw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpEqW, &dst, &src); }
-
- //! @brief Packed Compare for Equal (DWORDS) (SSE2).
- void pcmpeqd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPCmpEqD, &dst, &src); }
- //! @brief Packed Compare for Equal (DWORDS) (SSE2).
- void pcmpeqd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpEqD, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (BYTES) (SSE2).
- void pcmpgtb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPCmpGtB, &dst, &src); }
- //! @brief Packed Compare for Greater Than (BYTES) (SSE2).
- void pcmpgtb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpGtB, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (WORDS) (SSE2).
- void pcmpgtw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPCmpGtW, &dst, &src); }
- //! @brief Packed Compare for Greater Than (WORDS) (SSE2).
- void pcmpgtw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpGtW, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (DWORDS) (SSE2).
- void pcmpgtd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPCmpGtD, &dst, &src); }
- //! @brief Packed Compare for Greater Than (DWORDS) (SSE2).
- void pcmpgtd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpGtD, &dst, &src); }
-
- //! @brief Packed Signed Integer Word Maximum (SSE2).
- void pmaxsw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMaxSW, &dst, &src); }
- //! @brief Packed Signed Integer Word Maximum (SSE2).
- void pmaxsw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMaxSW, &dst, &src); }
-
- //! @brief Packed Unsigned Integer Byte Maximum (SSE2).
- void pmaxub(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMaxUB, &dst, &src); }
- //! @brief Packed Unsigned Integer Byte Maximum (SSE2).
- void pmaxub(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMaxUB, &dst, &src); }
-
- //! @brief Packed Signed Integer Word Minimum (SSE2).
- void pminsw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMinSW, &dst, &src); }
- //! @brief Packed Signed Integer Word Minimum (SSE2).
- void pminsw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMinSW, &dst, &src); }
-
- //! @brief Packed Unsigned Integer Byte Minimum (SSE2).
- void pminub(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMinUB, &dst, &src); }
- //! @brief Packed Unsigned Integer Byte Minimum (SSE2).
- void pminub(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMinUB, &dst, &src); }
-
- //! @brief Move Byte Mask (SSE2).
- void pmovmskb(const GpReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMovMskB, &dst, &src); }
-
- //! @brief Packed Multiply High (SSE2).
- void pmulhw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMulHW, &dst, &src); }
- //! @brief Packed Multiply High (SSE2).
- void pmulhw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMulHW, &dst, &src); }
-
- //! @brief Packed Multiply High Unsigned (SSE2).
- void pmulhuw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMulHUW, &dst, &src); }
- //! @brief Packed Multiply High Unsigned (SSE2).
- void pmulhuw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMulHUW, &dst, &src); }
-
- //! @brief Packed Multiply Low (SSE2).
- void pmullw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMulLW, &dst, &src); }
- //! @brief Packed Multiply Low (SSE2).
- void pmullw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMulLW, &dst, &src); }
-
- //! @brief Packed Multiply to QWORD (SSE2).
- void pmuludq(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPMulUDQ, &dst, &src); }
- //! @brief Packed Multiply to QWORD (SSE2).
- void pmuludq(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMulUDQ, &dst, &src); }
-
- //! @brief Packed Multiply to QWORD (SSE2).
- void pmuludq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMulUDQ, &dst, &src); }
- //! @brief Packed Multiply to QWORD (SSE2).
- void pmuludq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMulUDQ, &dst, &src); }
-
- //! @brief Bitwise Logical OR (SSE2).
- void por(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPOr, &dst, &src); }
- //! @brief Bitwise Logical OR (SSE2).
- void por(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPOr, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (SSE2).
- void pslld(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSllD, &dst, &src); }
- //! @brief Packed Shift Left Logical (SSE2).
- void pslld(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSllD, &dst, &src); }
- //! @brief Packed Shift Left Logical (SSE2).
- void pslld(const XmmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSllD, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (SSE2).
- void psllq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSllQ, &dst, &src); }
- //! @brief Packed Shift Left Logical (SSE2).
- void psllq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSllQ, &dst, &src); }
- //! @brief Packed Shift Left Logical (SSE2).
- void psllq(const XmmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSllQ, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (SSE2).
- void psllw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSllW, &dst, &src); }
- //! @brief Packed Shift Left Logical (SSE2).
- void psllw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSllW, &dst, &src); }
- //! @brief Packed Shift Left Logical (SSE2).
- void psllw(const XmmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSllW, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (SSE2).
- void pslldq(const XmmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSllDQ, &dst, &src); }
-
- //! @brief Packed Shift Right Arithmetic (SSE2).
- void psrad(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSraD, &dst, &src); }
- //! @brief Packed Shift Right Arithmetic (SSE2).
- void psrad(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSraD, &dst, &src); }
- //! @brief Packed Shift Right Arithmetic (SSE2).
- void psrad(const XmmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSraD, &dst, &src); }
-
- //! @brief Packed Shift Right Arithmetic (SSE2).
- void psraw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSraW, &dst, &src); }
- //! @brief Packed Shift Right Arithmetic (SSE2).
- void psraw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSraW, &dst, &src); }
- //! @brief Packed Shift Right Arithmetic (SSE2).
- void psraw(const XmmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSraW, &dst, &src); }
-
- //! @brief Packed Subtract (SSE2).
- void psubb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSubB, &dst, &src); }
- //! @brief Packed Subtract (SSE2).
- void psubb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubB, &dst, &src); }
-
- //! @brief Packed Subtract (SSE2).
- void psubw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSubW, &dst, &src); }
- //! @brief Packed Subtract (SSE2).
- void psubw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubW, &dst, &src); }
-
- //! @brief Packed Subtract (SSE2).
- void psubd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSubD, &dst, &src); }
- //! @brief Packed Subtract (SSE2).
- void psubd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubD, &dst, &src); }
-
- //! @brief Packed Subtract (SSE2).
- void psubq(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSubQ, &dst, &src); }
- //! @brief Packed Subtract (SSE2).
- void psubq(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubQ, &dst, &src); }
-
- //! @brief Packed Subtract (SSE2).
- void psubq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSubQ, &dst, &src); }
- //! @brief Packed Subtract (SSE2).
- void psubq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubQ, &dst, &src); }
-
- //! @brief Packed Multiply and Add (SSE2).
- void pmaddwd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMAddWD, &dst, &src); }
- //! @brief Packed Multiply and Add (SSE2).
- void pmaddwd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMAddWD, &dst, &src); }
-
- //! @brief Shuffle Packed DWORDs (SSE2).
- void pshufd(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPShufD, &dst, &src, &imm8); }
- //! @brief Shuffle Packed DWORDs (SSE2).
- void pshufd(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPShufD, &dst, &src, &imm8); }
-
- //! @brief Shuffle Packed High Words (SSE2).
- void pshufhw(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPShufHW, &dst, &src, &imm8); }
- //! @brief Shuffle Packed High Words (SSE2).
- void pshufhw(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPShufHW, &dst, &src, &imm8); }
-
- //! @brief Shuffle Packed Low Words (SSE2).
- void pshuflw(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPShufLW, &dst, &src, &imm8); }
- //! @brief Shuffle Packed Low Words (SSE2).
- void pshuflw(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPShufLW, &dst, &src, &imm8); }
-
- //! @brief Packed Shift Right Logical (SSE2).
- void psrld(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSrlD, &dst, &src); }
- //! @brief Packed Shift Right Logical (SSE2).
- void psrld(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSrlD, &dst, &src); }
- //! @brief Packed Shift Right Logical (SSE2).
- void psrld(const XmmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSrlD, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (SSE2).
- void psrlq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSrlQ, &dst, &src); }
- //! @brief Packed Shift Right Logical (SSE2).
- void psrlq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSrlQ, &dst, &src); }
- //! @brief Packed Shift Right Logical (SSE2).
- void psrlq(const XmmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSrlQ, &dst, &src); }
-
- //! @brief DQWord Shift Right Logical (MMX).
- void psrldq(const XmmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSrlDQ, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (SSE2).
- void psrlw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSrlW, &dst, &src); }
- //! @brief Packed Shift Right Logical (SSE2).
- void psrlw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSrlW, &dst, &src); }
- //! @brief Packed Shift Right Logical (SSE2).
- void psrlw(const XmmReg& dst, const Imm& src)
- { _emitInstruction(kX86InstPSrlW, &dst, &src); }
-
- //! @brief Packed Subtract with Saturation (SSE2).
- void psubsb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSubSB, &dst, &src); }
- //! @brief Packed Subtract with Saturation (SSE2).
- void psubsb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubSB, &dst, &src); }
-
- //! @brief Packed Subtract with Saturation (SSE2).
- void psubsw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSubSW, &dst, &src); }
- //! @brief Packed Subtract with Saturation (SSE2).
- void psubsw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubSW, &dst, &src); }
-
- //! @brief Packed Subtract with Unsigned Saturation (SSE2).
- void psubusb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSubUSB, &dst, &src); }
- //! @brief Packed Subtract with Unsigned Saturation (SSE2).
- void psubusb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubUSB, &dst, &src); }
-
- //! @brief Packed Subtract with Unsigned Saturation (SSE2).
- void psubusw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSubUSW, &dst, &src); }
- //! @brief Packed Subtract with Unsigned Saturation (SSE2).
- void psubusw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSubUSW, &dst, &src); }
-
- //! @brief Unpack High Data (SSE2).
- void punpckhbw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPunpckHBW, &dst, &src); }
- //! @brief Unpack High Data (SSE2).
- void punpckhbw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckHBW, &dst, &src); }
-
- //! @brief Unpack High Data (SSE2).
- void punpckhwd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPunpckHWD, &dst, &src); }
- //! @brief Unpack High Data (SSE2).
- void punpckhwd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckHWD, &dst, &src); }
-
- //! @brief Unpack High Data (SSE2).
- void punpckhdq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPunpckHDQ, &dst, &src); }
- //! @brief Unpack High Data (SSE2).
- void punpckhdq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckHDQ, &dst, &src); }
-
- //! @brief Unpack High Data (SSE2).
- void punpckhqdq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPunpckHQDQ, &dst, &src); }
- //! @brief Unpack High Data (SSE2).
- void punpckhqdq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckHQDQ, &dst, &src); }
-
- //! @brief Unpack Low Data (SSE2).
- void punpcklbw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPunpckLBW, &dst, &src); }
- //! @brief Unpack Low Data (SSE2).
- void punpcklbw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckLBW, &dst, &src); }
-
- //! @brief Unpack Low Data (SSE2).
- void punpcklwd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPunpckLWD, &dst, &src); }
- //! @brief Unpack Low Data (SSE2).
- void punpcklwd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckLWD, &dst, &src); }
-
- //! @brief Unpack Low Data (SSE2).
- void punpckldq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPunpckLDQ, &dst, &src); }
- //! @brief Unpack Low Data (SSE2).
- void punpckldq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckLDQ, &dst, &src); }
-
- //! @brief Unpack Low Data (SSE2).
- void punpcklqdq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPunpckLQDQ, &dst, &src); }
- //! @brief Unpack Low Data (SSE2).
- void punpcklqdq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPunpckLQDQ, &dst, &src); }
-
- //! @brief Bitwise Exclusive OR (SSE2).
- void pxor(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPXor, &dst, &src); }
- //! @brief Bitwise Exclusive OR (SSE2).
- void pxor(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPXor, &dst, &src); }
-
- //! @brief Shuffle DP-FP (SSE2).
- void shufpd(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstShufPD, &dst, &src, &imm8); }
- //! @brief Shuffle DP-FP (SSE2).
- void shufpd(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstShufPD, &dst, &src, &imm8); }
-
- //! @brief Compute Square Roots of Packed DP-FP Values (SSE2).
- void sqrtpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstSqrtPD, &dst, &src); }
- //! @brief Compute Square Roots of Packed DP-FP Values (SSE2).
- void sqrtpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstSqrtPD, &dst, &src); }
-
- //! @brief Compute Square Root of Scalar DP-FP Value (SSE2).
- void sqrtsd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstSqrtSD, &dst, &src); }
- //! @brief Compute Square Root of Scalar DP-FP Value (SSE2).
- void sqrtsd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstSqrtSD, &dst, &src); }
-
- //! @brief Packed DP-FP Subtract (SSE2).
- void subpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstSubPD, &dst, &src); }
- //! @brief Packed DP-FP Subtract (SSE2).
- void subpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstSubPD, &dst, &src); }
-
- //! @brief Scalar DP-FP Subtract (SSE2).
- void subsd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstSubSD, &dst, &src); }
- //! @brief Scalar DP-FP Subtract (SSE2).
- void subsd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstSubSD, &dst, &src); }
-
- //! @brief Scalar Unordered DP-FP Compare and Set EFLAGS (SSE2).
- void ucomisd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstUComISD, &dst, &src); }
- //! @brief Scalar Unordered DP-FP Compare and Set EFLAGS (SSE2).
- void ucomisd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstUComISD, &dst, &src); }
-
- //! @brief Unpack and Interleave High Packed Double-Precision FP Values (SSE2).
- void unpckhpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstUnpckHPD, &dst, &src); }
- //! @brief Unpack and Interleave High Packed Double-Precision FP Values (SSE2).
- void unpckhpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstUnpckHPD, &dst, &src); }
-
- //! @brief Unpack and Interleave Low Packed Double-Precision FP Values (SSE2).
- void unpcklpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstUnpckLPD, &dst, &src); }
- //! @brief Unpack and Interleave Low Packed Double-Precision FP Values (SSE2).
- void unpcklpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstUnpckLPD, &dst, &src); }
-
- //! @brief Bit-wise Logical OR for DP-FP Data (SSE2).
- void xorpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstXorPD, &dst, &src); }
- //! @brief Bit-wise Logical OR for DP-FP Data (SSE2).
- void xorpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstXorPD, &dst, &src); }
+ //! Packed DP-FP add (SSE2).
+ INST_2x(addpd, kX86InstIdAddpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(addpd, kX86InstIdAddpd, X86XmmReg, X86Mem)
+
+ //! Scalar DP-FP add (SSE2).
+ INST_2x(addsd, kX86InstIdAddsd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(addsd, kX86InstIdAddsd, X86XmmReg, X86Mem)
+
+ //! Packed DP-FP bitwise and-not (SSE2).
+ INST_2x(andnpd, kX86InstIdAndnpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(andnpd, kX86InstIdAndnpd, X86XmmReg, X86Mem)
+
+ //! Packed DP-FP bitwise and (SSE2).
+ INST_2x(andpd, kX86InstIdAndpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(andpd, kX86InstIdAndpd, X86XmmReg, X86Mem)
+
+ //! Flush cache line (SSE2).
+ INST_1x(clflush, kX86InstIdClflush, X86Mem)
+
+ //! Packed DP-FP compare (SSE2).
+ INST_3i(cmppd, kX86InstIdCmppd, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(cmppd, kX86InstIdCmppd, X86XmmReg, X86Mem, Imm)
+
+ //! Scalar SP-FP compare (SSE2).
+ INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmReg, X86Mem, Imm)
+
+ //! Scalar ordered DP-FP compare and set EFLAGS (SSE2).
+ INST_2x(comisd, kX86InstIdComisd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(comisd, kX86InstIdComisd, X86XmmReg, X86Mem)
+
+ //! Convert packed QWORDs to packed DP-FP (SSE2).
+ INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmReg, X86Mem)
+
+ //! Convert packed QWORDs to packed SP-FP (SSE2).
+ INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmReg, X86Mem)
+
+ //! Convert packed DP-FP to packed QWORDs (SSE2).
+ INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmReg, X86Mem)
+
+ //! Convert packed DP-FP to packed QRODSs (SSE2).
+ INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmReg, X86Mem)
+
+ //! Convert packed DP-FP to packed SP-FP (SSE2).
+ INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmReg, X86Mem)
+
+ //! Convert packed DWORDs integers to packed DP-FP (SSE2).
+ INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmReg, X86MmReg)
+ //! \overload
+ INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmReg, X86Mem)
+
+ //! Convert packed SP-FP to packed QWORDs (SSE2).
+ INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmReg, X86Mem)
+
+ //! Convert packed SP-FP to packed DP-FP (SSE2).
+ INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmReg, X86Mem)
+
+ //! Convert scalar DP-FP to DWORD integer (SSE2).
+ INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpReg, X86Mem)
+
+ //! Convert scalar DP-FP to scalar SP-FP (SSE2).
+ INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmReg, X86Mem)
+
+ //! Convert DWORD integer to scalar DP-FP (SSE2).
+ INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmReg, X86GpReg)
+ //! \overload
+ INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmReg, X86Mem)
+
+ //! Convert scalar SP-FP to DP-FP (SSE2).
+ INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmReg, X86Mem)
+
+ //! Convert with truncation packed DP-FP to packed DWORDs (SSE2).
+ INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmReg, X86Mem)
+
+ //! Convert with truncation packed DP-FP to packed QWORDs (SSE2).
+ INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmReg, X86Mem)
+
+ //! Convert with truncation packed SP-FP to packed QWORDs (SSE2).
+ INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmReg, X86Mem)
+
+ //! Convert with truncation scalar DP-FP to signed DWORDs (SSE2).
+ INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpReg, X86XmmReg)
+ //! \overload
+ INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpReg, X86Mem)
+
+ //! Packed DP-FP divide (SSE2).
+ INST_2x(divpd, kX86InstIdDivpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(divpd, kX86InstIdDivpd, X86XmmReg, X86Mem)
+
+ //! Scalar DP-FP divide (SSE2).
+ INST_2x(divsd, kX86InstIdDivsd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(divsd, kX86InstIdDivsd, X86XmmReg, X86Mem)
+
+ //! Load fence (SSE2).
+ INST_0x(lfence, kX86InstIdLfence)
+
+ //! Store selected bytes of OWORD to DS:EDI/RDI (SSE2).
+ INST_2x(maskmovdqu, kX86InstIdMaskmovdqu, X86XmmReg, X86XmmReg)
+
+ //! Packed DP-FP maximum (SSE2).
+ INST_2x(maxpd, kX86InstIdMaxpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(maxpd, kX86InstIdMaxpd, X86XmmReg, X86Mem)
+
+ //! Scalar DP-FP maximum (SSE2).
+ INST_2x(maxsd, kX86InstIdMaxsd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(maxsd, kX86InstIdMaxsd, X86XmmReg, X86Mem)
+
+ //! Memory fence (SSE2).
+ INST_0x(mfence, kX86InstIdMfence)
+
+ //! Packed DP-FP minimum (SSE2).
+ INST_2x(minpd, kX86InstIdMinpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(minpd, kX86InstIdMinpd, X86XmmReg, X86Mem)
+
+ //! Scalar DP-FP minimum (SSE2).
+ INST_2x(minsd, kX86InstIdMinsd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(minsd, kX86InstIdMinsd, X86XmmReg, X86Mem)
+
+ //! Move aligned OWORD (SSE2).
+ INST_2x(movdqa, kX86InstIdMovdqa, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(movdqa, kX86InstIdMovdqa, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(movdqa, kX86InstIdMovdqa, X86Mem, X86XmmReg)
+
+ //! Move unaligned OWORD (SSE2).
+ INST_2x(movdqu, kX86InstIdMovdqu, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(movdqu, kX86InstIdMovdqu, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(movdqu, kX86InstIdMovdqu, X86Mem, X86XmmReg)
+
+ //! Extract packed SP-FP sign mask (SSE2).
+ INST_2x(movmskps, kX86InstIdMovmskps, X86GpReg, X86XmmReg)
+
+ //! Extract packed DP-FP sign mask (SSE2).
+ INST_2x(movmskpd, kX86InstIdMovmskpd, X86GpReg, X86XmmReg)
+
+ //! Move scalar DP-FP (SSE2).
+ INST_2x(movsd, kX86InstIdMovsd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(movsd, kX86InstIdMovsd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(movsd, kX86InstIdMovsd, X86Mem, X86XmmReg)
+
+ //! Move aligned packed DP-FP (SSE2).
+ INST_2x(movapd, kX86InstIdMovapd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(movapd, kX86InstIdMovapd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(movapd, kX86InstIdMovapd, X86Mem, X86XmmReg)
+
+ //! Move QWORD from Xmm to Mm register (SSE2).
+ INST_2x(movdq2q, kX86InstIdMovdq2q, X86MmReg, X86XmmReg)
+
+ //! Move QWORD from Mm to Xmm register (SSE2).
+ INST_2x(movq2dq, kX86InstIdMovq2dq, X86XmmReg, X86MmReg)
+
+ //! Move high packed DP-FP (SSE2).
+ INST_2x(movhpd, kX86InstIdMovhpd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(movhpd, kX86InstIdMovhpd, X86Mem, X86XmmReg)
+
+ //! Move low packed DP-FP (SSE2).
+ INST_2x(movlpd, kX86InstIdMovlpd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(movlpd, kX86InstIdMovlpd, X86Mem, X86XmmReg)
+
+ //! Store OWORD using NT hint (SSE2).
+ INST_2x(movntdq, kX86InstIdMovntdq, X86Mem, X86XmmReg)
+
+ //! Store DWORD using NT hint (SSE2).
+ INST_2x(movnti, kX86InstIdMovnti, X86Mem, X86GpReg)
+
+ //! Store packed DP-FP using NT hint (SSE2).
+ INST_2x(movntpd, kX86InstIdMovntpd, X86Mem, X86XmmReg)
+
+ //! Move unaligned packed DP-FP (SSE2).
+ INST_2x(movupd, kX86InstIdMovupd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(movupd, kX86InstIdMovupd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(movupd, kX86InstIdMovupd, X86Mem, X86XmmReg)
+
+ //! Packed DP-FP multiply (SSE2).
+ INST_2x(mulpd, kX86InstIdMulpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(mulpd, kX86InstIdMulpd, X86XmmReg, X86Mem)
+
+ //! Scalar DP-FP multiply (SSE2).
+ INST_2x(mulsd, kX86InstIdMulsd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(mulsd, kX86InstIdMulsd, X86XmmReg, X86Mem)
+
+ //! Packed DP-FP bitwise or (SSE2).
+ INST_2x(orpd, kX86InstIdOrpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(orpd, kX86InstIdOrpd, X86XmmReg, X86Mem)
+
+ //! Pack WORDs to BYTEs with signed saturation (SSE2).
+ INST_2x(packsswb, kX86InstIdPacksswb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(packsswb, kX86InstIdPacksswb, X86XmmReg, X86Mem)
+
+ //! Pack DWORDs to WORDs with signed saturation (SSE2).
+ INST_2x(packssdw, kX86InstIdPackssdw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(packssdw, kX86InstIdPackssdw, X86XmmReg, X86Mem)
+
+ //! Pack WORDs to BYTEs with unsigned saturation (SSE2).
+ INST_2x(packuswb, kX86InstIdPackuswb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(packuswb, kX86InstIdPackuswb, X86XmmReg, X86Mem)
+
+ //! Packed BYTE Add (SSE2).
+ INST_2x(paddb, kX86InstIdPaddb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(paddb, kX86InstIdPaddb, X86XmmReg, X86Mem)
+
+ //! Packed WORD add (SSE2).
+ INST_2x(paddw, kX86InstIdPaddw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(paddw, kX86InstIdPaddw, X86XmmReg, X86Mem)
+
+ //! Packed DWORD add (SSE2).
+ INST_2x(paddd, kX86InstIdPaddd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(paddd, kX86InstIdPaddd, X86XmmReg, X86Mem)
+
+ //! Packed QWORD add (SSE2).
+ INST_2x(paddq, kX86InstIdPaddq, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(paddq, kX86InstIdPaddq, X86MmReg, X86Mem)
+
+ //! Packed QWORD add (SSE2).
+ INST_2x(paddq, kX86InstIdPaddq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(paddq, kX86InstIdPaddq, X86XmmReg, X86Mem)
+
+ //! Packed BYTE add with saturation (SSE2).
+ INST_2x(paddsb, kX86InstIdPaddsb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(paddsb, kX86InstIdPaddsb, X86XmmReg, X86Mem)
+
+ //! Packed WORD add with saturation (SSE2).
+ INST_2x(paddsw, kX86InstIdPaddsw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(paddsw, kX86InstIdPaddsw, X86XmmReg, X86Mem)
+
+ //! Packed BYTE add with unsigned saturation (SSE2).
+ INST_2x(paddusb, kX86InstIdPaddusb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(paddusb, kX86InstIdPaddusb, X86XmmReg, X86Mem)
+
+ //! Packed WORD add with unsigned saturation (SSE2).
+ INST_2x(paddusw, kX86InstIdPaddusw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(paddusw, kX86InstIdPaddusw, X86XmmReg, X86Mem)
+
+ //! Packed bitwise and (SSE2).
+ INST_2x(pand, kX86InstIdPand, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pand, kX86InstIdPand, X86XmmReg, X86Mem)
+
+ //! Packed bitwise and-not (SSE2).
+ INST_2x(pandn, kX86InstIdPandn, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pandn, kX86InstIdPandn, X86XmmReg, X86Mem)
+
+ //! Spin loop hint (SSE2).
+ INST_0x(pause, kX86InstIdPause)
+
+ //! Packed BYTE average (SSE2).
+ INST_2x(pavgb, kX86InstIdPavgb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pavgb, kX86InstIdPavgb, X86XmmReg, X86Mem)
+
+ //! Packed WORD average (SSE2).
+ INST_2x(pavgw, kX86InstIdPavgw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pavgw, kX86InstIdPavgw, X86XmmReg, X86Mem)
+
+ //! Packed BYTE compare for equality (SSE2).
+ INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmReg, X86Mem)
+
+ //! Packed WORD compare for equality (SSE2).
+ INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmReg, X86Mem)
+
+ //! Packed DWORD compare for equality (SSE2).
+ INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmReg, X86Mem)
+
+ //! Packed BYTE compare if greater than (SSE2).
+ INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmReg, X86Mem)
+
+ //! Packed WORD compare if greater than (SSE2).
+ INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmReg, X86Mem)
+
+ //! Packed DWORD compare if greater than (SSE2).
+ INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmReg, X86Mem)
+
+ //! Extract WORD based on selector (SSE2).
+ INST_3i(pextrw, kX86InstIdPextrw, X86GpReg, X86XmmReg, Imm)
+
+ //! Insert WORD based on selector (SSE2).
+ INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmReg, X86GpReg, Imm)
+ //! \overload
+ INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmReg, X86Mem, Imm)
+
+ //! Packed WORD maximum (SSE2).
+ INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmReg, X86Mem)
+
+ //! Packed BYTE unsigned maximum (SSE2).
+ INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmReg, X86Mem)
+
+ //! Packed WORD minimum (SSE2).
+ INST_2x(pminsw, kX86InstIdPminsw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pminsw, kX86InstIdPminsw, X86XmmReg, X86Mem)
+
+ //! Packed BYTE unsigned minimum (SSE2).
+ INST_2x(pminub, kX86InstIdPminub, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pminub, kX86InstIdPminub, X86XmmReg, X86Mem)
+
+ //! Move byte mask (SSE2).
+ INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpReg, X86XmmReg)
+
+ //! Packed WORD multiply high (SSE2).
+ INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmReg, X86Mem)
+
+ //! Packed WORD unsigned multiply high (SSE2).
+ INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmReg, X86Mem)
+
+ //! Packed WORD multiply low (SSE2).
+ INST_2x(pmullw, kX86InstIdPmullw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmullw, kX86InstIdPmullw, X86XmmReg, X86Mem)
+
+ //! Packed DWORD multiply to QWORD (SSE2).
+ INST_2x(pmuludq, kX86InstIdPmuludq, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pmuludq, kX86InstIdPmuludq, X86MmReg, X86Mem)
+
+ //! Packed DWORD multiply to QWORD (SSE2).
+ INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmReg, X86Mem)
+
+ //! Packed bitwise or (SSE2).
+ INST_2x(por, kX86InstIdPor, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(por, kX86InstIdPor, X86XmmReg, X86Mem)
+
+ //! Packed DWORD shift left logical (SSE2).
+ INST_2x(pslld, kX86InstIdPslld, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pslld, kX86InstIdPslld, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2i(pslld, kX86InstIdPslld, X86XmmReg, Imm)
+
+ //! Packed QWORD shift left logical (SSE2).
+ INST_2x(psllq, kX86InstIdPsllq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psllq, kX86InstIdPsllq, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2i(psllq, kX86InstIdPsllq, X86XmmReg, Imm)
+
+ //! Packed WORD shift left logical (SSE2).
+ INST_2x(psllw, kX86InstIdPsllw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psllw, kX86InstIdPsllw, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2i(psllw, kX86InstIdPsllw, X86XmmReg, Imm)
+
+ //! Packed OWORD shift left logical (SSE2).
+ INST_2i(pslldq, kX86InstIdPslldq, X86XmmReg, Imm)
+
+ //! Packed DWORD shift right arithmetic (SSE2).
+ INST_2x(psrad, kX86InstIdPsrad, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psrad, kX86InstIdPsrad, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2i(psrad, kX86InstIdPsrad, X86XmmReg, Imm)
+
+ //! Packed WORD shift right arithmetic (SSE2).
+ INST_2x(psraw, kX86InstIdPsraw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psraw, kX86InstIdPsraw, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2i(psraw, kX86InstIdPsraw, X86XmmReg, Imm)
+
+ //! Packed BYTE subtract (SSE2).
+ INST_2x(psubb, kX86InstIdPsubb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psubb, kX86InstIdPsubb, X86XmmReg, X86Mem)
+
+ //! Packed DWORD subtract (SSE2).
+ INST_2x(psubd, kX86InstIdPsubd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psubd, kX86InstIdPsubd, X86XmmReg, X86Mem)
+
+ //! Packed QWORD subtract (SSE2).
+ INST_2x(psubq, kX86InstIdPsubq, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psubq, kX86InstIdPsubq, X86MmReg, X86Mem)
+
+ //! Packed QWORD subtract (SSE2).
+ INST_2x(psubq, kX86InstIdPsubq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psubq, kX86InstIdPsubq, X86XmmReg, X86Mem)
+
+ //! Packed WORD subtract (SSE2).
+ INST_2x(psubw, kX86InstIdPsubw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psubw, kX86InstIdPsubw, X86XmmReg, X86Mem)
+
+ //! Packed WORD to DWORD multiply and add (SSE2).
+ INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmReg, X86Mem)
+
+ //! Packed DWORD shuffle (SSE2).
+ INST_3i(pshufd, kX86InstIdPshufd, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(pshufd, kX86InstIdPshufd, X86XmmReg, X86Mem, Imm)
+
+ //! Packed WORD shuffle high (SSE2).
+ INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmReg, X86Mem, Imm)
+
+ //! Packed WORD shuffle low (SSE2).
+ INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmReg, X86Mem, Imm)
+
+ //! Packed DWORD shift right logical (SSE2).
+ INST_2x(psrld, kX86InstIdPsrld, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psrld, kX86InstIdPsrld, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2i(psrld, kX86InstIdPsrld, X86XmmReg, Imm)
+
+ //! Packed QWORD shift right logical (SSE2).
+ INST_2x(psrlq, kX86InstIdPsrlq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psrlq, kX86InstIdPsrlq, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2i(psrlq, kX86InstIdPsrlq, X86XmmReg, Imm)
+
+ //! Scalar OWORD shift right logical (SSE2).
+ INST_2i(psrldq, kX86InstIdPsrldq, X86XmmReg, Imm)
+
+ //! Packed WORD shift right logical (SSE2).
+ INST_2x(psrlw, kX86InstIdPsrlw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psrlw, kX86InstIdPsrlw, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2i(psrlw, kX86InstIdPsrlw, X86XmmReg, Imm)
+
+ //! Packed BYTE subtract with saturation (SSE2).
+ INST_2x(psubsb, kX86InstIdPsubsb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psubsb, kX86InstIdPsubsb, X86XmmReg, X86Mem)
+
+ //! Packed WORD subtract with saturation (SSE2).
+ INST_2x(psubsw, kX86InstIdPsubsw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psubsw, kX86InstIdPsubsw, X86XmmReg, X86Mem)
+
+ //! Packed BYTE subtract with unsigned saturation (SSE2).
+ INST_2x(psubusb, kX86InstIdPsubusb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psubusb, kX86InstIdPsubusb, X86XmmReg, X86Mem)
+
+ //! Packed WORD subtract with unsigned saturation (SSE2).
+ INST_2x(psubusw, kX86InstIdPsubusw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psubusw, kX86InstIdPsubusw, X86XmmReg, X86Mem)
+
+ //! Unpack high packed BYTEs to WORDs (SSE2).
+ INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmReg, X86Mem)
+
+ //! Unpack high packed DWORDs to QWORDs (SSE2).
+ INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmReg, X86Mem)
+
+ //! Unpack high packed QWORDs to OWORD (SSE2).
+ INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmReg, X86Mem)
+
+ //! Unpack high packed WORDs to DWORDs (SSE2).
+ INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmReg, X86Mem)
+
+ //! Unpack low packed BYTEs to WORDs (SSE2).
+ INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmReg, X86Mem)
+
+ //! Unpack low packed DWORDs to QWORDs (SSE2).
+ INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmReg, X86Mem)
+
+ //! Unpack low packed QWORDs to OWORD (SSE2).
+ INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmReg, X86Mem)
+
+ //! Unpack low packed WORDs to DWORDs (SSE2).
+ INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmReg, X86Mem)
+
+ //! Packed bitwise xor (SSE2).
+ INST_2x(pxor, kX86InstIdPxor, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pxor, kX86InstIdPxor, X86XmmReg, X86Mem)
+
+ //! Shuffle DP-FP (SSE2).
+ INST_3i(shufpd, kX86InstIdShufpd, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(shufpd, kX86InstIdShufpd, X86XmmReg, X86Mem, Imm)
+
+ //! Packed DP-FP square root (SSE2).
+ INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmReg, X86Mem)
+
+ //! Scalar DP-FP square root (SSE2).
+ INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmReg, X86Mem)
+
+ //! Packed DP-FP subtract (SSE2).
+ INST_2x(subpd, kX86InstIdSubpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(subpd, kX86InstIdSubpd, X86XmmReg, X86Mem)
+
+ //! Scalar DP-FP subtract (SSE2).
+ INST_2x(subsd, kX86InstIdSubsd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(subsd, kX86InstIdSubsd, X86XmmReg, X86Mem)
+
+ //! Scalar DP-FP unordered compare and set EFLAGS (SSE2).
+ INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmReg, X86Mem)
+
+ //! Unpack and interleave high packed DP-FP (SSE2).
+ INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmReg, X86Mem)
+
+ //! Unpack and interleave low packed DP-FP (SSE2).
+ INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmReg, X86Mem)
+
+ //! Packed DP-FP bitwise xor (SSE2).
+ INST_2x(xorpd, kX86InstIdXorpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(xorpd, kX86InstIdXorpd, X86XmmReg, X86Mem)
// --------------------------------------------------------------------------
// [SSE3]
// --------------------------------------------------------------------------
- //! @brief Packed DP-FP Add/Subtract (SSE3).
- void addsubpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstAddSubPD, &dst, &src); }
- //! @brief Packed DP-FP Add/Subtract (SSE3).
- void addsubpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstAddSubPD, &dst, &src); }
-
- //! @brief Packed SP-FP Add/Subtract (SSE3).
- void addsubps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstAddSubPS, &dst, &src); }
- //! @brief Packed SP-FP Add/Subtract (SSE3).
- void addsubps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstAddSubPS, &dst, &src); }
-
- //! @brief Store Integer with Truncation (SSE3).
- void fisttp(const Mem& dst)
- { _emitInstruction(kX86InstFISttP, &dst); }
-
- //! @brief Packed DP-FP Horizontal Add (SSE3).
- void haddpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstHAddPD, &dst, &src); }
- //! @brief Packed DP-FP Horizontal Add (SSE3).
- void haddpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstHAddPD, &dst, &src); }
-
- //! @brief Packed SP-FP Horizontal Add (SSE3).
- void haddps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstHAddPS, &dst, &src); }
- //! @brief Packed SP-FP Horizontal Add (SSE3).
- void haddps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstHAddPS, &dst, &src); }
-
- //! @brief Packed DP-FP Horizontal Subtract (SSE3).
- void hsubpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstHSubPD, &dst, &src); }
- //! @brief Packed DP-FP Horizontal Subtract (SSE3).
- void hsubpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstHSubPD, &dst, &src); }
-
- //! @brief Packed SP-FP Horizontal Subtract (SSE3).
- void hsubps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstHSubPS, &dst, &src); }
- //! @brief Packed SP-FP Horizontal Subtract (SSE3).
- void hsubps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstHSubPS, &dst, &src); }
-
- //! @brief Load Unaligned Integer 128 Bits (SSE3).
- void lddqu(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstLdDQU, &dst, &src); }
-
- //! @brief Set Up Monitor Address (SSE3).
- void monitor()
- { _emitInstruction(kX86InstMonitor); }
-
- //! @brief Move One DP-FP and Duplicate (SSE3).
- void movddup(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovDDup, &dst, &src); }
- //! @brief Move One DP-FP and Duplicate (SSE3).
- void movddup(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovDDup, &dst, &src); }
-
- //! @brief Move Packed SP-FP High and Duplicate (SSE3).
- void movshdup(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovSHDup, &dst, &src); }
- //! @brief Move Packed SP-FP High and Duplicate (SSE3).
- void movshdup(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovSHDup, &dst, &src); }
-
- //! @brief Move Packed SP-FP Low and Duplicate (SSE3).
- void movsldup(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstMovSLDup, &dst, &src); }
- //! @brief Move Packed SP-FP Low and Duplicate (SSE3).
- void movsldup(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovSLDup, &dst, &src); }
-
- //! @brief Monitor Wait (SSE3).
- void mwait()
- { _emitInstruction(kX86InstMWait); }
+ //! Packed DP-FP add/subtract (SSE3).
+ INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP add/subtract (SSE3).
+ INST_2x(addsubps, kX86InstIdAddsubps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(addsubps, kX86InstIdAddsubps, X86XmmReg, X86Mem)
+
+ //! Store truncated `fp0` as 16-bit, 32-bit or 64-bit integer to `o0` and pop
+ //! the FPU stack (FPU / SSE3).
+ INST_1x(fisttp, kX86InstIdFisttp, X86Mem)
+
+ //! Packed DP-FP horizontal add (SSE3).
+ INST_2x(haddpd, kX86InstIdHaddpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(haddpd, kX86InstIdHaddpd, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP horizontal add (SSE3).
+ INST_2x(haddps, kX86InstIdHaddps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(haddps, kX86InstIdHaddps, X86XmmReg, X86Mem)
+
+ //! Packed DP-FP horizontal subtract (SSE3).
+ INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP horizontal subtract (SSE3).
+ INST_2x(hsubps, kX86InstIdHsubps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(hsubps, kX86InstIdHsubps, X86XmmReg, X86Mem)
+
+ //! Load 128-bits unaligned (SSE3).
+ INST_2x(lddqu, kX86InstIdLddqu, X86XmmReg, X86Mem)
+
+ //! Setup monitor address (SSE3).
+ INST_0x(monitor, kX86InstIdMonitor)
+
+ //! Move one DP-FP and duplicate (SSE3).
+ INST_2x(movddup, kX86InstIdMovddup, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(movddup, kX86InstIdMovddup, X86XmmReg, X86Mem)
+
+ //! Move packed SP-FP high and duplicate (SSE3).
+ INST_2x(movshdup, kX86InstIdMovshdup, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(movshdup, kX86InstIdMovshdup, X86XmmReg, X86Mem)
+
+ //! Move packed SP-FP low and duplicate (SSE3).
+ INST_2x(movsldup, kX86InstIdMovsldup, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(movsldup, kX86InstIdMovsldup, X86XmmReg, X86Mem)
+
+ //! Monitor wait (SSE3).
+ INST_0x(mwait, kX86InstIdMwait)
// --------------------------------------------------------------------------
// [SSSE3]
// --------------------------------------------------------------------------
- //! @brief Packed SIGN (SSSE3).
- void psignb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSignB, &dst, &src); }
- //! @brief Packed SIGN (SSSE3).
- void psignb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSignB, &dst, &src); }
-
- //! @brief Packed SIGN (SSSE3).
- void psignb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSignB, &dst, &src); }
- //! @brief Packed SIGN (SSSE3).
- void psignb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSignB, &dst, &src); }
-
- //! @brief Packed SIGN (SSSE3).
- void psignw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSignW, &dst, &src); }
- //! @brief Packed SIGN (SSSE3).
- void psignw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSignW, &dst, &src); }
-
- //! @brief Packed SIGN (SSSE3).
- void psignw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSignW, &dst, &src); }
- //! @brief Packed SIGN (SSSE3).
- void psignw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSignW, &dst, &src); }
-
- //! @brief Packed SIGN (SSSE3).
- void psignd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPSignD, &dst, &src); }
- //! @brief Packed SIGN (SSSE3).
- void psignd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSignD, &dst, &src); }
-
- //! @brief Packed SIGN (SSSE3).
- void psignd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPSignD, &dst, &src); }
- //! @brief Packed SIGN (SSSE3).
- void psignd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPSignD, &dst, &src); }
-
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPHAddW, &dst, &src); }
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPHAddW, &dst, &src); }
-
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPHAddW, &dst, &src); }
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPHAddW, &dst, &src); }
-
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPHAddD, &dst, &src); }
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPHAddD, &dst, &src); }
-
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPHAddD, &dst, &src); }
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPHAddD, &dst, &src); }
-
- //! @brief Packed Horizontal Add and Saturate (SSSE3).
- void phaddsw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPHAddSW, &dst, &src); }
- //! @brief Packed Horizontal Add and Saturate (SSSE3).
- void phaddsw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPHAddSW, &dst, &src); }
-
- //! @brief Packed Horizontal Add and Saturate (SSSE3).
- void phaddsw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPHAddSW, &dst, &src); }
- //! @brief Packed Horizontal Add and Saturate (SSSE3).
- void phaddsw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPHAddSW, &dst, &src); }
-
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPHSubW, &dst, &src); }
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPHSubW, &dst, &src); }
-
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPHSubW, &dst, &src); }
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPHSubW, &dst, &src); }
-
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPHSubD, &dst, &src); }
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPHSubD, &dst, &src); }
-
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPHSubD, &dst, &src); }
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPHSubD, &dst, &src); }
-
- //! @brief Packed Horizontal Subtract and Saturate (SSSE3).
- void phsubsw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPHSubSW, &dst, &src); }
- //! @brief Packed Horizontal Subtract and Saturate (SSSE3).
- void phsubsw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPHSubSW, &dst, &src); }
-
- //! @brief Packed Horizontal Subtract and Saturate (SSSE3).
- void phsubsw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPHSubSW, &dst, &src); }
- //! @brief Packed Horizontal Subtract and Saturate (SSSE3).
- void phsubsw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPHSubSW, &dst, &src); }
-
- //! @brief Multiply and Add Packed Signed and Unsigned Bytes (SSSE3).
- void pmaddubsw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPMAddUBSW, &dst, &src); }
- //! @brief Multiply and Add Packed Signed and Unsigned Bytes (SSSE3).
- void pmaddubsw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMAddUBSW, &dst, &src); }
-
- //! @brief Multiply and Add Packed Signed and Unsigned Bytes (SSSE3).
- void pmaddubsw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMAddUBSW, &dst, &src); }
- //! @brief Multiply and Add Packed Signed and Unsigned Bytes (SSSE3).
- void pmaddubsw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMAddUBSW, &dst, &src); }
-
- //! @brief Packed Absolute Value (SSSE3).
- void pabsb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAbsB, &dst, &src); }
- //! @brief Packed Absolute Value (SSSE3).
- void pabsb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAbsB, &dst, &src); }
-
- //! @brief Packed Absolute Value (SSSE3).
- void pabsb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAbsB, &dst, &src); }
- //! @brief Packed Absolute Value (SSSE3).
- void pabsb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAbsB, &dst, &src); }
-
- //! @brief Packed Absolute Value (SSSE3).
- void pabsw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAbsW, &dst, &src); }
- //! @brief Packed Absolute Value (SSSE3).
- void pabsw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAbsW, &dst, &src); }
-
- //! @brief Packed Absolute Value (SSSE3).
- void pabsw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAbsW, &dst, &src); }
- //! @brief Packed Absolute Value (SSSE3).
- void pabsw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAbsW, &dst, &src); }
-
- //! @brief Packed Absolute Value (SSSE3).
- void pabsd(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPAbsD, &dst, &src); }
- //! @brief Packed Absolute Value (SSSE3).
- void pabsd(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAbsD, &dst, &src); }
-
- //! @brief Packed Absolute Value (SSSE3).
- void pabsd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPAbsD, &dst, &src); }
- //! @brief Packed Absolute Value (SSSE3).
- void pabsd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPAbsD, &dst, &src); }
-
- //! @brief Packed Multiply High with Round and Scale (SSSE3).
- void pmulhrsw(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPMulHRSW, &dst, &src); }
- //! @brief Packed Multiply High with Round and Scale (SSSE3).
- void pmulhrsw(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMulHRSW, &dst, &src); }
-
- //! @brief Packed Multiply High with Round and Scale (SSSE3).
- void pmulhrsw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMulHRSW, &dst, &src); }
- //! @brief Packed Multiply High with Round and Scale (SSSE3).
- void pmulhrsw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMulHRSW, &dst, &src); }
-
- //! @brief Packed Shuffle Bytes (SSSE3).
- void pshufb(const MmReg& dst, const MmReg& src)
- { _emitInstruction(kX86InstPShufB, &dst, &src); }
- //! @brief Packed Shuffle Bytes (SSSE3).
- void pshufb(const MmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPShufB, &dst, &src); }
-
- //! @brief Packed Shuffle Bytes (SSSE3).
- void pshufb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPShufB, &dst, &src); }
- //! @brief Packed Shuffle Bytes (SSSE3).
- void pshufb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPShufB, &dst, &src); }
-
- //! @brief Packed Shuffle Bytes (SSSE3).
- void palignr(const MmReg& dst, const MmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPAlignR, &dst, &src, &imm8); }
- //! @brief Packed Shuffle Bytes (SSSE3).
- void palignr(const MmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPAlignR, &dst, &src, &imm8); }
-
- //! @brief Packed Shuffle Bytes (SSSE3).
- void palignr(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPAlignR, &dst, &src, &imm8); }
- //! @brief Packed Shuffle Bytes (SSSE3).
- void palignr(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPAlignR, &dst, &src, &imm8); }
+ //! Packed BYTE sign (SSSE3).
+ INST_2x(psignb, kX86InstIdPsignb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psignb, kX86InstIdPsignb, X86MmReg, X86Mem)
+
+ //! Packed BYTE sign (SSSE3).
+ INST_2x(psignb, kX86InstIdPsignb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psignb, kX86InstIdPsignb, X86XmmReg, X86Mem)
+
+ //! Packed DWORD sign (SSSE3).
+ INST_2x(psignd, kX86InstIdPsignd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psignd, kX86InstIdPsignd, X86MmReg, X86Mem)
+
+ //! Packed DWORD sign (SSSE3).
+ INST_2x(psignd, kX86InstIdPsignd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psignd, kX86InstIdPsignd, X86XmmReg, X86Mem)
+
+ //! Packed WORD sign (SSSE3).
+ INST_2x(psignw, kX86InstIdPsignw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(psignw, kX86InstIdPsignw, X86MmReg, X86Mem)
+
+ //! Packed WORD sign (SSSE3).
+ INST_2x(psignw, kX86InstIdPsignw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(psignw, kX86InstIdPsignw, X86XmmReg, X86Mem)
+
+ //! Packed DWORD horizontal add (SSSE3).
+ INST_2x(phaddd, kX86InstIdPhaddd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(phaddd, kX86InstIdPhaddd, X86MmReg, X86Mem)
+
+ //! Packed DWORD horizontal add (SSSE3).
+ INST_2x(phaddd, kX86InstIdPhaddd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(phaddd, kX86InstIdPhaddd, X86XmmReg, X86Mem)
+
+ //! Packed WORD horizontal add with saturation (SSSE3).
+ INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmReg, X86Mem)
+
+ //! Packed WORD horizontal add with saturation (SSSE3).
+ INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmReg, X86Mem)
+
+ //! Packed WORD horizontal add (SSSE3).
+ INST_2x(phaddw, kX86InstIdPhaddw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(phaddw, kX86InstIdPhaddw, X86MmReg, X86Mem)
+
+ //! Packed WORD horizontal add (SSSE3).
+ INST_2x(phaddw, kX86InstIdPhaddw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(phaddw, kX86InstIdPhaddw, X86XmmReg, X86Mem)
+
+ //! Packed DWORD horizontal subtract (SSSE3).
+ INST_2x(phsubd, kX86InstIdPhsubd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(phsubd, kX86InstIdPhsubd, X86MmReg, X86Mem)
+
+ //! Packed DWORD horizontal subtract (SSSE3).
+ INST_2x(phsubd, kX86InstIdPhsubd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(phsubd, kX86InstIdPhsubd, X86XmmReg, X86Mem)
+
+ //! Packed WORD horizontal subtract with saturation (SSSE3).
+ INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmReg, X86Mem)
+
+ //! Packed WORD horizontal subtract with saturation (SSSE3).
+ INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmReg, X86Mem)
+
+ //! Packed WORD horizontal subtract (SSSE3).
+ INST_2x(phsubw, kX86InstIdPhsubw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(phsubw, kX86InstIdPhsubw, X86MmReg, X86Mem)
+
+ //! Packed WORD horizontal subtract (SSSE3).
+ INST_2x(phsubw, kX86InstIdPhsubw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(phsubw, kX86InstIdPhsubw, X86XmmReg, X86Mem)
+
+ //! Packed multiply and add signed and unsigned bytes (SSSE3).
+ INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmReg, X86Mem)
+
+ //! Packed multiply and add signed and unsigned bytes (SSSE3).
+ INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmReg, X86Mem)
+
+ //! Packed BYTE absolute value (SSSE3).
+ INST_2x(pabsb, kX86InstIdPabsb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pabsb, kX86InstIdPabsb, X86MmReg, X86Mem)
+
+ //! Packed BYTE absolute value (SSSE3).
+ INST_2x(pabsb, kX86InstIdPabsb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pabsb, kX86InstIdPabsb, X86XmmReg, X86Mem)
+
+ //! Packed DWORD absolute value (SSSE3).
+ INST_2x(pabsd, kX86InstIdPabsd, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pabsd, kX86InstIdPabsd, X86MmReg, X86Mem)
+
+ //! Packed DWORD absolute value (SSSE3).
+ INST_2x(pabsd, kX86InstIdPabsd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pabsd, kX86InstIdPabsd, X86XmmReg, X86Mem)
+
+ //! Packed WORD absolute value (SSSE3).
+ INST_2x(pabsw, kX86InstIdPabsw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pabsw, kX86InstIdPabsw, X86MmReg, X86Mem)
+
+ //! Packed WORD absolute value (SSSE3).
+ INST_2x(pabsw, kX86InstIdPabsw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pabsw, kX86InstIdPabsw, X86XmmReg, X86Mem)
+
+ //! Packed WORD multiply high, round and scale (SSSE3).
+ INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmReg, X86Mem)
+
+ //! Packed WORD multiply high, round and scale (SSSE3).
+ INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmReg, X86Mem)
+
+ //! Packed BYTE shuffle (SSSE3).
+ INST_2x(pshufb, kX86InstIdPshufb, X86MmReg, X86MmReg)
+ //! \overload
+ INST_2x(pshufb, kX86InstIdPshufb, X86MmReg, X86Mem)
+
+ //! Packed BYTE shuffle (SSSE3).
+ INST_2x(pshufb, kX86InstIdPshufb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pshufb, kX86InstIdPshufb, X86XmmReg, X86Mem)
+
+ //! Packed align right (SSSE3).
+ INST_3i(palignr, kX86InstIdPalignr, X86MmReg, X86MmReg, Imm)
+ //! \overload
+ INST_3i(palignr, kX86InstIdPalignr, X86MmReg, X86Mem, Imm)
+
+ //! Packed align right (SSSE3).
+ INST_3i(palignr, kX86InstIdPalignr, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(palignr, kX86InstIdPalignr, X86XmmReg, X86Mem, Imm)
// --------------------------------------------------------------------------
// [SSE4.1]
// --------------------------------------------------------------------------
- //! @brief Blend Packed DP-FP Values (SSE4.1).
- void blendpd(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstBlendPD, &dst, &src, &imm8); }
- //! @brief Blend Packed DP-FP Values (SSE4.1).
- void blendpd(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstBlendPD, &dst, &src, &imm8); }
-
- //! @brief Blend Packed SP-FP Values (SSE4.1).
- void blendps(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstBlendPS, &dst, &src, &imm8); }
- //! @brief Blend Packed SP-FP Values (SSE4.1).
- void blendps(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstBlendPS, &dst, &src, &imm8); }
-
- //! @brief Variable Blend Packed DP-FP Values (SSE4.1).
- void blendvpd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstBlendVPD, &dst, &src); }
- //! @brief Variable Blend Packed DP-FP Values (SSE4.1).
- void blendvpd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstBlendVPD, &dst, &src); }
-
- //! @brief Variable Blend Packed SP-FP Values (SSE4.1).
- void blendvps(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstBlendVPS, &dst, &src); }
- //! @brief Variable Blend Packed SP-FP Values (SSE4.1).
- void blendvps(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstBlendVPS, &dst, &src); }
-
- //! @brief Dot Product of Packed DP-FP Values (SSE4.1).
- void dppd(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstDpPD, &dst, &src, &imm8); }
- //! @brief Dot Product of Packed DP-FP Values (SSE4.1).
- void dppd(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstDpPD, &dst, &src, &imm8); }
-
- //! @brief Dot Product of Packed SP-FP Values (SSE4.1).
- void dpps(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstDpPS, &dst, &src, &imm8); }
- //! @brief Dot Product of Packed SP-FP Values (SSE4.1).
- void dpps(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstDpPS, &dst, &src, &imm8); }
-
- //! @brief Extract Packed SP-FP Value (SSE4.1).
- void extractps(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstExtractPS, &dst, &src, &imm8); }
- //! @brief Extract Packed SP-FP Value (SSE4.1).
- void extractps(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstExtractPS, &dst, &src, &imm8); }
-
- //! @brief Load Double Quadword Non-Temporal Aligned Hint (SSE4.1).
- void movntdqa(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstMovNTDQA, &dst, &src); }
-
- //! @brief Compute Multiple Packed Sums of Absolute Difference (SSE4.1).
- void mpsadbw(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstMPSADBW, &dst, &src, &imm8); }
- //! @brief Compute Multiple Packed Sums of Absolute Difference (SSE4.1).
- void mpsadbw(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstMPSADBW, &dst, &src, &imm8); }
-
- //! @brief Pack with Unsigned Saturation (SSE4.1).
- void packusdw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPackUSDW, &dst, &src); }
- //! @brief Pack with Unsigned Saturation (SSE4.1).
- void packusdw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPackUSDW, &dst, &src); }
-
- //! @brief Variable Blend Packed Bytes (SSE4.1).
- void pblendvb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPBlendVB, &dst, &src); }
- //! @brief Variable Blend Packed Bytes (SSE4.1).
- void pblendvb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPBlendVB, &dst, &src); }
-
- //! @brief Blend Packed Words (SSE4.1).
- void pblendw(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPBlendW, &dst, &src, &imm8); }
- //! @brief Blend Packed Words (SSE4.1).
- void pblendw(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPBlendW, &dst, &src, &imm8); }
-
- //! @brief Compare Packed Qword Data for Equal (SSE4.1).
- void pcmpeqq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPCmpEqQ, &dst, &src); }
- //! @brief Compare Packed Qword Data for Equal (SSE4.1).
- void pcmpeqq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpEqQ, &dst, &src); }
-
- //! @brief Extract Byte (SSE4.1).
- void pextrb(const GpReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPExtrB, &dst, &src, &imm8); }
- //! @brief Extract Byte (SSE4.1).
- void pextrb(const Mem& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPExtrB, &dst, &src, &imm8); }
-
- //! @brief Extract Dword (SSE4.1).
- void pextrd(const GpReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPExtrD, &dst, &src, &imm8); }
- //! @brief Extract Dword (SSE4.1).
- void pextrd(const Mem& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPExtrD, &dst, &src, &imm8); }
-
- //! @brief Extract Dword (SSE4.1).
- void pextrq(const GpReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPExtrQ, &dst, &src, &imm8); }
- //! @brief Extract Dword (SSE4.1).
- void pextrq(const Mem& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPExtrQ, &dst, &src, &imm8); }
-
- //! @brief Extract Word (SSE4.1).
- void pextrw(const GpReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPExtrW, &dst, &src, &imm8); }
- //! @brief Extract Word (SSE4.1).
- void pextrw(const Mem& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPExtrW, &dst, &src, &imm8); }
-
- //! @brief Packed Horizontal Word Minimum (SSE4.1).
- void phminposuw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPHMinPOSUW, &dst, &src); }
- //! @brief Packed Horizontal Word Minimum (SSE4.1).
- void phminposuw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPHMinPOSUW, &dst, &src); }
-
- //! @brief Insert Byte (SSE4.1).
- void pinsrb(const XmmReg& dst, const GpReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPInsRB, &dst, &src, &imm8); }
- //! @brief Insert Byte (SSE4.1).
- void pinsrb(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPInsRB, &dst, &src, &imm8); }
-
- //! @brief Insert Dword (SSE4.1).
- void pinsrd(const XmmReg& dst, const GpReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPInsRD, &dst, &src, &imm8); }
- //! @brief Insert Dword (SSE4.1).
- void pinsrd(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPInsRD, &dst, &src, &imm8); }
-
- //! @brief Insert Dword (SSE4.1).
- void pinsrq(const XmmReg& dst, const GpReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPInsRQ, &dst, &src, &imm8); }
- //! @brief Insert Dword (SSE4.1).
- void pinsrq(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPInsRQ, &dst, &src, &imm8); }
-
- //! @brief Insert Word (SSE2).
- void pinsrw(const XmmReg& dst, const GpReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPInsRW, &dst, &src, &imm8); }
- //! @brief Insert Word (SSE2).
- void pinsrw(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPInsRW, &dst, &src, &imm8); }
-
- //! @brief Maximum of Packed Word Integers (SSE4.1).
- void pmaxuw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMaxUW, &dst, &src); }
- //! @brief Maximum of Packed Word Integers (SSE4.1).
- void pmaxuw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMaxUW, &dst, &src); }
-
- //! @brief Maximum of Packed Signed Byte Integers (SSE4.1).
- void pmaxsb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMaxSB, &dst, &src); }
- //! @brief Maximum of Packed Signed Byte Integers (SSE4.1).
- void pmaxsb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMaxSB, &dst, &src); }
-
- //! @brief Maximum of Packed Signed Dword Integers (SSE4.1).
- void pmaxsd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMaxSD, &dst, &src); }
- //! @brief Maximum of Packed Signed Dword Integers (SSE4.1).
- void pmaxsd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMaxSD, &dst, &src); }
-
- //! @brief Maximum of Packed Unsigned Dword Integers (SSE4.1).
- void pmaxud(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMaxUD, &dst, &src); }
- //! @brief Maximum of Packed Unsigned Dword Integers (SSE4.1).
- void pmaxud(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMaxUD, &dst, &src); }
-
- //! @brief Minimum of Packed Signed Byte Integers (SSE4.1).
- void pminsb(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMinSB, &dst, &src); }
- //! @brief Minimum of Packed Signed Byte Integers (SSE4.1).
- void pminsb(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMinSB, &dst, &src); }
-
- //! @brief Minimum of Packed Word Integers (SSE4.1).
- void pminuw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMinUW, &dst, &src); }
- //! @brief Minimum of Packed Word Integers (SSE4.1).
- void pminuw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMinUW, &dst, &src); }
-
- //! @brief Minimum of Packed Dword Integers (SSE4.1).
- void pminud(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMinUD, &dst, &src); }
- //! @brief Minimum of Packed Dword Integers (SSE4.1).
- void pminud(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMinUD, &dst, &src); }
-
- //! @brief Minimum of Packed Dword Integers (SSE4.1).
- void pminsd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMinSD, &dst, &src); }
- //! @brief Minimum of Packed Dword Integers (SSE4.1).
- void pminsd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMinSD, &dst, &src); }
-
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxbw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMovSXBW, &dst, &src); }
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxbw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMovSXBW, &dst, &src); }
-
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxbd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMovSXBD, &dst, &src); }
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxbd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMovSXBD, &dst, &src); }
-
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxbq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMovSXBQ, &dst, &src); }
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxbq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMovSXBQ, &dst, &src); }
-
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxwd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMovSXWD, &dst, &src); }
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxwd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMovSXWD, &dst, &src); }
-
- //! @brief (SSE4.1).
- void pmovsxwq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMovSXWQ, &dst, &src); }
- //! @brief (SSE4.1).
- void pmovsxwq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMovSXWQ, &dst, &src); }
-
- //! @brief (SSE4.1).
- void pmovsxdq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMovSXDQ, &dst, &src); }
- //! @brief (SSE4.1).
- void pmovsxdq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMovSXDQ, &dst, &src); }
-
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxbw(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMovZXBW, &dst, &src); }
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxbw(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMovZXBW, &dst, &src); }
-
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxbd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMovZXBD, &dst, &src); }
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxbd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMovZXBD, &dst, &src); }
-
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxbq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMovZXBQ, &dst, &src); }
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxbq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMovZXBQ, &dst, &src); }
-
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxwd(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMovZXWD, &dst, &src); }
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxwd(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMovZXWD, &dst, &src); }
-
- //! @brief (SSE4.1).
- void pmovzxwq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMovZXWQ, &dst, &src); }
- //! @brief (SSE4.1).
- void pmovzxwq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMovZXWQ, &dst, &src); }
-
- //! @brief (SSE4.1).
- void pmovzxdq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMovZXDQ, &dst, &src); }
- //! @brief (SSE4.1).
- void pmovzxdq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMovZXDQ, &dst, &src); }
-
- //! @brief Multiply Packed Signed Dword Integers (SSE4.1).
- void pmuldq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMulDQ, &dst, &src); }
- //! @brief Multiply Packed Signed Dword Integers (SSE4.1).
- void pmuldq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMulDQ, &dst, &src); }
-
- //! @brief Multiply Packed Signed Integers and Store Low Result (SSE4.1).
- void pmulld(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPMulLD, &dst, &src); }
- //! @brief Multiply Packed Signed Integers and Store Low Result (SSE4.1).
- void pmulld(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPMulLD, &dst, &src); }
-
- //! @brief Logical Compare (SSE4.1).
- void ptest(const XmmReg& op1, const XmmReg& op2)
- { _emitInstruction(kX86InstPTest, &op1, &op2); }
- //! @brief Logical Compare (SSE4.1).
- void ptest(const XmmReg& op1, const Mem& op2)
- { _emitInstruction(kX86InstPTest, &op1, &op2); }
-
- //! Round Packed SP-FP Values @brief (SSE4.1).
- void roundps(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstRoundPS, &dst, &src, &imm8); }
- //! Round Packed SP-FP Values @brief (SSE4.1).
- void roundps(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstRoundPS, &dst, &src, &imm8); }
-
- //! @brief Round Scalar SP-FP Values (SSE4.1).
- void roundss(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstRoundSS, &dst, &src, &imm8); }
- //! @brief Round Scalar SP-FP Values (SSE4.1).
- void roundss(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstRoundSS, &dst, &src, &imm8); }
-
- //! @brief Round Packed DP-FP Values (SSE4.1).
- void roundpd(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstRoundPD, &dst, &src, &imm8); }
- //! @brief Round Packed DP-FP Values (SSE4.1).
- void roundpd(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstRoundPD, &dst, &src, &imm8); }
-
- //! @brief Round Scalar DP-FP Values (SSE4.1).
- void roundsd(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstRoundSD, &dst, &src, &imm8); }
- //! @brief Round Scalar DP-FP Values (SSE4.1).
- void roundsd(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstRoundSD, &dst, &src, &imm8); }
+ //! Packed DP-FP blend (SSE4.1).
+ INST_3i(blendpd, kX86InstIdBlendpd, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(blendpd, kX86InstIdBlendpd, X86XmmReg, X86Mem, Imm)
+
+ //! Packed SP-FP blend (SSE4.1).
+ INST_3i(blendps, kX86InstIdBlendps, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(blendps, kX86InstIdBlendps, X86XmmReg, X86Mem, Imm)
+
+ //! Packed DP-FP variable blend (SSE4.1).
+ INST_2x(blendvpd, kX86InstIdBlendvpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(blendvpd, kX86InstIdBlendvpd, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP variable blend (SSE4.1).
+ INST_2x(blendvps, kX86InstIdBlendvps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(blendvps, kX86InstIdBlendvps, X86XmmReg, X86Mem)
+
+ //! Packed DP-FP dot product (SSE4.1).
+ INST_3i(dppd, kX86InstIdDppd, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(dppd, kX86InstIdDppd, X86XmmReg, X86Mem, Imm)
+
+ //! Packed SP-FP dot product (SSE4.1).
+ INST_3i(dpps, kX86InstIdDpps, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(dpps, kX86InstIdDpps, X86XmmReg, X86Mem, Imm)
+
+ //! Extract SP-FP based on selector (SSE4.1).
+ INST_3i(extractps, kX86InstIdExtractps, X86GpReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(extractps, kX86InstIdExtractps, X86Mem, X86XmmReg, Imm)
+
+ //! Insert SP-FP based on selector (SSE4.1).
+ INST_3i(insertps, kX86InstIdInsertps, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(insertps, kX86InstIdInsertps, X86XmmReg, X86Mem, Imm)
+
+ //! Load OWORD aligned using NT hint (SSE4.1).
+ INST_2x(movntdqa, kX86InstIdMovntdqa, X86XmmReg, X86Mem)
+
+ //! Packed WORD sums of absolute difference (SSE4.1).
+ INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmReg, X86Mem, Imm)
+
+ //! Pack DWORDs to WORDs with unsigned saturation (SSE4.1).
+ INST_2x(packusdw, kX86InstIdPackusdw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(packusdw, kX86InstIdPackusdw, X86XmmReg, X86Mem)
+
+ //! Packed BYTE variable blend (SSE4.1).
+ INST_2x(pblendvb, kX86InstIdPblendvb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pblendvb, kX86InstIdPblendvb, X86XmmReg, X86Mem)
+
+ //! Packed WORD blend (SSE4.1).
+ INST_3i(pblendw, kX86InstIdPblendw, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(pblendw, kX86InstIdPblendw, X86XmmReg, X86Mem, Imm)
+
+ //! Packed QWORD compare for equality (SSE4.1).
+ INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmReg, X86Mem)
+
+ //! Extract BYTE based on selector (SSE4.1).
+ INST_3i(pextrb, kX86InstIdPextrb, X86GpReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(pextrb, kX86InstIdPextrb, X86Mem, X86XmmReg, Imm)
+
+ //! Extract DWORD based on selector (SSE4.1).
+ INST_3i(pextrd, kX86InstIdPextrd, X86GpReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(pextrd, kX86InstIdPextrd, X86Mem, X86XmmReg, Imm)
+
+ //! Extract QWORD based on selector (SSE4.1).
+ INST_3i(pextrq, kX86InstIdPextrq, X86GpReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(pextrq, kX86InstIdPextrq, X86Mem, X86XmmReg, Imm)
+
+ //! Extract WORD based on selector (SSE4.1).
+ INST_3i(pextrw, kX86InstIdPextrw, X86Mem, X86XmmReg, Imm)
+
+ //! Packed WORD horizontal minimum (SSE4.1).
+ INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmReg, X86Mem)
+
+ //! Insert BYTE based on selector (SSE4.1).
+ INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmReg, X86GpReg, Imm)
+ //! \overload
+ INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmReg, X86Mem, Imm)
+
+ //! Insert DWORD based on selector (SSE4.1).
+ INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmReg, X86GpReg, Imm)
+ //! \overload
+ INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmReg, X86Mem, Imm)
+
+ //! Insert QWORD based on selector (SSE4.1).
+ INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmReg, X86GpReg, Imm)
+ //! \overload
+ INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmReg, X86Mem, Imm)
+
+ //! Packed BYTE maximum (SSE4.1).
+ INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmReg, X86Mem)
+
+ //! Packed DWORD maximum (SSE4.1).
+ INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmReg, X86Mem)
+
+ //! Packed DWORD unsigned maximum (SSE4.1).
+ INST_2x(pmaxud, kX86InstIdPmaxud, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmaxud,kX86InstIdPmaxud , X86XmmReg, X86Mem)
+
+ //! Packed WORD unsigned maximum (SSE4.1).
+ INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmReg, X86Mem)
+
+ //! Packed BYTE minimum (SSE4.1).
+ INST_2x(pminsb, kX86InstIdPminsb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pminsb, kX86InstIdPminsb, X86XmmReg, X86Mem)
+
+ //! Packed DWORD minimum (SSE4.1).
+ INST_2x(pminsd, kX86InstIdPminsd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pminsd, kX86InstIdPminsd, X86XmmReg, X86Mem)
+
+ //! Packed WORD unsigned minimum (SSE4.1).
+ INST_2x(pminuw, kX86InstIdPminuw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pminuw, kX86InstIdPminuw, X86XmmReg, X86Mem)
+
+ //! Packed DWORD unsigned minimum (SSE4.1).
+ INST_2x(pminud, kX86InstIdPminud, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pminud, kX86InstIdPminud, X86XmmReg, X86Mem)
+
+ //! BYTE to DWORD with sign extend (SSE4.1).
+ INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmReg, X86Mem)
+
+ //! Packed BYTE to QWORD with sign extend (SSE4.1).
+ INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmReg, X86Mem)
+
+ //! Packed BYTE to WORD with sign extend (SSE4.1).
+ INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmReg, X86Mem)
+
+ //! Packed DWORD to QWORD with sign extend (SSE4.1).
+ INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmReg, X86Mem)
+
+ //! Packed WORD to DWORD with sign extend (SSE4.1).
+ INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmReg, X86Mem)
+
+ //! Packed WORD to QWORD with sign extend (SSE4.1).
+ INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmReg, X86Mem)
+
+ //! BYTE to DWORD with zero extend (SSE4.1).
+ INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmReg, X86Mem)
+
+ //! Packed BYTE to QWORD with zero extend (SSE4.1).
+ INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmReg, X86Mem)
+
+ //! BYTE to WORD with zero extend (SSE4.1).
+ INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmReg, X86Mem)
+
+ //! Packed DWORD to QWORD with zero extend (SSE4.1).
+ INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmReg, X86Mem)
+
+ //! Packed WORD to DWORD with zero extend (SSE4.1).
+ INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmReg, X86Mem)
+
+ //! Packed WORD to QWORD with zero extend (SSE4.1).
+ INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmReg, X86Mem)
+
+ //! Packed DWORD to QWORD multiply (SSE4.1).
+ INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmReg, X86Mem)
+
+ //! Packed DWORD multiply low (SSE4.1).
+ INST_2x(pmulld, kX86InstIdPmulld, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pmulld, kX86InstIdPmulld, X86XmmReg, X86Mem)
+
+ //! Logical compare (SSE4.1).
+ INST_2x(ptest, kX86InstIdPtest, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(ptest, kX86InstIdPtest, X86XmmReg, X86Mem)
+
+ //! Packed DP-FP round (SSE4.1).
+ INST_3i(roundpd, kX86InstIdRoundpd, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(roundpd, kX86InstIdRoundpd, X86XmmReg, X86Mem, Imm)
+
+ //! Packed SP-FP round (SSE4.1).
+ INST_3i(roundps, kX86InstIdRoundps, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(roundps, kX86InstIdRoundps, X86XmmReg, X86Mem, Imm)
+
+ //! Scalar DP-FP round (SSE4.1).
+ INST_3i(roundsd, kX86InstIdRoundsd, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(roundsd, kX86InstIdRoundsd, X86XmmReg, X86Mem, Imm)
+
+ //! Scalar SP-FP round (SSE4.1).
+ INST_3i(roundss, kX86InstIdRoundss, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(roundss, kX86InstIdRoundss, X86XmmReg, X86Mem, Imm)
// --------------------------------------------------------------------------
// [SSE4.2]
// --------------------------------------------------------------------------
- //! @brief Accumulate CRC32 Value (polynomial 0x11EDC6F41) (SSE4.2).
- void crc32(const GpReg& dst, const GpReg& src)
- {
- ASMJIT_ASSERT(dst.isRegType(kX86RegTypeGpd) || dst.isRegType(kX86RegTypeGpq));
- _emitInstruction(kX86InstCrc32, &dst, &src);
- }
- //! @brief Accumulate CRC32 Value (polynomial 0x11EDC6F41) (SSE4.2).
- void crc32(const GpReg& dst, const Mem& src)
- {
- ASMJIT_ASSERT(dst.isRegType(kX86RegTypeGpd) || dst.isRegType(kX86RegTypeGpq));
- _emitInstruction(kX86InstCrc32, &dst, &src);
- }
-
- //! @brief Packed Compare Explicit Length Strings, Return Index (SSE4.2).
- void pcmpestri(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPCmpEStrI, &dst, &src, &imm8); }
- //! @brief Packed Compare Explicit Length Strings, Return Index (SSE4.2).
- void pcmpestri(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPCmpEStrI, &dst, &src, &imm8); }
-
- //! @brief Packed Compare Explicit Length Strings, Return Mask (SSE4.2).
- void pcmpestrm(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPCmpEStrM, &dst, &src, &imm8); }
- //! @brief Packed Compare Explicit Length Strings, Return Mask (SSE4.2).
- void pcmpestrm(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPCmpEStrM, &dst, &src, &imm8); }
-
- //! @brief Packed Compare Implicit Length Strings, Return Index (SSE4.2).
- void pcmpistri(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPCmpIStrI, &dst, &src, &imm8); }
- //! @brief Packed Compare Implicit Length Strings, Return Index (SSE4.2).
- void pcmpistri(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPCmpIStrI, &dst, &src, &imm8); }
-
- //! @brief Packed Compare Implicit Length Strings, Return Mask (SSE4.2).
- void pcmpistrm(const XmmReg& dst, const XmmReg& src, const Imm& imm8)
- { _emitInstruction(kX86InstPCmpIStrM, &dst, &src, &imm8); }
- //! @brief Packed Compare Implicit Length Strings, Return Mask (SSE4.2).
- void pcmpistrm(const XmmReg& dst, const Mem& src, const Imm& imm8)
- { _emitInstruction(kX86InstPCmpIStrM, &dst, &src, &imm8); }
-
- //! @brief Compare Packed Data for Greater Than (SSE4.2).
- void pcmpgtq(const XmmReg& dst, const XmmReg& src)
- { _emitInstruction(kX86InstPCmpGtQ, &dst, &src); }
- //! @brief Compare Packed Data for Greater Than (SSE4.2).
- void pcmpgtq(const XmmReg& dst, const Mem& src)
- { _emitInstruction(kX86InstPCmpGtQ, &dst, &src); }
-
- //! @brief Return the Count of Number of Bits Set to 1 (SSE4.2).
- void popcnt(const GpReg& dst, const GpReg& src)
- {
- ASMJIT_ASSERT(!dst.isGpb());
- ASMJIT_ASSERT(src.getRegType() == dst.getRegType());
- _emitInstruction(kX86InstPopCnt, &dst, &src);
- }
- //! @brief Return the Count of Number of Bits Set to 1 (SSE4.2).
- void popcnt(const GpReg& dst, const Mem& src)
- {
- ASMJIT_ASSERT(!dst.isGpb());
- _emitInstruction(kX86InstPopCnt, &dst, &src);
- }
-
- // -------------------------------------------------------------------------
- // [AMD only]
- // -------------------------------------------------------------------------
-
- //! @brief Prefetch (3dNow - Amd).
+ //! Packed compare explicit length strings, return index (SSE4.2).
+ INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmReg, X86Mem, Imm)
+
+ //! Packed compare explicit length strings, return mask (SSE4.2).
+ INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmReg, X86Mem, Imm)
+
+ //! Packed compare implicit length strings, return index (SSE4.2).
+ INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmReg, X86Mem, Imm)
+
+ //! Packed compare implicit length strings, return mask (SSE4.2).
+ INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmReg, X86Mem, Imm)
+
+ //! Packed QWORD compare if greater than (SSE4.2).
+ INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmReg, X86Mem)
+
+ // --------------------------------------------------------------------------
+ // [AESNI]
+ // --------------------------------------------------------------------------
+
+ //! Perform a single round of the AES decryption flow (AESNI).
+ INST_2x(aesdec, kX86InstIdAesdec, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(aesdec, kX86InstIdAesdec, X86XmmReg, X86Mem)
+
+ //! Perform the last round of the AES decryption flow (AESNI).
+ INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmReg, X86Mem)
+
+ //! Perform a single round of the AES encryption flow (AESNI).
+ INST_2x(aesenc, kX86InstIdAesenc, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(aesenc, kX86InstIdAesenc, X86XmmReg, X86Mem)
+
+ //! Perform the last round of the AES encryption flow (AESNI).
+ INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmReg, X86Mem)
+
+ //! Perform the InvMixColumns transformation (AESNI).
+ INST_2x(aesimc, kX86InstIdAesimc, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(aesimc, kX86InstIdAesimc, X86XmmReg, X86Mem)
+
+ //! Assist in expanding the AES cipher key (AESNI).
+ INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmReg, X86Mem, Imm)
+
+ // --------------------------------------------------------------------------
+ // [PCLMULQDQ]
+ // --------------------------------------------------------------------------
+
+ //! Packed QWORD to OWORD carry-less multiply (PCLMULQDQ).
+ INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmReg, X86Mem, Imm)
+
+ // --------------------------------------------------------------------------
+ // [AVX]
+ // --------------------------------------------------------------------------
+
+ //! Packed DP-FP add (AVX).
+ INST_3x(vaddpd, kX86InstIdVaddpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vaddpd, kX86InstIdVaddpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vaddpd, kX86InstIdVaddpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vaddpd, kX86InstIdVaddpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP add (AVX).
+ INST_3x(vaddps, kX86InstIdVaddps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vaddps, kX86InstIdVaddps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vaddps, kX86InstIdVaddps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vaddps, kX86InstIdVaddps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Scalar DP-FP add (AVX)
+ INST_3x(vaddsd, kX86InstIdVaddsd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vaddsd, kX86InstIdVaddsd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP add (AVX)
+ INST_3x(vaddss, kX86InstIdVaddss, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vaddss, kX86InstIdVaddss, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DP-FP add/subtract (AVX).
+ INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP add/subtract (AVX).
+ INST_3x(vaddsubps, kX86InstIdVaddsubps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vaddsubps, kX86InstIdVaddsubps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vaddsubps, kX86InstIdVaddsubps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vaddsubps, kX86InstIdVaddsubps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed DP-FP bitwise and (AVX).
+ INST_3x(vandpd, kX86InstIdVandpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vandpd, kX86InstIdVandpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vandpd, kX86InstIdVandpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vandpd, kX86InstIdVandpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP bitwise and (AVX).
+ INST_3x(vandps, kX86InstIdVandps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vandps, kX86InstIdVandps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vandps, kX86InstIdVandps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vandps, kX86InstIdVandps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed DP-FP bitwise and-not (AVX).
+ INST_3x(vandnpd, kX86InstIdVandnpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vandnpd, kX86InstIdVandnpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vandnpd, kX86InstIdVandnpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vandnpd, kX86InstIdVandnpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP bitwise and-not (AVX).
+ INST_3x(vandnps, kX86InstIdVandnps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vandnps, kX86InstIdVandnps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vandnps, kX86InstIdVandnps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vandnps, kX86InstIdVandnps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed DP-FP blend (AVX).
+ INST_4i(vblendpd, kX86InstIdVblendpd, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vblendpd, kX86InstIdVblendpd, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ //! \overload
+ INST_4i(vblendpd, kX86InstIdVblendpd, X86YmmReg, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_4i(vblendpd, kX86InstIdVblendpd, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Packed SP-FP blend (AVX).
+ INST_4i(vblendps, kX86InstIdVblendps, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vblendps, kX86InstIdVblendps, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ //! \overload
+ INST_4i(vblendps, kX86InstIdVblendps, X86YmmReg, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_4i(vblendps, kX86InstIdVblendps, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Packed DP-FP variable blend (AVX).
+ INST_4x(vblendvpd, kX86InstIdVblendvpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_4x(vblendvpd, kX86InstIdVblendvpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ //! \overload
+ INST_4x(vblendvpd, kX86InstIdVblendvpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_4x(vblendvpd, kX86InstIdVblendvpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+
+ //! Packed SP-FP variable blend (AVX).
+ INST_4x(vblendvps, kX86InstIdVblendvps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_4x(vblendvps, kX86InstIdVblendvps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ //! \overload
+ INST_4x(vblendvps, kX86InstIdVblendvps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_4x(vblendvps, kX86InstIdVblendvps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+
+ //! Broadcast 128-bits of FP data in `o1` to low and high 128-bits in `o0` (AVX).
+ INST_2x(vbroadcastf128, kX86InstIdVbroadcastf128, X86YmmReg, X86Mem)
+ //! Broadcast DP-FP element in `o1` to four locations in `o0` (AVX).
+ INST_2x(vbroadcastsd, kX86InstIdVbroadcastsd, X86YmmReg, X86Mem)
+ //! Broadcast SP-FP element in `o1` to four locations in `o0` (AVX).
+ INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86XmmReg, X86Mem)
+ //! Broadcast SP-FP element in `o1` to eight locations in `o0` (AVX).
+ INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86YmmReg, X86Mem)
+
+ //! Packed DP-FP compare (AVX).
+ INST_4i(vcmppd, kX86InstIdVcmppd, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vcmppd, kX86InstIdVcmppd, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ //! \overload
+ INST_4i(vcmppd, kX86InstIdVcmppd, X86YmmReg, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_4i(vcmppd, kX86InstIdVcmppd, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Packed SP-FP compare (AVX).
+ INST_4i(vcmpps, kX86InstIdVcmpps, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vcmpps, kX86InstIdVcmpps, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ //! \overload
+ INST_4i(vcmpps, kX86InstIdVcmpps, X86YmmReg, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_4i(vcmpps, kX86InstIdVcmpps, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Scalar DP-FP compare (AVX).
+ INST_4i(vcmpsd, kX86InstIdVcmpsd, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vcmpsd, kX86InstIdVcmpsd, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ //! Scalar SP-FP compare (AVX).
+ INST_4i(vcmpss, kX86InstIdVcmpss, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vcmpss, kX86InstIdVcmpss, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ //! Scalar DP-FP ordered compare and set EFLAGS (AVX).
+ INST_2x(vcomisd, kX86InstIdVcomisd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcomisd, kX86InstIdVcomisd, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP ordered compare and set EFLAGS (AVX).
+ INST_2x(vcomiss, kX86InstIdVcomiss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcomiss, kX86InstIdVcomiss, X86XmmReg, X86Mem)
+
+ //! Convert packed QWORDs to packed DP-FP (AVX).
+ INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86YmmReg, X86Mem)
+
+ //! Convert packed QWORDs to packed SP-FP (AVX).
+ INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86YmmReg, X86Mem)
+
+ //! Convert packed DP-FP to packed QWORDs (AVX).
+ INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86Mem)
+
+ //! Convert packed DP-FP to packed SP-FP (AVX).
+ INST_2x(vcvtpd2ps, kX86InstIdVcvtpd2ps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvtpd2ps, kX86InstIdVcvtpd2ps, X86XmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vcvtpd2ps, kX86InstIdVcvtpd2ps, X86XmmReg, X86Mem)
+
+ //! Convert packed SP-FP to packed QWORDs (AVX).
+ INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86YmmReg, X86Mem)
+
+ //! Convert packed SP-FP to packed DP-FP (AVX).
+ INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86YmmReg, X86Mem)
+
+ //! Convert scalar DP-FP to DWORD (AVX).
+ INST_2x(vcvtsd2si, kX86InstIdVcvtsd2si, X86GpReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvtsd2si, kX86InstIdVcvtsd2si, X86GpReg, X86Mem)
+
+ //! Convert scalar DP-FP to scalar SP-FP (AVX).
+ INST_3x(vcvtsd2ss, kX86InstIdVcvtsd2ss, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vcvtsd2ss, kX86InstIdVcvtsd2ss, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Convert DWORD integer to scalar DP-FP (AVX).
+ INST_3x(vcvtsi2sd, kX86InstIdVcvtsi2sd, X86XmmReg, X86XmmReg, X86GpReg)
+ //! \overload
+ INST_3x(vcvtsi2sd, kX86InstIdVcvtsi2sd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Convert scalar INT32 to SP-FP (AVX).
+ INST_3x(vcvtsi2ss, kX86InstIdVcvtsi2ss, X86XmmReg, X86XmmReg, X86GpReg)
+ //! \overload
+ INST_3x(vcvtsi2ss, kX86InstIdVcvtsi2ss, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Convert scalar SP-FP to DP-FP (AVX).
+ INST_3x(vcvtss2sd, kX86InstIdVcvtss2sd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vcvtss2sd, kX86InstIdVcvtss2sd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Convert scalar SP-FP to INT32 (AVX).
+ INST_2x(vcvtss2si, kX86InstIdVcvtss2si, X86GpReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvtss2si, kX86InstIdVcvtss2si, X86GpReg, X86Mem)
+
+ //! Convert with truncation packed DP-FP to packed QWORDs (AVX).
+ INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86Mem)
+
+ //! Convert with truncation packed SP-FP to packed QWORDs (AVX).
+ INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86YmmReg, X86Mem)
+
+ //! Convert with truncation scalar DP-FP to DWORD (AVX).
+ INST_2x(vcvttsd2si, kX86InstIdVcvttsd2si, X86GpReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvttsd2si, kX86InstIdVcvttsd2si, X86GpReg, X86Mem)
+
+ //! Convert with truncation scalar SP-FP to INT32 (AVX).
+ INST_2x(vcvttss2si, kX86InstIdVcvttss2si, X86GpReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvttss2si, kX86InstIdVcvttss2si, X86GpReg, X86Mem)
+
+ //! Packed DP-FP divide (AVX).
+ INST_3x(vdivpd, kX86InstIdVdivpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vdivpd, kX86InstIdVdivpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vdivpd, kX86InstIdVdivpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vdivpd, kX86InstIdVdivpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP divide (AVX).
+ INST_3x(vdivps, kX86InstIdVdivps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vdivps, kX86InstIdVdivps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vdivps, kX86InstIdVdivps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vdivps, kX86InstIdVdivps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Scalar DP-FP divide (AVX).
+ INST_3x(vdivsd, kX86InstIdVdivsd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vdivsd, kX86InstIdVdivsd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP divide (AVX).
+ INST_3x(vdivss, kX86InstIdVdivss, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vdivss, kX86InstIdVdivss, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DP-FP dot product (AVX).
+ INST_4i(vdppd, kX86InstIdVdppd, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vdppd, kX86InstIdVdppd, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ //! Packed SP-FP dot product (AVX).
+ INST_4i(vdpps, kX86InstIdVdpps, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vdpps, kX86InstIdVdpps, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ //! \overload
+ INST_4i(vdpps, kX86InstIdVdpps, X86YmmReg, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_4i(vdpps, kX86InstIdVdpps, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Extract 128 bits of packed FP data from `o1` and store results in `o0` (AVX).
+ INST_3i(vextractf128, kX86InstIdVextractf128, X86XmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_3i(vextractf128, kX86InstIdVextractf128, X86Mem, X86YmmReg, Imm)
+
+ //! Extract SP-FP based on selector (AVX).
+ INST_3i(vextractps, kX86InstIdVextractps, X86GpReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vextractps, kX86InstIdVextractps, X86Mem, X86XmmReg, Imm)
+
+ //! Packed DP-FP horizontal add (AVX).
+ INST_3x(vhaddpd, kX86InstIdVhaddpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vhaddpd, kX86InstIdVhaddpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vhaddpd, kX86InstIdVhaddpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vhaddpd, kX86InstIdVhaddpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP horizontal add (AVX).
+ INST_3x(vhaddps, kX86InstIdVhaddps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vhaddps, kX86InstIdVhaddps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vhaddps, kX86InstIdVhaddps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vhaddps, kX86InstIdVhaddps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed DP-FP horizontal subtract (AVX).
+ INST_3x(vhsubpd, kX86InstIdVhsubpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vhsubpd, kX86InstIdVhsubpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vhsubpd, kX86InstIdVhsubpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vhsubpd, kX86InstIdVhsubpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP horizontal subtract (AVX).
+ INST_3x(vhsubps, kX86InstIdVhsubps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vhsubps, kX86InstIdVhsubps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vhsubps, kX86InstIdVhsubps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vhsubps, kX86InstIdVhsubps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Insert 128-bit of packed FP data based on selector (AVX).
+ INST_4i(vinsertf128, kX86InstIdVinsertf128, X86YmmReg, X86YmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vinsertf128, kX86InstIdVinsertf128, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Insert SP-FP based on selector (AVX).
+ INST_4i(vinsertps, kX86InstIdVinsertps, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vinsertps, kX86InstIdVinsertps, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ //! Load 128-bits unaligned (AVX).
+ INST_2x(vlddqu, kX86InstIdVlddqu, X86XmmReg, X86Mem)
+ //! Load 256-bits unaligned (AVX).
+ INST_2x(vlddqu, kX86InstIdVlddqu, X86YmmReg, X86Mem)
+
+ //! Load streaming SIMD extension control/status (AVX).
+ INST_1x(vldmxcsr, kX86InstIdVldmxcsr, X86Mem)
+
+ //! Store selected bytes of OWORD to DS:EDI/RDI (AVX).
+ INST_2x(vmaskmovdqu, kX86InstIdVmaskmovdqu, X86XmmReg, X86XmmReg)
+
+ //! Conditionally load packed DP-FP from `o2` using mask in `o1 and store in `o0` (AVX).
+ INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86Mem, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86Mem, X86YmmReg, X86YmmReg)
+
+ //! Conditionally load packed SP-FP from `o2` using mask in `o1 and store in `o0` (AVX).
+ INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86Mem, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86Mem, X86YmmReg, X86YmmReg)
+
+ //! Packed DP-FP maximum (AVX).
+ INST_3x(vmaxpd, kX86InstIdVmaxpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vmaxpd, kX86InstIdVmaxpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vmaxpd, kX86InstIdVmaxpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vmaxpd, kX86InstIdVmaxpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP maximum (AVX).
+ INST_3x(vmaxps, kX86InstIdVmaxps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vmaxps, kX86InstIdVmaxps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vmaxps, kX86InstIdVmaxps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vmaxps, kX86InstIdVmaxps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Scalar DP-FP maximum (AVX).
+ INST_3x(vmaxsd, kX86InstIdVmaxsd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vmaxsd, kX86InstIdVmaxsd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP maximum (AVX).
+ INST_3x(vmaxss, kX86InstIdVmaxss, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vmaxss, kX86InstIdVmaxss, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DP-FP minimum (AVX).
+ INST_3x(vminpd, kX86InstIdVminpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vminpd, kX86InstIdVminpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vminpd, kX86InstIdVminpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vminpd, kX86InstIdVminpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP minimum (AVX).
+ INST_3x(vminps, kX86InstIdVminps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vminps, kX86InstIdVminps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vminps, kX86InstIdVminps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vminps, kX86InstIdVminps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Scalar DP-FP minimum (AVX).
+ INST_3x(vminsd, kX86InstIdVminsd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vminsd, kX86InstIdVminsd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP minimum (AVX).
+ INST_3x(vminss, kX86InstIdVminss, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vminss, kX86InstIdVminss, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Move 128-bits of aligned packed DP-FP (AVX).
+ INST_2x(vmovapd, kX86InstIdVmovapd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovapd, kX86InstIdVmovapd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovapd, kX86InstIdVmovapd, X86Mem, X86XmmReg)
+ //! Move 256-bits of aligned packed DP-FP (AVX).
+ INST_2x(vmovapd, kX86InstIdVmovapd, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vmovapd, kX86InstIdVmovapd, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovapd, kX86InstIdVmovapd, X86Mem, X86YmmReg)
+
+ //! Move 128-bits of aligned packed SP-FP (AVX).
+ INST_2x(vmovaps, kX86InstIdVmovaps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovaps, kX86InstIdVmovaps, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovaps, kX86InstIdVmovaps, X86Mem, X86XmmReg)
+ //! Move 256-bits of aligned packed SP-FP (AVX).
+ INST_2x(vmovaps, kX86InstIdVmovaps, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vmovaps, kX86InstIdVmovaps, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovaps, kX86InstIdVmovaps, X86Mem, X86YmmReg)
+
+ //! Move DWORD (AVX).
+ INST_2x(vmovd, kX86InstIdVmovd, X86XmmReg, X86GpReg)
+ //! \overload
+ INST_2x(vmovd, kX86InstIdVmovd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovd, kX86InstIdVmovd, X86GpReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovd, kX86InstIdVmovd, X86Mem, X86XmmReg)
+
+ //! Move QWORD (AVX).
+ INST_2x(vmovq, kX86InstIdVmovq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovq, kX86InstIdVmovq, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovq, kX86InstIdVmovq, X86Mem, X86XmmReg)
+
+ //! Move QWORD (AVX and X64 Only).
+ INST_2x(vmovq, kX86InstIdVmovq, X86XmmReg, X86GpReg)
+ //! \overload
+ INST_2x(vmovq, kX86InstIdVmovq, X86GpReg, X86XmmReg)
+
+ //! Move one DP-FP and duplicate (AVX).
+ INST_2x(vmovddup, kX86InstIdVmovddup, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovddup, kX86InstIdVmovddup, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovddup, kX86InstIdVmovddup, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vmovddup, kX86InstIdVmovddup, X86YmmReg, X86Mem)
+
+ //! Move 128-bits aligned (AVX).
+ INST_2x(vmovdqa, kX86InstIdVmovdqa, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovdqa, kX86InstIdVmovdqa, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovdqa, kX86InstIdVmovdqa, X86Mem, X86XmmReg)
+ //! Move 256-bits aligned (AVX).
+ INST_2x(vmovdqa, kX86InstIdVmovdqa, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vmovdqa, kX86InstIdVmovdqa, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovdqa, kX86InstIdVmovdqa, X86Mem, X86YmmReg)
+
+ //! Move 128-bits unaligned (AVX).
+ INST_2x(vmovdqu, kX86InstIdVmovdqu, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovdqu, kX86InstIdVmovdqu, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovdqu, kX86InstIdVmovdqu, X86Mem, X86XmmReg)
+ //! Move 256-bits unaligned (AVX).
+ INST_2x(vmovdqu, kX86InstIdVmovdqu, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vmovdqu, kX86InstIdVmovdqu, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovdqu, kX86InstIdVmovdqu, X86Mem, X86YmmReg)
+
+ //! High to low packed SP-FP (AVX).
+ INST_3x(vmovhlps, kX86InstIdVmovhlps, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ //! Move high packed DP-FP (AVX).
+ INST_3x(vmovhpd, kX86InstIdVmovhpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovhpd, kX86InstIdVmovhpd, X86Mem, X86XmmReg)
+
+ //! Move high packed SP-FP (AVX).
+ INST_3x(vmovhps, kX86InstIdVmovhps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovhps, kX86InstIdVmovhps, X86Mem, X86XmmReg)
+
+ //! Move low to high packed SP-FP (AVX).
+ INST_3x(vmovlhps, kX86InstIdVmovlhps, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ //! Move low packed DP-FP (AVX).
+ INST_3x(vmovlpd, kX86InstIdVmovlpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovlpd, kX86InstIdVmovlpd, X86Mem, X86XmmReg)
+
+ //! Move low packed SP-FP (AVX).
+ INST_3x(vmovlps, kX86InstIdVmovlps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovlps, kX86InstIdVmovlps, X86Mem, X86XmmReg)
+
+ //! Extract packed DP-FP sign mask (AVX).
+ INST_2x(vmovmskpd, kX86InstIdVmovmskpd, X86GpReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovmskpd, kX86InstIdVmovmskpd, X86GpReg, X86YmmReg)
+
+ //! Extract packed SP-FP sign mask (AVX).
+ INST_2x(vmovmskps, kX86InstIdVmovmskps, X86GpReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovmskps, kX86InstIdVmovmskps, X86GpReg, X86YmmReg)
+
+ //! Store 128-bits using NT hint (AVX).
+ INST_2x(vmovntdq, kX86InstIdVmovntdq, X86Mem, X86XmmReg)
+ //! Store 256-bits using NT hint (AVX).
+ INST_2x(vmovntdq, kX86InstIdVmovntdq, X86Mem, X86YmmReg)
+
+ //! Store 128-bits aligned using NT hint (AVX).
+ INST_2x(vmovntdqa, kX86InstIdVmovntdqa, X86XmmReg, X86Mem)
+
+ //! Store packed DP-FP (128-bits) using NT hint (AVX).
+ INST_2x(vmovntpd, kX86InstIdVmovntpd, X86Mem, X86XmmReg)
+ //! Store packed DP-FP (256-bits) using NT hint (AVX).
+ INST_2x(vmovntpd, kX86InstIdVmovntpd, X86Mem, X86YmmReg)
+
+ //! Store packed SP-FP (128-bits) using NT hint (AVX).
+ INST_2x(vmovntps, kX86InstIdVmovntps, X86Mem, X86XmmReg)
+ //! Store packed SP-FP (256-bits) using NT hint (AVX).
+ INST_2x(vmovntps, kX86InstIdVmovntps, X86Mem, X86YmmReg)
+
+ //! Move scalar DP-FP (AVX).
+ INST_3x(vmovsd, kX86InstIdVmovsd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovsd, kX86InstIdVmovsd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovsd, kX86InstIdVmovsd, X86Mem, X86XmmReg)
+
+ //! Move packed SP-FP high and duplicate (AVX).
+ INST_2x(vmovshdup, kX86InstIdVmovshdup, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovshdup, kX86InstIdVmovshdup, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovshdup, kX86InstIdVmovshdup, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vmovshdup, kX86InstIdVmovshdup, X86YmmReg, X86Mem)
+
+ //! Move packed SP-FP low and duplicate (AVX).
+ INST_2x(vmovsldup, kX86InstIdVmovsldup, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovsldup, kX86InstIdVmovsldup, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovsldup, kX86InstIdVmovsldup, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vmovsldup, kX86InstIdVmovsldup, X86YmmReg, X86Mem)
+
+ //! Move scalar SP-FP (AVX).
+ INST_3x(vmovss, kX86InstIdVmovss, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovss, kX86InstIdVmovss, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovss, kX86InstIdVmovss, X86Mem, X86XmmReg)
+
+ //! Move 128-bits of unaligned packed DP-FP (AVX).
+ INST_2x(vmovupd, kX86InstIdVmovupd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovupd, kX86InstIdVmovupd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovupd, kX86InstIdVmovupd, X86Mem, X86XmmReg)
+ //! Move 256-bits of unaligned packed DP-FP (AVX).
+ INST_2x(vmovupd, kX86InstIdVmovupd, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vmovupd, kX86InstIdVmovupd, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovupd, kX86InstIdVmovupd, X86Mem, X86YmmReg)
+
+ //! Move 128-bits of unaligned packed SP-FP (AVX).
+ INST_2x(vmovups, kX86InstIdVmovups, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vmovups, kX86InstIdVmovups, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovups, kX86InstIdVmovups, X86Mem, X86XmmReg)
+ //! Move 256-bits of unaligned packed SP-FP (AVX).
+ INST_2x(vmovups, kX86InstIdVmovups, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vmovups, kX86InstIdVmovups, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vmovups, kX86InstIdVmovups, X86Mem, X86YmmReg)
+
+ //! Packed WORD sums of absolute difference (AVX).
+ INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ //! Packed DP-FP multiply (AVX).
+ INST_3x(vmulpd, kX86InstIdVmulpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vmulpd, kX86InstIdVmulpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vmulpd, kX86InstIdVmulpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vmulpd, kX86InstIdVmulpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP multiply (AVX).
+ INST_3x(vmulps, kX86InstIdVmulps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vmulps, kX86InstIdVmulps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vmulps, kX86InstIdVmulps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vmulps, kX86InstIdVmulps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP multiply (AVX).
+ INST_3x(vmulsd, kX86InstIdVmulsd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vmulsd, kX86InstIdVmulsd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP multiply (AVX).
+ INST_3x(vmulss, kX86InstIdVmulss, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vmulss, kX86InstIdVmulss, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DP-FP bitwise or (AVX).
+ INST_3x(vorpd, kX86InstIdVorpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vorpd, kX86InstIdVorpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vorpd, kX86InstIdVorpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vorpd, kX86InstIdVorpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP bitwise or (AVX).
+ INST_3x(vorps, kX86InstIdVorps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vorps, kX86InstIdVorps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vorps, kX86InstIdVorps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vorps, kX86InstIdVorps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed BYTE absolute value (AVX).
+ INST_2x(vpabsb, kX86InstIdVpabsb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpabsb, kX86InstIdVpabsb, X86XmmReg, X86Mem)
+
+ //! Packed DWORD absolute value (AVX).
+ INST_2x(vpabsd, kX86InstIdVpabsd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpabsd, kX86InstIdVpabsd, X86XmmReg, X86Mem)
+
+ //! Packed WORD absolute value (AVX).
+ INST_2x(vpabsw, kX86InstIdVpabsw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpabsw, kX86InstIdVpabsw, X86XmmReg, X86Mem)
+
+ //! Pack DWORDs to WORDs with signed saturation (AVX).
+ INST_3x(vpackssdw, kX86InstIdVpackssdw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpackssdw, kX86InstIdVpackssdw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Pack WORDs to BYTEs with signed saturation (AVX).
+ INST_3x(vpacksswb, kX86InstIdVpacksswb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpacksswb, kX86InstIdVpacksswb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Pack DWORDs to WORDs with unsigned saturation (AVX).
+ INST_3x(vpackusdw, kX86InstIdVpackusdw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpackusdw, kX86InstIdVpackusdw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Pack WORDs to BYTEs with unsigned saturation (AVX).
+ INST_3x(vpackuswb, kX86InstIdVpackuswb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpackuswb, kX86InstIdVpackuswb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed BYTE add (AVX).
+ INST_3x(vpaddb, kX86InstIdVpaddb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpaddb, kX86InstIdVpaddb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DWORD add (AVX).
+ INST_3x(vpaddd, kX86InstIdVpaddd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpaddd, kX86InstIdVpaddd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed QWORD add (AVX).
+ INST_3x(vpaddq, kX86InstIdVpaddq, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpaddq, kX86InstIdVpaddq, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD add (AVX).
+ INST_3x(vpaddw, kX86InstIdVpaddw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpaddw, kX86InstIdVpaddw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed BYTE add with saturation (AVX).
+ INST_3x(vpaddsb, kX86InstIdVpaddsb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpaddsb, kX86InstIdVpaddsb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD add with saturation (AVX).
+ INST_3x(vpaddsw, kX86InstIdVpaddsw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpaddsw, kX86InstIdVpaddsw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed BYTE add with unsigned saturation (AVX).
+ INST_3x(vpaddusb, kX86InstIdVpaddusb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpaddusb, kX86InstIdVpaddusb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD add with unsigned saturation (AVX).
+ INST_3x(vpaddusw, kX86InstIdVpaddusw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpaddusw, kX86InstIdVpaddusw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed align right (AVX).
+ INST_4i(vpalignr, kX86InstIdVpalignr, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vpalignr, kX86InstIdVpalignr, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ //! Packed bitwise and (AVX).
+ INST_3x(vpand, kX86InstIdVpand, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpand, kX86InstIdVpand, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed bitwise and-not (AVX).
+ INST_3x(vpandn, kX86InstIdVpandn, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpandn, kX86InstIdVpandn, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed BYTE average (AVX).
+ INST_3x(vpavgb, kX86InstIdVpavgb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpavgb, kX86InstIdVpavgb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD average (AVX).
+ INST_3x(vpavgw, kX86InstIdVpavgw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpavgw, kX86InstIdVpavgw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed BYTE variable blend (AVX).
+ INST_4x(vpblendvb, kX86InstIdVpblendvb, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_4x(vpblendvb, kX86InstIdVpblendvb, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+
+ //! Packed WORD blend (AVX).
+ INST_4i(vpblendw, kX86InstIdVpblendw, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vpblendw, kX86InstIdVpblendw, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ //! Packed BYTEs compare for equality (AVX).
+ INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DWORDs compare for equality (AVX).
+ INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed QWORDs compare for equality (AVX).
+ INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORDs compare for equality (AVX).
+ INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed BYTEs compare if greater than (AVX).
+ INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DWORDs compare if greater than (AVX).
+ INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed QWORDs compare if greater than (AVX).
+ INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORDs compare if greater than (AVX).
+ INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed compare explicit length strings, return index (AVX).
+ INST_3i(vpcmpestri, kX86InstIdVpcmpestri, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vpcmpestri, kX86InstIdVpcmpestri, X86XmmReg, X86Mem, Imm)
+
+ //! Packed compare explicit length strings, return mask (AVX).
+ INST_3i(vpcmpestrm, kX86InstIdVpcmpestrm, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vpcmpestrm, kX86InstIdVpcmpestrm, X86XmmReg, X86Mem, Imm)
+
+ //! Packed compare implicit length strings, return index (AVX).
+ INST_3i(vpcmpistri, kX86InstIdVpcmpistri, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vpcmpistri, kX86InstIdVpcmpistri, X86XmmReg, X86Mem, Imm)
+
+ //! Packed compare implicit length strings, return mask (AVX).
+ INST_3i(vpcmpistrm, kX86InstIdVpcmpistrm, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vpcmpistrm, kX86InstIdVpcmpistrm, X86XmmReg, X86Mem, Imm)
+
+ //! Packed DP-FP permute (AVX).
+ INST_3x(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3i(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86Mem, Imm)
+ //! \overload
+ INST_3i(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_3i(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86Mem, Imm)
+
+ //! Packed SP-FP permute (AVX).
+ INST_3x(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3i(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86Mem, Imm)
+ //! \overload
+ INST_3i(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_3i(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86Mem, Imm)
+
+ //! Packed 128-bit FP permute (AVX).
+ INST_4i(vperm2f128, kX86InstIdVperm2f128, X86YmmReg, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_4i(vperm2f128, kX86InstIdVperm2f128, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Extract BYTE (AVX).
+ INST_3i(vpextrb, kX86InstIdVpextrb, X86GpReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vpextrb, kX86InstIdVpextrb, X86Mem, X86XmmReg, Imm)
+
+ //! Extract DWORD (AVX).
+ INST_3i(vpextrd, kX86InstIdVpextrd, X86GpReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vpextrd, kX86InstIdVpextrd, X86Mem, X86XmmReg, Imm)
+
+ //! Extract QWORD (AVX and X64 Only).
+ INST_3i(vpextrq, kX86InstIdVpextrq, X86GpReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vpextrq, kX86InstIdVpextrq, X86Mem, X86XmmReg, Imm)
+
+ //! Extract WORD (AVX).
+ INST_3i(vpextrw, kX86InstIdVpextrw, X86GpReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vpextrw, kX86InstIdVpextrw, X86Mem, X86XmmReg, Imm)
+
+ //! Packed DWORD horizontal add (AVX).
+ INST_3x(vphaddd, kX86InstIdVphaddd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vphaddd, kX86InstIdVphaddd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD horizontal add with saturation (AVX).
+ INST_3x(vphaddsw, kX86InstIdVphaddsw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vphaddsw, kX86InstIdVphaddsw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD horizontal add (AVX).
+ INST_3x(vphaddw, kX86InstIdVphaddw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vphaddw, kX86InstIdVphaddw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD horizontal minimum (AVX).
+ INST_2x(vphminposuw, kX86InstIdVphminposuw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vphminposuw, kX86InstIdVphminposuw, X86XmmReg, X86Mem)
+
+ //! Packed DWORD horizontal subtract (AVX).
+ INST_3x(vphsubd, kX86InstIdVphsubd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vphsubd, kX86InstIdVphsubd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD horizontal subtract with saturation (AVX).
+ INST_3x(vphsubsw, kX86InstIdVphsubsw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vphsubsw, kX86InstIdVphsubsw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD horizontal subtract (AVX).
+ INST_3x(vphsubw, kX86InstIdVphsubw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vphsubw, kX86InstIdVphsubw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Insert BYTE based on selector (AVX).
+ INST_4i(vpinsrb, kX86InstIdVpinsrb, X86XmmReg, X86XmmReg, X86GpReg, Imm)
+ //! \overload
+ INST_4i(vpinsrb, kX86InstIdVpinsrb, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ //! Insert DWORD based on selector (AVX).
+ INST_4i(vpinsrd, kX86InstIdVpinsrd, X86XmmReg, X86XmmReg, X86GpReg, Imm)
+ //! \overload
+ INST_4i(vpinsrd, kX86InstIdVpinsrd, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ //! Insert QWORD based on selector (AVX and X64 Only).
+ INST_4i(vpinsrq, kX86InstIdVpinsrq, X86XmmReg, X86XmmReg, X86GpReg, Imm)
+ //! \overload
+ INST_4i(vpinsrq, kX86InstIdVpinsrq, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ //! Insert WORD based on selector (AVX).
+ INST_4i(vpinsrw, kX86InstIdVpinsrw, X86XmmReg, X86XmmReg, X86GpReg, Imm)
+ //! \overload
+ INST_4i(vpinsrw, kX86InstIdVpinsrw, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ //! Packed multiply and add signed and unsigned bytes (AVX).
+ INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD multiply and add to packed DWORD (AVX).
+ INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed BYTE maximum (AVX).
+ INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DWORD maximum (AVX).
+ INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD maximum (AVX).
+ INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed BYTE unsigned maximum (AVX).
+ INST_3x(vpmaxub, kX86InstIdVpmaxub, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmaxub, kX86InstIdVpmaxub, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DWORD unsigned maximum (AVX).
+ INST_3x(vpmaxud, kX86InstIdVpmaxud, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmaxud, kX86InstIdVpmaxud, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD unsigned maximum (AVX).
+ INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed BYTE minimum (AVX).
+ INST_3x(vpminsb, kX86InstIdVpminsb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpminsb, kX86InstIdVpminsb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DWORD minimum (AVX).
+ INST_3x(vpminsd, kX86InstIdVpminsd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpminsd, kX86InstIdVpminsd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD minimum (AVX).
+ INST_3x(vpminsw, kX86InstIdVpminsw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpminsw, kX86InstIdVpminsw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed BYTE unsigned minimum (AVX).
+ INST_3x(vpminub, kX86InstIdVpminub, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpminub, kX86InstIdVpminub, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DWORD unsigned minimum (AVX).
+ INST_3x(vpminud, kX86InstIdVpminud, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpminud, kX86InstIdVpminud, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD unsigned minimum (AVX).
+ INST_3x(vpminuw, kX86InstIdVpminuw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpminuw, kX86InstIdVpminuw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Move Byte mask to integer (AVX).
+ INST_2x(vpmovmskb, kX86InstIdVpmovmskb, X86GpReg, X86XmmReg)
+
+ //! BYTE to DWORD with sign extend (AVX).
+ INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86XmmReg, X86Mem)
+
+ //! Packed BYTE to QWORD with sign extend (AVX).
+ INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86XmmReg, X86Mem)
+
+ //! Packed BYTE to WORD with sign extend (AVX).
+ INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86XmmReg, X86Mem)
+
+ //! Packed DWORD to QWORD with sign extend (AVX).
+ INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86XmmReg, X86Mem)
+
+ //! Packed WORD to DWORD with sign extend (AVX).
+ INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86XmmReg, X86Mem)
+
+ //! Packed WORD to QWORD with sign extend (AVX).
+ INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86XmmReg, X86Mem)
+
+ //! BYTE to DWORD with zero extend (AVX).
+ INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86XmmReg, X86Mem)
+
+ //! Packed BYTE to QWORD with zero extend (AVX).
+ INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86XmmReg, X86Mem)
+
+ //! BYTE to WORD with zero extend (AVX).
+ INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86XmmReg, X86Mem)
+
+ //! Packed DWORD to QWORD with zero extend (AVX).
+ INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86XmmReg, X86Mem)
+
+ //! Packed WORD to DWORD with zero extend (AVX).
+ INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86XmmReg, X86Mem)
+
+ //! Packed WORD to QWORD with zero extend (AVX).
+ INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86XmmReg, X86Mem)
+
+ //! Packed DWORD to QWORD multiply (AVX).
+ INST_3x(vpmuldq, kX86InstIdVpmuldq, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmuldq, kX86InstIdVpmuldq, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD multiply high, round and scale (AVX).
+ INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD unsigned multiply high (AVX).
+ INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD multiply high (AVX).
+ INST_3x(vpmulhw, kX86InstIdVpmulhw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmulhw, kX86InstIdVpmulhw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DWORD multiply low (AVX).
+ INST_3x(vpmulld, kX86InstIdVpmulld, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmulld, kX86InstIdVpmulld, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORDs multiply low (AVX).
+ INST_3x(vpmullw, kX86InstIdVpmullw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmullw, kX86InstIdVpmullw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DWORD multiply to QWORD (AVX).
+ INST_3x(vpmuludq, kX86InstIdVpmuludq, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpmuludq, kX86InstIdVpmuludq, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed bitwise or (AVX).
+ INST_3x(vpor, kX86InstIdVpor, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpor, kX86InstIdVpor, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD sum of absolute differences (AVX).
+ INST_3x(vpsadbw, kX86InstIdVpsadbw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsadbw, kX86InstIdVpsadbw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed BYTE shuffle (AVX).
+ INST_3x(vpshufb, kX86InstIdVpshufb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpshufb, kX86InstIdVpshufb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DWORD shuffle (AVX).
+ INST_3i(vpshufd, kX86InstIdVpshufd, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vpshufd, kX86InstIdVpshufd, X86XmmReg, X86Mem, Imm)
+
+ //! Packed WORD shuffle high (AVX).
+ INST_3i(vpshufhw, kX86InstIdVpshufhw, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vpshufhw, kX86InstIdVpshufhw, X86XmmReg, X86Mem, Imm)
+
+ //! Packed WORD shuffle low (AVX).
+ INST_3i(vpshuflw, kX86InstIdVpshuflw, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vpshuflw, kX86InstIdVpshuflw, X86XmmReg, X86Mem, Imm)
+
+ //! Packed BYTE sign (AVX).
+ INST_3x(vpsignb, kX86InstIdVpsignb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsignb, kX86InstIdVpsignb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DWORD sign (AVX).
+ INST_3x(vpsignd, kX86InstIdVpsignd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsignd, kX86InstIdVpsignd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD sign (AVX).
+ INST_3x(vpsignw, kX86InstIdVpsignw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsignw, kX86InstIdVpsignw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DWORD shift left logical (AVX).
+ INST_3x(vpslld, kX86InstIdVpslld, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpslld, kX86InstIdVpslld, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3i(vpslld, kX86InstIdVpslld, X86XmmReg, X86XmmReg, Imm)
+
+ //! Packed OWORD shift left logical (AVX).
+ INST_3i(vpslldq, kX86InstIdVpslldq, X86XmmReg, X86XmmReg, Imm)
+
+ //! Packed QWORD shift left logical (AVX).
+ INST_3x(vpsllq, kX86InstIdVpsllq, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsllq, kX86InstIdVpsllq, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3i(vpsllq, kX86InstIdVpsllq, X86XmmReg, X86XmmReg, Imm)
+
+ //! Packed WORD shift left logical (AVX).
+ INST_3x(vpsllw, kX86InstIdVpsllw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsllw, kX86InstIdVpsllw, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3i(vpsllw, kX86InstIdVpsllw, X86XmmReg, X86XmmReg, Imm)
+
+ //! Packed DWORD shift right arithmetic (AVX).
+ INST_3x(vpsrad, kX86InstIdVpsrad, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsrad, kX86InstIdVpsrad, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3i(vpsrad, kX86InstIdVpsrad, X86XmmReg, X86XmmReg, Imm)
+
+ //! Packed WORD shift right arithmetic (AVX).
+ INST_3x(vpsraw, kX86InstIdVpsraw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsraw, kX86InstIdVpsraw, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3i(vpsraw, kX86InstIdVpsraw, X86XmmReg, X86XmmReg, Imm)
+
+ //! Packed DWORD shift right logical (AVX).
+ INST_3x(vpsrld, kX86InstIdVpsrld, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsrld, kX86InstIdVpsrld, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3i(vpsrld, kX86InstIdVpsrld, X86XmmReg, X86XmmReg, Imm)
+
+ //! Scalar OWORD shift right logical (AVX).
+ INST_3i(vpsrldq, kX86InstIdVpsrldq, X86XmmReg, X86XmmReg, Imm)
+
+ //! Packed QWORD shift right logical (AVX).
+ INST_3x(vpsrlq, kX86InstIdVpsrlq, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsrlq, kX86InstIdVpsrlq, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3i(vpsrlq, kX86InstIdVpsrlq, X86XmmReg, X86XmmReg, Imm)
+
+ //! Packed WORD shift right logical (AVX).
+ INST_3x(vpsrlw, kX86InstIdVpsrlw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsrlw, kX86InstIdVpsrlw, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3i(vpsrlw, kX86InstIdVpsrlw, X86XmmReg, X86XmmReg, Imm)
+
+ //! Packed BYTE subtract (AVX).
+ INST_3x(vpsubb, kX86InstIdVpsubb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsubb, kX86InstIdVpsubb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DWORD subtract (AVX).
+ INST_3x(vpsubd, kX86InstIdVpsubd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsubd, kX86InstIdVpsubd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed QWORD subtract (AVX).
+ INST_3x(vpsubq, kX86InstIdVpsubq, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsubq, kX86InstIdVpsubq, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD subtract (AVX).
+ INST_3x(vpsubw, kX86InstIdVpsubw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsubw, kX86InstIdVpsubw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed BYTE subtract with saturation (AVX).
+ INST_3x(vpsubsb, kX86InstIdVpsubsb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsubsb, kX86InstIdVpsubsb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD subtract with saturation (AVX).
+ INST_3x(vpsubsw, kX86InstIdVpsubsw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsubsw, kX86InstIdVpsubsw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed BYTE subtract with unsigned saturation (AVX).
+ INST_3x(vpsubusb, kX86InstIdVpsubusb, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsubusb, kX86InstIdVpsubusb, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed WORD subtract with unsigned saturation (AVX).
+ INST_3x(vpsubusw, kX86InstIdVpsubusw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpsubusw, kX86InstIdVpsubusw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Logical compare (AVX).
+ INST_2x(vptest, kX86InstIdVptest, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vptest, kX86InstIdVptest, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vptest, kX86InstIdVptest, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vptest, kX86InstIdVptest, X86YmmReg, X86Mem)
+
+ //! Unpack high packed BYTEs to WORDs (AVX).
+ INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Unpack high packed DWORDs to QWORDs (AVX).
+ INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Unpack high packed QWORDs to OWORD (AVX).
+ INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Unpack high packed WORDs to DWORDs (AVX).
+ INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Unpack low packed BYTEs to WORDs (AVX).
+ INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Unpack low packed DWORDs to QWORDs (AVX).
+ INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Unpack low packed QWORDs to OWORD (AVX).
+ INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Unpack low packed WORDs to DWORDs (AVX).
+ INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed bitwise xor (AVX).
+ INST_3x(vpxor, kX86InstIdVpxor, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vpxor, kX86InstIdVpxor, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP reciprocal (AVX).
+ INST_2x(vrcpps, kX86InstIdVrcpps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vrcpps, kX86InstIdVrcpps, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vrcpps, kX86InstIdVrcpps, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vrcpps, kX86InstIdVrcpps, X86YmmReg, X86Mem)
+
+ //! Scalar SP-FP reciprocal (AVX).
+ INST_3x(vrcpss, kX86InstIdVrcpss, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vrcpss, kX86InstIdVrcpss, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed SP-FP square root reciprocal (AVX).
+ INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86YmmReg, X86Mem)
+
+ //! Scalar SP-FP square root reciprocal (AVX).
+ INST_3x(vrsqrtss, kX86InstIdVrsqrtss, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vrsqrtss, kX86InstIdVrsqrtss, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Packed DP-FP round (AVX).
+ INST_3i(vroundpd, kX86InstIdVroundpd, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vroundpd, kX86InstIdVroundpd, X86XmmReg, X86Mem, Imm)
+ //! \overload
+ INST_3i(vroundpd, kX86InstIdVroundpd, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_3i(vroundpd, kX86InstIdVroundpd, X86YmmReg, X86Mem, Imm)
+
+ //! Packed SP-FP round (AVX).
+ INST_3i(vroundps, kX86InstIdVroundps, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vroundps, kX86InstIdVroundps, X86XmmReg, X86Mem, Imm)
+ //! \overload
+ INST_3i(vroundps, kX86InstIdVroundps, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_3i(vroundps, kX86InstIdVroundps, X86YmmReg, X86Mem, Imm)
+
+ //! Scalar DP-FP round (AVX).
+ INST_4i(vroundsd, kX86InstIdVroundsd, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vroundsd, kX86InstIdVroundsd, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ //! Scalar SP-FP round (AVX).
+ INST_4i(vroundss, kX86InstIdVroundss, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vroundss, kX86InstIdVroundss, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ //! Shuffle DP-FP (AVX).
+ INST_4i(vshufpd, kX86InstIdVshufpd, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vshufpd, kX86InstIdVshufpd, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ //! \overload
+ INST_4i(vshufpd, kX86InstIdVshufpd, X86YmmReg, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_4i(vshufpd, kX86InstIdVshufpd, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Shuffle SP-FP (AVX).
+ INST_4i(vshufps, kX86InstIdVshufps, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vshufps, kX86InstIdVshufps, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ //! \overload
+ INST_4i(vshufps, kX86InstIdVshufps, X86YmmReg, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_4i(vshufps, kX86InstIdVshufps, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Packed DP-FP square root (AVX).
+ INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP square root (AVX).
+ INST_2x(vsqrtps, kX86InstIdVsqrtps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vsqrtps, kX86InstIdVsqrtps, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vsqrtps, kX86InstIdVsqrtps, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vsqrtps, kX86InstIdVsqrtps, X86YmmReg, X86Mem)
+
+ //! Scalar DP-FP square root (AVX).
+ INST_3x(vsqrtsd, kX86InstIdVsqrtsd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vsqrtsd, kX86InstIdVsqrtsd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP square root (AVX).
+ INST_3x(vsqrtss, kX86InstIdVsqrtss, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vsqrtss, kX86InstIdVsqrtss, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Store streaming SIMD extension control/status (AVX).
+ INST_1x(vstmxcsr, kX86InstIdVstmxcsr, X86Mem)
+
+ //! Packed DP-FP subtract (AVX).
+ INST_3x(vsubpd, kX86InstIdVsubpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vsubpd, kX86InstIdVsubpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vsubpd, kX86InstIdVsubpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vsubpd, kX86InstIdVsubpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP subtract (AVX).
+ INST_3x(vsubps, kX86InstIdVsubps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vsubps, kX86InstIdVsubps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vsubps, kX86InstIdVsubps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vsubps, kX86InstIdVsubps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Scalar DP-FP subtract (AVX).
+ INST_3x(vsubsd, kX86InstIdVsubsd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vsubsd, kX86InstIdVsubsd, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Scalar SP-FP subtract (AVX).
+ INST_3x(vsubss, kX86InstIdVsubss, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vsubss, kX86InstIdVsubss, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Logical compare DP-FP (AVX).
+ INST_2x(vtestpd, kX86InstIdVtestpd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vtestpd, kX86InstIdVtestpd, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vtestpd, kX86InstIdVtestpd, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vtestpd, kX86InstIdVtestpd, X86YmmReg, X86Mem)
+
+ //! Logical compare SP-FP (AVX).
+ INST_2x(vtestps, kX86InstIdVtestps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vtestps, kX86InstIdVtestps, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vtestps, kX86InstIdVtestps, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vtestps, kX86InstIdVtestps, X86YmmReg, X86Mem)
+
+ //! Scalar DP-FP unordered compare and set EFLAGS (AVX).
+ INST_2x(vucomisd, kX86InstIdVucomisd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vucomisd, kX86InstIdVucomisd, X86XmmReg, X86Mem)
+
+ //! Unordered scalar SP-FP compare and set EFLAGS (AVX).
+ INST_2x(vucomiss, kX86InstIdVucomiss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vucomiss, kX86InstIdVucomiss, X86XmmReg, X86Mem)
+
+ //! Unpack and interleave high packed DP-FP (AVX).
+ INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Unpack high packed SP-FP data (AVX).
+ INST_3x(vunpckhps, kX86InstIdVunpckhps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vunpckhps, kX86InstIdVunpckhps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vunpckhps, kX86InstIdVunpckhps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vunpckhps, kX86InstIdVunpckhps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Unpack and interleave low packed DP-FP (AVX).
+ INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Unpack low packed SP-FP data (AVX).
+ INST_3x(vunpcklps, kX86InstIdVunpcklps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vunpcklps, kX86InstIdVunpcklps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vunpcklps, kX86InstIdVunpcklps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vunpcklps, kX86InstIdVunpcklps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed DP-FP bitwise xor (AVX).
+ INST_3x(vxorpd, kX86InstIdVxorpd, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vxorpd, kX86InstIdVxorpd, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vxorpd, kX86InstIdVxorpd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vxorpd, kX86InstIdVxorpd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed SP-FP bitwise xor (AVX).
+ INST_3x(vxorps, kX86InstIdVxorps, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vxorps, kX86InstIdVxorps, X86XmmReg, X86XmmReg, X86Mem)
+ //! \overload
+ INST_3x(vxorps, kX86InstIdVxorps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vxorps, kX86InstIdVxorps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Zero all Ymm registers.
+ INST_0x(vzeroall, kX86InstIdVzeroall)
+ //! Zero upper 128-bits of all Ymm registers.
+ INST_0x(vzeroupper, kX86InstIdVzeroupper)
+
+ // --------------------------------------------------------------------------
+ // [AVX+AESNI]
+ // --------------------------------------------------------------------------
+
+ //! Perform a single round of the AES decryption flow (AVX+AESNI).
+ INST_3x(vaesdec, kX86InstIdVaesdec, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vaesdec, kX86InstIdVaesdec, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Perform the last round of the AES decryption flow (AVX+AESNI).
+ INST_3x(vaesdeclast, kX86InstIdVaesdeclast, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vaesdeclast, kX86InstIdVaesdeclast, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Perform a single round of the AES encryption flow (AVX+AESNI).
+ INST_3x(vaesenc, kX86InstIdVaesenc, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vaesenc, kX86InstIdVaesenc, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Perform the last round of the AES encryption flow (AVX+AESNI).
+ INST_3x(vaesenclast, kX86InstIdVaesenclast, X86XmmReg, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_3x(vaesenclast, kX86InstIdVaesenclast, X86XmmReg, X86XmmReg, X86Mem)
+
+ //! Perform the InvMixColumns transformation (AVX+AESNI).
+ INST_2x(vaesimc, kX86InstIdVaesimc, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vaesimc, kX86InstIdVaesimc, X86XmmReg, X86Mem)
+
+ //! Assist in expanding the AES cipher key (AVX+AESNI).
+ INST_3i(vaeskeygenassist, kX86InstIdVaeskeygenassist, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vaeskeygenassist, kX86InstIdVaeskeygenassist, X86XmmReg, X86Mem, Imm)
+
+ // --------------------------------------------------------------------------
+ // [AVX+PCLMULQDQ]
+ // --------------------------------------------------------------------------
+
+ //! Carry-less multiplication QWORD (AVX+PCLMULQDQ).
+ INST_4i(vpclmulqdq, kX86InstIdVpclmulqdq, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vpclmulqdq, kX86InstIdVpclmulqdq, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ // --------------------------------------------------------------------------
+ // [AVX2]
+ // --------------------------------------------------------------------------
+
+ //! Broadcast low 128-bit element in `o1` to `o0` (AVX2).
+ INST_2x(vbroadcasti128, kX86InstIdVbroadcasti128, X86YmmReg, X86Mem)
+ //! Broadcast low DP-FP element in `o1` to `o0` (AVX2).
+ INST_2x(vbroadcastsd, kX86InstIdVbroadcastsd, X86YmmReg, X86XmmReg)
+ //! Broadcast low SP-FP element in `o1` to `o0` (AVX2).
+ INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86YmmReg, X86XmmReg)
+
+ //! Extract 128-bit element from `o1` to `o0` based on selector (AVX2).
+ INST_3i(vextracti128, kX86InstIdVextracti128, X86XmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_3i(vextracti128, kX86InstIdVextracti128, X86Mem, X86YmmReg, Imm)
+
+ //! Gather DP-FP from DWORD indicies specified in `o1`s VSIB (AVX2).
+ INST_3x(vgatherdpd, kX86InstIdVgatherdpd, X86XmmReg, X86Mem, X86XmmReg)
+ //! \overload
+ INST_3x(vgatherdpd, kX86InstIdVgatherdpd, X86YmmReg, X86Mem, X86YmmReg)
+
+ //! Gather SP-FP from DWORD indicies specified in `o1`s VSIB (AVX2).
+ INST_3x(vgatherdps, kX86InstIdVgatherdps, X86XmmReg, X86Mem, X86XmmReg)
+ //! \overload
+ INST_3x(vgatherdps, kX86InstIdVgatherdps, X86YmmReg, X86Mem, X86YmmReg)
+
+ //! Gather DP-FP from QWORD indicies specified in `o1`s VSIB (AVX2).
+ INST_3x(vgatherqpd, kX86InstIdVgatherqpd, X86XmmReg, X86Mem, X86XmmReg)
+ //! \overload
+ INST_3x(vgatherqpd, kX86InstIdVgatherqpd, X86YmmReg, X86Mem, X86YmmReg)
+
+ //! Gather SP-FP from QWORD indicies specified in `o1`s VSIB (AVX2).
+ INST_3x(vgatherqps, kX86InstIdVgatherqps, X86XmmReg, X86Mem, X86XmmReg)
+
+ //! Insert 128-bit of packed data based on selector (AVX2).
+ INST_4i(vinserti128, kX86InstIdVinserti128, X86YmmReg, X86YmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vinserti128, kX86InstIdVinserti128, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Load 256-bits aligned using NT hint (AVX2).
+ INST_2x(vmovntdqa, kX86InstIdVmovntdqa, X86YmmReg, X86Mem)
+
+ //! Packed WORD sums of absolute difference (AVX2).
+ INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86YmmReg, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Packed BYTE absolute value (AVX2).
+ INST_2x(vpabsb, kX86InstIdVpabsb, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vpabsb, kX86InstIdVpabsb, X86YmmReg, X86Mem)
+
+ //! Packed DWORD absolute value (AVX2).
+ INST_2x(vpabsd, kX86InstIdVpabsd, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vpabsd, kX86InstIdVpabsd, X86YmmReg, X86Mem)
+
+ //! Packed WORD absolute value (AVX2).
+ INST_2x(vpabsw, kX86InstIdVpabsw, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_2x(vpabsw, kX86InstIdVpabsw, X86YmmReg, X86Mem)
+
+ //! Pack DWORDs to WORDs with signed saturation (AVX2).
+ INST_3x(vpackssdw, kX86InstIdVpackssdw, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpackssdw, kX86InstIdVpackssdw, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Pack WORDs to BYTEs with signed saturation (AVX2).
+ INST_3x(vpacksswb, kX86InstIdVpacksswb, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpacksswb, kX86InstIdVpacksswb, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Pack DWORDs to WORDs with unsigned saturation (AVX2).
+ INST_3x(vpackusdw, kX86InstIdVpackusdw, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpackusdw, kX86InstIdVpackusdw, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Pack WORDs to BYTEs with unsigned saturation (AVX2).
+ INST_3x(vpackuswb, kX86InstIdVpackuswb, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpackuswb, kX86InstIdVpackuswb, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed BYTE add (AVX2).
+ INST_3x(vpaddb, kX86InstIdVpaddb, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpaddb, kX86InstIdVpaddb, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed DWORD add (AVX2).
+ INST_3x(vpaddd, kX86InstIdVpaddd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpaddd, kX86InstIdVpaddd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed QDWORD add (AVX2).
+ INST_3x(vpaddq, kX86InstIdVpaddq, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpaddq, kX86InstIdVpaddq, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed WORD add (AVX2).
+ INST_3x(vpaddw, kX86InstIdVpaddw, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpaddw, kX86InstIdVpaddw, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed BYTE add with saturation (AVX2).
+ INST_3x(vpaddsb, kX86InstIdVpaddsb, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpaddsb, kX86InstIdVpaddsb, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed WORD add with saturation (AVX2).
+ INST_3x(vpaddsw, kX86InstIdVpaddsw, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpaddsw, kX86InstIdVpaddsw, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed BYTE add with unsigned saturation (AVX2).
+ INST_3x(vpaddusb, kX86InstIdVpaddusb, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpaddusb, kX86InstIdVpaddusb, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed WORD add with unsigned saturation (AVX2).
+ INST_3x(vpaddusw, kX86InstIdVpaddusw, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpaddusw, kX86InstIdVpaddusw, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed align right (AVX2).
+ INST_4i(vpalignr, kX86InstIdVpalignr, X86YmmReg, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_4i(vpalignr, kX86InstIdVpalignr, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Packed bitwise and (AVX2).
+ INST_3x(vpand, kX86InstIdVpand, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpand, kX86InstIdVpand, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed bitwise and-not (AVX2).
+ INST_3x(vpandn, kX86InstIdVpandn, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpandn, kX86InstIdVpandn, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed BYTE average (AVX2).
+ INST_3x(vpavgb, kX86InstIdVpavgb, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpavgb, kX86InstIdVpavgb, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed WORD average (AVX2).
+ INST_3x(vpavgw, kX86InstIdVpavgw, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpavgw, kX86InstIdVpavgw, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed DWORD blend (AVX2).
+ INST_4i(vpblendd, kX86InstIdVpblendd, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_4i(vpblendd, kX86InstIdVpblendd, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ //! \overload
+ INST_4i(vpblendd, kX86InstIdVpblendd, X86YmmReg, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_4i(vpblendd, kX86InstIdVpblendd, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Packed DWORD variable blend (AVX2).
+ INST_4x(vpblendvb, kX86InstIdVpblendvb, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_4x(vpblendvb, kX86InstIdVpblendvb, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+
+ //! Packed WORD blend (AVX2).
+ INST_4i(vpblendw, kX86InstIdVpblendw, X86YmmReg, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_4i(vpblendw, kX86InstIdVpblendw, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Broadcast BYTE from `o1` to 128-bits in `o0` (AVX2).
+ INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86XmmReg, X86Mem)
+ //! Broadcast BYTE from `o1` to 256-bits in `o0` (AVX2).
+ INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86YmmReg, X86Mem)
+
+ //! Broadcast DWORD from `o1` to 128-bits in `o0` (AVX2).
+ INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86XmmReg, X86Mem)
+ //! Broadcast DWORD from `o1` to 256-bits in `o0` (AVX2).
+ INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86YmmReg, X86Mem)
+
+ //! Broadcast QWORD from `o1` to 128-bits in `o0` (AVX2).
+ INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86XmmReg, X86Mem)
+ //! Broadcast QWORD from `o1` to 256-bits in `o0` (AVX2).
+ INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86YmmReg, X86Mem)
+
+ //! Broadcast WORD from `o1` to 128-bits in `o0` (AVX2).
+ INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86XmmReg, X86Mem)
+ //! Broadcast WORD from `o1` to 256-bits in `o0` (AVX2).
+ INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86YmmReg, X86Mem)
+
+ //! Packed BYTEs compare for equality (AVX2).
+ INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed DWORDs compare for equality (AVX2).
+ INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed QWORDs compare for equality (AVX2).
+ INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed WORDs compare for equality (AVX2).
+ INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed BYTEs compare if greater than (AVX2).
+ INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed DWORDs compare if greater than (AVX2).
+ INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed QWORDs compare if greater than (AVX2).
+ INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed WORDs compare if greater than (AVX2).
+ INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed OWORD permute (AVX2).
+ INST_4i(vperm2i128, kX86InstIdVperm2i128, X86YmmReg, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_4i(vperm2i128, kX86InstIdVperm2i128, X86YmmReg, X86YmmReg, X86Mem, Imm)
+
+ //! Packed DWORD permute (AVX2).
+ INST_3x(vpermd, kX86InstIdVpermd, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpermd, kX86InstIdVpermd, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed DP-FP permute (AVX2).
+ INST_3i(vpermpd, kX86InstIdVpermpd, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_3i(vpermpd, kX86InstIdVpermpd, X86YmmReg, X86Mem, Imm)
+
+ //! Packed SP-FP permute (AVX2).
+ INST_3x(vpermps, kX86InstIdVpermps, X86YmmReg, X86YmmReg, X86YmmReg)
+ //! \overload
+ INST_3x(vpermps, kX86InstIdVpermps, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed QWORD permute (AVX2).
+ INST_3i(vpermq, kX86InstIdVpermq, X86YmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_3i(vpermq, kX86InstIdVpermq, X86YmmReg, X86Mem, Imm)
+
+ INST_3x(vpgatherdd, kX86InstIdVpgatherdd, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vpgatherdd, kX86InstIdVpgatherdd, X86YmmReg, X86Mem, X86YmmReg)
+
+ INST_3x(vpgatherdq, kX86InstIdVpgatherdq, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vpgatherdq, kX86InstIdVpgatherdq, X86YmmReg, X86Mem, X86YmmReg)
+
+ INST_3x(vpgatherqd, kX86InstIdVpgatherqd, X86XmmReg, X86Mem, X86XmmReg)
+
+ INST_3x(vpgatherqq, kX86InstIdVpgatherqq, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vpgatherqq, kX86InstIdVpgatherqq, X86YmmReg, X86Mem, X86YmmReg)
+
+ //! Packed DWORD horizontal add (AVX2).
+ INST_3x(vphaddd, kX86InstIdVphaddd, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vphaddd, kX86InstIdVphaddd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD horizontal add with saturation (AVX2).
+ INST_3x(vphaddsw, kX86InstIdVphaddsw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vphaddsw, kX86InstIdVphaddsw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD horizontal add (AVX2).
+ INST_3x(vphaddw, kX86InstIdVphaddw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vphaddw, kX86InstIdVphaddw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed DWORD horizontal subtract (AVX2).
+ INST_3x(vphsubd, kX86InstIdVphsubd, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vphsubd, kX86InstIdVphsubd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD horizontal subtract with saturation (AVX2).
+ INST_3x(vphsubsw, kX86InstIdVphsubsw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vphsubsw, kX86InstIdVphsubsw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD horizontal subtract (AVX2).
+ INST_3x(vphsubw, kX86InstIdVphsubw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vphsubw, kX86InstIdVphsubw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Move Byte mask to integer (AVX2).
+ INST_2x(vpmovmskb, kX86InstIdVpmovmskb, X86GpReg, X86YmmReg)
+
+ //! BYTE to DWORD with sign extend (AVX).
+ INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86YmmReg, X86XmmReg)
+
+ //! Packed BYTE to QWORD with sign extend (AVX2).
+ INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86YmmReg, X86XmmReg)
+
+ //! Packed BYTE to WORD with sign extend (AVX2).
+ INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86YmmReg, X86XmmReg)
+
+ //! Packed DWORD to QWORD with sign extend (AVX2).
+ INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86YmmReg, X86XmmReg)
+
+ //! Packed WORD to DWORD with sign extend (AVX2).
+ INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86YmmReg, X86XmmReg)
+
+ //! Packed WORD to QWORD with sign extend (AVX2).
+ INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86YmmReg, X86XmmReg)
+
+ //! BYTE to DWORD with zero extend (AVX2).
+ INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86YmmReg, X86XmmReg)
+
+ //! Packed BYTE to QWORD with zero extend (AVX2).
+ INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86YmmReg, X86XmmReg)
+
+ //! BYTE to WORD with zero extend (AVX2).
+ INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86YmmReg, X86XmmReg)
+
+ //! Packed DWORD to QWORD with zero extend (AVX2).
+ INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86YmmReg, X86XmmReg)
+
+ //! Packed WORD to DWORD with zero extend (AVX2).
+ INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86YmmReg, X86XmmReg)
+
+ //! Packed WORD to QWORD with zero extend (AVX2).
+ INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86YmmReg, X86Mem)
+ //! \overload
+ INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86YmmReg, X86XmmReg)
+
+ //! Packed multiply and add signed and unsigned bytes (AVX2).
+ INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD multiply and add to packed DWORD (AVX2).
+ INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vpmaskmovd, kX86InstIdVpmaskmovd, X86Mem, X86XmmReg, X86XmmReg)
+ INST_3x(vpmaskmovd, kX86InstIdVpmaskmovd, X86Mem, X86YmmReg, X86YmmReg)
+ INST_3x(vpmaskmovd, kX86InstIdVpmaskmovd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vpmaskmovd, kX86InstIdVpmaskmovd, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_3x(vpmaskmovq, kX86InstIdVpmaskmovq, X86Mem, X86XmmReg, X86XmmReg)
+ INST_3x(vpmaskmovq, kX86InstIdVpmaskmovq, X86Mem, X86YmmReg, X86YmmReg)
+ INST_3x(vpmaskmovq, kX86InstIdVpmaskmovq, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vpmaskmovq, kX86InstIdVpmaskmovq, X86YmmReg, X86YmmReg, X86Mem)
+
+ //! Packed BYTE maximum (AVX2).
+ INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed DWORD maximum (AVX2).
+ INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD maximum (AVX2).
+ INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed BYTE unsigned maximum (AVX2).
+ INST_3x(vpmaxub, kX86InstIdVpmaxub, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmaxub, kX86InstIdVpmaxub, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed DWORD unsigned maximum (AVX2).
+ INST_3x(vpmaxud, kX86InstIdVpmaxud, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmaxud, kX86InstIdVpmaxud, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD unsigned maximum (AVX2).
+ INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed BYTE minimum (AVX2).
+ INST_3x(vpminsb, kX86InstIdVpminsb, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpminsb, kX86InstIdVpminsb, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed DWORD minimum (AVX2).
+ INST_3x(vpminsd, kX86InstIdVpminsd, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpminsd, kX86InstIdVpminsd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD minimum (AVX2).
+ INST_3x(vpminsw, kX86InstIdVpminsw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpminsw, kX86InstIdVpminsw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed BYTE unsigned minimum (AVX2).
+ INST_3x(vpminub, kX86InstIdVpminub, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpminub, kX86InstIdVpminub, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed DWORD unsigned minimum (AVX2).
+ INST_3x(vpminud, kX86InstIdVpminud, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpminud, kX86InstIdVpminud, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD unsigned minimum (AVX2).
+ INST_3x(vpminuw, kX86InstIdVpminuw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpminuw, kX86InstIdVpminuw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed DWORD to QWORD multiply (AVX2).
+ INST_3x(vpmuldq, kX86InstIdVpmuldq, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmuldq, kX86InstIdVpmuldq, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD multiply high, round and scale (AVX2).
+ INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD unsigned multiply high (AVX2).
+ INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD multiply high (AVX2).
+ INST_3x(vpmulhw, kX86InstIdVpmulhw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmulhw, kX86InstIdVpmulhw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed DWORD multiply low (AVX2).
+ INST_3x(vpmulld, kX86InstIdVpmulld, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmulld, kX86InstIdVpmulld, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORDs multiply low (AVX2).
+ INST_3x(vpmullw, kX86InstIdVpmullw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmullw, kX86InstIdVpmullw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed DWORD multiply to QWORD (AVX2).
+ INST_3x(vpmuludq, kX86InstIdVpmuludq, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpmuludq, kX86InstIdVpmuludq, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed bitwise or (AVX2).
+ INST_3x(vpor, kX86InstIdVpor, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpor, kX86InstIdVpor, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD sum of absolute differences (AVX2).
+ INST_3x(vpsadbw, kX86InstIdVpsadbw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsadbw, kX86InstIdVpsadbw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed BYTE shuffle (AVX2).
+ INST_3x(vpshufb, kX86InstIdVpshufb, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpshufb, kX86InstIdVpshufb, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed DWORD shuffle (AVX2).
+ INST_3i(vpshufd, kX86InstIdVpshufd, X86YmmReg, X86Mem, Imm)
+ //! \overload
+ INST_3i(vpshufd, kX86InstIdVpshufd, X86YmmReg, X86YmmReg, Imm)
+
+ //! Packed WORD shuffle high (AVX2).
+ INST_3i(vpshufhw, kX86InstIdVpshufhw, X86YmmReg, X86Mem, Imm)
+ //! \overload
+ INST_3i(vpshufhw, kX86InstIdVpshufhw, X86YmmReg, X86YmmReg, Imm)
+
+ //! Packed WORD shuffle low (AVX2).
+ INST_3i(vpshuflw, kX86InstIdVpshuflw, X86YmmReg, X86Mem, Imm)
+ //! \overload
+ INST_3i(vpshuflw, kX86InstIdVpshuflw, X86YmmReg, X86YmmReg, Imm)
+
+ //! Packed BYTE sign (AVX2).
+ INST_3x(vpsignb, kX86InstIdVpsignb, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsignb, kX86InstIdVpsignb, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed DWORD sign (AVX2).
+ INST_3x(vpsignd, kX86InstIdVpsignd, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsignd, kX86InstIdVpsignd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD sign (AVX2).
+ INST_3x(vpsignw, kX86InstIdVpsignw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsignw, kX86InstIdVpsignw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed DWORD shift left logical (AVX2).
+ INST_3x(vpslld, kX86InstIdVpslld, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpslld, kX86InstIdVpslld, X86YmmReg, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_3i(vpslld, kX86InstIdVpslld, X86YmmReg, X86YmmReg, Imm)
+
+ //! Packed OWORD shift left logical (AVX2).
+ INST_3i(vpslldq, kX86InstIdVpslldq, X86YmmReg, X86YmmReg, Imm)
+
+ //! Packed QWORD shift left logical (AVX2).
+ INST_3x(vpsllq, kX86InstIdVpsllq, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsllq, kX86InstIdVpsllq, X86YmmReg, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_3i(vpsllq, kX86InstIdVpsllq, X86YmmReg, X86YmmReg, Imm)
+
+ INST_3x(vpsllvd, kX86InstIdVpsllvd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vpsllvd, kX86InstIdVpsllvd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vpsllvd, kX86InstIdVpsllvd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vpsllvd, kX86InstIdVpsllvd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vpsllvq, kX86InstIdVpsllvq, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vpsllvq, kX86InstIdVpsllvq, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vpsllvq, kX86InstIdVpsllvq, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vpsllvq, kX86InstIdVpsllvq, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD shift left logical (AVX2).
+ INST_3x(vpsllw, kX86InstIdVpsllw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsllw, kX86InstIdVpsllw, X86YmmReg, X86YmmReg, X86XmmReg)
+ //! Packed WORD shift left logical (AVX2).
+ INST_3i(vpsllw, kX86InstIdVpsllw, X86YmmReg, X86YmmReg, Imm)
+
+ //! Packed DWORD shift right arithmetic (AVX2).
+ INST_3x(vpsrad, kX86InstIdVpsrad, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsrad, kX86InstIdVpsrad, X86YmmReg, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_3i(vpsrad, kX86InstIdVpsrad, X86YmmReg, X86YmmReg, Imm)
+
+ INST_3x(vpsravd, kX86InstIdVpsravd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vpsravd, kX86InstIdVpsravd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vpsravd, kX86InstIdVpsravd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vpsravd, kX86InstIdVpsravd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD shift right arithmetic (AVX2).
+ INST_3x(vpsraw, kX86InstIdVpsraw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsraw, kX86InstIdVpsraw, X86YmmReg, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_3i(vpsraw, kX86InstIdVpsraw, X86YmmReg, X86YmmReg, Imm)
+
+ //! Packed DWORD shift right logical (AVX2).
+ INST_3x(vpsrld, kX86InstIdVpsrld, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsrld, kX86InstIdVpsrld, X86YmmReg, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_3i(vpsrld, kX86InstIdVpsrld, X86YmmReg, X86YmmReg, Imm)
+
+ //! Scalar OWORD shift right logical (AVX2).
+ INST_3i(vpsrldq, kX86InstIdVpsrldq, X86YmmReg, X86YmmReg, Imm)
+
+ //! Packed QWORD shift right logical (AVX2).
+ INST_3x(vpsrlq, kX86InstIdVpsrlq, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsrlq, kX86InstIdVpsrlq, X86YmmReg, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_3i(vpsrlq, kX86InstIdVpsrlq, X86YmmReg, X86YmmReg, Imm)
+
+ INST_3x(vpsrlvd, kX86InstIdVpsrlvd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vpsrlvd, kX86InstIdVpsrlvd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vpsrlvd, kX86InstIdVpsrlvd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vpsrlvd, kX86InstIdVpsrlvd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vpsrlvq, kX86InstIdVpsrlvq, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vpsrlvq, kX86InstIdVpsrlvq, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vpsrlvq, kX86InstIdVpsrlvq, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vpsrlvq, kX86InstIdVpsrlvq, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD shift right logical (AVX2).
+ INST_3x(vpsrlw, kX86InstIdVpsrlw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsrlw, kX86InstIdVpsrlw, X86YmmReg, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_3i(vpsrlw, kX86InstIdVpsrlw, X86YmmReg, X86YmmReg, Imm)
+
+ //! Packed BYTE subtract (AVX2).
+ INST_3x(vpsubb, kX86InstIdVpsubb, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vpsubb, kX86InstIdVpsubb, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed DWORD subtract (AVX2).
+ INST_3x(vpsubd, kX86InstIdVpsubd, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsubd, kX86InstIdVpsubd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed QWORD subtract (AVX2).
+ INST_3x(vpsubq, kX86InstIdVpsubq, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsubq, kX86InstIdVpsubq, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed BYTE subtract with saturation (AVX2).
+ INST_3x(vpsubsb, kX86InstIdVpsubsb, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsubsb, kX86InstIdVpsubsb, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD subtract with saturation (AVX2).
+ INST_3x(vpsubsw, kX86InstIdVpsubsw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsubsw, kX86InstIdVpsubsw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed BYTE subtract with unsigned saturation (AVX2).
+ INST_3x(vpsubusb, kX86InstIdVpsubusb, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsubusb, kX86InstIdVpsubusb, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD subtract with unsigned saturation (AVX2).
+ INST_3x(vpsubusw, kX86InstIdVpsubusw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsubusw, kX86InstIdVpsubusw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed WORD subtract (AVX2).
+ INST_3x(vpsubw, kX86InstIdVpsubw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpsubw, kX86InstIdVpsubw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Unpack high packed BYTEs to WORDs (AVX2).
+ INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Unpack high packed DWORDs to QWORDs (AVX2).
+ INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Unpack high packed QWORDs to OWORD (AVX2).
+ INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Unpack high packed WORDs to DWORDs (AVX2).
+ INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Unpack low packed BYTEs to WORDs (AVX2).
+ INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Unpack low packed DWORDs to QWORDs (AVX2).
+ INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Unpack low packed QWORDs to OWORD (AVX2).
+ INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Unpack low packed WORDs to DWORDs (AVX2).
+ INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ //! Packed bitwise xor (AVX2).
+ INST_3x(vpxor, kX86InstIdVpxor, X86YmmReg, X86YmmReg, X86Mem)
+ //! \overload
+ INST_3x(vpxor, kX86InstIdVpxor, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ // --------------------------------------------------------------------------
+ // [FMA3]
+ // --------------------------------------------------------------------------
+
+ INST_3x(vfmadd132pd, kX86InstIdVfmadd132pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmadd132pd, kX86InstIdVfmadd132pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmadd132pd, kX86InstIdVfmadd132pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmadd132pd, kX86InstIdVfmadd132pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmadd132ps, kX86InstIdVfmadd132ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmadd132ps, kX86InstIdVfmadd132ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmadd132ps, kX86InstIdVfmadd132ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmadd132ps, kX86InstIdVfmadd132ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmadd132sd, kX86InstIdVfmadd132sd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmadd132sd, kX86InstIdVfmadd132sd, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfmadd132ss, kX86InstIdVfmadd132ss, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmadd132ss, kX86InstIdVfmadd132ss, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfmadd213pd, kX86InstIdVfmadd213pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmadd213pd, kX86InstIdVfmadd213pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmadd213pd, kX86InstIdVfmadd213pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmadd213pd, kX86InstIdVfmadd213pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmadd213ps, kX86InstIdVfmadd213ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmadd213ps, kX86InstIdVfmadd213ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmadd213ps, kX86InstIdVfmadd213ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmadd213ps, kX86InstIdVfmadd213ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmadd213sd, kX86InstIdVfmadd213sd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmadd213sd, kX86InstIdVfmadd213sd, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfmadd213ss, kX86InstIdVfmadd213ss, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmadd213ss, kX86InstIdVfmadd213ss, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfmadd231pd, kX86InstIdVfmadd231pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmadd231pd, kX86InstIdVfmadd231pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmadd231pd, kX86InstIdVfmadd231pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmadd231pd, kX86InstIdVfmadd231pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmadd231ps, kX86InstIdVfmadd231ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmadd231ps, kX86InstIdVfmadd231ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmadd231ps, kX86InstIdVfmadd231ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmadd231ps, kX86InstIdVfmadd231ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmadd231sd, kX86InstIdVfmadd231sd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmadd231sd, kX86InstIdVfmadd231sd, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfmadd231ss, kX86InstIdVfmadd231ss, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmadd231ss, kX86InstIdVfmadd231ss, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfmaddsub132pd, kX86InstIdVfmaddsub132pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmaddsub132pd, kX86InstIdVfmaddsub132pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmaddsub132pd, kX86InstIdVfmaddsub132pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmaddsub132pd, kX86InstIdVfmaddsub132pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmaddsub132ps, kX86InstIdVfmaddsub132ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmaddsub132ps, kX86InstIdVfmaddsub132ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmaddsub132ps, kX86InstIdVfmaddsub132ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmaddsub132ps, kX86InstIdVfmaddsub132ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmaddsub213pd, kX86InstIdVfmaddsub213pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmaddsub213pd, kX86InstIdVfmaddsub213pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmaddsub213pd, kX86InstIdVfmaddsub213pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmaddsub213pd, kX86InstIdVfmaddsub213pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmaddsub213ps, kX86InstIdVfmaddsub213ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmaddsub213ps, kX86InstIdVfmaddsub213ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmaddsub213ps, kX86InstIdVfmaddsub213ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmaddsub213ps, kX86InstIdVfmaddsub213ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmaddsub231pd, kX86InstIdVfmaddsub231pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmaddsub231pd, kX86InstIdVfmaddsub231pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmaddsub231pd, kX86InstIdVfmaddsub231pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmaddsub231pd, kX86InstIdVfmaddsub231pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmaddsub231ps, kX86InstIdVfmaddsub231ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmaddsub231ps, kX86InstIdVfmaddsub231ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmaddsub231ps, kX86InstIdVfmaddsub231ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmaddsub231ps, kX86InstIdVfmaddsub231ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmsub132pd, kX86InstIdVfmsub132pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsub132pd, kX86InstIdVfmsub132pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmsub132pd, kX86InstIdVfmsub132pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmsub132pd, kX86InstIdVfmsub132pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmsub132ps, kX86InstIdVfmsub132ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsub132ps, kX86InstIdVfmsub132ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmsub132ps, kX86InstIdVfmsub132ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmsub132ps, kX86InstIdVfmsub132ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmsub132sd, kX86InstIdVfmsub132sd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsub132sd, kX86InstIdVfmsub132sd, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfmsub132ss, kX86InstIdVfmsub132ss, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsub132ss, kX86InstIdVfmsub132ss, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfmsub213pd, kX86InstIdVfmsub213pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsub213pd, kX86InstIdVfmsub213pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmsub213pd, kX86InstIdVfmsub213pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmsub213pd, kX86InstIdVfmsub213pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmsub213ps, kX86InstIdVfmsub213ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsub213ps, kX86InstIdVfmsub213ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmsub213ps, kX86InstIdVfmsub213ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmsub213ps, kX86InstIdVfmsub213ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmsub213sd, kX86InstIdVfmsub213sd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsub213sd, kX86InstIdVfmsub213sd, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfmsub213ss, kX86InstIdVfmsub213ss, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsub213ss, kX86InstIdVfmsub213ss, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfmsub231pd, kX86InstIdVfmsub231pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsub231pd, kX86InstIdVfmsub231pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmsub231pd, kX86InstIdVfmsub231pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmsub231pd, kX86InstIdVfmsub231pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmsub231ps, kX86InstIdVfmsub231ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsub231ps, kX86InstIdVfmsub231ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmsub231ps, kX86InstIdVfmsub231ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmsub231ps, kX86InstIdVfmsub231ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmsub231sd, kX86InstIdVfmsub231sd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsub231sd, kX86InstIdVfmsub231sd, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfmsub231ss, kX86InstIdVfmsub231ss, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsub231ss, kX86InstIdVfmsub231ss, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfmsubadd132pd, kX86InstIdVfmsubadd132pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsubadd132pd, kX86InstIdVfmsubadd132pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmsubadd132pd, kX86InstIdVfmsubadd132pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmsubadd132pd, kX86InstIdVfmsubadd132pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmsubadd132ps, kX86InstIdVfmsubadd132ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsubadd132ps, kX86InstIdVfmsubadd132ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmsubadd132ps, kX86InstIdVfmsubadd132ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmsubadd132ps, kX86InstIdVfmsubadd132ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmsubadd213pd, kX86InstIdVfmsubadd213pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsubadd213pd, kX86InstIdVfmsubadd213pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmsubadd213pd, kX86InstIdVfmsubadd213pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmsubadd213pd, kX86InstIdVfmsubadd213pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmsubadd213ps, kX86InstIdVfmsubadd213ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsubadd213ps, kX86InstIdVfmsubadd213ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmsubadd213ps, kX86InstIdVfmsubadd213ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmsubadd213ps, kX86InstIdVfmsubadd213ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmsubadd231pd, kX86InstIdVfmsubadd231pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsubadd231pd, kX86InstIdVfmsubadd231pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmsubadd231pd, kX86InstIdVfmsubadd231pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmsubadd231pd, kX86InstIdVfmsubadd231pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfmsubadd231ps, kX86InstIdVfmsubadd231ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfmsubadd231ps, kX86InstIdVfmsubadd231ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfmsubadd231ps, kX86InstIdVfmsubadd231ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfmsubadd231ps, kX86InstIdVfmsubadd231ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfnmadd132pd, kX86InstIdVfnmadd132pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmadd132pd, kX86InstIdVfnmadd132pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfnmadd132pd, kX86InstIdVfnmadd132pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfnmadd132pd, kX86InstIdVfnmadd132pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfnmadd132ps, kX86InstIdVfnmadd132ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmadd132ps, kX86InstIdVfnmadd132ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfnmadd132ps, kX86InstIdVfnmadd132ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfnmadd132ps, kX86InstIdVfnmadd132ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfnmadd132sd, kX86InstIdVfnmadd132sd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmadd132sd, kX86InstIdVfnmadd132sd, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfnmadd132ss, kX86InstIdVfnmadd132ss, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmadd132ss, kX86InstIdVfnmadd132ss, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfnmadd213pd, kX86InstIdVfnmadd213pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmadd213pd, kX86InstIdVfnmadd213pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfnmadd213pd, kX86InstIdVfnmadd213pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfnmadd213pd, kX86InstIdVfnmadd213pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfnmadd213ps, kX86InstIdVfnmadd213ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmadd213ps, kX86InstIdVfnmadd213ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfnmadd213ps, kX86InstIdVfnmadd213ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfnmadd213ps, kX86InstIdVfnmadd213ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfnmadd213sd, kX86InstIdVfnmadd213sd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmadd213sd, kX86InstIdVfnmadd213sd, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfnmadd213ss, kX86InstIdVfnmadd213ss, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmadd213ss, kX86InstIdVfnmadd213ss, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfnmadd231pd, kX86InstIdVfnmadd231pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmadd231pd, kX86InstIdVfnmadd231pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfnmadd231pd, kX86InstIdVfnmadd231pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfnmadd231pd, kX86InstIdVfnmadd231pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfnmadd231ps, kX86InstIdVfnmadd231ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmadd231ps, kX86InstIdVfnmadd231ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfnmadd231ps, kX86InstIdVfnmadd231ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfnmadd231ps, kX86InstIdVfnmadd231ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfnmadd231sd, kX86InstIdVfnmadd231sd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmadd231sd, kX86InstIdVfnmadd231sd, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfnmadd231ss, kX86InstIdVfnmadd231ss, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmadd231ss, kX86InstIdVfnmadd231ss, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfnmsub132pd, kX86InstIdVfnmsub132pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmsub132pd, kX86InstIdVfnmsub132pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfnmsub132pd, kX86InstIdVfnmsub132pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfnmsub132pd, kX86InstIdVfnmsub132pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfnmsub132ps, kX86InstIdVfnmsub132ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmsub132ps, kX86InstIdVfnmsub132ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfnmsub132ps, kX86InstIdVfnmsub132ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfnmsub132ps, kX86InstIdVfnmsub132ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfnmsub132sd, kX86InstIdVfnmsub132sd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmsub132sd, kX86InstIdVfnmsub132sd, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfnmsub132ss, kX86InstIdVfnmsub132ss, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmsub132ss, kX86InstIdVfnmsub132ss, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfnmsub213pd, kX86InstIdVfnmsub213pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmsub213pd, kX86InstIdVfnmsub213pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfnmsub213pd, kX86InstIdVfnmsub213pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfnmsub213pd, kX86InstIdVfnmsub213pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfnmsub213ps, kX86InstIdVfnmsub213ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmsub213ps, kX86InstIdVfnmsub213ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfnmsub213ps, kX86InstIdVfnmsub213ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfnmsub213ps, kX86InstIdVfnmsub213ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfnmsub213sd, kX86InstIdVfnmsub213sd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmsub213sd, kX86InstIdVfnmsub213sd, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfnmsub213ss, kX86InstIdVfnmsub213ss, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmsub213ss, kX86InstIdVfnmsub213ss, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfnmsub231pd, kX86InstIdVfnmsub231pd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmsub231pd, kX86InstIdVfnmsub231pd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfnmsub231pd, kX86InstIdVfnmsub231pd, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfnmsub231pd, kX86InstIdVfnmsub231pd, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfnmsub231ps, kX86InstIdVfnmsub231ps, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmsub231ps, kX86InstIdVfnmsub231ps, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vfnmsub231ps, kX86InstIdVfnmsub231ps, X86YmmReg, X86YmmReg, X86Mem)
+ INST_3x(vfnmsub231ps, kX86InstIdVfnmsub231ps, X86YmmReg, X86YmmReg, X86YmmReg)
+
+ INST_3x(vfnmsub231sd, kX86InstIdVfnmsub231sd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmsub231sd, kX86InstIdVfnmsub231sd, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ INST_3x(vfnmsub231ss, kX86InstIdVfnmsub231ss, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3x(vfnmsub231ss, kX86InstIdVfnmsub231ss, X86XmmReg, X86XmmReg, X86XmmReg)
+
+ // --------------------------------------------------------------------------
+ // [FMA4]
+ // --------------------------------------------------------------------------
+
+ INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4x(vfmaddps, kX86InstIdVfmaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfmaddps, kX86InstIdVfmaddps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfmaddps, kX86InstIdVfmaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vfmaddps, kX86InstIdVfmaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vfmaddps, kX86InstIdVfmaddps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vfmaddps, kX86InstIdVfmaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4x(vfmaddsd, kX86InstIdVfmaddsd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfmaddsd, kX86InstIdVfmaddsd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfmaddsd, kX86InstIdVfmaddsd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_4x(vfmaddss, kX86InstIdVfmaddss, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfmaddss, kX86InstIdVfmaddss, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfmaddss, kX86InstIdVfmaddss, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4x(vfmsubps, kX86InstIdVfmsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfmsubps, kX86InstIdVfmsubps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfmsubps, kX86InstIdVfmsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vfmsubps, kX86InstIdVfmsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vfmsubps, kX86InstIdVfmsubps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vfmsubps, kX86InstIdVfmsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4x(vfmsubsd, kX86InstIdVfmsubsd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfmsubsd, kX86InstIdVfmsubsd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfmsubsd, kX86InstIdVfmsubsd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_4x(vfmsubss, kX86InstIdVfmsubss, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfmsubss, kX86InstIdVfmsubss, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfmsubss, kX86InstIdVfmsubss, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4x(vfnmaddsd, kX86InstIdVfnmaddsd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfnmaddsd, kX86InstIdVfnmaddsd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfnmaddsd, kX86InstIdVfnmaddsd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_4x(vfnmaddss, kX86InstIdVfnmaddss, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfnmaddss, kX86InstIdVfnmaddss, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfnmaddss, kX86InstIdVfnmaddss, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4x(vfnmsubsd, kX86InstIdVfnmsubsd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfnmsubsd, kX86InstIdVfnmsubsd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfnmsubsd, kX86InstIdVfnmsubsd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_4x(vfnmsubss, kX86InstIdVfnmsubss, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vfnmsubss, kX86InstIdVfnmsubss, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vfnmsubss, kX86InstIdVfnmsubss, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+
+ // --------------------------------------------------------------------------
+ // [XOP]
+ // --------------------------------------------------------------------------
+
+ INST_2x(vfrczpd, kX86InstIdVfrczpd, X86XmmReg, X86XmmReg)
+ INST_2x(vfrczpd, kX86InstIdVfrczpd, X86XmmReg, X86Mem)
+ INST_2x(vfrczpd, kX86InstIdVfrczpd, X86YmmReg, X86YmmReg)
+ INST_2x(vfrczpd, kX86InstIdVfrczpd, X86YmmReg, X86Mem)
+
+ INST_2x(vfrczps, kX86InstIdVfrczps, X86XmmReg, X86XmmReg)
+ INST_2x(vfrczps, kX86InstIdVfrczps, X86XmmReg, X86Mem)
+ INST_2x(vfrczps, kX86InstIdVfrczps, X86YmmReg, X86YmmReg)
+ INST_2x(vfrczps, kX86InstIdVfrczps, X86YmmReg, X86Mem)
+
+ INST_2x(vfrczsd, kX86InstIdVfrczsd, X86XmmReg, X86XmmReg)
+ INST_2x(vfrczsd, kX86InstIdVfrczsd, X86XmmReg, X86Mem)
+
+ INST_2x(vfrczss, kX86InstIdVfrczss, X86XmmReg, X86XmmReg)
+ INST_2x(vfrczss, kX86InstIdVfrczss, X86XmmReg, X86Mem)
+
+ INST_4x(vpcmov, kX86InstIdVpcmov, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpcmov, kX86InstIdVpcmov, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vpcmov, kX86InstIdVpcmov, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vpcmov, kX86InstIdVpcmov, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vpcmov, kX86InstIdVpcmov, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vpcmov, kX86InstIdVpcmov, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4i(vpcomb, kX86InstIdVpcomb, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ INST_4i(vpcomb, kX86InstIdVpcomb, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ INST_4i(vpcomd, kX86InstIdVpcomd, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ INST_4i(vpcomd, kX86InstIdVpcomd, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ INST_4i(vpcomq, kX86InstIdVpcomq, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ INST_4i(vpcomq, kX86InstIdVpcomq, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ INST_4i(vpcomw, kX86InstIdVpcomw, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ INST_4i(vpcomw, kX86InstIdVpcomw, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ INST_4i(vpcomub, kX86InstIdVpcomub, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ INST_4i(vpcomub, kX86InstIdVpcomub, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ INST_4i(vpcomud, kX86InstIdVpcomud, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ INST_4i(vpcomud, kX86InstIdVpcomud, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ INST_4i(vpcomuq, kX86InstIdVpcomuq, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ INST_4i(vpcomuq, kX86InstIdVpcomuq, X86XmmReg, X86XmmReg, X86Mem, Imm)
+ INST_4i(vpcomuw, kX86InstIdVpcomuw, X86XmmReg, X86XmmReg, X86XmmReg, Imm)
+ INST_4i(vpcomuw, kX86InstIdVpcomuw, X86XmmReg, X86XmmReg, X86Mem, Imm)
+
+ INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+ INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg)
+ INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg)
+ INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem)
+
+ INST_2x(vphaddbd, kX86InstIdVphaddbd, X86XmmReg, X86XmmReg)
+ INST_2x(vphaddbd, kX86InstIdVphaddbd, X86XmmReg, X86Mem)
+ INST_2x(vphaddbq, kX86InstIdVphaddbq, X86XmmReg, X86XmmReg)
+ INST_2x(vphaddbq, kX86InstIdVphaddbq, X86XmmReg, X86Mem)
+ INST_2x(vphaddbw, kX86InstIdVphaddbw, X86XmmReg, X86XmmReg)
+ INST_2x(vphaddbw, kX86InstIdVphaddbw, X86XmmReg, X86Mem)
+ INST_2x(vphadddq, kX86InstIdVphadddq, X86XmmReg, X86XmmReg)
+ INST_2x(vphadddq, kX86InstIdVphadddq, X86XmmReg, X86Mem)
+ INST_2x(vphaddwd, kX86InstIdVphaddwd, X86XmmReg, X86XmmReg)
+ INST_2x(vphaddwd, kX86InstIdVphaddwd, X86XmmReg, X86Mem)
+ INST_2x(vphaddwq, kX86InstIdVphaddwq, X86XmmReg, X86XmmReg)
+ INST_2x(vphaddwq, kX86InstIdVphaddwq, X86XmmReg, X86Mem)
+
+ INST_2x(vphaddubd, kX86InstIdVphaddubd, X86XmmReg, X86XmmReg)
+ INST_2x(vphaddubd, kX86InstIdVphaddubd, X86XmmReg, X86Mem)
+ INST_2x(vphaddubq, kX86InstIdVphaddubq, X86XmmReg, X86XmmReg)
+ INST_2x(vphaddubq, kX86InstIdVphaddubq, X86XmmReg, X86Mem)
+ INST_2x(vphaddubw, kX86InstIdVphaddubw, X86XmmReg, X86XmmReg)
+ INST_2x(vphaddubw, kX86InstIdVphaddubw, X86XmmReg, X86Mem)
+ INST_2x(vphaddudq, kX86InstIdVphaddudq, X86XmmReg, X86XmmReg)
+ INST_2x(vphaddudq, kX86InstIdVphaddudq, X86XmmReg, X86Mem)
+ INST_2x(vphadduwd, kX86InstIdVphadduwd, X86XmmReg, X86XmmReg)
+ INST_2x(vphadduwd, kX86InstIdVphadduwd, X86XmmReg, X86Mem)
+ INST_2x(vphadduwq, kX86InstIdVphadduwq, X86XmmReg, X86XmmReg)
+ INST_2x(vphadduwq, kX86InstIdVphadduwq, X86XmmReg, X86Mem)
+
+ INST_2x(vphsubbw, kX86InstIdVphsubbw, X86XmmReg, X86XmmReg)
+ INST_2x(vphsubbw, kX86InstIdVphsubbw, X86XmmReg, X86Mem)
+ INST_2x(vphsubdq, kX86InstIdVphsubdq, X86XmmReg, X86XmmReg)
+ INST_2x(vphsubdq, kX86InstIdVphsubdq, X86XmmReg, X86Mem)
+ INST_2x(vphsubwd, kX86InstIdVphsubwd, X86XmmReg, X86XmmReg)
+ INST_2x(vphsubwd, kX86InstIdVphsubwd, X86XmmReg, X86Mem)
+
+ INST_4x(vpmacsdd, kX86InstIdVpmacsdd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpmacsdd, kX86InstIdVpmacsdd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vpmacsdqh, kX86InstIdVpmacsdqh, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpmacsdqh, kX86InstIdVpmacsdqh, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vpmacsdql, kX86InstIdVpmacsdql, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpmacsdql, kX86InstIdVpmacsdql, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vpmacswd, kX86InstIdVpmacswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpmacswd, kX86InstIdVpmacswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vpmacsww, kX86InstIdVpmacsww, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpmacsww, kX86InstIdVpmacsww, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+
+ INST_4x(vpmacssdd, kX86InstIdVpmacssdd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpmacssdd, kX86InstIdVpmacssdd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vpmacssdqh, kX86InstIdVpmacssdqh, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpmacssdqh, kX86InstIdVpmacssdqh, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vpmacssdql, kX86InstIdVpmacssdql, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpmacssdql, kX86InstIdVpmacssdql, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vpmacsswd, kX86InstIdVpmacsswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpmacsswd, kX86InstIdVpmacsswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vpmacssww, kX86InstIdVpmacssww, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpmacssww, kX86InstIdVpmacssww, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+
+ INST_4x(vpmadcsswd, kX86InstIdVpmadcsswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpmadcsswd, kX86InstIdVpmadcsswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+
+ INST_4x(vpmadcswd, kX86InstIdVpmadcswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpmadcswd, kX86InstIdVpmadcswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+
+ INST_4x(vpperm, kX86InstIdVpperm, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_4x(vpperm, kX86InstIdVpperm, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg)
+ INST_4x(vpperm, kX86InstIdVpperm, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_3x(vprotb, kX86InstIdVprotb, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vprotb, kX86InstIdVprotb, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vprotb, kX86InstIdVprotb, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3i(vprotb, kX86InstIdVprotb, X86XmmReg, X86XmmReg, Imm)
+ INST_3i(vprotb, kX86InstIdVprotb, X86XmmReg, X86Mem, Imm)
+
+ INST_3x(vprotd, kX86InstIdVprotd, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vprotd, kX86InstIdVprotd, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vprotd, kX86InstIdVprotd, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3i(vprotd, kX86InstIdVprotd, X86XmmReg, X86XmmReg, Imm)
+ INST_3i(vprotd, kX86InstIdVprotd, X86XmmReg, X86Mem, Imm)
+
+ INST_3x(vprotq, kX86InstIdVprotq, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vprotq, kX86InstIdVprotq, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vprotq, kX86InstIdVprotq, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3i(vprotq, kX86InstIdVprotq, X86XmmReg, X86XmmReg, Imm)
+ INST_3i(vprotq, kX86InstIdVprotq, X86XmmReg, X86Mem, Imm)
+
+ INST_3x(vprotw, kX86InstIdVprotw, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vprotw, kX86InstIdVprotw, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vprotw, kX86InstIdVprotw, X86XmmReg, X86XmmReg, X86Mem)
+ INST_3i(vprotw, kX86InstIdVprotw, X86XmmReg, X86XmmReg, Imm)
+ INST_3i(vprotw, kX86InstIdVprotw, X86XmmReg, X86Mem, Imm)
+
+ INST_3x(vpshab, kX86InstIdVpshab, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vpshab, kX86InstIdVpshab, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vpshab, kX86InstIdVpshab, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_3x(vpshad, kX86InstIdVpshad, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vpshad, kX86InstIdVpshad, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vpshad, kX86InstIdVpshad, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_3x(vpshaq, kX86InstIdVpshaq, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vpshaq, kX86InstIdVpshaq, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vpshaq, kX86InstIdVpshaq, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_3x(vpshaw, kX86InstIdVpshaw, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vpshaw, kX86InstIdVpshaw, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vpshaw, kX86InstIdVpshaw, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_3x(vpshlb, kX86InstIdVpshlb, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vpshlb, kX86InstIdVpshlb, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vpshlb, kX86InstIdVpshlb, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_3x(vpshld, kX86InstIdVpshld, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vpshld, kX86InstIdVpshld, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vpshld, kX86InstIdVpshld, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_3x(vpshlq, kX86InstIdVpshlq, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vpshlq, kX86InstIdVpshlq, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vpshlq, kX86InstIdVpshlq, X86XmmReg, X86XmmReg, X86Mem)
+
+ INST_3x(vpshlw, kX86InstIdVpshlw, X86XmmReg, X86XmmReg, X86XmmReg)
+ INST_3x(vpshlw, kX86InstIdVpshlw, X86XmmReg, X86Mem, X86XmmReg)
+ INST_3x(vpshlw, kX86InstIdVpshlw, X86XmmReg, X86XmmReg, X86Mem)
+
+ // --------------------------------------------------------------------------
+ // [BMI]
+ // --------------------------------------------------------------------------
+
+ //! Bitwise and-not (BMI).
+ INST_3x(andn, kX86InstIdAndn, X86GpReg, X86GpReg, X86GpReg)
+ //! \overload
+ INST_3x(andn, kX86InstIdAndn, X86GpReg, X86GpReg, X86Mem)
+
+ //! Bit field extract (BMI).
+ INST_3x(bextr, kX86InstIdBextr, X86GpReg, X86GpReg, X86GpReg)
+ //! \overload
+ INST_3x(bextr, kX86InstIdBextr, X86GpReg, X86Mem, X86GpReg)
+
+ //! Extract lower set isolated bit (BMI).
+ INST_2x(blsi, kX86InstIdBlsi, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(blsi, kX86InstIdBlsi, X86GpReg, X86Mem)
+
+ //! Get mask up to lowest set bit (BMI).
+ INST_2x(blsmsk, kX86InstIdBlsmsk, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(blsmsk, kX86InstIdBlsmsk, X86GpReg, X86Mem)
+
+ //! Reset lowest set bit (BMI).
+ INST_2x(blsr, kX86InstIdBlsr, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(blsr, kX86InstIdBlsr, X86GpReg, X86Mem)
+
+ //! Count the number of trailing zero bits (BMI).
+ INST_2x(tzcnt, kX86InstIdTzcnt, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(tzcnt, kX86InstIdTzcnt, X86GpReg, X86Mem)
+
+ // --------------------------------------------------------------------------
+ // [LZCNT]
+ // --------------------------------------------------------------------------
+
+ //! Count the number of leading zero bits (LZCNT).
+ INST_2x(lzcnt, kX86InstIdLzcnt, X86GpReg, X86GpReg)
+ //! \overload
+ INST_2x(lzcnt, kX86InstIdLzcnt, X86GpReg, X86Mem)
+
+ // --------------------------------------------------------------------------
+ // [BMI2]
+ // --------------------------------------------------------------------------
+
+ //! Zero high bits starting with specified bit position (BMI2).
+ INST_3x(bzhi, kX86InstIdBzhi, X86GpReg, X86GpReg, X86GpReg)
+ //! \overload
+ INST_3x(bzhi, kX86InstIdBzhi, X86GpReg, X86Mem, X86GpReg)
+
+ //! Unsigned multiply without affecting flags (BMI2).
+ INST_3x(mulx, kX86InstIdMulx, X86GpReg, X86GpReg, X86GpReg)
+ //! \overload
+ INST_3x(mulx, kX86InstIdMulx, X86GpReg, X86GpReg, X86Mem)
+
+ //! Parallel bits deposit (BMI2).
+ INST_3x(pdep, kX86InstIdPdep, X86GpReg, X86GpReg, X86GpReg)
+ //! \overload
+ INST_3x(pdep, kX86InstIdPdep, X86GpReg, X86GpReg, X86Mem)
+
+ //! Parallel bits extract (BMI2).
+ INST_3x(pext, kX86InstIdPext, X86GpReg, X86GpReg, X86GpReg)
+ //! \overload
+ INST_3x(pext, kX86InstIdPext, X86GpReg, X86GpReg, X86Mem)
+
+ //! Rotate right without affecting flags (BMI2).
+ INST_3i(rorx, kX86InstIdRorx, X86GpReg, X86GpReg, Imm)
+ //! \overload
+ INST_3i(rorx, kX86InstIdRorx, X86GpReg, X86Mem, Imm)
+
+ //! Shift arithmetic right without affecting flags (BMI2).
+ INST_3x(sarx, kX86InstIdSarx, X86GpReg, X86GpReg, X86GpReg)
+ //! \overload
+ INST_3x(sarx, kX86InstIdSarx, X86GpReg, X86Mem, X86GpReg)
+
+ //! Shift logical left without affecting flags (BMI2).
+ INST_3x(shlx, kX86InstIdShlx, X86GpReg, X86GpReg, X86GpReg)
+ //! \overload
+ INST_3x(shlx, kX86InstIdShlx, X86GpReg, X86Mem, X86GpReg)
+
+ //! Shift logical right without affecting flags (BMI2).
+ INST_3x(shrx, kX86InstIdShrx, X86GpReg, X86GpReg, X86GpReg)
+ //! \overload
+ INST_3x(shrx, kX86InstIdShrx, X86GpReg, X86Mem, X86GpReg)
+
+ // --------------------------------------------------------------------------
+ // [RDRAND]
+ // --------------------------------------------------------------------------
+
+ //! Store a random number in destination register.
//!
- //! 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.
- void amd_prefetch(const Mem& mem)
- { _emitInstruction(kX86InstAmdPrefetch, &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).
- void amd_prefetchw(const Mem& mem)
- { _emitInstruction(kX86InstAmdPrefetchW, &mem); }
-
- // -------------------------------------------------------------------------
- // [Intel only]
- // -------------------------------------------------------------------------
-
- //! @brief Move Data After Swapping Bytes (SSE3 - Intel Atom).
- void movbe(const GpReg& dst, const Mem& src)
- {
- ASMJIT_ASSERT(!dst.isGpb());
- _emitInstruction(kX86InstMovBE, &dst, &src);
- }
-
- //! @brief Move Data After Swapping Bytes (SSE3 - Intel Atom).
- void movbe(const Mem& dst, const GpReg& src)
- {
- ASMJIT_ASSERT(!src.isGpb());
- _emitInstruction(kX86InstMovBE, &dst, &src);
- }
-
- // -------------------------------------------------------------------------
- // [Emit Options]
- // -------------------------------------------------------------------------
-
- //! @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.
- //!
- //! @sa @c kX86EmitOptionLock.
- void lock()
- { _emitOptions |= kX86EmitOptionLock; }
-
- //! @brief Force REX prefix to be emitted.
- //!
- //! This option should be used carefully, because there are unencodable
- //! combinations. If you want to access ah, bh, ch or dh registers then you
- //! can't emit REX prefix and it will cause an illegal instruction error.
- //!
- //! @note REX prefix is only valid for X64/AMD64 platform.
- //!
- //! @sa @c kX86EmitOptionRex.
- void rex()
- { _emitOptions |= kX86EmitOptionRex; }
+ //! Please do not use this instruction in cryptographic software. The result
+ //! doesn't necessarily have to be random which may cause a major security
+ //! issue in the software that relies on it.
+ INST_1x(rdrand, kX86InstIdRdrand, X86GpReg)
+
+ // --------------------------------------------------------------------------
+ // [F16C]
+ // --------------------------------------------------------------------------
+
+ //! Convert packed HP-FP to SP-FP.
+ INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86XmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86XmmReg, X86Mem)
+ //! \overload
+ INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86YmmReg, X86XmmReg)
+ //! \overload
+ INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86YmmReg, X86Mem)
+
+ //! Convert packed SP-FP to HP-FP.
+ INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86XmmReg, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86Mem, X86XmmReg, Imm)
+ //! \overload
+ INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86XmmReg, X86YmmReg, Imm)
+ //! \overload
+ INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86Mem, X86YmmReg, Imm)
+
+ // --------------------------------------------------------------------------
+ // [FSGSBASE]
+ // --------------------------------------------------------------------------
+
+ INST_1x(rdfsbase, kX86InstIdRdfsbase, X86GpReg)
+ INST_1x(rdgsbase, kX86InstIdRdgsbase, X86GpReg)
+ INST_1x(wrfsbase, kX86InstIdWrfsbase, X86GpReg)
+ INST_1x(wrgsbase, kX86InstIdWrgsbase, X86GpReg)
+
+#undef INST_0x
+
+#undef INST_1x
+#undef INST_1x_
+#undef INST_1i
+#undef INST_1cc
+
+#undef INST_2x
+#undef INST_2x_
+#undef INST_2i
+#undef INST_2cc
+
+#undef INST_3x
+#undef INST_3x_
+#undef INST_3i
+
+#undef INST_4x
+#undef INST_4x_
+#undef INST_4i
};
-//! @}
-
-} // AsmJit namespace
+//! \}
+
+} // asmjit namespace
// [Api-End]
-#include "../core/apiend.h"
-
+#include "../apiend.h"
+
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86compiler.cpp
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86compiler.cpp
@@ -1,869 +1,1377 @@
// [AsmJit]
-// Complete JIT Assembler for C++ Language.
+// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
-// Zlib - See COPYING file in this package.
-
+// Zlib - See LICENSE.md file in the package.
+
+// [Export]
#define ASMJIT_EXPORTS
+// [Guard]
+#include "../build.h"
+#if !defined(ASMJIT_DISABLE_COMPILER) && (defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64))
+
// [Dependencies - AsmJit]
-#include "../core/intutil.h"
-#include "../core/stringutil.h"
-
+#include "../base/intutil.h"
+#include "../base/string.h"
#include "../x86/x86assembler.h"
#include "../x86/x86compiler.h"
-#include "../x86/x86compilercontext.h"
-#include "../x86/x86compilerfunc.h"
-#include "../x86/x86compileritem.h"
-#include "../x86/x86util.h"
+#include "../x86/x86context_p.h"
// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::CompilerUtil]
-// ============================================================================
-
-bool CompilerUtil::isStack16ByteAligned()
-{
- // Stack is always aligned to 16-bytes when using 64-bit OS.
- bool result = sizeof(uintptr_t) == 8;
-
- // Modern Linux, APPLE and UNIX guarantees stack alignment to 16 bytes by
- // default. I'm really not sure about all UNIX operating systems, because
- // 16-byte alignment is an addition to an older specification.
-#if defined(__linux__) || defined(__linux) || defined(linux) || defined(__unix__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DARWIN__) || defined(__APPLE__)
- result = true;
-#endif // __linux__
-
- return result;
-}
-
-// ============================================================================
-// [AsmJit::X86Compiler - Construction / Destruction]
-// ============================================================================
-
-X86Compiler::X86Compiler(Context *context) : Compiler(context)
-{
- this->_properties |= IntUtil::maskFromIndex(kX86PropertyOptimizedAlign);
-}
-
-X86Compiler::~X86Compiler()
-{
-}
-
-// ============================================================================
-// [AsmJit::Compiler - Function Builder]
-// ============================================================================
-
-X86CompilerFuncDecl *X86Compiler::newFunc_(uint32_t convention, uint32_t returnType, const uint32_t *arguments, uint32_t argumentsCount)
-{
- ASMJIT_ASSERT(!this->_func);
-
- X86CompilerFuncDecl *func = Compiler_newItem<X86CompilerFuncDecl>(this);
-
- this->_func = func;
- this->_varNameId = 0;
-
- func->setPrototype(convention, returnType, arguments, argumentsCount);
- this->addItem(func);
-
- this->bind(func->_entryLabel);
- func->_createVariables();
-
- return func;
-}
-
-X86CompilerFuncDecl *X86Compiler::endFunc()
-{
- X86CompilerFuncDecl *func = this->getFunc();
- ASMJIT_ASSERT(func);
-
- this->bind(func->_exitLabel);
- this->addItem(func->_end);
-
- func->setFuncFlag(kFuncFlagIsFinished);
- this->_func = nullptr;
-
- return func;
-}
-
-// ============================================================================
-// [AsmJit::Compiler - EmitInstruction]
-// ============================================================================
-
-static inline X86CompilerInst *X86Compiler_newInstruction(X86Compiler *self, uint32_t code, Operand *opData, uint32_t opCount)
-{
- if (code >= _kX86InstJBegin && code <= _kX86InstJEnd)
- {
- void *p = self->_zoneMemory.alloc(sizeof(X86CompilerJmpInst));
- return new(p) X86CompilerJmpInst(self, code, opData, opCount);
- }
- else
- {
- void *p = self->_zoneMemory.alloc(sizeof(X86CompilerInst) + opCount * sizeof(Operand));
- return new(p) X86CompilerInst(self, code, opData, opCount);
- }
-}
-
-void X86Compiler::_emitInstruction(uint32_t code)
-{
- X86CompilerInst *inst = X86Compiler_newInstruction(this, code, nullptr, 0);
-
- if (!inst)
- {
- this->setError(kErrorNoHeapMemory);
- return;
- }
-
- this->addItem(inst);
-
- if (this->_cc)
- {
- inst->_offset = this->_cc->_currentOffset;
- inst->prepare(*this->_cc);
- }
-}
-
-void X86Compiler::_emitInstruction(uint32_t code, const Operand *o0)
-{
- Operand *operands = reinterpret_cast<Operand *>(this->_zoneMemory.alloc(sizeof(Operand)));
-
- if (!operands)
- {
- this->setError(kErrorNoHeapMemory);
- return;
- }
-
- operands[0] = *o0;
- X86CompilerInst *inst = X86Compiler_newInstruction(this, code, operands, 1);
-
- if (!inst)
- {
- this->setError(kErrorNoHeapMemory);
- return;
- }
-
- this->addItem(inst);
-
- if (this->_cc)
- {
- inst->_offset = this->_cc->_currentOffset;
- inst->prepare(*this->_cc);
- }
-}
-
-void X86Compiler::_emitInstruction(uint32_t code, const Operand *o0, const Operand *o1)
-{
- Operand *operands = reinterpret_cast<Operand *>(this->_zoneMemory.alloc(2 * sizeof(Operand)));
-
- if (!operands)
- {
- this->setError(kErrorNoHeapMemory);
- return;
- }
-
- operands[0] = *o0;
- operands[1] = *o1;
- X86CompilerInst *inst = X86Compiler_newInstruction(this, code, operands, 2);
-
- if (!inst)
- {
- this->setError(kErrorNoHeapMemory);
- return;
- }
-
- this->addItem(inst);
-
- if (this->_cc)
- {
- inst->_offset = this->_cc->_currentOffset;
- inst->prepare(*this->_cc);
- }
-}
-
-void X86Compiler::_emitInstruction(uint32_t code, const Operand *o0, const Operand *o1, const Operand *o2)
-{
- Operand *operands = reinterpret_cast<Operand *>(this->_zoneMemory.alloc(3 * sizeof(Operand)));
-
- if (!operands)
- {
- this->setError(kErrorNoHeapMemory);
- return;
- }
-
- operands[0] = *o0;
- operands[1] = *o1;
- operands[2] = *o2;
- X86CompilerInst *inst = X86Compiler_newInstruction(this, code, operands, 3);
-
- if (!inst)
- {
- this->setError(kErrorNoHeapMemory);
- return;
- }
-
- this->addItem(inst);
-
- if (this->_cc)
- {
- inst->_offset = this->_cc->_currentOffset;
- inst->prepare(*this->_cc);
- }
-}
-
-void X86Compiler::_emitInstruction(uint32_t code, const Operand *o0, const Operand *o1, const Operand *o2, const Operand *o3)
-{
- Operand *operands = reinterpret_cast<Operand *>(this->_zoneMemory.alloc(4 * sizeof(Operand)));
-
- if (!operands)
- {
- this->setError(kErrorNoHeapMemory);
- return;
- }
-
- operands[0] = *o0;
- operands[1] = *o1;
- operands[2] = *o2;
- operands[3] = *o3;
- X86CompilerInst *inst = X86Compiler_newInstruction(this, code, operands, 4);
-
- if (!inst)
- {
- this->setError(kErrorNoHeapMemory);
- return;
- }
-
- this->addItem(inst);
-
- if (this->_cc)
- {
- inst->_offset = this->_cc->_currentOffset;
- inst->prepare(*this->_cc);
- }
-}
-
-void X86Compiler::_emitInstruction(uint32_t code, const Operand *o0, const Operand *o1, const Operand *o2, const Operand *o3, const Operand *o4)
-{
- Operand *operands = reinterpret_cast<Operand *>(this->_zoneMemory.alloc(5 * sizeof(Operand)));
-
- if (!operands)
- {
- this->setError(kErrorNoHeapMemory);
- return;
- }
-
- operands[0] = *o0;
- operands[1] = *o1;
- operands[2] = *o2;
- operands[3] = *o3;
- operands[4] = *o4;
- X86CompilerInst *inst = X86Compiler_newInstruction(this, code, operands, 5);
-
- if (!inst)
- {
- this->setError(kErrorNoHeapMemory);
- return;
- }
-
- this->addItem(inst);
-
- if (this->_cc)
- {
- inst->_offset = this->_cc->_currentOffset;
- inst->prepare(*this->_cc);
- }
-}
-
-void X86Compiler::_emitJcc(uint32_t code, const Label *label, uint32_t hint)
-{
- if (hint == kCondHintNone)
- this->_emitInstruction(code, label);
- else
- {
- Imm imm(hint);
- this->_emitInstruction(code, label, &imm);
- }
-}
-
-X86CompilerFuncCall *X86Compiler::_emitCall(const Operand *o0)
-{
- X86CompilerFuncDecl *func = this->getFunc();
-
- if (!func)
- {
- this->setError(kErrorNoFunction);
- return nullptr;
- }
-
- X86CompilerFuncCall *call = Compiler_newItem<X86CompilerFuncCall>(this, func, o0);
- if (!call)
- {
- this->setError(kErrorNoHeapMemory);
- return nullptr;
- }
-
- this->addItem(call);
-
- return call;
-}
-
-void X86Compiler::_emitReturn(const Operand *first, const Operand *second)
-{
- X86CompilerFuncDecl *func = this->getFunc();
-
- if (!func)
- {
- this->setError(kErrorNoFunction);
- return;
- }
-
- X86CompilerFuncRet *ret = Compiler_newItem<X86CompilerFuncRet>(this, func, first, second);
-
- if (!ret)
- {
- this->setError(kErrorNoHeapMemory);
- return;
- }
-
- this->addItem(ret);
-}
-
-// ============================================================================
-// [AsmJit::Compiler - Align]
-// ============================================================================
-
-void X86Compiler::align(uint32_t m)
-{
- this->addItem(Compiler_newItem<X86CompilerAlign>(this, m));
-}
-
-// ============================================================================
-// [AsmJit::Compiler - Label]
-// ============================================================================
-
-Label X86Compiler::newLabel()
-{
- Label label;
- label._base.id = static_cast<uint32_t>(_targets.getLength()) | kOperandIdTypeLabel;
-
- CompilerTarget *target = Compiler_newItem<X86CompilerTarget>(this, label);
- this->_targets.append(target);
-
- return label;
-}
-
-void X86Compiler::bind(const Label &label)
-{
- uint32_t id = label.getId() & kOperandIdValueMask;
-
- ASMJIT_ASSERT(id != kInvalidValue);
- ASMJIT_ASSERT(id < this->_targets.getLength());
-
- this->addItem(this->_targets[id]);
-}
-
-// ============================================================================
-// [AsmJit::Compiler - Variables]
-// ============================================================================
-
-X86CompilerVar *X86Compiler::_newVar(const char *name, uint32_t type, uint32_t size)
-{
- X86CompilerVar *var = reinterpret_cast<X86CompilerVar *>(this->_zoneMemory.alloc(sizeof(X86CompilerVar)));
- if (!var)
- return nullptr;
-
- char nameBuffer[32];
- if (!name)
- {
- sprintf(nameBuffer, "var_%d", this->_varNameId);
- name = nameBuffer;
- ++this->_varNameId;
- }
-
- var->_name = this->_zoneMemory.sdup(name);
- var->_id = static_cast<uint32_t>(this->_vars.getLength()) | kOperandIdTypeVar;
-
- var->_type = static_cast<uint8_t>(type);
- var->_class = x86VarInfo[type].getClass();
- var->_priority = 10;
-
- var->_isRegArgument = false;
- var->_isMemArgument = false;
- var->_isCalculated = false;
- var->_unused = 0;
-
- var->_size = size;
-
- var->firstItem = nullptr;
- var->lastItem = nullptr;
- var->funcScope = this->getFunc();
- var->funcCall = nullptr;
-
- var->homeRegisterIndex = kRegIndexInvalid;
- var->prefRegisterMask = 0;
-
- var->homeMemoryOffset = 0;
- var->homeMemoryData = nullptr;
-
- var->regIndex = kRegIndexInvalid;
- var->workOffset = kInvalidValue;
-
- var->nextActive = nullptr;
- var->prevActive = nullptr;
-
- var->state = kVarStateUnused;
- var->changed = false;
- var->saveOnUnuse = false;
-
- var->regReadCount = 0;
- var->regWriteCount = 0;
- var->regRwCount = 0;
-
- var->regGpbLoCount = 0;
- var->regGpbHiCount = 0;
-
- var->memReadCount = 0;
- var->memWriteCount = 0;
- var->memRwCount = 0;
-
- var->tPtr = nullptr;
-
- this->_vars.append(var);
- return var;
-}
-
-GpVar X86Compiler::newGpVar(uint32_t varType, const char *name)
-{
- ASMJIT_ASSERT(varType < kX86VarTypeCount && (x86VarInfo[varType].getClass() & kX86VarClassGp));
-
-#ifdef ASMJIT_X86
- if (x86VarInfo[varType].getSize() > 4)
- {
- varType = kX86VarTypeGpd;
- if (this->_logger)
- this->_logger->logString("*** COMPILER WARNING: QWORD variable translated to DWORD, FIX YOUR CODE! ***\n");
- }
-#endif // ASMJIT_X86
-
- X86CompilerVar *var = this->_newVar(name, varType, x86VarInfo[varType].getSize());
- return var->asGpVar();
-}
-
-GpVar X86Compiler::getGpArg(uint32_t argIndex)
-{
- X86CompilerFuncDecl *func = this->getFunc();
- GpVar var;
-
- if (func)
- {
- X86FuncDecl *decl = func->getDecl();
-
- if (argIndex < decl->getArgumentsCount())
- {
- X86CompilerVar *cv = func->getVar(argIndex);
-
- var._var.id = cv->getId();
- var._var.size = cv->getSize();
- var._var.regCode = x86VarInfo[cv->getType()].getCode();
- var._var.varType = cv->getType();
- }
- }
-
- return var;
-}
-
-MmVar X86Compiler::newMmVar(uint32_t varType, const char *name)
-{
- ASMJIT_ASSERT(varType < kX86VarTypeCount && (x86VarInfo[varType].getClass() & kX86VarClassMm));
-
- X86CompilerVar *var = this->_newVar(name, varType, 8);
- return var->asMmVar();
-}
-
-MmVar X86Compiler::getMmArg(uint32_t argIndex)
-{
- X86CompilerFuncDecl *func = this->getFunc();
- MmVar var;
-
- if (func)
- {
- const X86FuncDecl *decl = func->getDecl();
-
- if (argIndex < decl->getArgumentsCount())
- {
- X86CompilerVar *cv = func->getVar(argIndex);
-
- var._var.id = cv->getId();
- var._var.size = cv->getSize();
- var._var.regCode = x86VarInfo[cv->getType()].getCode();
- var._var.varType = cv->getType();
- }
- }
-
- return var;
-}
-
-XmmVar X86Compiler::newXmmVar(uint32_t varType, const char *name)
-{
- ASMJIT_ASSERT(varType < kX86VarTypeCount && (x86VarInfo[varType].getClass() & kX86VarClassXmm));
-
- X86CompilerVar *var = this->_newVar(name, varType, 16);
- return var->asXmmVar();
-}
-
-XmmVar X86Compiler::getXmmArg(uint32_t argIndex)
-{
- X86CompilerFuncDecl *func = this->getFunc();
- XmmVar var;
-
- if (func)
- {
- const X86FuncDecl *decl = func->getDecl();
-
- if (argIndex < decl->getArgumentsCount())
- {
- X86CompilerVar *cv = func->getVar(argIndex);
-
- var._var.id = cv->getId();
- var._var.size = cv->getSize();
- var._var.regCode = x86VarInfo[cv->getType()].getCode();
- var._var.varType = cv->getType();
- }
- }
-
- return var;
-}
-
-void X86Compiler::_vhint(Var &var, uint32_t hintId, uint32_t hintValue)
-{
- if (var.getId() == kInvalidValue)
- return;
-
- X86CompilerVar *cv = this->_getVar(var.getId());
- ASMJIT_ASSERT(cv);
-
- X86CompilerHint *item = Compiler_newItem<X86CompilerHint>(this, cv, hintId, hintValue);
- this->addItem(item);
-}
-
-void X86Compiler::alloc(Var &var)
-{
- this->_vhint(var, kVarHintAlloc, kInvalidValue);
-}
-
-void X86Compiler::alloc(Var &var, uint32_t regIndex)
-{
- if (regIndex > 31)
- return;
-
- this->_vhint(var, kVarHintAlloc, IntUtil::maskFromIndex(regIndex));
-}
-
-void X86Compiler::alloc(Var &var, const Reg ®)
-{
- this->_vhint(var, kVarHintAlloc, IntUtil::maskFromIndex(reg.getRegIndex()));
-}
-
-void X86Compiler::save(Var &var)
-{
- this->_vhint(var, kVarHintSave, kInvalidValue);
-}
-
-void X86Compiler::spill(Var &var)
-{
- this->_vhint(var, kVarHintSpill, kInvalidValue);
-}
-
-void X86Compiler::unuse(Var &var)
-{
- this->_vhint(var, kVarHintUnuse, kInvalidValue);
-}
-
-uint32_t X86Compiler::getPriority(Var &var) const
-{
- if (var.getId() == kInvalidValue)
- return kInvalidValue;
-
- X86CompilerVar *vdata = this->_getVar(var.getId());
- ASMJIT_ASSERT(vdata);
-
- return vdata->getPriority();
-}
-
-void X86Compiler::setPriority(Var &var, uint32_t priority)
-{
- if (var.getId() == kInvalidValue)
- return;
-
- X86CompilerVar *vdata = this->_getVar(var.getId());
- ASMJIT_ASSERT(vdata);
-
- if (priority > 100)
- priority = 100;
- vdata->_priority = static_cast<uint8_t>(priority);
-}
-
-bool X86Compiler::getSaveOnUnuse(Var &var) const
-{
- if (var.getId() == kInvalidValue)
- return false;
-
- X86CompilerVar *vdata = this->_getVar(var.getId());
- ASMJIT_ASSERT(vdata);
-
- return !!vdata->saveOnUnuse;
-}
-
-void X86Compiler::setSaveOnUnuse(Var &var, bool value)
-{
- if (var.getId() == kInvalidValue)
- return;
-
- X86CompilerVar *vdata = this->_getVar(var.getId());
- ASMJIT_ASSERT(vdata);
-
- vdata->saveOnUnuse = value;
-}
-
-void X86Compiler::rename(Var &var, const char *name)
-{
- if (var.getId() == kInvalidValue)
- return;
-
- X86CompilerVar *vdata = this->_getVar(var.getId());
- ASMJIT_ASSERT(vdata);
-
- vdata->_name = this->_zoneMemory.sdup(name);
-}
-
-// ============================================================================
-// [AsmJit::Compiler - State]
-// ============================================================================
-
-X86CompilerState *X86Compiler::_newState(uint32_t memVarsCount)
-{
- X86CompilerState *state = reinterpret_cast<X86CompilerState *>(this->_zoneMemory.alloc(sizeof(X86CompilerState) + memVarsCount * sizeof(void *)));
- return state;
-}
-
-// ============================================================================
-// [AsmJit::Compiler - Make]
-// ============================================================================
-
-void *X86Compiler::make()
-{
- X86Assembler x86Asm(this->_context);
-
- x86Asm._properties = this->_properties;
- x86Asm.setLogger(this->_logger);
-
- this->serialize(x86Asm);
-
- if (this->getError())
- return nullptr;
-
- if (x86Asm.getError())
- {
- this->setError(x86Asm.getError());
- return nullptr;
- }
-
- void *result = x86Asm.make();
-
- if (this->_logger)
- this->_logger->logFormat("*** COMPILER SUCCESS - Wrote %u bytes, code: %u, trampolines: %u.\n\n", static_cast<unsigned>(x86Asm.getCodeSize()), static_cast<unsigned>(x86Asm.getOffset()),
- static_cast<unsigned>(x86Asm.getTrampolineSize()));
-
- return result;
-}
-
-void X86Compiler::serialize(Assembler &a)
-{
- X86CompilerContext x86Context(this);
- X86Assembler &x86Asm = static_cast<X86Assembler &>(a);
-
- CompilerItem *start = this->_first;
- CompilerItem *stop = nullptr;
-
- // Register all labels.
- x86Asm.registerLabels(this->_targets.getLength());
-
- // Make code.
- for (;;)
- {
- this->_cc = nullptr;
-
- // ------------------------------------------------------------------------
- // [Find Function]
- // ------------------------------------------------------------------------
-
- for (;;)
- {
- if (!start)
- return;
-
- if (start->getType() == kCompilerItemFuncDecl)
- break;
-
- start->emit(x86Asm);
- start = start->getNext();
- }
-
- // ------------------------------------------------------------------------
- // [Setup CompilerContext]
- // ------------------------------------------------------------------------
-
- stop = static_cast<X86CompilerFuncDecl *>(start)->getEnd();
-
- x86Context._func = static_cast<X86CompilerFuncDecl *>(start);
- x86Context._start = start;
- x86Context._stop = stop;
- x86Context._extraBlock = stop->getPrev();
-
- // Detect whether the function generation was finished.
- if (!x86Context._func->isFinished() || !x86Context._func->getEnd()->getPrev())
- {
- this->setError(kErrorIncompleteFunction);
- return;
- }
-
- // ------------------------------------------------------------------------
- // Step 1:
- // - Assign/increment offset of each item.
- // - Extract variables from instructions.
- // - Prepare variables for register allocator:
- // - Update read(r) / write(w) / read/write(x) statistics.
- // - Update register / memory usage statistics.
- // - Find scope (first / last item) of variables.
- // ------------------------------------------------------------------------
-
- CompilerItem *cur;
- for (cur = start; ; cur = cur->getNext())
- {
- cur->prepare(x86Context);
- if (cur == stop)
- break;
- }
-
- // We set compiler context also to Compiler so newly emitted instructions
- // can call CompilerItem::prepare() on itself.
- this->_cc = &x86Context;
-
- // ------------------------------------------------------------------------
- // Step 2:
- // - Translate special instructions (imul, cmpxchg8b, ...).
- // - Alloc registers.
- // - Translate forward jumps.
- // - Alloc memory operands (variables related).
- // - Emit function prolog.
- // - Emit function epilog.
- // - Patch memory operands (variables related).
- // - Dump function prototype and variable statistics (if enabled).
- // ------------------------------------------------------------------------
-
- // Translate special instructions and run alloc registers.
- cur = start;
-
- do
- {
- do
- {
- // Assign current offset of each item back to CompilerContext.
- x86Context._currentOffset = cur->_offset;
- // Assign previous item to compiler so each variable spill/alloc will
- // be emitted before.
- this->_current = cur->getPrev();
-
- cur = cur->translate(x86Context);
- } while (cur);
-
- x86Context._isUnreachable = true;
-
- size_t len = x86Context._backCode.getLength();
- while (x86Context._backPos < len)
- {
- cur = x86Context._backCode[x86Context._backPos++]->getNext();
- if (!cur->isTranslated())
- break;
-
- cur = nullptr;
- }
- } while (cur);
-
- // Translate forward jumps.
- ForwardJumpData *j = x86Context._forwardJumps;
- while (j)
- {
- x86Context._assignState(j->state);
- this->_current = j->inst->getPrev();
- j->inst->doJump(x86Context);
- j = j->next;
- }
-
- // Alloc memory operands (variables related).
- x86Context._allocMemoryOperands();
-
- // Emit function prolog / epilog.
- x86Context.getFunc()->_preparePrologEpilog(x86Context);
-
- this->_current = x86Context._func->getEntryTarget();
- x86Context.getFunc()->_emitProlog(x86Context);
-
- this->_current = x86Context._func->getExitTarget();
- x86Context.getFunc()->_emitEpilog(x86Context);
-
- // Patch memory operands (variables related).
- this->_current = this->_last;
- x86Context._patchMemoryOperands(start, stop);
-
- // Dump function prototype and variable statistics (if enabled).
- if (this->_logger)
- x86Context.getFunc()->_dumpFunction(x86Context);
-
- // ------------------------------------------------------------------------
- // Hack: need to register labels that was created by the Step 2.
- // ------------------------------------------------------------------------
-
- if (x86Asm._labels.size() < this->_targets.getLength())
- x86Asm.registerLabels(this->_targets.getLength() - x86Asm._labels.size());
-
- CompilerItem *extraBlock = x86Context._extraBlock;
-
- // ------------------------------------------------------------------------
- // Step 3:
- // - Emit instructions to Assembler stream.
- // ------------------------------------------------------------------------
-
- for (cur = start; ; cur = cur->getNext())
- {
- cur->emit(x86Asm);
- if (cur == extraBlock)
- break;
- }
-
- // ------------------------------------------------------------------------
- // Step 4:
- // - Emit everything else (post action).
- // ------------------------------------------------------------------------
-
- for (cur = start; ; cur = cur->getNext())
- {
- cur->post(x86Asm);
- if (cur == extraBlock)
- break;
- }
-
- start = extraBlock->getNext();
- x86Context._clear();
- }
-}
-
-} // AsmJit namespace
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [Debug]
+// ============================================================================
+
+#ifndef ASMJIT_DEBUG
+#define ASMJIT_ASSERT_UNINITIALIZED(op) \
+ do {} while(0)
+#else
+#define ASMJIT_ASSERT_UNINITIALIZED(op) \
+ do { \
+ if (op.isVar() || op.isLabel()) { \
+ ASMJIT_ASSERT(op.getId() != kInvalidValue); \
+ } \
+ } while(0)
+#endif
+
+// ============================================================================
+// [asmjit::X86VarInfo]
+// ============================================================================
+
+#define C(_Class_) kX86RegClass##_Class_
+#define D(_Desc_) kVarFlag##_Desc_
+
+const X86VarInfo _x86VarInfo[] = {
+ /* 00: kVarTypeInt8 */ { kX86RegTypeGpbLo, 1 , C(Gp) , 0 , "gpb" },
+ /* 01: kVarTypeUInt8 */ { kX86RegTypeGpbLo, 1 , C(Gp) , 0 , "gpb" },
+ /* 02: kVarTypeInt16 */ { kX86RegTypeGpw , 2 , C(Gp) , 0 , "gpw" },
+ /* 03: kVarTypeUInt16 */ { kX86RegTypeGpw , 2 , C(Gp) , 0 , "gpw" },
+ /* 04: kVarTypeInt32 */ { kX86RegTypeGpd , 4 , C(Gp) , 0 , "gpd" },
+ /* 05: kVarTypeUInt32 */ { kX86RegTypeGpd , 4 , C(Gp) , 0 , "gpd" },
+ /* 06: kVarTypeInt64 */ { kX86RegTypeGpq , 8 , C(Gp) , 0 , "gpq" },
+ /* 07: kVarTypeUInt64 */ { kX86RegTypeGpq , 8 , C(Gp) , 0 , "gpq" },
+ /* 08: kVarTypeIntPtr */ { 0 , 0 , C(Gp) , 0 , "" }, // Remapped.
+ /* 09: kVarTypeUIntPtr */ { 0 , 0 , C(Gp) , 0 , "" }, // Remapped.
+ /* 10: kVarTypeFp32 */ { kX86RegTypeFp , 4 , C(Fp) , D(Sp) , "fp" },
+ /* 11: kVarTypeFp64 */ { kX86RegTypeFp , 8 , C(Fp) , D(Dp) , "fp" },
+ /* 12: kX86VarTypeMm */ { kX86RegTypeMm , 8 , C(Mm) , 0 , "mm" },
+ /* 13: kX86VarTypeXmm */ { kX86RegTypeXmm , 16, C(Xyz), 0 , "xmm" },
+ /* 14: kX86VarTypeXmmSs */ { kX86RegTypeXmm , 4 , C(Xyz), D(Sp) , "xmm" },
+ /* 15: kX86VarTypeXmmPs */ { kX86RegTypeXmm , 16, C(Xyz), D(Sp) | D(Packed), "xmm" },
+ /* 16: kX86VarTypeXmmSd */ { kX86RegTypeXmm , 8 , C(Xyz), D(Dp) , "xmm" },
+ /* 17: kX86VarTypeXmmPd */ { kX86RegTypeXmm , 16, C(Xyz), D(Dp) | D(Packed), "xmm" },
+ /* 18: kX86VarTypeYmm */ { kX86RegTypeYmm , 32, C(Xyz), 0 , "ymm" },
+ /* 19: kX86VarTypeYmmPs */ { kX86RegTypeYmm , 32, C(Xyz), D(Sp) | D(Packed), "ymm" },
+ /* 20: kX86VarTypeYmmPd */ { kX86RegTypeYmm , 32, C(Xyz), D(Dp) | D(Packed), "ymm" }
+};
+
+#undef D
+#undef C
+
+#ifdef ASMJIT_BUILD_X86
+const uint8_t _x86VarMapping[kX86VarTypeCount] = {
+ /* 00: kVarTypeInt8 */ kVarTypeInt8,
+ /* 01: kVarTypeUInt8 */ kVarTypeUInt8,
+ /* 02: kVarTypeInt16 */ kVarTypeInt16,
+ /* 03: kVarTypeUInt16 */ kVarTypeUInt16,
+ /* 04: kVarTypeInt32 */ kVarTypeInt32,
+ /* 05: kVarTypeUInt32 */ kVarTypeUInt32,
+ /* 06: kVarTypeInt64 */ kInvalidVar, // Invalid in 32-bit mode.
+ /* 07: kVarTypeUInt64 */ kInvalidVar, // Invalid in 32-bit mode.
+ /* 08: kVarTypeIntPtr */ kVarTypeInt32, // Remapped to Int32.
+ /* 09: kVarTypeUIntPtr */ kVarTypeUInt32, // Remapped to UInt32.
+ /* 10: kVarTypeFp32 */ kVarTypeFp32,
+ /* 11: kVarTypeFp64 */ kVarTypeFp64,
+ /* 12: kX86VarTypeMm */ kX86VarTypeMm,
+ /* 13: kX86VarTypeXmm */ kX86VarTypeXmm,
+ /* 14: kX86VarTypeXmmSs */ kX86VarTypeXmmSs,
+ /* 15: kX86VarTypeXmmPs */ kX86VarTypeXmmPs,
+ /* 16: kX86VarTypeXmmSd */ kX86VarTypeXmmSd,
+ /* 17: kX86VarTypeXmmPd */ kX86VarTypeXmmPd,
+ /* 18: kX86VarTypeYmm */ kX86VarTypeYmm,
+ /* 19: kX86VarTypeYmmPs */ kX86VarTypeYmmPs,
+ /* 20: kX86VarTypeYmmPd */ kX86VarTypeYmmPd
+};
+#endif // ASMJIT_BUILD_X86
+
+#ifdef ASMJIT_BUILD_X64
+const uint8_t _x64VarMapping[kX86VarTypeCount] = {
+ /* 00: kVarTypeInt8 */ kVarTypeInt8,
+ /* 01: kVarTypeUInt8 */ kVarTypeUInt8,
+ /* 02: kVarTypeInt16 */ kVarTypeInt16,
+ /* 03: kVarTypeUInt16 */ kVarTypeUInt16,
+ /* 04: kVarTypeInt32 */ kVarTypeInt32,
+ /* 05: kVarTypeUInt32 */ kVarTypeUInt32,
+ /* 06: kVarTypeInt64 */ kVarTypeInt64,
+ /* 07: kVarTypeUInt64 */ kVarTypeUInt64,
+ /* 08: kVarTypeIntPtr */ kVarTypeInt64, // Remapped to Int64.
+ /* 09: kVarTypeUIntPtr */ kVarTypeUInt64, // Remapped to UInt64.
+ /* 10: kVarTypeFp32 */ kVarTypeFp32,
+ /* 11: kVarTypeFp64 */ kVarTypeFp64,
+ /* 12: kX86VarTypeMm */ kX86VarTypeMm,
+ /* 13: kX86VarTypeXmm */ kX86VarTypeXmm,
+ /* 14: kX86VarTypeXmmSs */ kX86VarTypeXmmSs,
+ /* 15: kX86VarTypeXmmPs */ kX86VarTypeXmmPs,
+ /* 16: kX86VarTypeXmmSd */ kX86VarTypeXmmSd,
+ /* 17: kX86VarTypeXmmPd */ kX86VarTypeXmmPd,
+ /* 18: kX86VarTypeYmm */ kX86VarTypeYmm,
+ /* 19: kX86VarTypeYmmPs */ kX86VarTypeYmmPs,
+ /* 20: kX86VarTypeYmmPd */ kX86VarTypeYmmPd
+};
+#endif // ASMJIT_BUILD_X64
+
+// ============================================================================
+// [asmjit::X86FuncDecl - Helpers]
+// ============================================================================
+
+static ASMJIT_INLINE bool x86ArgIsInt(uint32_t aType) {
+ ASMJIT_ASSERT(aType < kX86VarTypeCount);
+ return IntUtil::inInterval<uint32_t>(aType, _kVarTypeIntStart, _kVarTypeIntEnd);
+}
+
+static ASMJIT_INLINE bool x86ArgIsFp(uint32_t aType) {
+ ASMJIT_ASSERT(aType < kX86VarTypeCount);
+ return IntUtil::inInterval<uint32_t>(aType, _kVarTypeFpStart, _kVarTypeFpEnd);
+}
+
+#ifdef ASMJIT_BUILD_X64
+static ASMJIT_INLINE uint32_t x86ArgTypeToXmmType(uint32_t aType) {
+ if (aType == kVarTypeFp32)
+ return kX86VarTypeXmmSs;
+ if (aType == kVarTypeFp64)
+ return kX86VarTypeXmmSd;
+ return aType;
+}
+#endif
+
+//! Get an architecture from calling convention.
+//!
+//! Returns `kArchX86` or `kArchX64` depending on `conv`.
+static ASMJIT_INLINE uint32_t x86GetArchFromCConv(uint32_t conv) {
+ return IntUtil::inInterval<uint32_t>(conv, kX86FuncConvW64, kX86FuncConvU64) ? kArchX64 : kArchX86;
+}
+
+// ============================================================================
+// [asmjit::X86FuncDecl - SetPrototype]
+// ============================================================================
+
+#define R(_Index_) kX86RegIndex##_Index_
+static uint32_t X86FuncDecl_initConv(X86FuncDecl* self, uint32_t arch, uint32_t conv) {
+ // Setup defaults.
+ self->_argStackSize = 0;
+ self->_redZoneSize = 0;
+ self->_spillZoneSize = 0;
+
+ self->_convention = static_cast<uint8_t>(conv);
+ self->_calleePopsStack = false;
+ self->_direction = kFuncDirRtl;
+
+ self->_passed.reset();
+ self->_preserved.reset();
+
+ ::memset(self->_passedOrderGp, kInvalidReg, ASMJIT_ARRAY_SIZE(self->_passedOrderGp));
+ ::memset(self->_passedOrderXmm, kInvalidReg, ASMJIT_ARRAY_SIZE(self->_passedOrderXmm));
+
+ // --------------------------------------------------------------------------
+ // [X86 Support]
+ // --------------------------------------------------------------------------
+
+#ifdef ASMJIT_BUILD_X86
+ if (arch == kArchX86) {
+ self->_preserved.set(kX86RegClassGp, IntUtil::mask(R(Bx), R(Sp), R(Bp), R(Si), R(Di)));
+
+ switch (conv) {
+ case kX86FuncConvCDecl:
+ break;
+
+ case kX86FuncConvStdCall:
+ self->_calleePopsStack = true;
+ break;
+
+ case kX86FuncConvMsThisCall:
+ self->_calleePopsStack = true;
+ self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Cx)));
+ self->_passedOrderGp[0] = R(Cx);
+ break;
+
+ case kX86FuncConvMsFastCall:
+ self->_calleePopsStack = true;
+ self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Cx), R(Cx)));
+ self->_passedOrderGp[0] = R(Cx);
+ self->_passedOrderGp[1] = R(Dx);
+ break;
+
+ case kX86FuncConvBorlandFastCall:
+ self->_calleePopsStack = true;
+ self->_direction = kFuncDirLtr;
+ self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Ax), R(Dx), R(Cx)));
+ self->_passedOrderGp[0] = R(Ax);
+ self->_passedOrderGp[1] = R(Dx);
+ self->_passedOrderGp[2] = R(Cx);
+ break;
+
+ case kX86FuncConvGccFastCall:
+ self->_calleePopsStack = true;
+ self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Cx), R(Dx)));
+ self->_passedOrderGp[0] = R(Cx);
+ self->_passedOrderGp[1] = R(Dx);
+ break;
+
+ case kX86FuncConvGccRegParm1:
+ self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Ax)));
+ self->_passedOrderGp[0] = R(Ax);
+ break;
+
+ case kX86FuncConvGccRegParm2:
+ self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Ax), R(Dx)));
+ self->_passedOrderGp[0] = R(Ax);
+ self->_passedOrderGp[1] = R(Dx);
+ break;
+
+ case kX86FuncConvGccRegParm3:
+ self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Ax), R(Dx), R(Cx)));
+ self->_passedOrderGp[0] = R(Ax);
+ self->_passedOrderGp[1] = R(Dx);
+ self->_passedOrderGp[2] = R(Cx);
+ break;
+
+ default:
+ ASMJIT_ASSERT(!"Reached");
+ }
+
+ return kErrorOk;
+ }
+#endif // ASMJIT_BUILD_X86
+
+ // --------------------------------------------------------------------------
+ // [X64 Support]
+ // --------------------------------------------------------------------------
+
+#ifdef ASMJIT_BUILD_X64
+ switch (conv) {
+ case kX86FuncConvW64:
+ self->_spillZoneSize = 32;
+
+ self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Cx), R(Dx), 8, 9));
+ self->_passedOrderGp[0] = R(Cx);
+ self->_passedOrderGp[1] = R(Dx);
+ self->_passedOrderGp[2] = 8;
+ self->_passedOrderGp[3] = 9;
+
+ self->_passed.set(kX86RegClassXyz, IntUtil::mask(0, 1, 2, 3));
+ self->_passedOrderXmm[0] = 0;
+ self->_passedOrderXmm[1] = 1;
+ self->_passedOrderXmm[2] = 2;
+ self->_passedOrderXmm[3] = 3;
+
+ self->_preserved.set(kX86RegClassGp , IntUtil::mask(R(Bx), R(Sp), R(Bp), R(Si), R(Di), 12, 13, 14, 15));
+ self->_preserved.set(kX86RegClassXyz, IntUtil::mask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15));
+ break;
+
+ case kX86FuncConvU64:
+ self->_redZoneSize = 128;
+
+ self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Di), R(Si), R(Dx), R(Cx), 8, 9));
+ self->_passedOrderGp[0] = R(Di);
+ self->_passedOrderGp[1] = R(Si);
+ self->_passedOrderGp[2] = R(Dx);
+ self->_passedOrderGp[3] = R(Cx);
+ self->_passedOrderGp[4] = 8;
+ self->_passedOrderGp[5] = 9;
+
+ self->_passed.set(kX86RegClassXyz, IntUtil::mask(0, 1, 2, 3, 4, 5, 6, 7));
+ self->_passedOrderXmm[0] = 0;
+ self->_passedOrderXmm[1] = 1;
+ self->_passedOrderXmm[2] = 2;
+ self->_passedOrderXmm[3] = 3;
+ self->_passedOrderXmm[4] = 4;
+ self->_passedOrderXmm[5] = 5;
+ self->_passedOrderXmm[6] = 6;
+ self->_passedOrderXmm[7] = 7;
+
+ self->_preserved.set(kX86RegClassGp, IntUtil::mask(R(Bx), R(Sp), R(Bp), 12, 13, 14, 15));
+ break;
+
+ default:
+ ASMJIT_ASSERT(!"Reached");
+ }
+#endif // ASMJIT_BUILD_X64
+
+ return kErrorOk;
+}
+#undef R
+
+static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch,
+ uint32_t ret, const uint32_t* argList, uint32_t argCount) {
+
+ ASMJIT_ASSERT(argCount <= kFuncArgCount);
+
+#ifdef ASMJIT_BUILD_X64
+ uint32_t conv = self->_convention;
+#endif
+ uint32_t regSize = (arch == kArchX86) ? 4 : 8;
+
+ int32_t i = 0;
+ int32_t gpPos = 0;
+#ifdef ASMJIT_BUILD_X64
+ int32_t xmmPos = 0;
+#endif
+ int32_t stackOffset = 0;
+
+ const uint8_t* varMapping;
+
+#ifdef ASMJIT_BUILD_X86
+ if (arch == kArchX86)
+ varMapping = _x86VarMapping;
+#endif // ASMJIT_BUILD_X86
+
+#ifdef ASMJIT_BUILD_X64
+ if (arch == kArchX64)
+ varMapping = _x64VarMapping;
+#endif // ASMJIT_BUILD_X64
+
+ self->_argCount = static_cast<uint8_t>(argCount);
+ self->_retCount = 0;
+
+ for (i = 0; i < static_cast<int32_t>(argCount); i++) {
+ FuncInOut& arg = self->getArg(i);
+ arg._varType = static_cast<uint8_t>(varMapping[argList[i]]);
+ arg._regIndex = kInvalidReg;
+ arg._stackOffset = kFuncStackInvalid;
+ }
+
+ for (; i < kFuncArgCount; i++) {
+ self->_argList[i].reset();
+ }
+
+ self->_retList[0].reset();
+ self->_retList[1].reset();
+ self->_argStackSize = 0;
+ self->_used.reset();
+
+ if (ret != kInvalidVar) {
+ ret = varMapping[ret];
+ switch (ret) {
+ case kVarTypeInt64:
+ case kVarTypeUInt64:
+ // 64-bit value is returned in EDX:EAX on x86.
+#ifdef ASMJIT_BUILD_X86
+ if (arch == kArchX86) {
+ self->_retCount = 2;
+ self->_retList[0]._varType = kVarTypeUInt32;
+ self->_retList[0]._regIndex = kX86RegIndexAx;
+ self->_retList[1]._varType = static_cast<uint8_t>(ret - 2);
+ self->_retList[1]._regIndex = kX86RegIndexDx;
+ }
+#endif // ASMJIT_BUILD_X86
+ // ... Fall through ...
+
+ case kVarTypeInt8:
+ case kVarTypeUInt8:
+ case kVarTypeInt16:
+ case kVarTypeUInt16:
+ case kVarTypeInt32:
+ case kVarTypeUInt32:
+ self->_retCount = 1;
+ self->_retList[0]._varType = static_cast<uint8_t>(ret);
+ self->_retList[0]._regIndex = kX86RegIndexAx;
+ break;
+
+ case kX86VarTypeMm:
+ self->_retCount = 1;
+ self->_retList[0]._varType = static_cast<uint8_t>(ret);
+ self->_retList[0]._regIndex = 0;
+ break;
+
+ case kVarTypeFp32:
+ self->_retCount = 1;
+ if (arch == kArchX86) {
+ self->_retList[0]._varType = kVarTypeFp32;
+ self->_retList[0]._regIndex = 0;
+ }
+ else {
+ self->_retList[0]._varType = kX86VarTypeXmmSs;
+ self->_retList[0]._regIndex = 0;
+ }
+ break;
+
+ case kVarTypeFp64:
+ self->_retCount = 1;
+ if (arch == kArchX86) {
+ self->_retList[0]._varType = kVarTypeFp64;
+ self->_retList[0]._regIndex = 0;
+ }
+ else {
+ self->_retList[0]._varType = kX86VarTypeXmmSd;
+ self->_retList[0]._regIndex = 0;
+ break;
+ }
+ break;
+
+ case kX86VarTypeXmm:
+ case kX86VarTypeXmmSs:
+ case kX86VarTypeXmmSd:
+ case kX86VarTypeXmmPs:
+ case kX86VarTypeXmmPd:
+ self->_retCount = 1;
+ self->_retList[0]._varType = static_cast<uint8_t>(ret);
+ self->_retList[0]._regIndex = 0;
+ break;
+ }
+ }
+
+ if (self->_argCount == 0)
+ return kErrorOk;
+
+#ifdef ASMJIT_BUILD_X86
+ if (arch == kArchX86) {
+ // Register arguments (Integer), always left-to-right.
+ for (i = 0; i != static_cast<int32_t>(argCount); i++) {
+ FuncInOut& arg = self->getArg(i);
+ uint32_t varType = varMapping[arg.getVarType()];
+
+ if (!x86ArgIsInt(varType) || gpPos >= static_cast<int32_t>(ASMJIT_ARRAY_SIZE(self->_passedOrderGp)))
+ continue;
+
+ if (self->_passedOrderGp[gpPos] == kInvalidReg)
+ continue;
+
+ arg._regIndex = self->_passedOrderGp[gpPos++];
+ self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex()));
+ }
+
+ // Stack arguments.
+ int32_t iStart = static_cast<int32_t>(argCount - 1);
+ int32_t iEnd = -1;
+ int32_t iStep = -1;
+
+ if (self->_direction == kFuncDirLtr) {
+ iStart = 0;
+ iEnd = static_cast<int32_t>(argCount);
+ iStep = 1;
+ }
+
+ for (i = iStart; i != iEnd; i += iStep) {
+ FuncInOut& arg = self->getArg(i);
+ uint32_t varType = varMapping[arg.getVarType()];
+
+ if (arg.hasRegIndex())
+ continue;
+
+ if (x86ArgIsInt(varType)) {
+ stackOffset -= 4;
+ arg._stackOffset = static_cast<int16_t>(stackOffset);
+ }
+ else if (x86ArgIsFp(varType)) {
+ int32_t size = static_cast<int32_t>(_x86VarInfo[varType].getSize());
+ stackOffset -= size;
+ arg._stackOffset = static_cast<int16_t>(stackOffset);
+ }
+ }
+ }
+#endif // ASMJIT_BUILD_X86
+
+#ifdef ASMJIT_BUILD_X64
+ if (arch == kArchX64) {
+ if (conv == kX86FuncConvW64) {
+ int32_t argMax = IntUtil::iMin<int32_t>(argCount, 4);
+
+ // Register arguments (Gp/Xmm), always left-to-right.
+ for (i = 0; i != argMax; i++) {
+ FuncInOut& arg = self->getArg(i);
+ uint32_t varType = varMapping[arg.getVarType()];
+
+ if (x86ArgIsInt(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderGp)) {
+ arg._regIndex = self->_passedOrderGp[i];
+ self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex()));
+ continue;
+ }
+
+ if (x86ArgIsFp(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderXmm)) {
+ arg._varType = static_cast<uint8_t>(x86ArgTypeToXmmType(varType));
+ arg._regIndex = self->_passedOrderXmm[i];
+ self->_used.add(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex()));
+ }
+ }
+
+ // Stack arguments (always right-to-left).
+ for (i = argCount - 1; i != -1; i--) {
+ FuncInOut& arg = self->getArg(i);
+ uint32_t varType = varMapping[arg.getVarType()];
+
+ if (arg.hasRegIndex())
+ continue;
+
+ if (x86ArgIsInt(varType)) {
+ stackOffset -= 8; // Always 8 bytes.
+ arg._stackOffset = stackOffset;
+ }
+ else if (x86ArgIsFp(varType)) {
+ stackOffset -= 8; // Always 8 bytes (float/double).
+ arg._stackOffset = stackOffset;
+ }
+ }
+
+ // 32 bytes shadow space (X64W calling convention specific).
+ stackOffset -= 4 * 8;
+ }
+ else {
+ // Register arguments (Gp), always left-to-right.
+ for (i = 0; i != static_cast<int32_t>(argCount); i++) {
+ FuncInOut& arg = self->getArg(i);
+ uint32_t varType = varMapping[arg.getVarType()];
+
+ if (!x86ArgIsInt(varType) || gpPos >= ASMJIT_ARRAY_SIZE(self->_passedOrderGp))
+ continue;
+
+ if (self->_passedOrderGp[gpPos] == kInvalidReg)
+ continue;
+
+ arg._regIndex = self->_passedOrderGp[gpPos++];
+ self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex()));
+ }
+
+ // Register arguments (Xmm), always left-to-right.
+ for (i = 0; i != static_cast<int32_t>(argCount); i++) {
+ FuncInOut& arg = self->getArg(i);
+ uint32_t varType = varMapping[arg.getVarType()];
+
+ if (x86ArgIsFp(varType)) {
+ arg._varType = static_cast<uint8_t>(x86ArgTypeToXmmType(varType));
+ arg._regIndex = self->_passedOrderXmm[xmmPos++];
+ self->_used.add(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex()));
+ }
+ }
+
+ // Stack arguments.
+ for (i = argCount - 1; i != -1; i--) {
+ FuncInOut& arg = self->getArg(i);
+ uint32_t varType = varMapping[arg.getVarType()];
+
+ if (arg.hasRegIndex())
+ continue;
+
+ if (x86ArgIsInt(varType)) {
+ stackOffset -= 8;
+ arg._stackOffset = static_cast<int16_t>(stackOffset);
+ }
+ else if (x86ArgIsFp(varType)) {
+ int32_t size = static_cast<int32_t>(_x86VarInfo[varType].getSize());
+
+ stackOffset -= size;
+ arg._stackOffset = static_cast<int16_t>(stackOffset);
+ }
+ }
+ }
+ }
+#endif // ASMJIT_BUILD_X64
+
+ // Modify the stack offset, thus in result all parameters would have positive
+ // non-zero stack offset.
+ for (i = 0; i < static_cast<int32_t>(argCount); i++) {
+ FuncInOut& arg = self->getArg(i);
+ if (!arg.hasRegIndex()) {
+ arg._stackOffset += static_cast<uint16_t>(static_cast<int32_t>(regSize) - stackOffset);
+ }
+ }
+
+ self->_argStackSize = static_cast<uint32_t>(-stackOffset);
+ return kErrorOk;
+}
+
+Error X86FuncDecl::setPrototype(uint32_t conv, const FuncPrototype& p) {
+ if (conv == kFuncConvNone || conv >= _kX86FuncConvCount)
+ return kErrorInvalidArgument;
+
+ if (p.getArgCount() > kFuncArgCount)
+ return kErrorInvalidArgument;
+
+ // Validate that the required convention is supported by the current asmjit
+ // configuration, if only one target is compiled.
+ uint32_t arch = x86GetArchFromCConv(conv);
+#if defined(ASMJIT_BUILD_X86) && !defined(ASMJIT_BUILD_X64)
+ if (arch == kArchX64)
+ return kErrorInvalidState;
+#endif // ASMJIT_BUILD_X86 && !ASMJIT_BUILD_X64
+
+#if !defined(ASMJIT_BUILD_X86) && defined(ASMJIT_BUILD_X64)
+ if (arch == kArchX86)
+ return kErrorInvalidState;
+#endif // !ASMJIT_BUILD_X86 && ASMJIT_BUILD_X64
+
+ ASMJIT_PROPAGATE_ERROR(X86FuncDecl_initConv(this, arch, conv));
+ ASMJIT_PROPAGATE_ERROR(X86FuncDecl_initFunc(this, arch, p.getRet(), p.getArgList(), p.getArgCount()));
+
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86FuncDecl - Reset]
+// ============================================================================
+
+void X86FuncDecl::reset() {
+ uint32_t i;
+
+ _convention = kFuncConvNone;
+ _calleePopsStack = false;
+ _direction = kFuncDirRtl;
+ _reserved0 = 0;
+
+ _argCount = 0;
+ _retCount = 0;
+
+ _argStackSize = 0;
+ _redZoneSize = 0;
+ _spillZoneSize = 0;
+
+ for (i = 0; i < ASMJIT_ARRAY_SIZE(_argList); i++) {
+ _argList[i].reset();
+ }
+
+ _retList[0].reset();
+ _retList[1].reset();
+
+ _used.reset();
+ _passed.reset();
+ _preserved.reset();
+
+ ::memset(_passedOrderGp, kInvalidReg, ASMJIT_ARRAY_SIZE(_passedOrderGp));
+ ::memset(_passedOrderXmm, kInvalidReg, ASMJIT_ARRAY_SIZE(_passedOrderXmm));
+}
+
+// ============================================================================
+// [asmjit::X86CallNode - Prototype]
+// ============================================================================
+
+Error X86CallNode::setPrototype(uint32_t conv, const FuncPrototype& p) {
+ return _x86Decl.setPrototype(conv, p);
+}
+
+// ============================================================================
+// [asmjit::X86CallNode - Arg / Ret]
+// ============================================================================
+
+bool X86CallNode::_setArg(uint32_t i, const Operand& op) {
+ if ((i & ~kFuncArgHi) >= _x86Decl.getArgCount())
+ return false;
+
+ _args[i] = op;
+ return true;
+}
+
+bool X86CallNode::_setRet(uint32_t i, const Operand& op) {
+ if (i >= 2)
+ return false;
+
+ _ret[i] = op;
+ return true;
+}
+
+// ============================================================================
+// [asmjit::X86Compiler - Helpers (Private)]
+// ============================================================================
+
+static Error X86Compiler_emitConstPool(X86Compiler* self,
+ Label& label, ConstPool& pool) {
+
+ if (label.getId() == kInvalidValue)
+ return kErrorOk;
+
+ self->align(kAlignData, static_cast<uint32_t>(pool.getAlignment()));
+ self->bind(label);
+
+ EmbedNode* embedNode = self->embed(nullptr, static_cast<uint32_t>(pool.getSize()));
+ if (!embedNode)
+ return kErrorNoHeapMemory;
+
+ pool.fill(embedNode->getData());
+ pool.reset();
+ label.reset();
+
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86Compiler - Construction / Destruction]
+// ============================================================================
+
+X86Compiler::X86Compiler(Runtime* runtime, uint32_t arch) :
+ Compiler(runtime),
+ zax(NoInit),
+ zcx(NoInit),
+ zdx(NoInit),
+ zbx(NoInit),
+ zsp(NoInit),
+ zbp(NoInit),
+ zsi(NoInit),
+ zdi(NoInit) {
+
+ setArch(arch);
+}
+
+X86Compiler::~X86Compiler() {}
+
+// ============================================================================
+// [asmjit::X86Compiler - Arch]
+// ============================================================================
+
+Error X86Compiler::setArch(uint32_t arch) {
+#ifdef ASMJIT_BUILD_X86
+ if (arch == kArchX86) {
+ _arch = kArchX86;
+ _regSize = 4;
+
+ _regCount.reset();
+ _regCount._gp = 8;
+ _regCount._fp = 8;
+ _regCount._mm = 8;
+ _regCount._xy = 8;
+
+ zax = x86::eax;
+ zcx = x86::ecx;
+ zdx = x86::edx;
+ zbx = x86::ebx;
+ zsp = x86::esp;
+ zbp = x86::ebp;
+ zsi = x86::esi;
+ zdi = x86::edi;
+
+ _targetVarMapping = _x86VarMapping;
+ return kErrorOk;
+ }
+#endif // ASMJIT_BUILD_X86
+
+#ifdef ASMJIT_BUILD_X64
+ if (arch == kArchX64) {
+ _arch = kArchX64;
+ _regSize = 8;
+
+ _regCount.reset();
+ _regCount._gp = 16;
+ _regCount._fp = 8;
+ _regCount._mm = 8;
+ _regCount._xy = 16;
+
+ zax = x86::rax;
+ zcx = x86::rcx;
+ zdx = x86::rdx;
+ zbx = x86::rbx;
+ zsp = x86::rsp;
+ zbp = x86::rbp;
+ zsi = x86::rsi;
+ zdi = x86::rdi;
+
+ _targetVarMapping = _x64VarMapping;
+ return kErrorOk;
+ }
+#endif // ASMJIT_BUILD_X64
+
+ ASMJIT_ASSERT(!"Reached");
+ return kErrorInvalidArgument;
+}
+
+// ============================================================================
+// [asmjit::X86Compiler - Inst]
+// ============================================================================
+
+//! Get compiler instruction item size without operands assigned.
+static ASMJIT_INLINE size_t X86Compiler_getInstSize(uint32_t code) {
+ return IntUtil::inInterval<uint32_t>(code, _kX86InstIdJbegin, _kX86InstIdJend) ? sizeof(JumpNode) : sizeof(InstNode);
+}
+
+static InstNode* X86Compiler_newInst(X86Compiler* self, void* p, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) {
+ if (IntUtil::inInterval<uint32_t>(code, _kX86InstIdJbegin, _kX86InstIdJend)) {
+ JumpNode* node = new(p) JumpNode(self, code, options, opList, opCount);
+ TargetNode* jTarget = self->getTargetById(opList[0].getId());
+
+ node->addFlags(code == kX86InstIdJmp ? kNodeFlagIsJmp | kNodeFlagIsTaken : kNodeFlagIsJcc);
+ node->_target = jTarget;
+ node->_jumpNext = static_cast<JumpNode*>(jTarget->_from);
+
+ jTarget->_from = node;
+ jTarget->addNumRefs();
+
+ // The 'jmp' is always taken, conditional jump can contain hint, we detect it.
+ if (code == kX86InstIdJmp)
+ node->addFlags(kNodeFlagIsTaken);
+ else if (options & kInstOptionTaken)
+ node->addFlags(kNodeFlagIsTaken);
+
+ node->addOptions(options);
+ return node;
+ }
+ else {
+ InstNode* node = new(p) InstNode(self, code, options, opList, opCount);
+ node->addOptions(options);
+ return node;
+ }
+}
+
+InstNode* X86Compiler::newInst(uint32_t code) {
+ size_t size = X86Compiler_getInstSize(code);
+ InstNode* inst = static_cast<InstNode*>(_baseZone.alloc(size));
+
+ if (!inst)
+ goto _NoMemory;
+
+ return X86Compiler_newInst(this, inst, code, getInstOptionsAndReset(), nullptr, 0);
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0) {
+ size_t size = X86Compiler_getInstSize(code);
+ InstNode* inst = static_cast<InstNode*>(_baseZone.alloc(size + 1 * sizeof(Operand)));
+
+ if (!inst)
+ goto _NoMemory;
+
+ {
+ Operand* opList = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(inst) + size);
+ opList[0] = o0;
+ ASMJIT_ASSERT_UNINITIALIZED(o0);
+ return X86Compiler_newInst(this, inst, code, getInstOptionsAndReset(), opList, 1);
+ }
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1) {
+ size_t size = X86Compiler_getInstSize(code);
+ InstNode* inst = static_cast<InstNode*>(_baseZone.alloc(size + 2 * sizeof(Operand)));
+
+ if (!inst)
+ goto _NoMemory;
+
+ {
+ Operand* opList = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(inst) + size);
+ opList[0] = o0;
+ opList[1] = o1;
+ ASMJIT_ASSERT_UNINITIALIZED(o0);
+ ASMJIT_ASSERT_UNINITIALIZED(o1);
+ return X86Compiler_newInst(this, inst, code, getInstOptionsAndReset(), opList, 2);
+ }
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2) {
+ size_t size = X86Compiler_getInstSize(code);
+ InstNode* inst = static_cast<InstNode*>(_baseZone.alloc(size + 3 * sizeof(Operand)));
+
+ if (!inst)
+ goto _NoMemory;
+
+ {
+ Operand* opList = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(inst) + size);
+ opList[0] = o0;
+ opList[1] = o1;
+ opList[2] = o2;
+ ASMJIT_ASSERT_UNINITIALIZED(o0);
+ ASMJIT_ASSERT_UNINITIALIZED(o1);
+ ASMJIT_ASSERT_UNINITIALIZED(o2);
+ return X86Compiler_newInst(this, inst, code, getInstOptionsAndReset(), opList, 3);
+ }
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) {
+ size_t size = X86Compiler_getInstSize(code);
+ InstNode* inst = static_cast<InstNode*>(_baseZone.alloc(size + 4 * sizeof(Operand)));
+
+ if (!inst)
+ goto _NoMemory;
+
+ {
+ Operand* opList = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(inst) + size);
+ opList[0] = o0;
+ opList[1] = o1;
+ opList[2] = o2;
+ opList[3] = o3;
+ ASMJIT_ASSERT_UNINITIALIZED(o0);
+ ASMJIT_ASSERT_UNINITIALIZED(o1);
+ ASMJIT_ASSERT_UNINITIALIZED(o2);
+ ASMJIT_ASSERT_UNINITIALIZED(o3);
+ return X86Compiler_newInst(this, inst, code, getInstOptionsAndReset(), opList, 4);
+ }
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4) {
+ size_t size = X86Compiler_getInstSize(code);
+ InstNode* inst = static_cast<InstNode*>(_baseZone.alloc(size + 5 * sizeof(Operand)));
+
+ if (!inst)
+ goto _NoMemory;
+
+ {
+ Operand* opList = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(inst) + size);
+ opList[0] = o0;
+ opList[1] = o1;
+ opList[2] = o2;
+ opList[3] = o3;
+ opList[4] = o4;
+ ASMJIT_ASSERT_UNINITIALIZED(o0);
+ ASMJIT_ASSERT_UNINITIALIZED(o1);
+ ASMJIT_ASSERT_UNINITIALIZED(o2);
+ ASMJIT_ASSERT_UNINITIALIZED(o3);
+ ASMJIT_ASSERT_UNINITIALIZED(o4);
+ return X86Compiler_newInst(this, inst, code, getInstOptionsAndReset(), opList, 5);
+ }
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+InstNode* X86Compiler::emit(uint32_t code) {
+ InstNode* node = newInst(code);
+ if (!node)
+ return nullptr;
+ return static_cast<InstNode*>(addNode(node));
+}
+
+InstNode* X86Compiler::emit(uint32_t code, const Operand& o0) {
+ InstNode* node = newInst(code, o0);
+ if (!node)
+ return nullptr;
+ return static_cast<InstNode*>(addNode(node));
+}
+
+InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1){
+ InstNode* node = newInst(code, o0, o1);
+ if (!node)
+ return nullptr;
+ return static_cast<InstNode*>(addNode(node));
+}
+
+InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2) {
+ InstNode* node = newInst(code, o0, o1, o2);
+ if (!node)
+ return nullptr;
+ return static_cast<InstNode*>(addNode(node));
+}
+
+InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3){
+ InstNode* node = newInst(code, o0, o1, o2, o3);
+ if (!node)
+ return nullptr;
+ return static_cast<InstNode*>(addNode(node));
+}
+
+InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4) {
+ InstNode* node = newInst(code, o0, o1, o2, o3, o4);
+ if (!node)
+ return nullptr;
+ return static_cast<InstNode*>(addNode(node));
+}
+
+InstNode* X86Compiler::emit(uint32_t code, int o0_) {
+ Imm o0(o0_);
+ InstNode* node = newInst(code, o0);
+ if (!node)
+ return nullptr;
+ return static_cast<InstNode*>(addNode(node));
+}
+
+InstNode* X86Compiler::emit(uint32_t code, uint64_t o0_) {
+ Imm o0(o0_);
+ InstNode* node = newInst(code, o0);
+ if (!node)
+ return nullptr;
+ return static_cast<InstNode*>(addNode(node));
+}
+
+InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, int o1_) {
+ Imm o1(o1_);
+ InstNode* node = newInst(code, o0, o1);
+ if (!node)
+ return nullptr;
+ return static_cast<InstNode*>(addNode(node));
+}
+
+InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, uint64_t o1_) {
+ Imm o1(o1_);
+ InstNode* node = newInst(code, o0, o1);
+ if (!node)
+ return nullptr;
+ return static_cast<InstNode*>(addNode(node));
+}
+
+InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, int o2_) {
+ Imm o2(o2_);
+ InstNode* node = newInst(code, o0, o1, o2);
+ if (!node)
+ return nullptr;
+ return static_cast<InstNode*>(addNode(node));
+}
+
+InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2_) {
+ Imm o2(o2_);
+ InstNode* node = newInst(code, o0, o1, o2);
+ if (!node)
+ return nullptr;
+ return static_cast<InstNode*>(addNode(node));
+}
+
+// ============================================================================
+// [asmjit::X86Compiler - Func]
+// ============================================================================
+
+X86FuncNode* X86Compiler::newFunc(uint32_t conv, const FuncPrototype& p) {
+ X86FuncNode* func = newNode<X86FuncNode>();
+ Error error;
+
+ if (!func)
+ goto _NoMemory;
+
+ // Create helper nodes.
+ func->_entryNode = newTarget();
+ func->_exitNode = newTarget();
+ func->_end = newNode<EndNode>();
+
+ if (!func->_entryNode || !func->_exitNode || !func->_end)
+ goto _NoMemory;
+
+ // Emit push/pop sequence by default.
+ func->_funcHints |= IntUtil::mask(kX86FuncHintPushPop);
+
+ // Function prototype.
+ if ((error = func->_x86Decl.setPrototype(conv, p)) != kErrorOk) {
+ setError(error);
+ return nullptr;
+ }
+
+ // Function arguments stack size. Since function requires _argStackSize to be
+ // set, we have to copy it from X86FuncDecl.
+ func->_argStackSize = func->_x86Decl.getArgStackSize();
+ func->_redZoneSize = static_cast<uint16_t>(func->_x86Decl.getRedZoneSize());
+ func->_spillZoneSize = static_cast<uint16_t>(func->_x86Decl.getSpillZoneSize());
+
+ // Expected/Required stack alignment.
+ func->_expectedStackAlignment = getRuntime()->getStackAlignment();
+ func->_requiredStackAlignment = 0;
+
+ // Allocate space for function arguments.
+ func->_argList = nullptr;
+ if (func->getArgCount() != 0) {
+ func->_argList = _baseZone.allocT<VarData*>(func->getArgCount() * sizeof(VarData*));
+ if (!func->_argList)
+ goto _NoMemory;
+ ::memset(func->_argList, 0, func->getArgCount() * sizeof(VarData*));
+ }
+
+ return func;
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+X86FuncNode* X86Compiler::addFunc(uint32_t conv, const FuncPrototype& p) {
+ X86FuncNode* func = newFunc(conv, p);
+
+ if (!func) {
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+ }
+
+ ASMJIT_ASSERT(!_func);
+ _func = func;
+
+ addNode(func);
+ addNode(func->getEntryNode());
+
+ return func;
+}
+
+EndNode* X86Compiler::endFunc() {
+ X86FuncNode* func = getFunc();
+ ASMJIT_ASSERT(func);
+
+ // App function exit / epilog marker.
+ addNode(func->getExitNode());
+
+ // Add local constant pool at the end of the function (if exist).
+ X86Compiler_emitConstPool(this, _localConstPoolLabel, _localConstPool);
+
+ // Add function end marker.
+ addNode(func->getEnd());
+
+ // Finalize...
+ func->addFuncFlags(kFuncFlagIsFinished);
+ _func = nullptr;
+
+ return func->getEnd();
+}
+
+// ============================================================================
+// [asmjit::X86Compiler - Ret]
+// ============================================================================
+
+RetNode* X86Compiler::newRet(const Operand& o0, const Operand& o1) {
+ RetNode* node = newNode<RetNode>(o0, o1);
+ if (!node)
+ goto _NoMemory;
+ return node;
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+RetNode* X86Compiler::addRet(const Operand& o0, const Operand& o1) {
+ RetNode* node = newRet(o0, o1);
+ if (!node)
+ return node;
+ return static_cast<RetNode*>(addNode(node));
+}
+
+// ============================================================================
+// [asmjit::X86Compiler - Call]
+// ============================================================================
+
+X86CallNode* X86Compiler::newCall(const Operand& o0, uint32_t conv, const FuncPrototype& p) {
+ X86CallNode* node = newNode<X86CallNode>(o0);
+ Error error;
+ uint32_t nArgs;
+
+ if (!node)
+ goto _NoMemory;
+
+ if ((error = node->_x86Decl.setPrototype(conv, p)) != kErrorOk) {
+ setError(error);
+ return nullptr;
+ }
+
+ // If there are no arguments skip the allocation.
+ if ((nArgs = p.getArgCount()) == 0)
+ return node;
+
+ node->_args = static_cast<Operand*>(_baseZone.alloc(nArgs * sizeof(Operand)));
+ if (!node->_args)
+ goto _NoMemory;
+
+ ::memset(node->_args, 0, nArgs * sizeof(Operand));
+ return node;
+
+_NoMemory:
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+}
+
+X86CallNode* X86Compiler::addCall(const Operand& o0, uint32_t conv, const FuncPrototype& p) {
+ X86CallNode* node = newCall(o0, conv, p);
+ if (!node)
+ return nullptr;
+ return static_cast<X86CallNode*>(addNode(node));
+}
+
+// ============================================================================
+// [asmjit::X86Compiler - Vars]
+// ============================================================================
+
+Error X86Compiler::setArg(uint32_t argIndex, Var& var) {
+ X86FuncNode* func = getFunc();
+
+ if (!func)
+ return kErrorInvalidArgument;
+
+ if (!isVarValid(var))
+ return kErrorInvalidState;
+
+ VarData* vd = getVd(var);
+ func->setArg(argIndex, vd);
+
+ return kErrorOk;
+}
+
+Error X86Compiler::_newVar(Var* var, uint32_t vType, const char* name) {
+ ASMJIT_ASSERT(vType < kX86VarTypeCount);
+
+ vType = _targetVarMapping[vType];
+ ASMJIT_ASSERT(vType != kInvalidVar);
+
+ // There is not ASSERT in release mode and this should be checked.
+ if (vType == kInvalidVar) {
+ static_cast<X86Var*>(var)->reset();
+ return kErrorInvalidArgument;
+ }
+
+ const X86VarInfo& vInfo = _x86VarInfo[vType];
+ VarData* vd = _newVd(vType, vInfo.getSize(), vInfo.getClass(), name);
+
+ if (!vd) {
+ static_cast<X86Var*>(var)->reset();
+ return getError();
+ }
+
+ var->_init_packed_op_sz_w0_id(kOperandTypeVar, vd->getSize(), vInfo.getReg() << 8, vd->getId());
+ var->_vreg.vType = vType;
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86Compiler - Stack]
+// ============================================================================
+
+Error X86Compiler::_newStack(BaseMem* mem, uint32_t size, uint32_t alignment, const char* name) {
+ if (size == 0)
+ return kErrorInvalidArgument;
+
+ if (alignment > 64)
+ alignment = 64;
+
+ VarData* vd = _newVd(kInvalidVar, size, kInvalidReg, name);
+ if (!vd) {
+ static_cast<X86Mem*>(mem)->reset();
+ return getError();
+ }
+
+ vd->_isStack = true;
+ vd->_alignment = static_cast<uint8_t>(alignment);
+
+ static_cast<X86Mem*>(mem)->_init(kMemTypeStackIndex, vd->getId(), 0, 0);
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86Compiler - Const]
+// ============================================================================
+
+Error X86Compiler::_newConst(BaseMem* mem, uint32_t scope, const void* data, size_t size) {
+ Error error = kErrorOk;
+ size_t offset;
+
+ Label* dstLabel;
+ ConstPool* dstPool;
+
+ if (scope == kConstScopeLocal) {
+ dstLabel = &_localConstPoolLabel;
+ dstPool = &_localConstPool;
+ }
+ else if (scope == kConstScopeGlobal) {
+ dstLabel = &_globalConstPoolLabel;
+ dstPool = &_globalConstPool;
+ }
+ else {
+ error = kErrorInvalidArgument;
+ goto _OnError;
+ }
+
+ error = dstPool->add(data, size, offset);
+ if (error != kErrorOk)
+ goto _OnError;
+
+ if (dstLabel->getId() == kInvalidValue) {
+ error = _newLabel(dstLabel);
+ if (error != kErrorOk)
+ goto _OnError;
+ }
+
+ *static_cast<X86Mem*>(mem) = x86::ptr(*dstLabel, static_cast<int32_t>(offset), static_cast<uint32_t>(size));
+ return kErrorOk;
+
+_OnError:
+ return error;
+}
+
+// ============================================================================
+// [asmjit::X86Compiler - Make]
+// ============================================================================
+
+void* X86Compiler::make() {
+ Assembler* assembler = getAssembler();
+ if (!assembler) {
+ setError(kErrorNoHeapMemory);
+ return nullptr;
+ }
+
+ Error error = serialize(assembler);
+ if (error != kErrorOk) {
+ setError(error);
+ return nullptr;
+ }
+
+ void* result = assembler->make();
+ return result;
+}
+
+// ============================================================================
+// [asmjit::X86Compiler - Assembler]
+// ============================================================================
+
+Assembler* X86Compiler::_newAssembler() {
+ return new(std::nothrow) X86Assembler(_runtime, _arch);
+}
+
+// ============================================================================
+// [asmjit::X86Compiler - Serialize]
+// ============================================================================
+
+Error X86Compiler::serialize(Assembler* assembler) {
+ // Flush the global constant pool.
+ X86Compiler_emitConstPool(this, _globalConstPoolLabel, _globalConstPool);
+
+ if (!_firstNode)
+ return kErrorOk;
+
+ X86Context context(this);
+ Error error = kErrorOk;
+
+ Node* node = _firstNode;
+ Node* start;
+
+ // Find function and use the context to translate/emit.
+ do {
+ start = node;
+
+ if (node->getType() == kNodeTypeFunc) {
+ node = static_cast<X86FuncNode*>(start)->getEnd();
+ error = context.compile(static_cast<X86FuncNode*>(start));
+
+ if (error != kErrorOk)
+ goto _Error;
+ }
+
+ do {
+ node = node->getNext();
+ } while (node && node->getType() != kNodeTypeFunc);
+
+ error = context.serialize(assembler, start, node);
+ if (error != kErrorOk)
+ goto _Error;
+ context.cleanup();
+ } while (node);
+ return kErrorOk;
+
+_Error:
+ context.cleanup();
+ return error;
+}
+
+} // asmjit namespace
// [Api-End]
-#include "../core/apiend.h"
-
+#include "../apiend.h"
+
+// [Guard]
+#endif // !ASMJIT_DISABLE_COMPILER && (ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64)
+
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86compiler.h
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86compiler.h
@@ -1,395 +1,1448 @@
// [AsmJit]
-// Complete JIT Assembler for C++ Language.
+// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
-// Zlib - See COPYING file in this package.
+// Zlib - See LICENSE.md file in the package.
#pragma once
+#include "../build.h"
+#ifndef ASMJIT_DISABLE_COMPILER
+
// [Dependencies - AsmJit]
-#include "../core/build.h"
-#include "../core/compiler.h"
-#include "../core/compilercontext.h"
-#include "../core/compilerfunc.h"
-#include "../core/compileritem.h"
-
+#include "../base/compiler.h"
+#include "../base/vectypes.h"
#include "../x86/x86assembler.h"
-#include "../x86/x86defs.h"
-#include "../x86/x86func.h"
-#include "../x86/x86util.h"
// [Api-Begin]
-#include "../core/apibegin.h"
-
-//! @internal
-//!
-//! @brief Mark methods not supported by @ref Compiler. These methods are
-//! usually used only in function prologs/epilogs or to manage stack.
-#define ASMJIT_NOT_SUPPORTED_BY_COMPILER 0
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_X86
-//! @{
+#include "../apibegin.h"
+
+namespace asmjit {
// ============================================================================
// [Forward Declarations]
// ============================================================================
-struct X86Compiler;
-struct X86CompilerAlign;
-struct X86CompilerContext;
-struct X86CompilerFuncCall;
-struct X86CompilerFuncDecl;
-struct X86CompilerFuncEnd;
-struct X86CompilerInst;
-struct X86CompilerJmpInst;
-struct X86CompilerState;
-struct X86CompilerTarget;
-struct X86CompilerVar;
+struct X86CallNode;
+struct X86FuncNode;
+struct X86VarState;
+
+//! \addtogroup asmjit_x86_compiler
+//! \{
// ============================================================================
-// [AsmJit::X86CompilerVar]
+// [asmjit::k86VarType]
// ============================================================================
-//! @brief @ref X86Compiler variable.
-struct X86CompilerVar : public CompilerVar
-{
- // --------------------------------------------------------------------------
- // [AsVar]
- // --------------------------------------------------------------------------
-
- GpVar asGpVar() const
- {
- GpVar var;
- var._var.id = this->_id;
- var._var.size = this->_size;
- var._var.regCode = x86VarInfo[this->_type].getCode();
- var._var.varType = this->_type;
- return var;
- }
-
- MmVar asMmVar() const
- {
- MmVar var;
- var._var.id = this->_id;
- var._var.size = this->_size;
- var._var.regCode = x86VarInfo[this->_type].getCode();
- var._var.varType = this->_type;
- return var;
- }
-
- XmmVar asXmmVar() const
- {
- XmmVar var;
- var._var.id = this->_id;
- var._var.size = this->_size;
- var._var.regCode = x86VarInfo[this->_type].getCode();
- var._var.varType = this->_type;
- return var;
- }
-
- // --------------------------------------------------------------------------
- // [Members - Scope]
- // --------------------------------------------------------------------------
-
- //! @brief The first item where the variable is accessed.
- //! @note If this member is @c NULL then variable isn't used.
- CompilerItem *firstItem;
- //! @brief The last item where the variable is accessed.
- CompilerItem *lastItem;
-
- //! @brief Scope (NULL if variable is global).
- X86CompilerFuncDecl *funcScope;
- //! @brief The first call which is after the @c firstItem.
- X86CompilerFuncCall *funcCall;
-
- // --------------------------------------------------------------------------
- // [Members - Home]
- // --------------------------------------------------------------------------
-
- //! @brief Home register index or @c kRegIndexInvalid (used by register allocator).
- uint32_t homeRegisterIndex;
- //! @brief Preferred registers mask.
- uint32_t prefRegisterMask;
-
- //! @brief Home memory address offset.
- int32_t homeMemoryOffset;
- //! @brief Used by @c CompilerContext, do not touch (initially NULL).
- void *homeMemoryData;
-
- // --------------------------------------------------------------------------
- // [Members - Actual]
- // --------------------------------------------------------------------------
-
- //! @brief Actual register index (connected with actual @c X86CompilerState).
- uint32_t regIndex;
- //! @brief Actual working offset. This member is set before register allocator
- //! is called. If workOffset is same as CompilerContext::_currentOffset then
- //! this variable is probably used in next instruction and can't be spilled.
- uint32_t workOffset;
-
- //! @brief Next active variable in circular double-linked list.
- X86CompilerVar *nextActive;
- //! @brief Previous active variable in circular double-linked list.
- X86CompilerVar *prevActive;
-
- // --------------------------------------------------------------------------
- // [Members - Flags]
- // --------------------------------------------------------------------------
-
- //! @brief Variable state (connected with actual @c X86CompilerState).
- uint8_t state;
- //! @brief Whether variable was changed (connected with actual @c X86CompilerState).
- uint8_t changed;
- //! @brief Save on unuse (at end of the variable scope).
- uint8_t saveOnUnuse;
-
- // --------------------------------------------------------------------------
- // [Members - Statistics]
- // --------------------------------------------------------------------------
-
- //! @brief Register read access statistics.
- uint32_t regReadCount;
- //! @brief Register write access statistics.
- uint32_t regWriteCount;
- //! @brief Register read/write access statistics (related to a single instruction).
- uint32_t regRwCount;
-
- //! @brief Register GpbLo access statistics.
- uint32_t regGpbLoCount;
- //! @brief Register GpbHi access statistics.
- uint32_t regGpbHiCount;
-
- //! @brief Memory read statistics.
- uint32_t memReadCount;
- //! @brief Memory write statistics.
- uint32_t memWriteCount;
- //! @brief Memory read+write statistics.
- uint32_t memRwCount;
-
- // --------------------------------------------------------------------------
- // [Members - Temporary]
- // --------------------------------------------------------------------------
-
- //! @brief Temporary data that can be used in prepare/translate stage.
- //!
- //! Initial value is NULL and it's expected that after use it's set back to
- //! NULL.
- //!
- //! The temporary data is designed to be used by algorithms that need to
- //! set some state into variables, do something and then clean-up. See
- //! state switch and function call for details.
- union
- {
- void *tPtr;
- intptr_t tInt;
- };
+//! X86/X64 variable type.
+ASMJIT_ENUM(kX86VarType) {
+ //! Variable is SP-FP (x87).
+ kX86VarTypeFp32 = kVarTypeFp32,
+ //! Variable is DP-FP (x87).
+ kX86VarTypeFp64 = kVarTypeFp64,
+
+ //! Variable is Mm (MMX).
+ kX86VarTypeMm = 12,
+
+ //! Variable is Xmm (SSE+).
+ kX86VarTypeXmm,
+ //! Variable is scalar Xmm SP-FP number.
+ kX86VarTypeXmmSs,
+ //! Variable is packed Xmm SP-FP number (4 floats).
+ kX86VarTypeXmmPs,
+ //! Variable is scalar Xmm DP-FP number.
+ kX86VarTypeXmmSd,
+ //! Variable is packed Xmm DP-FP number (2 doubles).
+ kX86VarTypeXmmPd,
+
+ //! Variable is Ymm (AVX+).
+ kX86VarTypeYmm,
+ //! Variable is packed Ymm SP-FP number (8 floats).
+ kX86VarTypeYmmPs,
+ //! Variable is packed Ymm DP-FP number (4 doubles).
+ kX86VarTypeYmmPd,
+
+ //! Count of variable types.
+ kX86VarTypeCount,
+
+ //! \internal
+ //! \{
+ _kX86VarTypeMmStart = kX86VarTypeMm,
+ _kX86VarTypeMmEnd = kX86VarTypeMm,
+
+ _kX86VarTypeXmmStart = kX86VarTypeXmm,
+ _kX86VarTypeXmmEnd = kX86VarTypeXmmPd,
+
+ _kX86VarTypeYmmStart = kX86VarTypeYmm,
+ _kX86VarTypeYmmEnd = kX86VarTypeYmmPd
+ //! \}
};
// ============================================================================
-// [AsmJit::X86CompilerState]
+// [asmjit::kX86VarAttr]
// ============================================================================
-//! @brief @ref X86Compiler state.
-struct X86CompilerState : CompilerState
-{
- enum
- {
- //! @brief Base for Gp registers.
- kStateRegGpBase = 0,
- //! @brief Base for Mm registers.
- kStateRegMmBase = 16,
- //! @brief Base for Xmm registers.
- kStateRegXmmBase = 24,
-
- //! @brief Count of all registers in @ref X86CompilerState.
- kStateRegCount = 16 + 8 + 16
- };
-
- // --------------------------------------------------------------------------
- // [Clear]
- // --------------------------------------------------------------------------
-
- void clear() { memset(this, 0, sizeof(*this)); }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- union
- {
- //! @brief All allocated variables in one array.
- X86CompilerVar *regs[kStateRegCount];
-
- struct
- {
- //! @brief Allocated GP registers.
- X86CompilerVar *gp[16];
- //! @brief Allocated MM registers.
- X86CompilerVar *mm[8];
- //! @brief Allocated XMM registers.
- X86CompilerVar *xmm[16];
- };
- };
-
- //! @brief Used GP registers bit-mask.
- uint32_t usedGP;
- //! @brief Used MM registers bit-mask.
- uint32_t usedMM;
- //! @brief Used XMM registers bit-mask.
- uint32_t usedXMM;
-
- //! @brief Changed GP registers bit-mask.
- uint32_t changedGP;
- //! @brief Changed MM registers bit-mask.
- uint32_t changedMM;
- //! @brief Changed XMM registers bit-mask.
- uint32_t changedXMM;
-
- //! @brief Count of variables in @c memVarsData.
- uint32_t memVarsCount;
- //! @brief Variables stored in memory (@c kVarStateMem).
- //!
- //! When saving / restoring state it's important to keep registers which are
- //! still in memory. Register is always unused when it is going out-of-scope.
- //! All variables which are not here are unused (@c kVarStateUnused).
- X86CompilerVar *memVarsData[1];
+//! X86/X64 VarAttr flags.
+ASMJIT_ENUM(kX86VarAttr) {
+ kX86VarAttrGpbLo = 0x10000000,
+ kX86VarAttrGpbHi = 0x20000000
};
// ============================================================================
-// [AsmJit::VarMemBlock]
+// [asmjit::kX86FuncConv]
// ============================================================================
-struct VarMemBlock
-{
- int32_t offset;
- uint32_t size;
-
- VarMemBlock *nextUsed;
- VarMemBlock *nextFree;
+//! X86 function calling conventions.
+//!
+//! 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:
+//! - `kX86FuncConvCDecl` - Calling convention for C runtime.
+//! - `kX86FuncConvStdCall` - Calling convention for WinAPI functions.
+//! - `kX86FuncConvMsThisCall` - Calling convention for C++ members under
+//! Windows (produced by MSVC and all MSVC compatible compilers).
+//! - `kX86FuncConvMsFastCall` - Fastest calling convention that can be used
+//! by MSVC compiler.
+//! - `kX86FuncConvBorlandFastCall` - Borland fastcall convention.
+//! - `kX86FuncConvGccFastCall` - GCC fastcall convention (2 register arguments).
+//! - `kX86FuncConvGccRegParm1` - GCC regparm(1) convention.
+//! - `kX86FuncConvGccRegParm2` - GCC regparm(2) convention.
+//! - `kX86FuncConvGccRegParm3` - GCC regparm(3) convention.
+//!
+//! List of calling conventions for 64-bit x86 mode (x64):
+//! - `kX86FuncConvW64` - Windows 64-bit calling convention (WIN64 ABI).
+//! - `kX86FuncConvU64` - Unix 64-bit calling convention (AMD64 ABI).
+//!
+//! There is also `kFuncConvHost` that is defined to fit the host calling
+//! convention.
+//!
+//! These types are used together with `Compiler::addFunc()` method.
+ASMJIT_ENUM(kX86FuncConv) {
+ // --------------------------------------------------------------------------
+ // [X64]
+ // --------------------------------------------------------------------------
+
+ //! X64 calling convention for Windows platform (WIN64 ABI).
+ //!
+ //! 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 in 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-byte 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 information about this calling convention can be found on MSDN:
+ //! http://msdn.microsoft.com/en-us/library/9b372w95.aspx .
+ kX86FuncConvW64 = 1,
+
+ //! 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.
+ kX86FuncConvU64 = 2,
+
+ // --------------------------------------------------------------------------
+ // [X86]
+ // --------------------------------------------------------------------------
+
+ //! Cdecl calling convention (used by C runtime).
+ //!
+ //! Compatible across MSVC and GCC.
+ //!
+ //! Arguments direction:
+ //! - Right to Left
+ //!
+ //! Stack is cleaned by:
+ //! - Caller.
+ kX86FuncConvCDecl = 3,
+
+ //! 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 - fp0 register.
+ kX86FuncConvStdCall = 4,
+
+ //! 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 - fp0 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.
+ kX86FuncConvMsThisCall = 5,
+
+ //! 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 - fp0 register.
+ //!
+ //! \note This calling convention differs to GCC one in stack cleaning
+ //! mechanism.
+ kX86FuncConvMsFastCall = 6,
+
+ //! 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 - fp0 register.
+ //!
+ //! \note Arguments on the stack are in left-to-right order that differs
+ //! to other fastcall conventions used in different compilers.
+ kX86FuncConvBorlandFastCall = 7,
+
+ //! GCC specific fastcall convention.
+ //!
+ //! 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 - fp0 register.
+ //!
+ //! \note This calling convention should be compatible with `kX86FuncConvMsFastCall`.
+ kX86FuncConvGccFastCall = 8,
+
+ //! GCC specific regparm(1) convention.
+ //!
+ //! The first parameter (evaluated from left-to-right) is in EAX register,
+ //! all others on the stack in right-to-left order.
+ //!
+ //! Arguments direction:
+ //! - Right to Left (except to first one integer argument in EAX)
+ //!
+ //! Stack is cleaned by:
+ //! - Caller.
+ //!
+ //! Return value:
+ //! - Integer types - EAX:EDX registers.
+ //! - Floating points - fp0 register.
+ kX86FuncConvGccRegParm1 = 9,
+
+ //! GCC specific regparm(2) convention.
+ //!
+ //! Two first parameters (evaluated from left-to-right) are in EAX:EDX
+ //! registers, all others on the stack in right-to-left order.
+ //!
+ //! Arguments direction:
+ //! - Right to Left (except to first two integer arguments in EAX:EDX)
+ //!
+ //! Stack is cleaned by:
+ //! - Caller.
+ //!
+ //! Return value:
+ //! - Integer types - EAX:EDX registers.
+ //! - Floating points - fp0 register.
+ kX86FuncConvGccRegParm2 = 10,
+
+ //! GCC specific fastcall with 3 parameters in registers.
+ //!
+ //! Three first parameters (evaluated from left-to-right) are in
+ //! EAX:EDX:ECX registers, all others on the stack in right-to-left order.
+ //!
+ //! Arguments direction:
+ //! - Right to Left (except to first three integer arguments in EAX:EDX:ECX)
+ //!
+ //! Stack is cleaned by:
+ //! - Caller.
+ //!
+ //! Return value:
+ //! - Integer types - EAX:EDX registers.
+ //! - Floating points - fp0 register.
+ kX86FuncConvGccRegParm3 = 11,
+
+ //! \internal
+ //!
+ //! Count of function calling conventions.
+ _kX86FuncConvCount = 12
};
+#ifndef ASMJIT_DOCGEN
+// X86/X64 Host Support - documented in base/compiler.h.
+# ifdef ASMJIT_HOST_X86
+enum {
+ // X86.
+ kFuncConvHost = kX86FuncConvCDecl,
+ kFuncConvHostCDecl = kX86FuncConvCDecl,
+ kFuncConvHostStdCall = kX86FuncConvStdCall,
+# ifdef _MSC_VER
+ kFuncConvHostFastCall = kX86FuncConvMsFastCall
+# elif defined(__GNUC__)
+ kFuncConvHostFastCall = kX86FuncConvGccFastCall
+# elif defined(__BORLANDC__)
+ kFuncConvHostFastCall = kX86FuncConvBorlandFastCall
+# else
+# error "kFuncConvHostFastCall not determined."
+# endif
+};
+# endif // ASMJIT_HOST_X86
+
+# ifdef ASMJIT_HOST_X64
+enum {
+# ifdef ASMJIT_OS_WINDOWS
+ kFuncConvHost = kX86FuncConvW64,
+# else
+ kFuncConvHost = kX86FuncConvU64,
+# endif
+ kFuncConvHostCDecl = kFuncConvHost,
+ kFuncConvHostStdCall = kFuncConvHost,
+ kFuncConvHostFastCall = kFuncConvHost
+};
+# endif // ASMJIT_HOST_X64
+#endif // !ASMJIT_DOCGEN
+
// ============================================================================
-// [AsmJit::VarAllocRecord]
+// [asmjit::kX86FuncHint]
// ============================================================================
-//! @brief Variable alloc record (for each instruction that uses variables).
-//!
-//! Variable record contains pointer to variable data and register allocation
-//! flags. These flags are important to determine the best alloc instruction.
-struct VarAllocRecord
-{
- //! @brief Variable data (the structure owned by @c Compiler).
- X86CompilerVar *vdata;
- //! @brief Variable alloc flags, see @c kVarAllocFlags.
- uint32_t vflags;
- //! @brief Register mask (default is 0).
- uint32_t regMask;
+//! X86 function hints.
+ASMJIT_ENUM(kX86FuncHint) {
+ //! Use push/pop sequences instead of mov sequences in function prolog
+ //! and epilog.
+ kX86FuncHintPushPop = 16,
+ //! Add emms instruction to the function epilog.
+ kX86FuncHintEmms = 17,
+ //! Add sfence instruction to the function epilog.
+ kX86FuncHintSFence = 18,
+ //! Add lfence instruction to the function epilog.
+ kX86FuncHintLFence = 19
};
// ============================================================================
-// [AsmJit::VarCallRecord]
+// [asmjit::kX86FuncFlags]
// ============================================================================
-//! @brief Variable call-fn record (for each callable that uses variables).
-//!
-//! This record contains variables that are used to call a function (using
-//! @c X86CompilerFuncCall item). Each variable contains the registers where
-//! it must be and registers where the value will be returned.
-struct VarCallRecord
-{
- //! @brief Variable data (the structure owned by @c Compiler).
- X86CompilerVar *vdata;
- uint32_t flags;
-
- uint8_t inCount;
- uint8_t inDone;
-
- uint8_t outCount;
- uint8_t outDone;
-
- enum FLAGS
- {
- kFlagInGp = 0x0001,
- kFlagInMm = 0x0002,
- kFlagInXmm = 0x0004,
- kFlagInStack = 0x0008,
-
- kFlagOutEax = 0x0010,
- kFlagOutEdx = 0x0020,
- kFlagOutSt0 = 0x0040,
- kFlagOutSt1 = 0x0080,
- kFlagOutMm0 = 0x0100,
- kFlagOutXmm0 = 0x0400,
- kFlagOutXmm1 = 0x0800,
-
- kFlagInMemPtr = 0x1000,
- kFlagCallReg = 0x2000,
- kFlagCallMem = 0x4000,
- kFlagUnuseAfterUse = 0x8000
- };
+//! X86 function flags.
+ASMJIT_ENUM(kX86FuncFlags) {
+ //! Whether to emit register load/save sequence using push/pop pairs.
+ kX86FuncFlagPushPop = 0x00010000,
+
+ //! Whether to emit `enter` instead of three instructions in case
+ //! that the function is not naked or misaligned.
+ kX86FuncFlagEnter = 0x00020000,
+
+ //! Whether to emit `leave` instead of two instructions in case
+ //! that the function is not naked or misaligned.
+ kX86FuncFlagLeave = 0x00040000,
+
+ //! Whether it's required to move arguments to a new stack location,
+ //! because of manual aligning.
+ kX86FuncFlagMoveArgs = 0x00080000,
+
+ //! Whether to emit `emms` instruction in epilog (auto-detected).
+ kX86FuncFlagEmms = 0x01000000,
+
+ //! Whether to emit `sfence` instruction in epilog (auto-detected).
+ //!
+ //! `kX86FuncFlagSFence` with `kX86FuncFlagLFence` results in emitting `mfence`.
+ kX86FuncFlagSFence = 0x02000000,
+
+ //! Whether to emit `lfence` instruction in epilog (auto-detected).
+ //!
+ //! `kX86FuncFlagSFence` with `kX86FuncFlagLFence` results in emitting `mfence`.
+ kX86FuncFlagLFence = 0x04000000
};
// ============================================================================
-// [AsmJit::VarHintRecord]
+// [asmjit::X86VarInfo]
// ============================================================================
-struct VarHintRecord
-{
- X86CompilerVar *vdata;
- uint32_t hint;
+//! \internal
+//!
+//! X86 variable information.
+struct X86VarInfo {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get register type, see `kX86RegType`.
+ ASMJIT_INLINE uint32_t getReg() const { return _reg; }
+ //! Get register size in bytes.
+ ASMJIT_INLINE uint32_t getSize() const { return _size; }
+ //! Get variable class, see `kRegClass`.
+ ASMJIT_INLINE uint32_t getClass() const { return _class; }
+ //! Get variable description, see `kVarFlag`.
+ ASMJIT_INLINE uint32_t getDesc() const { return _desc; }
+ //! Get variable type name.
+ ASMJIT_INLINE const char* getName() const { return _name; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Register type, see `kX86RegType`.
+ uint8_t _reg;
+ //! Register size in bytes.
+ uint8_t _size;
+ //! Register class, see `kRegClass`.
+ uint8_t _class;
+ //! Variable flags, see `kVarFlag`.
+ uint8_t _desc;
+ //! Variable type name.
+ char _name[4];
};
+//! \internal
+ASMJIT_VAR const X86VarInfo _x86VarInfo[];
+
+#ifdef ASMJIT_BUILD_X86
+//! \internal
+//!
+//! Mapping of x86 variables into their real IDs.
+//!
+//! This mapping translates the following:
+//! - `kVarTypeInt64` to `kInvalidVar`.
+//! - `kVarTypeUInt64` to `kInvalidVar`.
+//! - `kVarTypeIntPtr` to `kVarTypeInt32`.
+//! - `kVarTypeUIntPtr` to `kVarTypeUInt32`.
+ASMJIT_VAR const uint8_t _x86VarMapping[kX86VarTypeCount];
+#endif // ASMJIT_BUILD_X86
+
+#ifdef ASMJIT_BUILD_X64
+//! \internal
+//!
+//! Mapping of x64 variables into their real IDs.
+//!
+//! This mapping translates the following:
+//! - `kVarTypeIntPtr` to `kVarTypeInt64`.
+//! - `kVarTypeUIntPtr` to `kVarTypeUInt64`.
+ASMJIT_VAR const uint8_t _x64VarMapping[kX86VarTypeCount];
+#endif // ASMJIT_BUILD_X64
+
// ============================================================================
-// [AsmJit::ForwardJumpData]
+// [asmjit::X86Var]
// ============================================================================
-struct ForwardJumpData
-{
- X86CompilerJmpInst *inst;
- X86CompilerState *state;
- ForwardJumpData *next;
+//! Base class for all X86 variables.
+struct X86Var : public Var {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE X86Var() : Var(NoInit) {
+ reset();
+ }
+
+ ASMJIT_INLINE X86Var(const X86Var& other) : Var(other) {}
+
+ explicit ASMJIT_INLINE X86Var(const _NoInit&) : Var(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [X86Var Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone X86Var operand.
+ ASMJIT_INLINE X86Var clone() const {
+ return X86Var(*this);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Type]
+ // --------------------------------------------------------------------------
+
+ //! Get register type.
+ ASMJIT_INLINE uint32_t getRegType() const { return _vreg.type; }
+ //! Get variable type.
+ ASMJIT_INLINE uint32_t getVarType() const { return _vreg.vType; }
+
+ //! Get whether the variable is Gp register.
+ ASMJIT_INLINE bool isGp() const { return _vreg.type <= kX86RegTypeGpq; }
+ //! Get whether the variable is Gpb (8-bit) register.
+ ASMJIT_INLINE bool isGpb() const { return _vreg.type <= kX86RegTypeGpbHi; }
+ //! Get whether the variable is Gpb-lo (8-bit) register.
+ ASMJIT_INLINE bool isGpbLo() const { return _vreg.type == kX86RegTypeGpbLo; }
+ //! Get whether the variable is Gpb-hi (8-bit) register.
+ ASMJIT_INLINE bool isGpbHi() const { return _vreg.type == kX86RegTypeGpbHi; }
+ //! Get whether the variable is Gpw (16-bit) register.
+ ASMJIT_INLINE bool isGpw() const { return _vreg.type == kX86RegTypeGpw; }
+ //! Get whether the variable is Gpd (32-bit) register.
+ ASMJIT_INLINE bool isGpd() const { return _vreg.type == kX86RegTypeGpd; }
+ //! Get whether the variable is Gpq (64-bit) register.
+ ASMJIT_INLINE bool isGpq() const { return _vreg.type == kX86RegTypeGpq; }
+
+ //! Get whether the variable is Mm (64-bit) register.
+ ASMJIT_INLINE bool isMm() const { return _vreg.type == kX86RegTypeMm; }
+ //! Get whether the variable is Xmm (128-bit) register.
+ ASMJIT_INLINE bool isXmm() const { return _vreg.type == kX86RegTypeXmm; }
+ //! Get whether the variable is Ymm (256-bit) register.
+ ASMJIT_INLINE bool isYmm() const { return _vreg.type == kX86RegTypeYmm; }
+ //! Get whether the variable is Zmm (512-bit) register.
+ ASMJIT_INLINE bool isZmm() const { return _vreg.type == kX86RegTypeZmm; }
+
+ // --------------------------------------------------------------------------
+ // [Memory Cast]
+ // --------------------------------------------------------------------------
+
+ //! Cast this variable to a memory operand.
+ //!
+ //! \note Size of operand depends on native variable type, you can use other
+ //! variants if you want specific one.
+ ASMJIT_INLINE X86Mem m(int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, disp, getSize());
+ }
+
+ //! \overload
+ ASMJIT_INLINE X86Mem m(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, getSize());
+ }
+
+ //! Cast this variable to 8-bit memory operand.
+ ASMJIT_INLINE X86Mem m8(int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, disp, 1);
+ }
+
+ //! \overload
+ ASMJIT_INLINE X86Mem m8(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 1);
+ }
+
+ //! Cast this variable to 16-bit memory operand.
+ ASMJIT_INLINE X86Mem m16(int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, disp, 2);
+ }
+
+ //! \overload
+ ASMJIT_INLINE X86Mem m16(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 2);
+ }
+
+ //! Cast this variable to 32-bit memory operand.
+ ASMJIT_INLINE X86Mem m32(int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, disp, 4);
+ }
+
+ //! \overload
+ ASMJIT_INLINE X86Mem m32(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 4);
+ }
+
+ //! Cast this variable to 64-bit memory operand.
+ ASMJIT_INLINE X86Mem m64(int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, disp, 8);
+ }
+
+ //! \overload
+ ASMJIT_INLINE X86Mem m64(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 8);
+ }
+
+ //! Cast this variable to 80-bit memory operand (long double).
+ ASMJIT_INLINE X86Mem m80(int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, disp, 10);
+ }
+
+ //! \overload
+ ASMJIT_INLINE X86Mem m80(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 10);
+ }
+
+ //! Cast this variable to 128-bit memory operand.
+ ASMJIT_INLINE X86Mem m128(int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, disp, 16);
+ }
+
+ //! \overload
+ ASMJIT_INLINE X86Mem m128(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 16);
+ }
+
+ //! Cast this variable to 256-bit memory operand.
+ ASMJIT_INLINE X86Mem m256(int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, disp, 32);
+ }
+
+ //! \overload
+ ASMJIT_INLINE X86Mem m256(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 32);
+ }
+
+ //! Cast this variable to 256-bit memory operand.
+ ASMJIT_INLINE X86Mem m512(int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, disp, 64);
+ }
+
+ //! \overload
+ ASMJIT_INLINE X86Mem m512(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const {
+ return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 64);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE X86Var& operator=(const X86Var& other) {
+ _copy(other);
+ return *this;
+ }
+
+ ASMJIT_INLINE bool operator==(const X86Var& other) const {
+ return _packed[0] == other._packed[0];
+ }
+
+ ASMJIT_INLINE bool operator!=(const X86Var& other) const {
+ return _packed[0] != other._packed[0];
+ }
+
+ // --------------------------------------------------------------------------
+ // [Private]
+ // --------------------------------------------------------------------------
+
+protected:
+ ASMJIT_INLINE X86Var(const X86Var& other, uint32_t reg, uint32_t size) : Var(NoInit) {
+ _init_packed_op_sz_w0_id(kOperandTypeVar, size, (reg << 8) + other._vreg.index, other._base.id);
+ _vreg.vType = other._vreg.vType;
+ }
};
// ============================================================================
-// [AsmJit::CompilerUtil]
+// [asmjit::X86GpVar]
// ============================================================================
-//! @brief Static class that contains utility methods.
-struct CompilerUtil
-{
- ASMJIT_API static bool isStack16ByteAligned();
+//! Gp variable.
+struct X86GpVar : public X86Var {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new uninitialized `X86GpVar` instance.
+ ASMJIT_INLINE X86GpVar() : X86Var() {}
+
+ //! Create a new initialized `X86GpVar` instance.
+ ASMJIT_INLINE X86GpVar(Compiler& c, uint32_t type = kVarTypeIntPtr, const char* name = nullptr) : X86Var(NoInit) {
+ c._newVar(this, type, name);
+ }
+
+ //! Create a clone of `other`.
+ ASMJIT_INLINE X86GpVar(const X86GpVar& other) : X86Var(other) {}
+
+ //! Create a new uninitialized `X86GpVar` instance (internal).
+ explicit ASMJIT_INLINE X86GpVar(const _NoInit&) : X86Var(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [X86GpVar Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone X86GpVar operand.
+ ASMJIT_INLINE X86GpVar clone() const {
+ return X86GpVar(*this);
+ }
+
+ //! Reset X86GpVar operand.
+ ASMJIT_INLINE void reset() {
+ X86Var::reset();
+ }
+
+ // --------------------------------------------------------------------------
+ // [X86GpVar Cast]
+ // --------------------------------------------------------------------------
+
+ //! Cast this variable to 8-bit (LO) part of variable
+ ASMJIT_INLINE X86GpVar r8() const { return X86GpVar(*this, kX86RegTypeGpbLo, 1); }
+ //! Cast this variable to 8-bit (LO) part of variable
+ ASMJIT_INLINE X86GpVar r8Lo() const { return X86GpVar(*this, kX86RegTypeGpbLo, 1); }
+ //! Cast this variable to 8-bit (HI) part of variable
+ ASMJIT_INLINE X86GpVar r8Hi() const { return X86GpVar(*this, kX86RegTypeGpbHi, 1); }
+
+ //! Cast this variable to 16-bit part of variable
+ ASMJIT_INLINE X86GpVar r16() const { return X86GpVar(*this, kX86RegTypeGpw, 2); }
+ //! Cast this variable to 32-bit part of variable
+ ASMJIT_INLINE X86GpVar r32() const { return X86GpVar(*this, kX86RegTypeGpd, 4); }
+ //! Cast this variable to 64-bit part of variable
+ ASMJIT_INLINE X86GpVar r64() const { return X86GpVar(*this, kX86RegTypeGpq, 8); }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE X86GpVar& operator=(const X86GpVar& other) { _copy(other); return *this; }
+
+ ASMJIT_INLINE bool operator==(const X86GpVar& other) const { return X86Var::operator==(other); }
+ ASMJIT_INLINE bool operator!=(const X86GpVar& other) const { return X86Var::operator!=(other); }
+
+ // --------------------------------------------------------------------------
+ // [Private]
+ // --------------------------------------------------------------------------
+
+protected:
+ ASMJIT_INLINE X86GpVar(const X86GpVar& other, uint32_t reg, uint32_t size) : X86Var(other, reg, size) {}
};
// ============================================================================
-// [AsmJit::X86Compiler]
+// [asmjit::X86MmVar]
// ============================================================================
-//! @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.
-//!
-//! @section AsmJit_Compiler_TheStory The Story
+//! Mm variable.
+struct X86MmVar : public X86Var {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new uninitialized `X86MmVar` instance.
+ ASMJIT_INLINE X86MmVar() : X86Var() {}
+ //! Create a new initialized `X86MmVar` instance.
+ ASMJIT_INLINE X86MmVar(Compiler& c, uint32_t type = kX86VarTypeMm, const char* name = nullptr) : X86Var(NoInit) {
+ c._newVar(this, type, name);
+ }
+
+ //! Create a clone of `other`.
+ ASMJIT_INLINE X86MmVar(const X86MmVar& other) : X86Var(other) {}
+
+ //! Create a new uninitialized `X86MmVar` instance (internal).
+ explicit ASMJIT_INLINE X86MmVar(const _NoInit&) : X86Var(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [X86MmVar Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone X86MmVar operand.
+ ASMJIT_INLINE X86MmVar clone() const {
+ return X86MmVar(*this);
+ }
+
+ //! Reset X86MmVar operand.
+ ASMJIT_INLINE void reset() {
+ X86Var::reset();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE X86MmVar& operator=(const X86MmVar& other) { _copy(other); return *this; }
+
+ ASMJIT_INLINE bool operator==(const X86MmVar& other) const { return X86Var::operator==(other); }
+ ASMJIT_INLINE bool operator!=(const X86MmVar& other) const { return X86Var::operator!=(other); }
+};
+
+// ============================================================================
+// [asmjit::X86XmmVar]
+// ============================================================================
+
+//! Xmm variable.
+struct X86XmmVar : public X86Var {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new uninitialized `X86XmmVar` instance.
+ ASMJIT_INLINE X86XmmVar() : X86Var() {}
+ //! Create a new initialized `X86XmmVar` instance.
+ ASMJIT_INLINE X86XmmVar(Compiler& c, uint32_t type = kX86VarTypeXmm, const char* name = nullptr) : X86Var(NoInit) {
+ c._newVar(this, type, name);
+ }
+
+ //! Create a clone of `other`.
+ ASMJIT_INLINE X86XmmVar(const X86XmmVar& other) : X86Var(other) {}
+
+ //! Create a new uninitialized `X86XmmVar` instance (internal).
+ explicit ASMJIT_INLINE X86XmmVar(const _NoInit&) : X86Var(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [X86XmmVar Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone X86XmmVar operand.
+ ASMJIT_INLINE X86XmmVar clone() const {
+ return X86XmmVar(*this);
+ }
+
+ //! Reset X86XmmVar operand.
+ ASMJIT_INLINE void reset() {
+ X86Var::reset();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE X86XmmVar& operator=(const X86XmmVar& other) { _copy(other); return *this; }
+
+ ASMJIT_INLINE bool operator==(const X86XmmVar& other) const { return X86Var::operator==(other); }
+ ASMJIT_INLINE bool operator!=(const X86XmmVar& other) const { return X86Var::operator!=(other); }
+};
+
+// ============================================================================
+// [asmjit::X86YmmVar]
+// ============================================================================
+
+//! Ymm variable.
+struct X86YmmVar : public X86Var {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new uninitialized `X86YmmVar` instance.
+ ASMJIT_INLINE X86YmmVar() : X86Var() {}
+ //! Create a new initialized `X86YmmVar` instance.
+ ASMJIT_INLINE X86YmmVar(Compiler& c, uint32_t type = kX86VarTypeYmm, const char* name = nullptr) : X86Var(NoInit) {
+ c._newVar(this, type, name);
+ }
+
+ //! Create a clone of `other`.
+ ASMJIT_INLINE X86YmmVar(const X86YmmVar& other) : X86Var(other) {}
+
+ //! Create a new uninitialized `X86YmmVar` instance (internal).
+ explicit ASMJIT_INLINE X86YmmVar(const _NoInit&) : X86Var(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [X86YmmVar Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone X86YmmVar operand.
+ ASMJIT_INLINE X86YmmVar clone() const {
+ return X86YmmVar(*this);
+ }
+
+ //! Reset X86YmmVar operand.
+ ASMJIT_INLINE void reset() {
+ X86Var::reset();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE X86YmmVar& operator=(const X86YmmVar& other) { _copy(other); return *this; }
+
+ ASMJIT_INLINE bool operator==(const X86YmmVar& other) const { return X86Var::operator==(other); }
+ ASMJIT_INLINE bool operator!=(const X86YmmVar& other) const { return X86Var::operator!=(other); }
+};
+
+// ============================================================================
+// [asmjit::X86VarMap]
+// ============================================================================
+
+struct X86VarMap : public VarMap {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get variable-attributes list as VarAttr data.
+ ASMJIT_INLINE VarAttr* getVaList() const {
+ return const_cast<VarAttr*>(_list);
+ }
+
+ //! Get variable-attributes list as VarAttr data (by class).
+ ASMJIT_INLINE VarAttr* getVaListByClass(uint32_t c) const {
+ return const_cast<VarAttr*>(_list) + _start.get(c);
+ }
+
+ //! Get position of variables (by class).
+ ASMJIT_INLINE uint32_t getVaStart(uint32_t c) const {
+ return _start.get(c);
+ }
+
+ //! Get count of variables (by class).
+ ASMJIT_INLINE uint32_t getVaCountByClass(uint32_t c) const {
+ return _count.get(c);
+ }
+
+ //! Get VarAttr at `index`.
+ ASMJIT_INLINE VarAttr* getVa(uint32_t index) const {
+ ASMJIT_ASSERT(index < _vaCount);
+ return getVaList() + index;
+ }
+
+ //! Get VarAttr of `c` class at `index`.
+ ASMJIT_INLINE VarAttr* getVaByClass(uint32_t c, uint32_t index) const {
+ ASMJIT_ASSERT(index < _count._regs[c]);
+ return getVaListByClass(c) + index;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Utils]
+ // --------------------------------------------------------------------------
+
+ //! Find VarAttr.
+ ASMJIT_INLINE VarAttr* findVa(VarData* vd) const {
+ VarAttr* list = getVaList();
+ uint32_t count = getVaCount();
+
+ for (uint32_t i = 0; i < count; i++)
+ if (list[i].getVd() == vd)
+ return &list[i];
+
+ return nullptr;
+ }
+
+ //! Find VarAttr (by class).
+ ASMJIT_INLINE VarAttr* findVaByClass(uint32_t c, VarData* vd) const {
+ VarAttr* list = getVaListByClass(c);
+ uint32_t count = getVaCountByClass(c);
+
+ for (uint32_t i = 0; i < count; i++)
+ if (list[i].getVd() == vd)
+ return &list[i];
+
+ return nullptr;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Special registers on input.
+ //!
+ //! Special register(s) restricted to one or more physical register. If there
+ //! is more than one special register it means that we have to duplicate the
+ //! variable content to all of them (it means that the same varible was used
+ //! by two or more operands). We forget about duplicates after the register
+ //! allocation finishes and marks all duplicates as non-assigned.
+ X86RegMask _inRegs;
+
+ //! Special registers on output.
+ //!
+ //! Special register(s) used on output. Each variable can have only one
+ //! special register on the output, 'X86VarMap' contains all registers from
+ //! all 'VarAttr's.
+ X86RegMask _outRegs;
+
+ //! Clobbered registers (by a function call).
+ X86RegMask _clobberedRegs;
+
+ //! Start indexes of variables per register class.
+ X86RegCount _start;
+ //! Count of variables per register class.
+ X86RegCount _count;
+
+ //! VarAttr list.
+ VarAttr _list[1];
+};
+
+// ============================================================================
+// [asmjit::X86StateCell]
+// ============================================================================
+
+//! X86/X64 state-cell.
+union X86StateCell {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE uint32_t getState() const {
+ return _state;
+ }
+
+ ASMJIT_INLINE void setState(uint32_t state) {
+ _state = static_cast<uint8_t>(state);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void reset() { _packed = 0; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ uint8_t _packed;
+
+ struct {
+ uint8_t _state : 2;
+ uint8_t _unused : 6;
+ };
+};
+
+// ============================================================================
+// [asmjit::X86VarState]
+// ============================================================================
+
+//! X86/X64 state.
+struct X86VarState : VarState {
+ enum {
+ //! Base index of Gp registers.
+ kGpIndex = 0,
+ //! Count of Gp registers.
+ kGpCount = 16,
+
+ //! Base index of Mm registers.
+ kMmIndex = kGpIndex + kGpCount,
+ //! Count of Mm registers.
+ kMmCount = 8,
+
+ //! Base index of Xmm registers.
+ kXmmIndex = kMmIndex + kMmCount,
+ //! Count of Xmm registers.
+ kXmmCount = 16,
+
+ //! Count of all registers in `X86VarState`.
+ kAllCount = kXmmIndex + kXmmCount
+ };
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE VarData** getList() {
+ return _list;
+ }
+
+ ASMJIT_INLINE VarData** getListByClass(uint32_t c) {
+ switch (c) {
+ case kX86RegClassGp : return _listGp;
+ case kX86RegClassMm : return _listMm;
+ case kX86RegClassXyz: return _listXmm;
+
+ default:
+ return nullptr;
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // [Clear]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void reset(size_t numCells) {
+ ::memset(this, 0, kAllCount * sizeof(VarData*) +
+ 2 * sizeof(X86RegMask) +
+ numCells * sizeof(X86StateCell));
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ union {
+ //! List of all allocated variables in one array.
+ VarData* _list[kAllCount];
+
+ struct {
+ //! Allocated Gp registers.
+ VarData* _listGp[kGpCount];
+ //! Allocated Mm registers.
+ VarData* _listMm[kMmCount];
+ //! Allocated Xmm registers.
+ VarData* _listXmm[kXmmCount];
+ };
+ };
+
+ //! Occupied registers (mask).
+ X86RegMask _occupied;
+ //! Modified registers (mask).
+ X86RegMask _modified;
+
+ //! Variables data, the length is stored in `X86Context`.
+ X86StateCell _cells[1];
+};
+
+// ============================================================================
+// [asmjit::X86FuncDecl]
+// ============================================================================
+
+//! X86 function, including calling convention, arguments and their
+//! register indices or stack positions.
+struct X86FuncDecl : public FuncDecl {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `X86FuncDecl` instance.
+ ASMJIT_INLINE X86FuncDecl() {
+ reset();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - X86]
+ // --------------------------------------------------------------------------
+
+ //! Get used registers (mask).
+ //!
+ //! \note The result depends on the function calling convention AND the
+ //! function prototype. Returned mask contains only registers actually used
+ //! to pass function arguments.
+ ASMJIT_INLINE uint32_t getUsed(uint32_t c) const {
+ return _used.get(c);
+ }
+
+ //! Get passed registers (mask).
+ //!
+ //! \note The result depends on the function calling convention used; the
+ //! prototype of the function doesn't affect the mask returned.
+ ASMJIT_INLINE uint32_t getPassed(uint32_t c) const {
+ return _passed.get(c);
+ }
+
+ //! Get preserved registers (mask).
+ //!
+ //! \note The result depends on the function calling convention used; the
+ //! prototype of the function doesn't affect the mask returned.
+ ASMJIT_INLINE uint32_t getPreserved(uint32_t c) const {
+ return _preserved.get(c);
+ }
+
+ //! Get ther order of passed registers (Gp).
+ //!
+ //! \note The result depends on the function calling convention used; the
+ //! prototype of the function doesn't affect the mask returned.
+ ASMJIT_INLINE const uint8_t* getPassedOrderGp() const {
+ return _passedOrderGp;
+ }
+
+ //! Get ther order of passed registers (Xmm).
+ //!
+ //! \note The result depends on the function calling convention used; the
+ //! prototype of the function doesn't affect the mask returned.
+ ASMJIT_INLINE const uint8_t* getPassedOrderXmm() const {
+ return _passedOrderXmm;
+ }
+
+ // --------------------------------------------------------------------------
+ // [SetPrototype]
+ // --------------------------------------------------------------------------
+
+ //! Set function prototype.
+ //!
+ //! This will set function calling convention and setup arguments variables.
+ //!
+ //! \note This function will allocate variables, it can be called only once.
+ ASMJIT_API Error setPrototype(uint32_t conv, const FuncPrototype& p);
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API void reset();
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Used registers.
+ X86RegMask _used;
+
+ //! Passed registers (defined by the calling convention).
+ X86RegMask _passed;
+ //! Preserved registers (defined by the calling convention).
+ X86RegMask _preserved;
+
+ //! Order of registers defined to pass function arguments (Gp).
+ uint8_t _passedOrderGp[8];
+ //! Order of registers defined to pass function arguments (Xmm).
+ uint8_t _passedOrderXmm[8];
+};
+
+// ============================================================================
+// [asmjit::X86FuncNode]
+// ============================================================================
+
+//! X86/X64 function node.
+struct X86FuncNode : public FuncNode {
+ ASMJIT_NO_COPY(X86FuncNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `X86FuncNode` instance.
+ ASMJIT_INLINE X86FuncNode(Compiler* compiler) : FuncNode(compiler) {
+ _decl = &_x86Decl;
+ _saveRestoreRegs.reset();
+
+ _alignStackSize = 0;
+ _alignedMemStackSize = 0;
+ _pushPopStackSize = 0;
+ _moveStackSize = 0;
+ _extraStackSize = 0;
+
+ _stackFrameRegIndex = kInvalidReg;
+ _isStackFrameRegPreserved = false;
+ _stackFrameCopyGpIndex[0] = kInvalidReg;
+ _stackFrameCopyGpIndex[1] = kInvalidReg;
+ _stackFrameCopyGpIndex[2] = kInvalidReg;
+ _stackFrameCopyGpIndex[3] = kInvalidReg;
+ _stackFrameCopyGpIndex[4] = kInvalidReg;
+ _stackFrameCopyGpIndex[5] = kInvalidReg;
+ }
+
+ //! Destroy the `X86FuncNode` instance.
+ ASMJIT_INLINE ~X86FuncNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get function declaration as `X86FuncDecl`.
+ ASMJIT_INLINE X86FuncDecl* getDecl() const {
+ return const_cast<X86FuncDecl*>(&_x86Decl);
+ }
+
+ //! Get argument.
+ ASMJIT_INLINE VarData* getArg(uint32_t i) const {
+ ASMJIT_ASSERT(i < _x86Decl.getArgCount());
+ return static_cast<VarData*>(_argList[i]);
+ }
+
+ //! Get registers which have to be saved in prolog/epilog.
+ ASMJIT_INLINE uint32_t getSaveRestoreRegs(uint32_t c) { return _saveRestoreRegs.get(c); }
+
+ //! Get stack size needed to align stack back to the nature alignment.
+ ASMJIT_INLINE uint32_t getAlignStackSize() const { return _alignStackSize; }
+ //! Set stack size needed to align stack back to the nature alignment.
+ ASMJIT_INLINE void setAlignStackSize(uint32_t s) { _alignStackSize = s; }
+
+ //! Get aligned stack size used by variables and memory allocated on the stack.
+ ASMJIT_INLINE uint32_t getAlignedMemStackSize() const { return _alignedMemStackSize; }
+
+ //! Get stack size used by push/pop sequences in prolog/epilog.
+ ASMJIT_INLINE uint32_t getPushPopStackSize() const { return _pushPopStackSize; }
+ //! Set stack size used by push/pop sequences in prolog/epilog.
+ ASMJIT_INLINE void setPushPopStackSize(uint32_t s) { _pushPopStackSize = s; }
+
+ //! Get stack size used by mov sequences in prolog/epilog.
+ ASMJIT_INLINE uint32_t getMoveStackSize() const { return _moveStackSize; }
+ //! Set stack size used by mov sequences in prolog/epilog.
+ ASMJIT_INLINE void setMoveStackSize(uint32_t s) { _moveStackSize = s; }
+
+ //! Get extra stack size.
+ ASMJIT_INLINE uint32_t getExtraStackSize() const { return _extraStackSize; }
+ //! Set extra stack size.
+ ASMJIT_INLINE void setExtraStackSize(uint32_t s) { _extraStackSize = s; }
+
+ //! Get whether the function has stack frame register.
+ //!
+ //! \note Stack frame register can be used for both - aligning purposes or
+ //! generating standard prolog/epilog sequence.
+ //!
+ //! \note Used only when stack is misaligned.
+ ASMJIT_INLINE bool hasStackFrameReg() const { return _stackFrameRegIndex != kInvalidReg; }
+ //! Get stack frame register index.
+ //!
+ //! \note Used only when stack is misaligned.
+ ASMJIT_INLINE uint32_t getStackFrameRegIndex() const { return _stackFrameRegIndex; }
+ //! Get whether the stack frame register is preserved.
+ //!
+ //! \note Used only when stack is misaligned.
+ ASMJIT_INLINE bool isStackFrameRegPreserved() const { return static_cast<bool>(_isStackFrameRegPreserved); }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! X86 function decl.
+ X86FuncDecl _x86Decl;
+ //! Registers which must be saved/restored in prolog/epilog.
+ X86RegMask _saveRestoreRegs;
+
+ //! Stack size needed to align function back to the nature alignment.
+ uint32_t _alignStackSize;
+ //! Like `_memStackSize`, but aligned.
+ uint32_t _alignedMemStackSize;
+
+ //! Stack required for push/pop in prolog/epilog (X86/X64 specific).
+ uint32_t _pushPopStackSize;
+ //! Stack required for movs in prolog/epilog (X86/X64 specific).
+ uint32_t _moveStackSize;
+
+ //! Stack required to put extra data (for example function arguments
+ //! when manually aligning to requested alignment).
+ uint32_t _extraStackSize;
+
+ //! Stack frame register.
+ uint8_t _stackFrameRegIndex;
+ //! Whether the stack frame register is preserved.
+ uint8_t _isStackFrameRegPreserved;
+ //! Gp registers indexes that can be used to copy function arguments
+ //! to a new location in case we are doing manual stack alignment.
+ uint8_t _stackFrameCopyGpIndex[6];
+};
+
+// ============================================================================
+// [asmjit::X86CallNode]
+// ============================================================================
+
+//! X86/X64 function-call node.
+struct X86CallNode : public CallNode {
+ ASMJIT_NO_COPY(X86CallNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `X86CallNode` instance.
+ ASMJIT_INLINE X86CallNode(Compiler* compiler, const Operand& target) : CallNode(compiler, target) {
+ _decl = &_x86Decl;
+ _usedArgs.reset();
+ }
+
+ //! Destroy the `X86CallNode` instance.
+ ASMJIT_INLINE ~X86CallNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get function prototype.
+ ASMJIT_INLINE X86FuncDecl* getDecl() const {
+ return const_cast<X86FuncDecl*>(&_x86Decl);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Prototype]
+ // --------------------------------------------------------------------------
+
+ //! Set function prototype.
+ ASMJIT_API Error setPrototype(uint32_t conv, const FuncPrototype& p);
+
+ // --------------------------------------------------------------------------
+ // [Arg / Ret]
+ // --------------------------------------------------------------------------
+
+ //! Set argument at `i` to `op`.
+ ASMJIT_API bool _setArg(uint32_t i, const Operand& op);
+ //! Set return at `i` to `op`.
+ ASMJIT_API bool _setRet(uint32_t i, const Operand& op);
+
+ //! Set argument at `i` to `var`.
+ ASMJIT_INLINE bool setArg(uint32_t i, const Var& var) { return _setArg(i, var); }
+ //! Set argument at `i` to `reg` (FP registers only).
+ ASMJIT_INLINE bool setArg(uint32_t i, const X86FpReg& reg) { return _setArg(i, reg); }
+ //! Set argument at `i` to `imm`.
+ ASMJIT_INLINE bool setArg(uint32_t i, const Imm& imm) { return _setArg(i, imm); }
+
+ //! Set return at `i` to `var`.
+ ASMJIT_INLINE bool setRet(uint32_t i, const Var& var) { return _setRet(i, var); }
+ //! Set return at `i` to `reg` (FP registers only).
+ ASMJIT_INLINE bool setRet(uint32_t i, const X86FpReg& reg) { return _setRet(i, reg); }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! X86 declaration.
+ X86FuncDecl _x86Decl;
+ //! Mask of all registers actually used to pass function arguments.
+ //!
+ //! \note This bit-mask is not the same as `X86Func::_passed`. It contains
+ //! only registers actually used to do the call while `X86Func::_passed`
+ //! mask contains all registers for all function prototype combinations.
+ X86RegMask _usedArgs;
+};
+
+// ============================================================================
+// [asmjit::X86TypeId / VarMapping]
+// ============================================================================
+
+#ifndef ASMJIT_DOCGEN
+ASMJIT_TYPE_ID(X86MmReg, kX86VarTypeMm);
+ASMJIT_TYPE_ID(X86MmVar, kX86VarTypeMm);
+ASMJIT_TYPE_ID(X86XmmReg, kX86VarTypeXmm);
+ASMJIT_TYPE_ID(X86XmmVar, kX86VarTypeXmm);
+ASMJIT_TYPE_ID(X86YmmReg, kX86VarTypeYmm);
+ASMJIT_TYPE_ID(X86YmmVar, kX86VarTypeYmm);
+#endif // !ASMJIT_DOCGEN
+
+// ============================================================================
+// [asmjit::X86Compiler]
+// ============================================================================
+
+//! X86/X64 compiler.
+//!
+//! This class is used to store instruction stream and allows to modify it on
+//! the fly. It uses different concept than `Assembler` class and in fact
+//! `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.
+//!
+//! `X86Compiler` moves code generation to a higher level. Higher level
+//! constructs allows to write more abstract and extensible code that is not
+//! possible with pure `X86Assembler`.
+//!
+//! The Story
+//! ---------
//!
//! Before telling you how Compiler works I'd like to write a story. I'd like
-//! to cover reasons why this class was created and why I'm recommending to use
+//! to cover reasons why this class was created and why I'm recommending to use
//! it. When I released the first version of AsmJit (0.1) it was a toy. The
//! first function I wrote was function which is still available as testjit and
//! which simply returns 1024. The reason why function works for both 32-bit/
@@ -399,7 +1452,7 @@
//! Then I started a project called BlitJit which was targetted to generating
//! JIT code for computer graphics. After writing some lines I decided that I
//! can't join pieces of code together without abstraction, should be
-//! pixels source pointer in ESI/RSI or EDI/RDI or it's completelly
+//! pixels source pointer in ESI/RSI or EDI/RDI or it's completelly
//! irrellevant? What about destination pointer and SSE2 register for reading
//! input pixels? The simple answer might be "just pick some one and use it".
//!
@@ -415,31 +1468,31 @@
//!
//! The first version of AsmJit with Compiler was 0.5 (or 0.6?, can't remember).
//! There was support for 32-bit and 64-bit mode, function calling conventions,
-//! but when emitting instructions the developer needed to decide which
+//! but when emitting instructions the developer needed to decide which
//! registers are changed, which are only read or completely overwritten. This
//! model helped a lot when generating code, especially when joining more
//! code-sections together, but there was also small possibility for mistakes.
-//! Simply the first version of Compiler was great improvement over low-level
+//! Simply the first version of Compiler was great improvement over low-level
//! Assembler class, but the API design wasn't perfect.
//!
-//! The second version of Compiler, completelly rewritten and based on
+//! The second version of Compiler, completelly rewritten and based on
//! different goals, is part of AsmJit starting at version 1.0. This version
//! was designed after the first one and it contains serious improvements over
-//! the old one. The first improvement is that you just use instructions with
+//! the old one. The first improvement is that you just use instructions with
//! virtual registers - called variables. When using compiler there is no way
-//! to use native registers, there are variables instead. AsmJit is smarter
-//! than before and it knows which register is needed only for read (r),
-//! read/write (w) or overwrite (x). Supported are also instructions which
+//! to use native registers, there are variables instead. AsmJit is smarter
+//! than before and it knows which register is needed only for read (r),
+//! read/write (w) or overwrite (x). Supported are also instructions which
//! are using some registers in implicit way (these registers are not part of
-//! instruction definition in string form). For example to use CPUID instruction
-//! you must give it four variables which will be automatically allocated to
+//! instruction definition in string form). For example to use CPUID instruction
+//! you must give it four variables which will be automatically allocated in
//! input/output registers (EAX, EBX, ECX, EDX).
-//!
+//!
//! Another improvement is algorithm used by a register allocator. In first
//! version the registers were allocated when creating instruction stream. In
-//! new version registers are allocated after calling @c Compiler::make(). This
-//! means that register allocator has information about scope of all variables
-//! and their usage statistics. The algorithm to allocate registers is very
+//! new version registers are allocated after calling `Compiler::make()`,
+//! thus register allocator has information about scope of all variables and
+//! statistics of their usage. The algorithm to allocate registers is very
//! simple and it's always called as a 'linear scan register allocator'. When
//! you get out of registers the all possible variables are scored and the worst
//! is spilled. Of course algorithm ignores the variables used for current
@@ -447,209 +1500,211 @@
//!
//! In addition, because registers are allocated after the code stream is
//! generated, the state switches between jumps are handled by Compiler too.
-//! You don't need to worry about jumps, compiler always do this dirty work
+//! You don't need to worry about jumps, compiler always do this dirty work
//! for you.
//!
-//! The nearly last thing I'd like to present is calling other functions from
-//! the generated code. AsmJit uses a @c FunctionPrototype class to hold
-//! the function parameters, their position in stack (or register index) and
-//! function return value. This class is used internally, but it can be
-//! used to create your own function calling-convention. All standard function
-//! calling conventions are implemented.
+//! The nearly last thing I'd like to present is calling other functions from
+//! the generated code. AsmJit uses a `FuncPrototype` class to hold function
+//! parameters, their position in stack (or register index) and return value.
+//! This class is used internally, but it can be used to create your own
+//! function calling-convention. All standard function calling conventions are
+//! implemented.
//!
//! Please enjoy the new version of Compiler, it was created for writing a
-//! low-level code using high-level API, leaving developer to concentrate to
+//! low-level code using high-level API, leaving developer to concentrate on
//! real problems and not to solving a register puzzle.
//!
-//! @section AsmJit_Compiler_CodeGeneration Code Generation
+//! 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
+//! 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
+//! generate machine code directly without creating @c asmjit::Assembler
//! instance.
//!
//! Comparison of generating machine code through @c Assembler and directly
//! by @c Compiler:
//!
-//! @code
+//! ~~~
//! // Assembler instance is low level code generation class that emits
//! // machine code.
-//! X86Assembler a;
+//! Assembler a;
//!
//! // Compiler instance is high level code generation class that stores all
//! // instructions in internal representation.
-//! X86Compiler c;
+//! Compiler c;
//!
//! // ... put your code here ...
//!
-//! // Final step - generate code. AsmJit::Compiler::serialize() will serialize
-//! // all instructions into Assembler and this ensures generating real machine
-//! // code.
-//! c.serialize(a);
+//! // Final step - generate code. asmjit::Compiler::serialize() will send 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.
-//! X86Compiler c;
+//! Compiler c;
//!
//! // ... put your code here ...
//!
//! // 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
+//! ~~~
+//!
+//! 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).
-//!
-//! The @c make() method allocates memory using @c Context instance passed
-//! into the @c X86Compiler constructor. If code generator is used to create JIT
-//! function then virtual memory allocated by @c MemoryManager is used. To get
-//! global memory manager use @c MemoryManager::getGlobal().
-//!
-//! @code
-//! // Compiler instance is enough.
-//! X86Compiler c;
+//! duplication. For convenience there is also @c asmjit::Compiler::make()
+//! method that can create your function using @c asmjit::Assembler, but
+//! internally (this is preferred bahavior when using @c asmjit::Compiler).
+//!
+//! The @c make() method allocates memory using `Runtime` instance passed
+//! into the @c Compiler constructor. If code generator is used to create JIT
+//! function then virtual memory allocated by `VMemMgr` is used.
+//!
+//! ~~~
+//! JitRuntime runtime;
+//! Compiler c(&runtime);
//!
//! // ... 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::getGlobal()->free(fn);
-//! @endcode
-//!
-//! @section AsmJit_Compiler_Functions Functions
-//!
-//! To build functions with @c Compiler, see @c AsmJit::Compiler::newFunc()
+//! runtime.release(fn);
+//! ~~~
+//!
+//! Functions
+//! ---------
+//!
+//! To build functions with @c Compiler, see @c asmjit::Compiler::addFunc()
//! method.
//!
-//! @section AsmJit_Compiler_Variables Variables
-//!
-//! Compiler is able to manage variables and function arguments. Internally
-//! there is no difference between function argument and variable declared
-//! inside. To get function argument you use @c getGpArg() method and to declare
-//! variable use @c newGpVar(), @c newMmVar() and @c newXmmVar() methods. The @c newXXX()
-//! methods accept also parameter describing the variable type. For example
-//! the @c newGpVar() method always creates variable which size matches the target
-//! architecture size (for 32-bit target the 32-bit variable is created, for
-//! 64-bit target the variable size is 64-bit). To override this behavior the
-//! variable type must be specified.
-//!
-//! @code
+//! Variables
+//! ---------
+//!
+//! Compiler is able to manage variables and function arguments. Function
+//! arguments are moved to variables by using @c setArg() method, where the
+//! first parameter is argument index and second parameter is the variable
+//! instance. To declare variable use @c newGpVar(), @c newMmVar() and @c
+//! newXmmVar() methods. The @c newXXX() methods accept also parameter
+//! describing the variable type. For example the @c newGpVar() method always
+//! creates variable which size matches the target architecture size (for
+//! 32-bit target the 32-bit variable is created, for 64-bit target the
+//! variable size is 64-bit). To override this behavior the variable type
+//! must be specified.
+//!
+//! ~~~
//! // Compiler and function declaration - void f(int*);
-//! X86Compiler c;
-//! c.newFunc(kX86FuncConvDefault, BuildFunction1<int*>());
-//!
-//! // Get argument variable (it's pointer).
-//! GpVar a1(c.getGpArg(0));
+//! Compiler c;
+//! X86GpVar a0(c, kVarTypeIntPtr);
+//!
+//! c.addFunc(kFuncConvHost, FuncBuilder1<Void, int*>());
+//! c.setArg(0, a0);
//!
//! // Create your variables.
-//! GpVar x1(c.newGpVar(kX86VarTypeGpd));
-//! GpVar x2(c.newGpVar(kX86VarTypeGpd));
+//! X86GpVar x0(c, kVarTypeInt32);
+//! X86GpVar x1(c, kVarTypeInt32);
//!
//! // Init your variables.
-//! c.mov(x1, 1);
-//! c.mov(x2, 2);
+//! c.mov(x0, 1);
+//! c.mov(x1, 2);
//!
//! // ... your code ...
-//! c.add(x1, x2);
+//! c.add(x0, x1);
//! // ... your code ...
//!
//! // Store result to a given pointer in first argument
-//! c.mov(dword_ptr(a1), x1);
+//! c.mov(dword_ptr(a0), x0);
//!
//! // End of function body.
//! c.endFunc();
//!
//! // Make the function.
-//! typedef void (*MyFn)(int*);
-//! MyFn fn = asmjit_cast<MyFn>(c.make());
-//! @endcode
-//!
-//! This code snipped needs to be explained. You can see that there are more
-//! variable types that can be used by @c Compiler. Most useful variables can
-//! be allocated using general purpose registers (@c GpVar), MMX registers
-//! (@c MmVar) or SSE registers (@c XmmVar).
+//! typedef void (*MyFunc)(int*);
+//! MyFunc func = asmjit_cast<MyFunc>(c.make());
+//! ~~~
+//!
+//! This code snipped needs to be explained. You can see that there are more
+//! variable types that can be used by `Compiler`. Most useful variables can
+//! be allocated using general purpose registers (`X86GpVar`), MMX registers
+//! (`X86MmVar`) or SSE/SSE2 registers (`X86XmmVar`).
//!
//! X86/X64 variable types:
-//!
-//! - @c kX86VarTypeGpd - 32-bit general purpose register (EAX, EBX, ...).
-//! - @c kX86VarTypeGpq - 64-bit general purpose register (RAX, RBX, ...).
-//! - @c kX86VarTypeGpz - 32-bit or 64-bit general purpose register, depends
-//! to target architecture. Mapped to @c kX86VarTypeGpd or @c kX86VarTypeGpq.
-//!
-//! - @c kX86VarTypeX87 - 80-bit floating point stack register st(0 to 7).
-//! - @c kX86VarTypeX87SS - 32-bit floating point stack register st(0 to 7).
-//! - @c kX86VarTypeX87SD - 64-bit floating point stack register st(0 to 7).
-//!
-//! - @c VARIALBE_TYPE_MM - 64-bit MMX register.
-//!
-//! - @c kX86VarTypeXmm - 128-bit SSE register.
-//! - @c kX86VarTypeXmmSS - 128-bit SSE register which contains
-//! scalar 32-bit single precision floating point.
-//! - @c kX86VarTypeXmmSD - 128-bit SSE register which contains
-//! scalar 64-bit double precision floating point.
-//! - @c kX86VarTypeXmmPS - 128-bit SSE register which contains
-//! 4 packed 32-bit single precision floating points.
-//! - @c kX86VarTypeXmmPD - 128-bit SSE register which contains
-//! 2 packed 64-bit double precision floating points.
-//!
-//! Unified variable types:
-//!
-//! - @c kX86VarTypeInt32 - 32-bit general purpose register.
-//! - @c kX86VarTypeInt64 - 64-bit general purpose register.
-//! - @c kX86VarTypeIntPtr - 32-bit or 64-bit general purpose register / pointer.
-//!
-//! - @c kX86VarTypeFloat - 32-bit single precision floating point.
-//! - @c kX86VarTypeDouble - 64-bit double precision floating point.
+//!
+//! - `kVarTypeInt8` - Signed 8-bit integer, mapped to Gpd register (eax, ebx, ...).
+//! - `kVarTypeUInt8` - Unsigned 8-bit integer, mapped to Gpd register (eax, ebx, ...).
+//!
+//! - `kVarTypeInt16` - Signed 16-bit integer, mapped to Gpd register (eax, ebx, ...).
+//! - `kVarTypeUInt16` - Unsigned 16-bit integer, mapped to Gpd register (eax, ebx, ...).
+//!
+//! - `kVarTypeInt32` - Signed 32-bit integer, mapped to Gpd register (eax, ebx, ...).
+//! - `kVarTypeUInt32` - Unsigned 32-bit integer, mapped to Gpd register (eax, ebx, ...).
+//!
+//! - `kVarTypeInt64` - Signed 64-bit integer, mapped to Gpq register (rax, rbx, ...).
+//! - `kVarTypeUInt64` - Unsigned 64-bit integer, mapped to Gpq register (rax, rbx, ...).
+//!
+//! - `kVarTypeIntPtr` - intptr_t, mapped to Gpd/Gpq register; depends on target, not host!
+//! - `kVarTypeUIntPtr` - uintptr_t, mapped to Gpd/Gpq register; depends on target, not host!
+//!
+//! - `kVarTypeFp32` - 32-bit floating point register (fp0, fp1, ...).
+//! - `kVarTypeFp64` - 64-bit floating point register (fp0, fp1, ...).
+//!
+//! - `kX86VarTypeMm` - 64-bit Mm register (mm0, mm1, ...).
+//!
+//! - `kX86VarTypeXmm` - 128-bit SSE register.
+//! - `kX86VarTypeXmmSs` - 128-bit SSE register that contains a scalar 32-bit SP-FP value.
+//! - `kX86VarTypeXmmSd` - 128-bit SSE register that contains a scalar 64-bit DP-FP value.
+//! - `kX86VarTypeXmmPs` - 128-bit SSE register that contains 4 packed 32-bit SP-FP values.
+//! - `kX86VarTypeXmmPd` - 128-bit SSE register that contains 2 packed 64-bit DP-FP values.
+//!
+//! - `kX86VarTypeYmm` - 256-bit AVX register.
+//! - `kX86VarTypeYmmPs` - 256-bit AVX register that contains 4 packed 32-bit SP-FP values.
+//! - `kX86VarTypeYmmPd` - 256-bit AVX register that contains 2 packed 64-bit DP-FP values.
//!
//! Variable states:
//!
-//! - @c kVarStateUnused - State that is assigned to newly created
-//! variables or to not used variables (dereferenced to zero).
-//! - @c kVarStateReg - State that means that variable is currently
-//! allocated in register.
-//! - @c kVarStateMem - State that means that variable is currently
-//! only in memory location.
-//!
-//! When you create new variable, initial state is always @c kVarStateUnused,
+//! - `kVarStateUnused - State that is assigned to newly created variables or
+//! to not used variables (dereferenced to zero).
+//! - `kVarStateReg - State that means that variable is currently allocated in
+//! register.
+//! - `kVarStateMem - State that means that variable is currently only in
+//! memory location.
+//!
+//! When you create new variable, initial state is always `kVarStateUnused`,
//! allocating it to register or spilling to memory changes this state to
-//! @c kVarStateReg or @c kVarStateMem, 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).
+//! `kVarStateReg` or `kVarStateMem`, 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 Compiler::alloc() - Explicit method to alloc variable into
-//! register. You can use this before loops or code blocks.
-//!
-//! - @c Compiler::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.
-//!
-//! - @c Compiler::unuse() - Unuse variable (you can use this to end the
-//! variable scope or sub-scope).
+//! - `Compiler::alloc()` - Explicit method to alloc variable into register.
+//! It can be used to force allocation a variable before a loop for example.
+//!
+//! - `Compiler::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.
+//!
+//! - `Compiler::unuse()` - Unuse variable (you can use this to end the
+//! variable scope or sub-scope).
//!
//! Please see AsmJit tutorials (testcompiler.cpp and testvariables.cpp) for
//! more complete examples.
//!
-//! @section AsmJit_Compiler_MemoryManagement Memory Management
-//!
-//! @c Compiler Memory management follows these rules:
-//! - Everything created by @c Compiler is always freed by @c Compiler.
+//! Memory Management
+//! -----------------
+//!
+//! Compiler Memory management follows these rules:
+//!
+//! - Everything created by `Compiler` is always freed by `Compiler`.
//! - To get decent performance, compiler always uses larger memory buffer
//! for objects to allocate and when compiler instance is destroyed, this
//! buffer is freed. Destructors of active objects are called when
@@ -657,21 +1712,23 @@
//! objects are called immediately after abadonding them.
//! - This type of memory management is called 'zone memory management'.
//!
-//! This means that you can't use any @c Compiler object after destructing it,
-//! it also means that each object like @c Label, @c Var and others are created
-//! and managed by @c Compiler itself. These objects contain ID which is used
-//! internally by Compiler to store additional information about these objects.
-//!
-//! @section AsmJit_Compiler_StateManagement Control-Flow and State Management.
-//!
-//! The @c Compiler automatically manages state of the variables when using
+//! This means that you can't use any `Compiler` object after destructing it,
+//! it also means that each object like `Label`, `Var` and others are created
+//! and managed by @c Compiler itself. These objects contain ID which is
+//! used internally by Compiler to store additional information about these
+//! objects.
+//!
+//! Control-Flow and State Management
+//! ---------------------------------
+//!
+//! The `Compiler` automatically manages state of the variables when using
//! control flow instructions like jumps, conditional jumps and calls. There
//! is minimal heuristics for choosing the method how state is saved or restored.
//!
//! Generally the state can be changed only when using jump or conditional jump
//! instruction. When using non-conditional jump then state change is embedded
//! into the instruction stream before the jump. When using conditional jump
-//! the @c Compiler decides whether to restore state before the jump or whether
+//! the `Compiler` decides whether to restore state before the jump or whether
//! to use another block where state is restored. The last case is that no-code
//! have to be emitted and there is no state change (this is of course ideal).
//!
@@ -683,18 +1740,17 @@
//! Next example is the situation where the extended code block is used to
//! do state-change:
//!
-//! @code
-//! X86Compiler c;
-//!
-//! c.newFunc(kX86FuncConvDefault, FuncBuilder0<Void>());
-//! c.getFunc()->setHint(kFuncHintNaked, true);
+//! ~~~
+//! Compiler c;
+//!
+//! c.addFunc(kFuncConvHost, FuncBuilder0<Void>());
//!
//! // Labels.
-//! Label L0 = c.newLabel();
+//! Label L0(c);
//!
//! // Variables.
-//! GpVar var0 = c.newGpVar();
-//! GpVar var1 = c.newGpVar();
+//! X86GpVar var0(c, kVarTypeInt32);
+//! X86GpVar var1(c, kVarTypeInt32);
//!
//! // Cleanup. After these two lines, the var0 and var1 will be always stored
//! // in registers. Our example is very small, but in larger code the var0 can
@@ -738,11 +1794,11 @@
//! // var1 - register.
//!
//! c.endFunc();
-//! @endcode
+//! ~~~
//!
//! The output:
//!
-//! @verbatim
+//! ~~~
//! xor eax, eax ; xor var_0, var_0
//! xor ecx, ecx ; xor var_1, var_1
//! cmp eax, ecx ; cmp var_0, var_1
@@ -763,31 +1819,30 @@
//! mov ecx, [esp - 28] ; alloc var_1
//! jmp short L0
//! ; state-switch end
-//! @endverbatim
+//! ~~~
//!
//! You can see that the state-switch section was generated (see L0_Switch0).
//! The compiler is unable to restore state immediately when emitting the
//! forward jump (the code is generated from first to last instruction and
//! the target state is simply not known at this time).
//!
-//! To tell @c Compiler that you want to embed state-switch code before jump
+//! To tell `Compiler` that you want to embed state-switch code before jump
//! it's needed to create backward jump (where also processor expects that it
//! will be taken). To demonstrate the possibility to embed state-switch before
//! jump we use slightly modified code:
//!
-//! @code
-//! X86Compiler c;
-//!
-//! c.newFunc(kX86FuncConvDefault, FuncBuilder0<Void>());
-//! c.getFunc()->setHint(kFuncHintNaked, true);
-//!
+//! ~~~
+//! Compiler c;
+//!
+//! c.addFunc(kFuncConvHost, FuncBuilder0<Void>());
+//!
//! // Labels.
-//! Label L0 = c.newLabel();
-//!
+//! Label L0(c);
+//!
//! // Variables.
-//! GpVar var0 = c.newGpVar();
-//! GpVar var1 = c.newGpVar();
-//!
+//! X86GpVar var0(c, kVarTypeInt32);
+//! X86GpVar var1(c, kVarTypeInt32);
+//!
//! // Cleanup. After these two lines, the var0 and var1 will be always stored
//! // in registers. Our example is very small, but in larger code the var0 can
//! // be spilled by xor(var1, var1).
@@ -796,39 +1851,39 @@
//! // State:
//! // var0 - register.
//! // var1 - register.
-//!
+//!
//! // We manually spill these variables.
//! c.spill(var0);
//! c.spill(var1);
//! // State:
//! // var0 - memory.
//! // var1 - memory.
-//!
+//!
//! // Bind our label here.
//! c.bind(L0);
-//!
+//!
//! // Do something, the variables will be allocated again.
//! c.add(var0, 1);
//! c.add(var1, 2);
//! // State:
//! // var0 - register.
//! // var1 - register.
-//!
+//!
//! // Backward conditional jump to L0. The default behavior is that it is taken
//! // so state-change code will be embedded here.
//! c.je(L0);
-//!
+//!
//! c.endFunc();
-//! @endcode
+//! ~~~
//!
//! The output:
//!
-//! @verbatim
+//! ~~~
//! xor ecx, ecx ; xor var_0, var_0
//! xor edx, edx ; xor var_1, var_1
//! mov [esp - 24], ecx ; spill var_0
//! mov [esp - 28], edx ; spill var_1
-//! L.2:
+//! L2:
//! mov ecx, [esp - 24] ; alloc var_0
//! add ecx, 1 ; add var_0, 1
//! mov edx, [esp - 28] ; alloc var_1
@@ -839,19 +1894,19 @@
//! mov [esp - 28], edx ; spill var_1
//! ; state-switch end
//!
-//! je short L.2
+//! je short L2
//! ret
-//! @endverbatim
-//!
-//! Please notice where the state-switch section is located. The @c Compiler
+//! ~~~
+//!
+//! Please notice where the state-switch section is located. The `Compiler`
//! decided that jump is likely to be taken so the state change is embedded
//! before the conditional jump. To change this behavior into the previous
-//! case it's needed to add a hint (@c kCondHintLikely or @c kCondHintUnlikely).
-//!
-//! Replacing the <code>c.je(L0)</code> by <code>c.je(L0, kCondHintUnlikely)
+//! case it's needed to add an option (kInstOptionTaken/kInstOptionNotTaken).
+//!
+//! Replacing the <code>c.je(L0)</code> by <code>c.taken(); c.je(L0)</code>
//! will generate code like this:
//!
-//! @verbatim
+//! ~~~
//! xor ecx, ecx ; xor var_0, var_0
//! xor edx, edx ; xor var_1, var_1
//! mov [esp - 24], ecx ; spill var_0
@@ -870,4026 +1925,3556 @@
//! mov [esp - 28], edx ; spill var_1
//! jmp short L0
//! ; state-switch end
-//! @endverbatim
-//!
-//! This section provided information about how state-change works. The
+//! ~~~
+//!
+//! This section provided information about how state-change works. The
//! behavior is deterministic and it can be overridden.
//!
-//! @section AsmJit_Compiler_AdvancedCodeGeneration Advanced Code Generation
+//! Advanced Code Generation
+//! ------------------------
//!
//! This section describes advanced method of code generation available to
-//! @c Compiler (but also to @c Assembler). When emitting code to instruction
-//! stream the methods like @c mov(), @c add(), @c sub() can be called directly
-//! (advantage is static-type control performed also by C++ compiler) or
-//! indirectly using @c emit() method. The @c emit() method needs only
-//! instruction code and operands.
+//! `Compiler` (but also to `Assembler`). When emitting code to instruction
+//! stream the methods like `mov()`, `add()`, `sub()` can be called directly
+//! (advantage is static-type control performed also by C++ compiler) or
+//! indirectly using `emit()` method. The `emit()` method needs only instruction
+//! code and operands.
//!
//! Example of code generating by standard type-safe API:
//!
-//! @code
-//! X86Compiler c;
-//! GpVar var0 = c.newGpVar();
-//! GpVar var1 = c.newGpVar();
+//! ~~~
+//! Compiler c;
+//!
+//! X86GpVar var0(c, kVarTypeInt32);
+//! X86GpVar var1(c, kVarTypeInt32);
//!
//! ...
//!
-//! c.mov(var0, imm(0));
+//! c.mov(var0, 0);
//! c.add(var0, var1);
//! c.sub(var0, var1);
-//! @endcode
+//! ~~~
//!
//! The code above can be rewritten as:
//!
-//! @code
-//! X86Compiler c;
-//! GpVar var0 = c.newGpVar();
-//! GpVar var1 = c.newGpVar();
+//! ~~~
+//! Compiler c;
+//!
+//! X86GpVar var0(c, kVarTypeInt32);
+//! X86GpVar var1(c, kVarTypeInt32);
//!
//! ...
//!
-//! c.emit(kX86InstMov, var0, imm(0));
-//! c.emit(kX86InstAdd, var0, var1);
-//! c.emit(kX86InstSub, var0, var1);
-//! @endcode
+//! c.emit(kX86InstIdMov, var0, 0);
+//! c.emit(kX86InstIdAdd, var0, var1);
+//! c.emit(kX86InstIdSub, var0, var1);
+//! ~~~
//!
//! The advantage of first snippet is very friendly API and type-safe control
//! that is controlled by the C++ compiler. The advantage of second snippet is
//! availability to replace or generate instruction code in different places.
-//! See the next example how the @c emit() method can be used to generate
-//! abstract code.
+//! See the next example how the `emit()` method can be used to generate abstract
+//! code.
//!
//! Use case:
//!
-//! @code
-//! bool emitArithmetic(Compiler& c, XmmVar& var0, XmmVar& var1, const char* op)
-//! {
-//! uint code = kInstNone;
+//! ~~~
+//! bool emitArithmetic(Compiler& c, X86XmmVar& var0, X86XmmVar& var1, const char* op) {
+//! uint32_t code = kInstIdNone;
//!
//! if (strcmp(op, "ADD") == 0)
-//! code = kX86InstAddSS;
-//! else if (strcmp(op, "SUBTRACT") == 0)
-//! code = kX86InstSubSS;
-//! else if (strcmp(op, "MULTIPLY") == 0)
-//! code = kX86InstMulSS;
-//! else if (strcmp(op, "DIVIDE") == 0)
-//! code = kX86InstDivSS;
+//! code = kX86InstIdAddss;
+//! else if (::strcmp(op, "SUBTRACT") == 0)
+//! code = kX86InstIdSubss;
+//! else if (::strcmp(op, "MULTIPLY") == 0)
+//! code = kX86InstIdMulss;
+//! else if (::strcmp(op, "DIVIDE") == 0)
+//! code = kX86InstIdDivss;
//! else
//! // Invalid parameter?
//! return false;
//!
//! c.emit(code, var0, var1);
//! }
-//! @endcode
-//!
-//! Other use cases are waiting for you! Be sure that instruction you are
+//! ~~~
+//!
+//! Other use cases are waiting for you! Be sure that instruction you are
//! emitting is correct and encodable, because if not, Assembler will set
-//! error code to @c kErrorUnknownInstruction.
-//!
-//! @section AsmJit_Compiler_CompilerDetails Compiler 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 @c Compiler instance is ready, you can create function and add
-//! compiler-items using intrinsics or higher level methods implemented by the
-//! @c AsmJit::Compiler. When you are done (all instructions serialized) you
-//! should call @c AsmJit::Compiler::make() method which will analyze your code,
-//! allocate registers and memory for local variables and serialize all items
-//! to @c AsmJit::Assembler instance. Next steps shows what's done internally
-//! before code is serialized into @c AsmJit::Assembler
-//! (implemented in @c AsmJit::Compiler::serialize() method).
-//!
-//! 1. Compiler try to match function and end-function items (these items
-//! define function body and blocks).
-//!
-//! 2. For all items inside the function-body the virtual functions
-//! are called in this order:
-//! - CompilerItem::prepare()
-//! - CompilerItem::translate()
-//! - CompilerItem::emit()
-//! - CompilerItem::post()
-//!
-//! There is some extra work when emitting function prolog / epilog and
-//! register allocator.
-//!
-//! 3. Emit jump tables data.
-//!
-//! When everything here ends, @c AsmJit::Assembler contains binary stream
-//! that needs only relocation to be callable by C/C++ code.
-//!
-//! @section AsmJit_Compiler_Differences Summary of Differences between @c Assembler and @c Compiler
-//!
-//! - Instructions are not translated to machine code immediately, they are
-//! stored as emmitables, see @c AsmJit::CompilerItem.
-//! - Contains function builder and ability to call other functions.
-//! - Contains register allocator and variable management.
-//! - Contains a lot of helper methods to simplify the code generation not
-//! available/possible in @c AsmJit::Assembler.
-//! - Ability to pre-process or post-process the code which is being generated.
-struct X86Compiler : public Compiler
-{
- // Special X86 instructions:
- // - cpuid,
- // - cbw, cwd, cwde, cdq, cdqe, cqo
- // - cmpxchg
- // - cmpxchg8b, cmpxchg16b,
- // - daa, das,
- // - imul, mul, idiv, div,
- // - mov_ptr
- // - lahf, sahf
- // - maskmovq, maskmovdqu
- // - enter, leave
- // - ret
- // - monitor, mwait
- // - pop, popad, popfd, popfq,
- // - push, pushad, pushfd, pushfq
- // - rcl, rcr, rol, ror, sal, sar, shl, shr
- // - shld, shrd
- // - rdtsc. rdtscp
- // - lodsb, lodsd, lodsq, lodsw
- // - movsb, movsd, movsq, movsw
- // - stosb, stosd, stosq, stosw
- // - cmpsb, cmpsd, cmpsq, cmpsw
- // - scasb, scasd, scasq, scasw
- //
- // Special X87 instructions:
- // - fisttp
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a @ref X86Compiler instance.
- ASMJIT_API X86Compiler(Context *context = JitContext::getGlobal());
- //! @brief Destroy the @ref X86Compiler instance.
- ASMJIT_API ~X86Compiler();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get current function as @ref X86CompilerFuncDecl.
- //!
- //! This method can be called within @c newFunc() and @c endFunc()
- //! block to get current function you are working with. It's recommended
- //! to store @c AsmJit::Function pointer returned by @c newFunc<> method,
- //! because this allows you in future implement function sections outside of
- //! function itself (yeah, this is possible!).
- X86CompilerFuncDecl *getFunc() const { return reinterpret_cast<X86CompilerFuncDecl *>(this->_func); }
-
- // --------------------------------------------------------------------------
- // [Function Builder]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new function.
- //!
- //! @param cconv Calling convention to use (see @c kX86FuncConv 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
- //! X86Compiler c;
- //!
- //! // Begin of function (also emits function @c Prolog)
- //! c.newFunc(
- //! // Default calling convention (32-bit cdecl or 64-bit for host OS)
- //! kX86FuncConvDefault,
- //! // Using function builder to generate arguments list
- //! BuildFunction2<int, int>());
- //!
- //! // End of function (also emits function @c Epilog)
- //! c.endFunc();
- //! @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
- //! X86Compiler c;
- //!
- //! // Begin of function (also emits function @c Prolog)
- //! c.newFunc(
- //! // Default calling convention (32-bit cdecl or 64-bit for host OS)
- //! kX86FuncConvDefault,
- //! // Using function builder to generate arguments list
- //! BuildFunction2<int, int>());
- //!
- //! // Arguments are like other variables, you need to reference them by
- //! // variable operands:
- //! GpVar a0 = c.getGpArg(0);
- //! GpVar a1 = c.getGpArg(1);
- //!
- //! // Use them.
- //! c.add(a0, a1);
- //!
- //! // End of function (emits function epilog and return)
- //! c.endFunc();
- //! @endcode
- //!
- //! Arguments are like variables. How to manipulate with variables is
- //! documented in @c AsmJit::Compiler, variables section.
- //!
- //! @note To get current function use @c currentFunction() method or save
- //! pointer to @c AsmJit::Function returned by @c AsmJit::Compiler::newFunc<>
- //! method. Recommended is to save the pointer.
- //!
- //! @sa @c BuildFunction0, @c BuildFunction1, @c BuildFunction2, ...
- X86CompilerFuncDecl *newFunc(uint32_t convention, const FuncPrototype &func) { return this->newFunc_(convention, func.getReturnType(), func.getArguments(), func.getArgumentsCount()); }
-
- //! @brief Create a new function (low level version).
- //!
- //! @param cconv Function calling convention (see @c AsmJit::kX86FuncConv).
- //! @param args Function arguments (see @c AsmJit::kX86VarType).
- //! @param count Arguments count.
- //!
- //! This method is internally called from @c newFunc() method and
- //! contains arguments thats used internally by @c AsmJit::Compiler.
- //!
- //! @note To get current function use @c currentFunction() method.
- ASMJIT_API X86CompilerFuncDecl *newFunc_(uint32_t convenion, uint32_t returnType, const uint32_t *arguments, uint32_t argumentsCount);
-
- //! @brief End of current function scope and all variables.
- ASMJIT_API X86CompilerFuncDecl *endFunc();
-
- // --------------------------------------------------------------------------
- // [Emit]
- // --------------------------------------------------------------------------
-
- //! @brief Emit instruction with no operand.
- ASMJIT_API void _emitInstruction(uint32_t code);
-
- //! @brief Emit instruction with one operand.
- ASMJIT_API void _emitInstruction(uint32_t code, const Operand *o0);
-
- //! @brief Emit instruction with two operands.
- ASMJIT_API void _emitInstruction(uint32_t code, const Operand *o0, const Operand *o1);
-
- //! @brief Emit instruction with three operands.
- ASMJIT_API void _emitInstruction(uint32_t code, const Operand *o0, const Operand *o1, const Operand *o2);
-
- //! @brief Emit instruction with four operands (Special instructions).
- ASMJIT_API void _emitInstruction(uint32_t code, const Operand *o0, const Operand *o1, const Operand *o2, const Operand *o3);
-
- //! @brief Emit instruction with five operands (Special instructions).
- ASMJIT_API void _emitInstruction(uint32_t code, const Operand *o0, const Operand *o1, const Operand *o2, const Operand *o3, const Operand *o4);
-
- //! @brief Private method for emitting jcc.
- ASMJIT_API void _emitJcc(uint32_t code, const Label *label, uint32_t hint);
-
- //! @brief Private method for emitting function call.
- ASMJIT_API X86CompilerFuncCall *_emitCall(const Operand *o0);
-
- //! @brief Private method for returning a value from the function.
- ASMJIT_API void _emitReturn(const Operand *first, const Operand *second);
-
- // --------------------------------------------------------------------------
- // [Align]
- // --------------------------------------------------------------------------
-
- //! @brief Align target buffer to @a m bytes.
- //!
- //! Typical usage of this is to align labels at start of the inner loops.
- //!
- //! Inserts @c nop() instructions or CPU optimized NOPs.
- ASMJIT_API void align(uint32_t m);
-
- // --------------------------------------------------------------------------
- // [Label]
- // --------------------------------------------------------------------------
-
- //! @brief Create and return new label.
- ASMJIT_API Label newLabel();
-
- //! @brief Bind label to the current offset.
- //!
- //! @note Label can be bound only once!
- ASMJIT_API void bind(const Label &label);
-
- // --------------------------------------------------------------------------
- // [Variables]
- // --------------------------------------------------------------------------
-
- //! @brief Get compiler variable at @a id.
- X86CompilerVar *_getVar(uint32_t id) const
- {
- ASMJIT_ASSERT(id != kInvalidValue);
- return reinterpret_cast<X86CompilerVar *>(this->_vars[id & kOperandIdValueMask]);
- }
-
- //! @internal
- //!
- //! @brief Create a new variable data.
- ASMJIT_API X86CompilerVar *_newVar(const char *name, uint32_t type, uint32_t size);
-
- //! @brief Create a new general-purpose variable.
- ASMJIT_API GpVar newGpVar(uint32_t varType = kX86VarTypeGpz, const char *name = nullptr);
- //! @brief Get argument as general-purpose variable.
- ASMJIT_API GpVar getGpArg(uint32_t argIndex);
-
- //! @brief Create a new MM variable.
- ASMJIT_API MmVar newMmVar(uint32_t varType = kX86VarTypeMm, const char *name = nullptr);
- //! @brief Get argument as MM variable.
- ASMJIT_API MmVar getMmArg(uint32_t argIndex);
-
- //! @brief Create a new XMM variable.
- ASMJIT_API XmmVar newXmmVar(uint32_t varType = kX86VarTypeXmm, const char *name = nullptr);
- //! @brief Get argument as XMM variable.
- ASMJIT_API XmmVar getXmmArg(uint32_t argIndex);
-
- //! @internal
- //!
- //! @brief Serialize variable hint.
- ASMJIT_API void _vhint(Var &var, uint32_t hintId, uint32_t hintValue);
-
- //! @brief Alloc variable @a var.
- ASMJIT_API void alloc(Var &var);
- //! @brief Alloc variable @a var using @a regIndex as a register index.
- ASMJIT_API void alloc(Var &var, uint32_t regIndex);
- //! @brief Alloc variable @a var using @a reg as a demanded register.
- ASMJIT_API void alloc(Var &var, const Reg ®);
- //! @brief Spill variable @a var.
- ASMJIT_API void spill(Var &var);
- //! @brief Save variable @a var if modified.
- ASMJIT_API void save(Var &var);
- //! @brief Unuse variable @a var.
- ASMJIT_API void unuse(Var &var);
-
- //! @brief Get memory home of variable @a var.
- ASMJIT_API void getMemoryHome(Var &var, GpVar *home, int *displacement = nullptr);
-
- //! @brief Set memory home of variable @a var.
- //!
- //! Default memory home location is on stack (ESP/RSP), but when needed the
- //! bebahior can be changed by this method.
- //!
- //! It is an error to chaining memory home locations. For example the given
- //! code is invalid:
- //!
- //! @code
- //! X86Compiler c;
- //!
- //! ...
- //! GpVar v0 = c.newGpVar();
- //! GpVar v1 = c.newGpVar();
- //! GpVar v2 = c.newGpVar();
- //! GpVar v3 = c.newGpVar();
- //!
- //! c.setMemoryHome(v1, v0, 0); // Allowed, [v0] is memory home for v1.
- //! c.setMemoryHome(v2, v0, 4); // Allowed, [v0+4] is memory home for v2.
- //! c.setMemoryHome(v3, v2); // CHAINING, NOT ALLOWED!
- //! @endcode
- ASMJIT_API void setMemoryHome(Var &var, const GpVar &home, int displacement = 0);
-
- //! @brief Get priority of variable @a var.
- ASMJIT_API uint32_t getPriority(Var &var) const;
- //! @brief Set priority of variable @a var to @a priority.
- ASMJIT_API void setPriority(Var &var, uint32_t priority);
-
- //! @brief Get save-on-unuse @a var property.
- ASMJIT_API bool getSaveOnUnuse(Var &var) const;
- //! @brief Set save-on-unuse @a var property to @a value.
- ASMJIT_API void setSaveOnUnuse(Var &var, bool value);
-
- //! @brief Rename variable @a var to @a name.
- //!
- //! @note Only new name will appear in the logger.
- ASMJIT_API void rename(Var &var, const char *name);
-
- // --------------------------------------------------------------------------
- // [State]
- // --------------------------------------------------------------------------
-
- //! @internal
- //!
- //! @brief Create a new @ref X86CompilerState.
- ASMJIT_API X86CompilerState *_newState(uint32_t memVarsCount);
-
- // --------------------------------------------------------------------------
- // [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 getError() method doesn't
- //! return @c kErrorOk (zero) then this function always returns @c NULL and
- //! error value remains the same.
- ASMJIT_API virtual void *make();
-
- //! @brief Method that will emit everything to @c Assembler instance @a a.
- ASMJIT_API virtual void serialize(Assembler &a);
-
- // --------------------------------------------------------------------------
- // [Data]
- // --------------------------------------------------------------------------
-
- //! @brief Get target from label @a id.
- X86CompilerTarget *_getTarget(uint32_t id)
- {
- ASMJIT_ASSERT((id & kOperandIdTypeMask) == kOperandIdTypeLabel);
- return reinterpret_cast<X86CompilerTarget *>(this->_targets[id & kOperandIdValueMask]);
- }
-
- // --------------------------------------------------------------------------
- // [Embed]
- // --------------------------------------------------------------------------
-
- //! @brief Add 8-bit integer data to the instuction stream.
- void db(uint8_t x) { this->embed(&x, 1); }
- //! @brief Add 16-bit integer data to the instuction stream.
- void dw(uint16_t x) { this->embed(&x, 2); }
- //! @brief Add 32-bit integer data to the instuction stream.
- void dd(uint32_t x) { this->embed(&x, 4); }
- //! @brief Add 64-bit integer data to the instuction stream.
- void dq(uint64_t x) { this->embed(&x, 8); }
-
- //! @brief Add 8-bit integer data to the instuction stream.
- void dint8(int8_t x) { this->embed(&x, sizeof(int8_t)); }
- //! @brief Add 8-bit integer data to the instuction stream.
- void duint8(uint8_t x) { this->embed(&x, sizeof(uint8_t)); }
-
- //! @brief Add 16-bit integer data to the instuction stream.
- void dint16(int16_t x) { this->embed(&x, sizeof(int16_t)); }
- //! @brief Add 16-bit integer data to the instuction stream.
- void duint16(uint16_t x) { this->embed(&x, sizeof(uint16_t)); }
-
- //! @brief Add 32-bit integer data to the instuction stream.
- void dint32(int32_t x) { this->embed(&x, sizeof(int32_t)); }
- //! @brief Add 32-bit integer data to the instuction stream.
- void duint32(uint32_t x) { this->embed(&x, sizeof(uint32_t)); }
-
- //! @brief Add 64-bit integer data to the instuction stream.
- void dint64(int64_t x) { this->embed(&x, sizeof(int64_t)); }
- //! @brief Add 64-bit integer data to the instuction stream.
- void duint64(uint64_t x) { this->embed(&x, sizeof(uint64_t)); }
-
- //! @brief Add system-integer data to the instuction stream.
- void dintptr(intptr_t x) { this->embed(&x, sizeof(intptr_t)); }
- //! @brief Add system-integer data to the instuction stream.
- void duintptr(uintptr_t x) { this->embed(&x, sizeof(uintptr_t)); }
-
- //! @brief Add float data to the instuction stream.
- void dfloat(float x) { this->embed(&x, sizeof(float)); }
- //! @brief Add double data to the instuction stream.
- void ddouble(double x) { this->embed(&x, sizeof(double)); }
-
- //! @brief Add pointer data to the instuction stream.
- void dptr(void *x) { this->embed(&x, sizeof(void *)); }
-
- //! @brief Add MM data to the instuction stream.
- void dmm(const MmData &x) { this->embed(&x, sizeof(MmData)); }
- //! @brief Add XMM data to the instuction stream.
- void dxmm(const XmmData &x) { this->embed(&x, sizeof(XmmData)); }
-
- //! @brief Add data to the instuction stream.
- void data(const void *data, size_t size) { this->embed(data, size); }
-
- //! @brief Add data in a given structure instance to the instuction stream.
- template<typename T> void dstruct(const T &x) { this->embed(&x, sizeof(T)); }
-
- // --------------------------------------------------------------------------
- // [Custom Instructions]
- // --------------------------------------------------------------------------
-
- // These emitters are used by custom compiler code (register alloc / spill,
- // prolog / epilog generator, ...).
-
- void emit(uint32_t code) { this->_emitInstruction(code); }
-
- void emit(uint32_t code, const Operand &o0) { this->_emitInstruction(code, &o0); }
-
- void emit(uint32_t code, const Operand &o0, const Operand &o1) { this->_emitInstruction(code, &o0, &o1); }
-
- void emit(uint32_t code, const Operand &o0, const Operand &o1, const Operand &o2) { this->_emitInstruction(code, &o0, &o1, &o2); }
-
- // --------------------------------------------------------------------------
- // [X86 Instructions]
- // --------------------------------------------------------------------------
-
- //! @brief Add with Carry.
- void adc(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstAdc, &dst, &src); }
-
- //! @brief Add with Carry.
- void adc(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstAdc, &dst, &src); }
-
- //! @brief Add with Carry.
- void adc(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstAdc, &dst, &src); }
-
- //! @brief Add with Carry.
- void adc(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstAdc, &dst, &src); }
-
- //! @brief Add with Carry.
- void adc(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstAdc, &dst, &src); }
-
- //! @brief Add.
- void add(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstAdd, &dst, &src); }
-
- //! @brief Add.
- void add(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstAdd, &dst, &src); }
-
- //! @brief Add.
- void add(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstAdd, &dst, &src); }
-
- //! @brief Add.
- void add(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstAdd, &dst, &src); }
-
- //! @brief Add.
- void add(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstAdd, &dst, &src); }
-
- //! @brief Logical And.
- void and_(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstAnd, &dst, &src); }
-
- //! @brief Logical And.
- void and_(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstAnd, &dst, &src); }
-
- //! @brief Logical And.
- void and_(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstAnd, &dst, &src); }
-
- //! @brief Logical And.
- void and_(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstAnd, &dst, &src); }
-
- //! @brief Logical And.
- void and_(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstAnd, &dst, &src); }
-
- //! @brief Bit Scan Forward.
- void bsf(const GpVar &dst, const GpVar &src)
- {
- ASMJIT_ASSERT(!dst.isGpb());
- this->_emitInstruction(kX86InstBsf, &dst, &src);
- }
-
- //! @brief Bit Scan Forward.
- void bsf(const GpVar &dst, const Mem &src)
- {
- ASMJIT_ASSERT(!dst.isGpb());
- this->_emitInstruction(kX86InstBsf, &dst, &src);
- }
-
- //! @brief Bit Scan Reverse.
- void bsr(const GpVar &dst, const GpVar &src)
- {
- ASMJIT_ASSERT(!dst.isGpb());
- this->_emitInstruction(kX86InstBsr, &dst, &src);
- }
-
- //! @brief Bit Scan Reverse.
- void bsr(const GpVar &dst, const Mem &src)
- {
- ASMJIT_ASSERT(!dst.isGpb());
- this->_emitInstruction(kX86InstBsr, &dst, &src);
- }
-
- //! @brief Byte swap (32-bit or 64-bit registers only) (i486).
- void bswap(const GpVar &dst)
- {
- // ASMJIT_ASSERT(dst.getRegType() == kX86RegGPD || dst.getRegType() == kX86RegGPQ);
- this->_emitInstruction(kX86InstBSwap, &dst);
- }
-
- //! @brief Bit test.
- void bt(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstBt, &dst, &src); }
-
- //! @brief Bit test.
- void bt(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstBt, &dst, &src); }
-
- //! @brief Bit test.
- void bt(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstBt, &dst, &src); }
-
- //! @brief Bit test.
- void bt(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstBt, &dst, &src); }
-
- //! @brief Bit test and complement.
- void btc(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstBtc, &dst, &src); }
-
- //! @brief Bit test and complement.
- void btc(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstBtc, &dst, &src); }
-
- //! @brief Bit test and complement.
- void btc(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstBtc, &dst, &src); }
-
- //! @brief Bit test and complement.
- void btc(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstBtc, &dst, &src); }
-
- //! @brief Bit test and reset.
- void btr(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstBtr, &dst, &src); }
-
- //! @brief Bit test and reset.
- void btr(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstBtr, &dst, &src); }
-
- //! @brief Bit test and reset.
- void btr(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstBtr, &dst, &src); }
-
- //! @brief Bit test and reset.
- void btr(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstBtr, &dst, &src); }
-
- //! @brief Bit test and set.
- void bts(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstBts, &dst, &src); }
-
- //! @brief Bit test and set.
- void bts(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstBts, &dst, &src); }
-
- //! @brief Bit test and set.
- void bts(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstBts, &dst, &src); }
-
- //! @brief Bit test and set.
- void bts(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstBts, &dst, &src); }
-
- //! @brief Call Procedure.
- X86CompilerFuncCall *call(const GpVar &dst) { return this->_emitCall(&dst); }
-
- //! @brief Call Procedure.
- X86CompilerFuncCall *call(const Mem &dst) { return this->_emitCall(&dst); }
-
- //! @brief Call Procedure.
- X86CompilerFuncCall *call(const Imm &dst) { return this->_emitCall(&dst); }
-
- //! @brief Call Procedure.
- //! @overload
- X86CompilerFuncCall *call(void *dst)
- {
- Imm imm(reinterpret_cast<sysint_t>(dst));
- return this->_emitCall(&imm);
- }
-
- //! @brief Call Procedure.
- X86CompilerFuncCall *call(const Label &label) { return this->_emitCall(&label); }
-
- //! @brief Convert Byte to Word (Sign Extend).
- void cbw(const GpVar &dst) { this->_emitInstruction(kX86InstCbw, &dst); }
-
- //! @brief Convert Word to DWord (Sign Extend).
- void cwd(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCwd, &dst, &src); }
-
- //! @brief Convert Word to DWord (Sign Extend).
- void cwde(const GpVar &dst) { this->_emitInstruction(kX86InstCwde, &dst); }
-
- //! @brief Convert Word to DWord (Sign Extend).
- void cdq(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCdq, &dst, &src); }
-
-#ifdef ASMJIT_X64
- //! @brief Convert DWord to QWord (Sign Extend).
- void cdqe(const GpVar &dst) { this->_emitInstruction(kX86InstCdqe, &dst); }
-
- //! @brief Convert QWord to DQWord (Sign Extend).
- void cqo(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCqo, &dst, &src); }
-#endif // ASMJIT_X64
-
- //! @brief Clear Carry flag
- //!
- //! This instruction clears the CF flag in the EFLAGS register.
- void clc() { this->_emitInstruction(kX86InstClc); }
-
- //! @brief Clear Direction flag
- //!
- //! This instruction clears the DF flag in the EFLAGS register.
- void cld() { this->_emitInstruction(kX86InstCld); }
-
- //! @brief Complement Carry Flag.
- //!
- //! This instruction complements the CF flag in the EFLAGS register.
- //! (CF = NOT CF)
- void cmc() { this->_emitInstruction(kX86InstCmc); }
-
- //! @brief Conditional Move.
- void cmov(kX86Cond cc, const GpVar &dst, const GpVar &src) { this->_emitInstruction(X86Util::getCMovccInstFromCond(cc), &dst, &src); }
-
- //! @brief Conditional Move.
- void cmov(kX86Cond cc, const GpVar &dst, const Mem &src) { this->_emitInstruction(X86Util::getCMovccInstFromCond(cc), &dst, &src); }
-
- //! @brief Conditional Move.
- void cmova(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovA, &dst, &src); }
- //! @brief Conditional Move.
- void cmova(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovA, &dst, &src); }
- //! @brief Conditional Move.
- void cmovae(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovAE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovae(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovAE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovb(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovB, &dst, &src); }
- //! @brief Conditional Move.
- void cmovb(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovB, &dst, &src); }
- //! @brief Conditional Move.
- void cmovbe(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovBE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovbe(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovBE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovc(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovC, &dst, &src); }
- //! @brief Conditional Move.
- void cmovc(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovC, &dst, &src); }
- //! @brief Conditional Move.
- void cmove(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovE, &dst, &src); }
- //! @brief Conditional Move.
- void cmove(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovg(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovG, &dst, &src); }
- //! @brief Conditional Move.
- void cmovg(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovG, &dst, &src); }
- //! @brief Conditional Move.
- void cmovge(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovGE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovge(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovGE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovl(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovL, &dst, &src); }
- //! @brief Conditional Move.
- void cmovl(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovL, &dst, &src); }
- //! @brief Conditional Move.
- void cmovle(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovLE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovle(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovLE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovna(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNA, &dst, &src); }
- //! @brief Conditional Move.
- void cmovna(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNA, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnae(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNAE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnae(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNAE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnb(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNB, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnb(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNB, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnbe(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNBE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnbe(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNBE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnc(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNC, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnc(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNC, &dst, &src); }
- //! @brief Conditional Move.
- void cmovne(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovne(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovng(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNG, &dst, &src); }
- //! @brief Conditional Move.
- void cmovng(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNG, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnge(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNGE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnge(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNGE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnl(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNL, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnl(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNL, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnle(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNLE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnle(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNLE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovno(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNO, &dst, &src); }
- //! @brief Conditional Move.
- void cmovno(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNO, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnp(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNP, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnp(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNP, &dst, &src); }
- //! @brief Conditional Move.
- void cmovns(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNS, &dst, &src); }
- //! @brief Conditional Move.
- void cmovns(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNS, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnz(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovNZ, &dst, &src); }
- //! @brief Conditional Move.
- void cmovnz(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovNZ, &dst, &src); }
- //! @brief Conditional Move.
- void cmovo(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovO, &dst, &src); }
- //! @brief Conditional Move.
- void cmovo(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovO, &dst, &src); }
- //! @brief Conditional Move.
- void cmovp(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovP, &dst, &src); }
- //! @brief Conditional Move.
- void cmovp(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovP, &dst, &src); }
- //! @brief Conditional Move.
- void cmovpe(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovPE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovpe(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovPE, &dst, &src); }
- //! @brief Conditional Move.
- void cmovpo(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovPO, &dst, &src); }
- //! @brief Conditional Move.
- void cmovpo(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovPO, &dst, &src); }
- //! @brief Conditional Move.
- void cmovs(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovS, &dst, &src); }
- //! @brief Conditional Move.
- void cmovs(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovS, &dst, &src); }
- //! @brief Conditional Move.
- void cmovz(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCMovZ, &dst, &src); }
- //! @brief Conditional Move.
- void cmovz(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCMovZ, &dst, &src); }
-
- //! @brief Compare Two Operands.
- void cmp(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCmp, &dst, &src); }
-
- //! @brief Compare Two Operands.
- void cmp(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCmp, &dst, &src); }
-
- //! @brief Compare Two Operands.
- void cmp(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstCmp, &dst, &src); }
-
- //! @brief Compare Two Operands.
- void cmp(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstCmp, &dst, &src); }
-
- //! @brief Compare Two Operands.
- void cmp(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstCmp, &dst, &src); }
-
- //! @brief Compare and Exchange (i486).
- void cmpxchg(const GpVar &cmp_1_eax, const GpVar &cmp_2, const GpVar &src)
- {
- ASMJIT_ASSERT(cmp_1_eax.getId() != src.getId());
- this->_emitInstruction(kX86InstCmpXCHG, &cmp_1_eax, &cmp_2, &src);
- }
-
- //! @brief Compare and Exchange (i486).
- void cmpxchg(const GpVar &cmp_1_eax, const Mem &cmp_2, const GpVar &src)
- {
- ASMJIT_ASSERT(cmp_1_eax.getId() != src.getId());
- this->_emitInstruction(kX86InstCmpXCHG, &cmp_1_eax, &cmp_2, &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.
- void cmpxchg8b(const GpVar &cmp_edx, const GpVar &cmp_eax, const GpVar &cmp_ecx, const GpVar &cmp_ebx, const Mem &dst)
- {
- ASMJIT_ASSERT(cmp_edx.getId() != cmp_eax.getId() && cmp_eax.getId() != cmp_ecx.getId() && cmp_ecx.getId() != cmp_ebx.getId());
-
- this->_emitInstruction(kX86InstCmpXCHG8B, &cmp_edx, &cmp_eax, &cmp_ecx, &cmp_ebx, &dst);
- }
-
-#ifdef ASMJIT_X64
- //! @brief Compares the 128-bit value in RDX:RAX with the memory operand (X64).
- //!
- //! 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.
- void cmpxchg16b(const GpVar &cmp_edx, const GpVar &cmp_eax, const GpVar &cmp_ecx, const GpVar &cmp_ebx, const Mem &dst)
- {
- ASMJIT_ASSERT(cmp_edx.getId() != cmp_eax.getId() && cmp_eax.getId() != cmp_ecx.getId() && cmp_ecx.getId() != cmp_ebx.getId());
-
- this->_emitInstruction(kX86InstCmpXCHG16B, &cmp_edx, &cmp_eax, &cmp_ecx, &cmp_ebx, &dst);
- }
-#endif // ASMJIT_X64
-
- //! @brief CPU Identification (i486).
- void cpuid(const GpVar &inout_eax, const GpVar &out_ebx, const GpVar &out_ecx, const GpVar &out_edx)
- {
- // Destination variables must be different.
- ASMJIT_ASSERT(inout_eax.getId() != out_ebx.getId() && out_ebx.getId() != out_ecx.getId() && out_ecx.getId() != out_edx.getId());
-
- this->_emitInstruction(kX86InstCpuId, &inout_eax, &out_ebx, &out_ecx, &out_edx);
- }
-
-#ifdef ASMJIT_X86
- void daa(const GpVar &dst) { this->_emitInstruction(kX86InstDaa, &dst); }
-
- void das(const GpVar &dst) { this->_emitInstruction(kX86InstDas, &dst); }
-#endif // ASMJIT_X86
-
- //! @brief Decrement by 1.
- //! @note This instruction can be slower than sub(dst, 1)
- void dec(const GpVar &dst) { this->_emitInstruction(kX86InstDec, &dst); }
-
- //! @brief Decrement by 1.
- //! @note This instruction can be slower than sub(dst, 1)
- void dec(const Mem &dst) { this->_emitInstruction(kX86InstDec, &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.
- void div(const GpVar &dst_rem, const GpVar &dst_quot, const GpVar &src)
- {
- // Destination variables must be different.
- ASMJIT_ASSERT(dst_rem.getId() != dst_quot.getId());
- this->_emitInstruction(kX86InstDiv, &dst_rem, &dst_quot, &src);
- }
-
- //! @brief Unsigned divide.
- //! @overload
- void div(const GpVar &dst_rem, const GpVar &dst_quot, const Mem &src)
- {
- // Destination variables must be different.
- ASMJIT_ASSERT(dst_rem.getId() != dst_quot.getId());
- this->_emitInstruction(kX86InstDiv, &dst_rem, &dst_quot, &src);
- }
-
-#if ASMJIT_NOT_SUPPORTED_BY_COMPILER
- //! @brief Make Stack Frame for Procedure Parameters.
- void enter(const Imm &imm16, const Imm &imm8) { this->_emitInstruction(kX86InstEnter, &imm16, &imm8); }
-#endif // ASMJIT_NOT_SUPPORTED_BY_COMPILER
-
- //! @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.
- void idiv(const GpVar &dst_rem, const GpVar &dst_quot, const GpVar &src)
- {
- // Destination variables must be different.
- ASMJIT_ASSERT(dst_rem.getId() != dst_quot.getId());
- this->_emitInstruction(kX86InstIDiv, &dst_rem, &dst_quot, &src);
- }
-
- //! @brief Signed divide.
- //! @overload
- void idiv(const GpVar &dst_rem, const GpVar &dst_quot, const Mem &src)
- {
- // Destination variables must be different.
- ASMJIT_ASSERT(dst_rem.getId() != dst_quot.getId());
- this->_emitInstruction(kX86InstIDiv, &dst_rem, &dst_quot, &src);
- }
-
- //! @brief Signed multiply.
- //!
- //! [dst_lo:dst_hi] = dst_hi * src.
- void imul(const GpVar &dst_hi, const GpVar &dst_lo, const GpVar &src)
- {
- // Destination variables must be different.
- ASMJIT_ASSERT(dst_hi.getId() != dst_lo.getId());
- this->_emitInstruction(kX86InstIMul, &dst_hi, &dst_lo, &src);
- }
-
- //! @overload
- void imul(const GpVar &dst_hi, const GpVar &dst_lo, const Mem &src)
- {
- // Destination variables must be different.
- ASMJIT_ASSERT(dst_hi.getId() != dst_lo.getId());
- this->_emitInstruction(kX86InstIMul, &dst_hi, &dst_lo, &src);
- }
-
- //! @brief Signed multiply.
- //!
- //! Destination operand (the first operand) is multiplied by the source
- //! operand (second operand). The destination operand is a general-purpose
- //! 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.
- void imul(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstIMul, &dst, &src); }
-
- //! @brief Signed multiply.
- //! @overload
- void imul(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstIMul, &dst, &src); }
-
- //! @brief Signed multiply.
- //! @overload
- void imul(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstIMul, &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).
- void imul(const GpVar &dst, const GpVar &src, const Imm &imm) { this->_emitInstruction(kX86InstIMul, &dst, &src, &imm); }
-
- //! @overload
- void imul(const GpVar &dst, const Mem &src, const Imm &imm) { this->_emitInstruction(kX86InstIMul, &dst, &src, &imm); }
-
- //! @brief Increment by 1.
- //! @note This instruction can be slower than add(dst, 1)
- void inc(const GpVar &dst) { this->_emitInstruction(kX86InstInc, &dst); }
-
- //! @brief Increment by 1.
- //! @note This instruction can be slower than add(dst, 1)
- void inc(const Mem &dst) { this->_emitInstruction(kX86InstInc, &dst); }
-
- //! @brief Interrupt 3 - trap to debugger.
- void int3() { this->_emitInstruction(kX86InstInt3); }
-
- //! @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.
- void j(kX86Cond cc, const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(X86Util::getJccInstFromCond(cc), &label, hint); }
-
- //! @brief Jump to label @a label if condition is met.
- void ja(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJA, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jae(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJAE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jb(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJB, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jbe(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJBE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jc(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJC, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void je(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jg(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJG, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jge(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJGE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jl(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJL, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jle(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJLE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jna(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNA, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnae(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNAE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnb(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNB, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnbe(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNBE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnc(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNC, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jne(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jng(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNG, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnge(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNGE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnl(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNL, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnle(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNLE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jno(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNO, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnp(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNP, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jns(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNS, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jnz(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJNZ, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jo(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJO, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jp(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJP, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jpe(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJPE, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jpo(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJPO, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void js(const Label &label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJS, &label, hint); }
- //! @brief Jump to label @a label if condition is met.
- void jz(const Label& label, uint32_t hint = kCondHintNone) { this->_emitJcc(kX86InstJZ, &label, hint); }
-
- //! @brief Jump.
- //! @overload
- void jmp(const GpVar &dst) { this->_emitInstruction(kX86InstJmp, &dst); }
-
- //! @brief Jump.
- //! @overload
- void jmp(const Mem &dst) { this->_emitInstruction(kX86InstJmp, &dst); }
-
- //! @brief Jump.
- //! @overload
- void jmp(const Imm &dst) { this->_emitInstruction(kX86InstJmp, &dst); }
-
- //! @brief Jump.
- //! @overload
- void jmp(void *dst)
- {
- Imm imm(reinterpret_cast<sysint_t>(dst));
- this->_emitInstruction(kX86InstJmp, &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.
- void jmp(const Label &label) { this->_emitInstruction(kX86InstJmp, &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.
- void lea(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstLea, &dst, &src); }
-
-#if ASMJIT_NOT_SUPPORTED_BY_COMPILER
- //! @brief High Level Procedure Exit.
- void leave() { this->_emitInstruction(kX86InstLeave); }
-#endif // ASMJIT_NOT_SUPPORTED_BY_COMPILER
-
- //! @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.
- void mov(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move.
- //! @overload
- void mov(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move.
- //! @overload
- void mov(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move.
- //! @overload
- void mov(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move.
- //! @overload
- void mov(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move from segment register.
- //! @overload.
- void mov(const GpVar &dst, const SegmentReg &src) { this->_emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move from segment register.
- //! @overload.
- void mov(const Mem &dst, const SegmentReg &src) { this->_emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move to segment register.
- //! @overload.
- void mov(const SegmentReg &dst, const GpVar &src) { this->_emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move to segment register.
- //! @overload.
- void mov(const SegmentReg &dst, const Mem &src) { this->_emitInstruction(kX86InstMov, &dst, &src); }
-
- //! @brief Move byte, word, dword or qword from absolute address @a src to
- //! AL, AX, EAX or RAX register.
- void mov_ptr(const GpVar &dst, void *src)
- {
- Imm imm(reinterpret_cast<sysint_t>(src));
- this->_emitInstruction(kX86InstMovPtr, &dst, &imm);
- }
-
- //! @brief Move byte, word, dword or qword from AL, AX, EAX or RAX register
- //! to absolute address @a dst.
- void mov_ptr(void *dst, const GpVar &src)
- {
- Imm imm(reinterpret_cast<sysint_t>(dst));
- this->_emitInstruction(kX86InstMovPtr, &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 GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstMovSX, &dst, &src); }
-
- //! @brief Move with Sign-Extension.
- //! @overload
- void movsx(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovSX, &dst, &src); }
-
-#ifdef ASMJIT_X64
- //! @brief Move DWord to QWord with sign-extension.
- void movsxd(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstMovSXD, &dst, &src); }
-
- //! @brief Move DWord to QWord with sign-extension.
- //! @overload
- void movsxd(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovSXD, &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.
- void movzx(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstMovZX, &dst, &src); }
-
- //! @brief Move with Zero-Extend.
- //! @brief Overload
- void movzx(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovZX, &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.
- void mul(const GpVar &dst_hi, const GpVar &dst_lo, const GpVar &src)
- {
- // Destination variables must be different.
- ASMJIT_ASSERT(dst_hi.getId() != dst_lo.getId());
- this->_emitInstruction(kX86InstMul, &dst_hi, &dst_lo, &src);
- }
-
- //! @brief Unsigned multiply.
- //! @overload
- void mul(const GpVar &dst_hi, const GpVar &dst_lo, const Mem &src)
- {
- // Destination variables must be different.
- ASMJIT_ASSERT(dst_hi.getId() != dst_lo.getId());
- this->_emitInstruction(kX86InstMul, &dst_hi, &dst_lo, &src);
- }
-
- //! @brief Two's Complement Negation.
- void neg(const GpVar &dst) { this->_emitInstruction(kX86InstNeg, &dst); }
-
- //! @brief Two's Complement Negation.
- void neg(const Mem &dst) { this->_emitInstruction(kX86InstNeg, &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.
- void nop() { this->_emitInstruction(kX86InstNop); }
-
- //! @brief One's Complement Negation.
- void not_(const GpVar &dst) { this->_emitInstruction(kX86InstNot, &dst); }
-
- //! @brief One's Complement Negation.
- void not_(const Mem &dst) { this->_emitInstruction(kX86InstNot, &dst); }
-
- //! @brief Logical Inclusive OR.
- void or_(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstOr, &dst, &src); }
-
- //! @brief Logical Inclusive OR.
- void or_(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstOr, &dst, &src); }
-
- //! @brief Logical Inclusive OR.
- void or_(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstOr, &dst, &src); }
-
- //! @brief Logical Inclusive OR.
- void or_(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstOr, &dst, &src); }
-
- //! @brief Logical Inclusive OR.
- void or_(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstOr, &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.
- void pop(const GpVar &dst) { this->_emitInstruction(kX86InstPop, &dst); }
-
- void pop(const Mem &dst)
- {
- ASMJIT_ASSERT(dst.getSize() == 2 || dst.getSize() == sizeof(sysint_t));
- this->_emitInstruction(kX86InstPop, &dst);
- }
-
-#ifdef ASMJIT_X86
- //! @brief Pop All General-Purpose Registers.
- //!
- //! Pop EDI, ESI, EBP, EBX, EDX, ECX, and EAX.
- void popad() { this->_emitInstruction(kX86InstPopAD); }
-#endif // ASMJIT_X86
-
- //! @brief Pop Stack into EFLAGS Register (32-bit or 64-bit).
- void popf()
- {
-#ifdef ASMJIT_X86
- this->popfd();
-#else
- this->popfq();
-#endif
- }
-
-#ifdef ASMJIT_X86
- //! @brief Pop Stack into EFLAGS Register (32-bit).
- void popfd() { this->_emitInstruction(kX86InstPopFD); }
-#else
- //! @brief Pop Stack into EFLAGS Register (64-bit).
- void popfq() { this->_emitInstruction(kX86InstPopFQ); }
-#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.
- void push(const GpVar &src) { this->_emitInstruction(kX86InstPush, &src); }
-
- //! @brief Push WORD/DWORD/QWORD Onto the Stack.
- void push(const Mem &src)
- {
- ASMJIT_ASSERT(src.getSize() == 2 || src.getSize() == sizeof(sysint_t));
- this->_emitInstruction(kX86InstPush, &src);
- }
-
- //! @brief Push WORD/DWORD/QWORD Onto the Stack.
- void push(const Imm &src) { this->_emitInstruction(kX86InstPush, &src); }
-
-#ifdef ASMJIT_X86
- //! @brief Push All General-Purpose Registers.
- //!
- //! Push EAX, ECX, EDX, EBX, original ESP, EBP, ESI, and EDI.
- void pushad() { this->_emitInstruction(kX86InstPushAD); }
-#endif // ASMJIT_X86
-
- //! @brief Push EFLAGS Register (32-bit or 64-bit) onto the Stack.
- void pushf()
- {
-#ifdef ASMJIT_X86
- this->pushfd();
-#else
- this->pushfq();
-#endif
- }
-
-#ifdef ASMJIT_X86
- //! @brief Push EFLAGS Register (32-bit) onto the Stack.
- void pushfd() { this->_emitInstruction(kX86InstPushFD); }
-#else
- //! @brief Push EFLAGS Register (64-bit) onto the Stack.
- void pushfq() { this->_emitInstruction(kX86InstPushFQ); }
-#endif // ASMJIT_X86
-
- //! @brief Rotate Bits Left.
- //! @note @a src register can be only @c cl.
- void rcl(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstRcl, &dst, &src); }
-
- //! @brief Rotate Bits Left.
- void rcl(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstRcl, &dst, &src); }
-
- //! @brief Rotate Bits Left.
- //! @note @a src register can be only @c cl.
- void rcl(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstRcl, &dst, &src); }
-
- //! @brief Rotate Bits Left.
- void rcl(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstRcl, &dst, &src); }
-
- //! @brief Rotate Bits Right.
- //! @note @a src register can be only @c cl.
- void rcr(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstRcr, &dst, &src); }
-
- //! @brief Rotate Bits Right.
- void rcr(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstRcr, &dst, &src); }
-
- //! @brief Rotate Bits Right.
- //! @note @a src register can be only @c cl.
- void rcr(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstRcr, &dst, &src); }
-
- //! @brief Rotate Bits Right.
- void rcr(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstRcr, &dst, &src); }
-
- //! @brief Read Time-Stamp Counter (Pentium).
- void rdtsc(const GpVar &dst_edx, const GpVar &dst_eax)
- {
- // Destination registers must be different.
- ASMJIT_ASSERT(dst_edx.getId() != dst_eax.getId());
- this->_emitInstruction(kX86InstRdtsc, &dst_edx, &dst_eax);
- }
-
- //! @brief Read Time-Stamp Counter and Processor ID (New).
- void rdtscp(const GpVar &dst_edx, const GpVar &dst_eax, const GpVar &dst_ecx)
- {
- // Destination registers must be different.
- ASMJIT_ASSERT(dst_edx.getId() != dst_eax.getId() && dst_eax.getId() != dst_ecx.getId());
- this->_emitInstruction(kX86InstRdtscP, &dst_edx, &dst_eax, &dst_ecx);
- }
-
- //! @brief Load ECX/RCX BYTEs from DS:[ESI/RSI] to AL.
- void rep_lodsb(const GpVar &dst_val, const GpVar &src_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to dst=EAX,RAX, src=DS:ESI/RSI, cnt=ECX/RCX.
- ASMJIT_ASSERT(dst_val.getId() != src_addr.getId() && src_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepLodSB, &dst_val, &src_addr, &cnt_ecx);
- }
-
- //! @brief Load ECX/RCX DWORDs from DS:[ESI/RSI] to EAX.
- void rep_lodsd(const GpVar &dst_val, const GpVar &src_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to dst=EAX,RAX, src=DS:ESI/RSI, cnt=ECX/RCX.
- ASMJIT_ASSERT(dst_val.getId() != src_addr.getId() && src_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepLodSD, &dst_val, &src_addr, &cnt_ecx);
- }
-
-#ifdef ASMJIT_X64
- //! @brief Load ECX/RCX QWORDs from DS:[ESI/RSI] to RAX.
- void rep_lodsq(const GpVar &dst_val, const GpVar &src_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to dst=EAX,RAX, src=DS:ESI/RSI, cnt=ECX/RCX.
- ASMJIT_ASSERT(dst_val.getId() != src_addr.getId() && src_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepLodSQ, &dst_val, &src_addr, &cnt_ecx);
- }
-#endif // ASMJIT_X64
-
- //! @brief Load ECX/RCX WORDs from DS:[ESI/RSI] to AX.
- void rep_lodsw(const GpVar &dst_val, const GpVar &src_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to dst=EAX,RAX, src=DS:ESI/RSI, cnt=ECX/RCX.
- ASMJIT_ASSERT(dst_val.getId() != src_addr.getId() && src_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepLodSW, &dst_val, &src_addr, &cnt_ecx);
- }
-
- //! @brief Move ECX/RCX BYTEs from DS:[ESI/RSI] to ES:[EDI/RDI].
- void rep_movsb(const GpVar &dst_addr, const GpVar &src_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to dst=ES:EDI,RDI, src=DS:ESI/RSI, cnt=ECX/RCX.
- ASMJIT_ASSERT(dst_addr.getId() != src_addr.getId() && src_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepMovSB, &dst_addr, &src_addr, &cnt_ecx);
- }
-
- //! @brief Move ECX/RCX DWORDs from DS:[ESI/RSI] to ES:[EDI/RDI].
- void rep_movsd(const GpVar &dst_addr, const GpVar &src_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to dst=ES:EDI,RDI, src=DS:ESI/RSI, cnt=ECX/RCX.
- ASMJIT_ASSERT(dst_addr.getId() != src_addr.getId() && src_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepMovSD, &dst_addr, &src_addr, &cnt_ecx);
- }
-
-#ifdef ASMJIT_X64
- //! @brief Move ECX/RCX QWORDs from DS:[ESI/RSI] to ES:[EDI/RDI].
- void rep_movsq(const GpVar &dst_addr, const GpVar &src_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to dst=ES:EDI,RDI, src=DS:ESI/RSI, cnt=ECX/RCX.
- ASMJIT_ASSERT(dst_addr.getId() != src_addr.getId() && src_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepMovSQ, &dst_addr, &src_addr, &cnt_ecx);
- }
-#endif // ASMJIT_X64
-
- //! @brief Move ECX/RCX WORDs from DS:[ESI/RSI] to ES:[EDI/RDI].
- void rep_movsw(const GpVar &dst_addr, const GpVar &src_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to dst=ES:EDI,RDI, src=DS:ESI/RSI, cnt=ECX/RCX.
- ASMJIT_ASSERT(dst_addr.getId() != src_addr.getId() && src_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepMovSW, &dst_addr, &src_addr, &cnt_ecx);
- }
-
- //! @brief Fill ECX/RCX BYTEs at ES:[EDI/RDI] with AL.
- void rep_stosb(const GpVar &dst_addr, const GpVar &src_val, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to dst=ES:EDI,RDI, src=EAX/RAX, cnt=ECX/RCX.
- ASMJIT_ASSERT(dst_addr.getId() != src_val.getId() && src_val.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepStoSB, &dst_addr, &src_val, &cnt_ecx);
- }
-
- //! @brief Fill ECX/RCX DWORDs at ES:[EDI/RDI] with EAX.
- void rep_stosd(const GpVar &dst_addr, const GpVar &src_val, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to dst=ES:EDI,RDI, src=EAX/RAX, cnt=ECX/RCX.
- ASMJIT_ASSERT(dst_addr.getId() != src_val.getId() && src_val.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepStoSD, &dst_addr, &src_val, &cnt_ecx);
- }
-
-#ifdef ASMJIT_X64
- //! @brief Fill ECX/RCX QWORDs at ES:[EDI/RDI] with RAX.
- void rep_stosq(const GpVar &dst_addr, const GpVar &src_val, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to dst=ES:EDI,RDI, src=EAX/RAX, cnt=ECX/RCX.
- ASMJIT_ASSERT(dst_addr.getId() != src_val.getId() && src_val.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepStoSQ, &dst_addr, &src_val, &cnt_ecx);
- }
-#endif // ASMJIT_X64
-
- //! @brief Fill ECX/RCX WORDs at ES:[EDI/RDI] with AX.
- void rep_stosw(const GpVar &dst_addr, const GpVar &src_val, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to dst=ES:EDI,RDI, src=EAX/RAX, cnt=ECX/RCX.
- ASMJIT_ASSERT(dst_addr.getId() != src_val.getId() && src_val.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepStoSW, &dst_addr, &src_val, &cnt_ecx);
- }
-
- //! @brief Repeated find nonmatching BYTEs in ES:[EDI/RDI] and DS:[ESI/RDI].
- void repe_cmpsb(const GpVar &cmp1_addr, const GpVar &cmp2_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, cmp2=ES:[EDI/RDI], cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_addr.getId() && cmp2_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepECmpSB, &cmp1_addr, &cmp2_addr, &cnt_ecx);
- }
-
- //! @brief Repeated find nonmatching DWORDs in ES:[EDI/RDI] and DS:[ESI/RDI].
- void repe_cmpsd(const GpVar &cmp1_addr, const GpVar &cmp2_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, cmp2=ES:[EDI/RDI], cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_addr.getId() && cmp2_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepECmpSD, &cmp1_addr, &cmp2_addr, &cnt_ecx);
- }
-
-#ifdef ASMJIT_X64
- //! @brief Repeated find nonmatching QWORDs in ES:[EDI/RDI] and DS:[ESI/RDI].
- void repe_cmpsq(const GpVar &cmp1_addr, const GpVar &cmp2_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, cmp2=ES:[EDI/RDI], cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_addr.getId() && cmp2_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepECmpSQ, &cmp1_addr, &cmp2_addr, &cnt_ecx);
- }
-#endif // ASMJIT_X64
-
- //! @brief Repeated find nonmatching WORDs in ES:[EDI/RDI] and DS:[ESI/RDI].
- void repe_cmpsw(const GpVar &cmp1_addr, const GpVar &cmp2_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, cmp2=ES:[EDI/RDI], cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_addr.getId() && cmp2_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepECmpSW, &cmp1_addr, &cmp2_addr, &cnt_ecx);
- }
-
- //! @brief Find non-AL BYTE starting at ES:[EDI/RDI].
- void repe_scasb(const GpVar &cmp1_addr, const GpVar &cmp2_val, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, src=AL, cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_val.getId() && cmp2_val.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepEScaSB, &cmp1_addr, &cmp2_val, &cnt_ecx);
- }
-
- //! @brief Find non-EAX DWORD starting at ES:[EDI/RDI].
- void repe_scasd(const GpVar &cmp1_addr, const GpVar &cmp2_val, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, src=EAX, cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_val.getId() && cmp2_val.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepEScaSD, &cmp1_addr, &cmp2_val, &cnt_ecx);
- }
-
-#ifdef ASMJIT_X64
- //! @brief Find non-RAX QWORD starting at ES:[EDI/RDI].
- void repe_scasq(const GpVar &cmp1_addr, const GpVar &cmp2_val, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, src=RAX, cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_val.getId() && cmp2_val.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepEScaSQ, &cmp1_addr, &cmp2_val, &cnt_ecx);
- }
-#endif // ASMJIT_X64
-
- //! @brief Find non-AX WORD starting at ES:[EDI/RDI].
- void repe_scasw(const GpVar &cmp1_addr, const GpVar &cmp2_val, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, src=AX, cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_val.getId() && cmp2_val.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepEScaSW, &cmp1_addr, &cmp2_val, &cnt_ecx);
- }
-
- //! @brief Find matching BYTEs in [RDI] and [RSI].
- void repne_cmpsb(const GpVar &cmp1_addr, const GpVar &cmp2_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, cmp2=ES:[EDI/RDI], cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_addr.getId() && cmp2_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepNECmpSB, &cmp1_addr, &cmp2_addr, &cnt_ecx);
- }
-
- //! @brief Find matching DWORDs in [RDI] and [RSI].
- void repne_cmpsd(const GpVar &cmp1_addr, const GpVar &cmp2_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, cmp2=ES:[EDI/RDI], cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_addr.getId() && cmp2_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepNECmpSD, &cmp1_addr, &cmp2_addr, &cnt_ecx);
- }
-
-#ifdef ASMJIT_X64
- //! @brief Find matching QWORDs in [RDI] and [RSI].
- void repne_cmpsq(const GpVar &cmp1_addr, const GpVar &cmp2_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, cmp2=ES:[EDI/RDI], cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_addr.getId() && cmp2_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepNECmpSQ, &cmp1_addr, &cmp2_addr, &cnt_ecx);
- }
-#endif // ASMJIT_X64
-
- //! @brief Find matching WORDs in [RDI] and [RSI].
- void repne_cmpsw(const GpVar &cmp1_addr, const GpVar &cmp2_addr, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, cmp2=ES:[EDI/RDI], cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_addr.getId() && cmp2_addr.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepNECmpSW, &cmp1_addr, &cmp2_addr, &cnt_ecx);
- }
-
- //! @brief Find AL, starting at ES:[EDI/RDI].
- void repne_scasb(const GpVar &cmp1_addr, const GpVar &cmp2_val, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, src=AL, cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_val.getId() && cmp2_val.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepNEScaSB, &cmp1_addr, &cmp2_val, &cnt_ecx);
- }
-
- //! @brief Find EAX, starting at ES:[EDI/RDI].
- void repne_scasd(const GpVar &cmp1_addr, const GpVar &cmp2_val, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, src=EAX, cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_val.getId() && cmp2_val.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepNEScaSD, &cmp1_addr, &cmp2_val, &cnt_ecx);
- }
-
-#ifdef ASMJIT_X64
- //! @brief Find RAX, starting at ES:[EDI/RDI].
- void repne_scasq(const GpVar &cmp1_addr, const GpVar &cmp2_val, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, src=RAX, cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_val.getId() && cmp2_val.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepNEScaSQ, &cmp1_addr, &cmp2_val, &cnt_ecx);
- }
-#endif // ASMJIT_X64
-
- //! @brief Find AX, starting at ES:[EDI/RDI].
- void repne_scasw(const GpVar &cmp1_addr, const GpVar &cmp2_val, const GpVar &cnt_ecx)
- {
- // All registers must be unique, they will be reallocated to cmp1=ES:EDI,RDI, src=AX, cnt=ECX/RCX.
- ASMJIT_ASSERT(cmp1_addr.getId() != cmp2_val.getId() && cmp2_val.getId() != cnt_ecx.getId());
- this->_emitInstruction(kX86InstRepNEScaSW, &cmp1_addr, &cmp2_val, &cnt_ecx);
- }
-
- //! @brief Return from Procedure.
- void ret() { this->_emitReturn(nullptr, nullptr); }
-
- //! @brief Return from Procedure.
- void ret(const GpVar &first) { this->_emitReturn(&first, nullptr); }
-
- //! @brief Return from Procedure.
- void ret(const GpVar &first, const GpVar &second) { this->_emitReturn(&first, &second); }
-
- //! @brief Return from Procedure.
- void ret(const XmmVar &first) { this->_emitReturn(&first, nullptr); }
-
- //! @brief Return from Procedure.
- void ret(const XmmVar &first, const XmmVar &second) { this->_emitReturn(&first, &second); }
-
- //! @brief Rotate Bits Left.
- //! @note @a src register can be only @c cl.
- void rol(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstRol, &dst, &src); }
-
- //! @brief Rotate Bits Left.
- void rol(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstRol, &dst, &src); }
-
- //! @brief Rotate Bits Left.
- //! @note @a src register can be only @c cl.
- void rol(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstRol, &dst, &src); }
-
- //! @brief Rotate Bits Left.
- void rol(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstRol, &dst, &src); }
-
- //! @brief Rotate Bits Right.
- //! @note @a src register can be only @c cl.
- void ror(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstRor, &dst, &src); }
-
- //! @brief Rotate Bits Right.
- void ror(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstRor, &dst, &src); }
-
- //! @brief Rotate Bits Right.
- //! @note @a src register can be only @c cl.
- void ror(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstRor, &dst, &src); }
-
- //! @brief Rotate Bits Right.
- void ror(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstRor, &dst, &src); }
-
-#ifdef ASMJIT_X86
- //! @brief Store @a var (allocated to AH/AX/EAX/RAX) into Flags.
- void sahf(const GpVar &var) { this->_emitInstruction(kX86InstSahf, &var); }
-#endif // ASMJIT_X86
-
- //! @brief Integer subtraction with borrow.
- void sbb(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstSbb, &dst, &src); }
-
- //! @brief Integer subtraction with borrow.
- void sbb(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstSbb, &dst, &src); }
-
- //! @brief Integer subtraction with borrow.
- void sbb(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstSbb, &dst, &src); }
-
- //! @brief Integer subtraction with borrow.
- void sbb(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstSbb, &dst, &src); }
-
- //! @brief Integer subtraction with borrow.
- void sbb(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstSbb, &dst, &src); }
-
- //! @brief Shift Bits Left.
- //! @note @a src register can be only @c cl.
- void sal(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstSal, &dst, &src); }
-
- //! @brief Shift Bits Left.
- void sal(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstSal, &dst, &src); }
-
- //! @brief Shift Bits Left.
- //! @note @a src register can be only @c cl.
- void sal(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstSal, &dst, &src); }
-
- //! @brief Shift Bits Left.
- void sal(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstSal, &dst, &src); }
-
- //! @brief Shift Bits Right.
- //! @note @a src register can be only @c cl.
- void sar(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstSar, &dst, &src); }
-
- //! @brief Shift Bits Right.
- void sar(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstSar, &dst, &src); }
-
- //! @brief Shift Bits Right.
- //! @note @a src register can be only @c cl.
- void sar(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstSar, &dst, &src); }
-
- //! @brief Shift Bits Right.
- void sar(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstSar, &dst, &src); }
-
- //! @brief Set Byte on Condition.
- void set(kX86Cond cc, const GpVar &dst)
- {
- ASMJIT_ASSERT(dst.getSize() == 1);
- this->_emitInstruction(X86Util::getSetccInstFromCond(cc), &dst);
- }
-
- //! @brief Set Byte on Condition.
- void set(kX86Cond cc, const Mem &dst)
- {
- ASMJIT_ASSERT(dst.getSize() <= 1);
- this->_emitInstruction(X86Util::getSetccInstFromCond(cc), &dst);
- }
-
- //! @brief Set Byte on Condition.
- void seta(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetA, &dst); }
- //! @brief Set Byte on Condition.
- void seta(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetA, &dst); }
- //! @brief Set Byte on Condition.
- void setae(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetAE, &dst); }
- //! @brief Set Byte on Condition.
- void setae(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetAE, &dst); }
- //! @brief Set Byte on Condition.
- void setb(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetB, &dst); }
- //! @brief Set Byte on Condition.
- void setb(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetB, &dst); }
- //! @brief Set Byte on Condition.
- void setbe(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetBE, &dst); }
- //! @brief Set Byte on Condition.
- void setbe(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetBE, &dst); }
- //! @brief Set Byte on Condition.
- void setc(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetC, &dst); }
- //! @brief Set Byte on Condition.
- void setc(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetC, &dst); }
- //! @brief Set Byte on Condition.
- void sete(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetE, &dst); }
- //! @brief Set Byte on Condition.
- void sete(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetE, &dst); }
- //! @brief Set Byte on Condition.
- void setg(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetG, &dst); }
- //! @brief Set Byte on Condition.
- void setg(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetG, &dst); }
- //! @brief Set Byte on Condition.
- void setge(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetGE, &dst); }
- //! @brief Set Byte on Condition.
- void setge(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetGE, &dst); }
- //! @brief Set Byte on Condition.
- void setl(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetL, &dst); }
- //! @brief Set Byte on Condition.
- void setl(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetL, &dst); }
- //! @brief Set Byte on Condition.
- void setle(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetLE, &dst); }
- //! @brief Set Byte on Condition.
- void setle(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetLE, &dst); }
- //! @brief Set Byte on Condition.
- void setna(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNA, &dst); }
- //! @brief Set Byte on Condition.
- void setna(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNA, &dst); }
- //! @brief Set Byte on Condition.
- void setnae(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNAE, &dst); }
- //! @brief Set Byte on Condition.
- void setnae(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNAE, &dst); }
- //! @brief Set Byte on Condition.
- void setnb(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNB, &dst); }
- //! @brief Set Byte on Condition.
- void setnb(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNB, &dst); }
- //! @brief Set Byte on Condition.
- void setnbe(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNBE, &dst); }
- //! @brief Set Byte on Condition.
- void setnbe(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNBE, &dst); }
- //! @brief Set Byte on Condition.
- void setnc(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNC, &dst); }
- //! @brief Set Byte on Condition.
- void setnc(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNC, &dst); }
- //! @brief Set Byte on Condition.
- void setne(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNE, &dst); }
- //! @brief Set Byte on Condition.
- void setne(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNE, &dst); }
- //! @brief Set Byte on Condition.
- void setng(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNG, &dst); }
- //! @brief Set Byte on Condition.
- void setng(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNG, &dst); }
- //! @brief Set Byte on Condition.
- void setnge(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNGE, &dst); }
- //! @brief Set Byte on Condition.
- void setnge(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNGE, &dst); }
- //! @brief Set Byte on Condition.
- void setnl(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNL, &dst); }
- //! @brief Set Byte on Condition.
- void setnl(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNL, &dst); }
- //! @brief Set Byte on Condition.
- void setnle(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNLE, &dst); }
- //! @brief Set Byte on Condition.
- void setnle(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNLE, &dst); }
- //! @brief Set Byte on Condition.
- void setno(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNO, &dst); }
- //! @brief Set Byte on Condition.
- void setno(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNO, &dst); }
- //! @brief Set Byte on Condition.
- void setnp(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNP, &dst); }
- //! @brief Set Byte on Condition.
- void setnp(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNP, &dst); }
- //! @brief Set Byte on Condition.
- void setns(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNS, &dst); }
- //! @brief Set Byte on Condition.
- void setns(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNS, &dst); }
- //! @brief Set Byte on Condition.
- void setnz(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetNZ, &dst); }
- //! @brief Set Byte on Condition.
- void setnz(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetNZ, &dst); }
- //! @brief Set Byte on Condition.
- void seto(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetO, &dst); }
- //! @brief Set Byte on Condition.
- void seto(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetO, &dst); }
- //! @brief Set Byte on Condition.
- void setp(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetP, &dst); }
- //! @brief Set Byte on Condition.
- void setp(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetP, &dst); }
- //! @brief Set Byte on Condition.
- void setpe(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetPE, &dst); }
- //! @brief Set Byte on Condition.
- void setpe(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetPE, &dst); }
- //! @brief Set Byte on Condition.
- void setpo(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetPO, &dst); }
- //! @brief Set Byte on Condition.
- void setpo(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetPO, &dst); }
- //! @brief Set Byte on Condition.
- void sets(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetS, &dst); }
- //! @brief Set Byte on Condition.
- void sets(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetS, &dst); }
- //! @brief Set Byte on Condition.
- void setz(const GpVar &dst) { ASMJIT_ASSERT(dst.getSize() == 1); this->_emitInstruction(kX86InstSetZ, &dst); }
- //! @brief Set Byte on Condition.
- void setz(const Mem &dst) { ASMJIT_ASSERT(dst.getSize() <= 1); this->_emitInstruction(kX86InstSetZ, &dst); }
-
- //! @brief Shift Bits Left.
- //! @note @a src register can be only @c cl.
- void shl(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstShl, &dst, &src); }
-
- //! @brief Shift Bits Left.
- void shl(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstShl, &dst, &src); }
-
- //! @brief Shift Bits Left.
- //! @note @a src register can be only @c cl.
- void shl(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstShl, &dst, &src); }
-
- //! @brief Shift Bits Left.
- void shl(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstShl, &dst, &src); }
-
- //! @brief Shift Bits Right.
- //! @note @a src register can be only @c cl.
- void shr(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstShr, &dst, &src); }
-
- //! @brief Shift Bits Right.
- void shr(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstShr, &dst, &src); }
-
- //! @brief Shift Bits Right.
- //! @note @a src register can be only @c cl.
- void shr(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstShr, &dst, &src); }
-
- //! @brief Shift Bits Right.
- void shr(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstShr, &dst, &src); }
-
- //! @brief Double Precision Shift Left.
- //! @note src2 register can be only @c cl register.
- void shld(const GpVar &dst, const GpVar &src1, const GpVar &src2) { this->_emitInstruction(kX86InstShld, &dst, &src1, &src2); }
-
- //! @brief Double Precision Shift Left.
- void shld(const GpVar &dst, const GpVar &src1, const Imm &src2) { this->_emitInstruction(kX86InstShld, &dst, &src1, &src2); }
-
- //! @brief Double Precision Shift Left.
- //! @note src2 register can be only @c cl register.
- void shld(const Mem &dst, const GpVar &src1, const GpVar &src2) { this->_emitInstruction(kX86InstShld, &dst, &src1, &src2); }
-
- //! @brief Double Precision Shift Left.
- void shld(const Mem &dst, const GpVar &src1, const Imm &src2) { this->_emitInstruction(kX86InstShld, &dst, &src1, &src2); }
-
- //! @brief Double Precision Shift Right.
- //! @note src2 register can be only @c cl register.
- void shrd(const GpVar &dst, const GpVar &src1, const GpVar &src2) { this->_emitInstruction(kX86InstShrd, &dst, &src1, &src2); }
-
- //! @brief Double Precision Shift Right.
- void shrd(const GpVar &dst, const GpVar &src1, const Imm &src2) { this->_emitInstruction(kX86InstShrd, &dst, &src1, &src2); }
-
- //! @brief Double Precision Shift Right.
- //! @note src2 register can be only @c cl register.
- void shrd(const Mem &dst, const GpVar &src1, const GpVar &src2) { this->_emitInstruction(kX86InstShrd, &dst, &src1, &src2); }
-
- //! @brief Double Precision Shift Right.
- void shrd(const Mem &dst, const GpVar &src1, const Imm &src2) { this->_emitInstruction(kX86InstShrd, &dst, &src1, &src2); }
-
- //! @brief Set Carry Flag to 1.
- void stc() { this->_emitInstruction(kX86InstStc); }
-
- //! @brief Set Direction Flag to 1.
- void std() { this->_emitInstruction(kX86InstStd); }
-
- //! @brief Subtract.
- void sub(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstSub, &dst, &src); }
-
- //! @brief Subtract.
- void sub(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstSub, &dst, &src); }
-
- //! @brief Subtract.
- void sub(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstSub, &dst, &src); }
-
- //! @brief Subtract.
- void sub(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstSub, &dst, &src); }
-
- //! @brief Subtract.
- void sub(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstSub, &dst, &src); }
-
- //! @brief Logical Compare.
- void test(const GpVar &op1, const GpVar &op2) { this->_emitInstruction(kX86InstTest, &op1, &op2); }
-
- //! @brief Logical Compare.
- void test(const GpVar &op1, const Imm &op2) { this->_emitInstruction(kX86InstTest, &op1, &op2); }
-
- //! @brief Logical Compare.
- void test(const Mem &op1, const GpVar &op2) { this->_emitInstruction(kX86InstTest, &op1, &op2); }
-
- //! @brief Logical Compare.
- void test(const Mem &op1, const Imm &op2) { this->_emitInstruction(kX86InstTest, &op1, &op2); }
-
- //! @brief Undefined instruction - Raise invalid opcode exception.
- void ud2() { this->_emitInstruction(kX86InstUd2); }
-
- //! @brief Exchange and Add.
- void xadd(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstXadd, &dst, &src); }
-
- //! @brief Exchange and Add.
- void xadd(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstXadd, &dst, &src); }
-
- //! @brief Exchange Register/Memory with Register.
- void xchg(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstXchg, &dst, &src); }
-
- //! @brief Exchange Register/Memory with Register.
- void xchg(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstXchg, &dst, &src); }
-
- //! @brief Exchange Register/Memory with Register.
- void xchg(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstXchg, &src, &dst); }
-
- //! @brief Exchange Register/Memory with Register.
- void xor_(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstXor, &dst, &src); }
-
- //! @brief Exchange Register/Memory with Register.
- void xor_(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstXor, &dst, &src); }
-
- //! @brief Exchange Register/Memory with Register.
- void xor_(const GpVar &dst, const Imm &src) { this->_emitInstruction(kX86InstXor, &dst, &src); }
-
- //! @brief Exchange Register/Memory with Register.
- void xor_(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstXor, &dst, &src); }
-
- //! @brief Exchange Register/Memory with Register.
- void xor_(const Mem &dst, const Imm &src) { this->_emitInstruction(kX86InstXor, &dst, &src); }
-
- // --------------------------------------------------------------------------
- // [MMX]
- // --------------------------------------------------------------------------
-
- //! @brief Empty MMX state.
- void emms() { this->_emitInstruction(kX86InstEmms); }
-
- //! @brief Move DWord (MMX).
- void movd(const Mem &dst, const MmVar &src) { this->_emitInstruction(kX86InstMovD, &dst, &src); }
-
- //! @brief Move DWord (MMX).
- void movd(const GpVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstMovD, &dst, &src); }
-
- //! @brief Move DWord (MMX).
- void movd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovD, &dst, &src); }
-
- //! @brief Move DWord (MMX).
- void movd(const MmVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstMovD, &dst, &src); }
-
- //! @brief Move QWord (MMX).
- void movq(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstMovQ, &dst, &src); }
-
- //! @brief Move QWord (MMX).
- void movq(const Mem &dst, const MmVar &src) { this->_emitInstruction(kX86InstMovQ, &dst, &src); }
-
-#ifdef ASMJIT_X64
- //! @brief Move QWord (MMX).
- void movq(const GpVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstMovQ, &dst, &src); }
-#endif
-
- //! @brief Move QWord (MMX).
- void movq(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovQ, &dst, &src); }
-
-#ifdef ASMJIT_X64
- //! @brief Move QWord (MMX).
- void movq(const MmVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstMovQ, &dst, &src); }
-#endif
-
- //! @brief Pack with Signed Saturation (MMX).
- void packsswb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPackSSWB, &dst, &src); }
-
- //! @brief Pack with Signed Saturation (MMX).
- void packsswb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPackSSWB, &dst, &src); }
-
- //! @brief Pack with Signed Saturation (MMX).
- void packssdw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPackSSDW, &dst, &src); }
-
- //! @brief Pack with Signed Saturation (MMX).
- void packssdw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPackSSDW, &dst, &src); }
-
- //! @brief Pack with Unsigned Saturation (MMX).
- void packuswb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPackUSWB, &dst, &src); }
-
- //! @brief Pack with Unsigned Saturation (MMX).
- void packuswb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPackUSWB, &dst, &src); }
-
- //! @brief Packed BYTE Add (MMX).
- void paddb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAddB, &dst, &src); }
-
- //! @brief Packed BYTE Add (MMX).
- void paddb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddB, &dst, &src); }
-
- //! @brief Packed WORD Add (MMX).
- void paddw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAddW, &dst, &src); }
-
- //! @brief Packed WORD Add (MMX).
- void paddw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddW, &dst, &src); }
-
- //! @brief Packed DWORD Add (MMX).
- void paddd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAddD, &dst, &src); }
-
- //! @brief Packed DWORD Add (MMX).
- void paddd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddD, &dst, &src); }
-
- //! @brief Packed Add with Saturation (MMX).
- void paddsb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAddSB, &dst, &src); }
-
- //! @brief Packed Add with Saturation (MMX).
- void paddsb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddSB, &dst, &src); }
-
- //! @brief Packed Add with Saturation (MMX).
- void paddsw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAddSW, &dst, &src); }
-
- //! @brief Packed Add with Saturation (MMX).
- void paddsw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddSW, &dst, &src); }
-
- //! @brief Packed Add Unsigned with Saturation (MMX).
- void paddusb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAddUSB, &dst, &src); }
-
- //! @brief Packed Add Unsigned with Saturation (MMX).
- void paddusb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddUSB, &dst, &src); }
-
- //! @brief Packed Add Unsigned with Saturation (MMX).
- void paddusw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAddUSW, &dst, &src); }
-
- //! @brief Packed Add Unsigned with Saturation (MMX).
- void paddusw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddUSW, &dst, &src); }
-
- //! @brief Logical AND (MMX).
- void pand(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAnd, &dst, &src); }
-
- //! @brief Logical AND (MMX).
- void pand(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAnd, &dst, &src); }
-
- //! @brief Logical AND Not (MMX).
- void pandn(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAndN, &dst, &src); }
-
- //! @brief Logical AND Not (MMX).
- void pandn(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAndN, &dst, &src); }
-
- //! @brief Packed Compare for Equal (BYTES) (MMX).
- void pcmpeqb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPCmpEqB, &dst, &src); }
-
- //! @brief Packed Compare for Equal (BYTES) (MMX).
- void pcmpeqb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpEqB, &dst, &src); }
-
- //! @brief Packed Compare for Equal (WORDS) (MMX).
- void pcmpeqw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPCmpEqW, &dst, &src); }
-
- //! @brief Packed Compare for Equal (WORDS) (MMX).
- void pcmpeqw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpEqW, &dst, &src); }
-
- //! @brief Packed Compare for Equal (DWORDS) (MMX).
- void pcmpeqd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPCmpEqD, &dst, &src); }
-
- //! @brief Packed Compare for Equal (DWORDS) (MMX).
- void pcmpeqd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpEqD, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (BYTES) (MMX).
- void pcmpgtb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPCmpGtB, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (BYTES) (MMX).
- void pcmpgtb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpGtB, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (WORDS) (MMX).
- void pcmpgtw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPCmpGtW, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (WORDS) (MMX).
- void pcmpgtw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpGtW, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (DWORDS) (MMX).
- void pcmpgtd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPCmpGtD, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (DWORDS) (MMX).
- void pcmpgtd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpGtD, &dst, &src); }
-
- //! @brief Packed Multiply High (MMX).
- void pmulhw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPMulHW, &dst, &src); }
-
- //! @brief Packed Multiply High (MMX).
- void pmulhw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMulHW, &dst, &src); }
-
- //! @brief Packed Multiply Low (MMX).
- void pmullw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPMulLW, &dst, &src); }
-
- //! @brief Packed Multiply Low (MMX).
- void pmullw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMulLW, &dst, &src); }
-
- //! @brief Bitwise Logical OR (MMX).
- void por(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPOr, &dst, &src); }
-
- //! @brief Bitwise Logical OR (MMX).
- void por(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPOr, &dst, &src); }
-
- //! @brief Packed Multiply and Add (MMX).
- void pmaddwd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPMAddWD, &dst, &src); }
-
- //! @brief Packed Multiply and Add (MMX).
- void pmaddwd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMAddWD, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (MMX).
- void pslld(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSllD, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (MMX).
- void pslld(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSllD, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (MMX).
- void pslld(const MmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSllD, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (MMX).
- void psllq(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSllQ, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (MMX).
- void psllq(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSllQ, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (MMX).
- void psllq(const MmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSllQ, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (MMX).
- void psllw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSllW, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (MMX).
- void psllw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSllW, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (MMX).
- void psllw(const MmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSllW, &dst, &src); }
-
- //! @brief Packed Shift Right Arithmetic (MMX).
- void psrad(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSraD, &dst, &src); }
-
- //! @brief Packed Shift Right Arithmetic (MMX).
- void psrad(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSraD, &dst, &src);}
-
- //! @brief Packed Shift Right Arithmetic (MMX).
- void psrad(const MmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSraD, &dst, &src); }
-
- //! @brief Packed Shift Right Arithmetic (MMX).
- void psraw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSraW, &dst, &src); }
-
- //! @brief Packed Shift Right Arithmetic (MMX).
- void psraw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSraW, &dst, &src); }
-
- //! @brief Packed Shift Right Arithmetic (MMX).
- void psraw(const MmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSraW, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (MMX).
- void psrld(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSrlD, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (MMX).
- void psrld(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSrlD, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (MMX).
- void psrld(const MmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSrlD, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (MMX).
- void psrlq(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSrlQ, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (MMX).
- void psrlq(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSrlQ, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (MMX).
- void psrlq(const MmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSrlQ, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (MMX).
- void psrlw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSrlW, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (MMX).
- void psrlw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSrlW, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (MMX).
- void psrlw(const MmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSrlW, &dst, &src); }
-
- //! @brief Packed Subtract (MMX).
- void psubb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSubB, &dst, &src); }
-
- //! @brief Packed Subtract (MMX).
- void psubb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubB, &dst, &src); }
-
- //! @brief Packed Subtract (MMX).
- void psubw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSubW, &dst, &src); }
-
- //! @brief Packed Subtract (MMX).
- void psubw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubW, &dst, &src); }
-
- //! @brief Packed Subtract (MMX).
- void psubd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSubD, &dst, &src); }
-
- //! @brief Packed Subtract (MMX).
- void psubd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubD, &dst, &src); }
-
- //! @brief Packed Subtract with Saturation (MMX).
- void psubsb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSubSB, &dst, &src); }
-
- //! @brief Packed Subtract with Saturation (MMX).
- void psubsb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubSB, &dst, &src); }
-
- //! @brief Packed Subtract with Saturation (MMX).
- void psubsw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSubSW, &dst, &src); }
-
- //! @brief Packed Subtract with Saturation (MMX).
- void psubsw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubSW, &dst, &src); }
-
- //! @brief Packed Subtract with Unsigned Saturation (MMX).
- void psubusb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSubUSB, &dst, &src); }
-
- //! @brief Packed Subtract with Unsigned Saturation (MMX).
- void psubusb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubUSB, &dst, &src); }
-
- //! @brief Packed Subtract with Unsigned Saturation (MMX).
- void psubusw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSubUSW, &dst, &src); }
-
- //! @brief Packed Subtract with Unsigned Saturation (MMX).
- void psubusw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubUSW, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpckhbw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPunpckHBW, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpckhbw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckHBW, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpckhwd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPunpckHWD, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpckhwd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckHWD, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpckhdq(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPunpckHDQ, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpckhdq(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckHDQ, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpcklbw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPunpckLBW, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpcklbw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckLBW, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpcklwd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPunpckLWD, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpcklwd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckLWD, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpckldq(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPunpckLDQ, &dst, &src); }
-
- //! @brief Unpack High Packed Data (MMX).
- void punpckldq(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckLDQ, &dst, &src); }
-
- //! @brief Bitwise Exclusive OR (MMX).
- void pxor(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPXor, &dst, &src); }
-
- //! @brief Bitwise Exclusive OR (MMX).
- void pxor(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPXor, &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() ).
- void femms() { this->_emitInstruction(kX86InstFEmms); }
-
- //! @brief Packed SP-FP to Integer Convert (3dNow!).
- void pf2id(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPF2ID, &dst, &src); }
-
- //! @brief Packed SP-FP to Integer Convert (3dNow!).
- void pf2id(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPF2ID, &dst, &src); }
-
- //! @brief Packed SP-FP to Integer Word Convert (3dNow!).
- void pf2iw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPF2IW, &dst, &src); }
-
- //! @brief Packed SP-FP to Integer Word Convert (3dNow!).
- void pf2iw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPF2IW, &dst, &src); }
-
- //! @brief Packed SP-FP Accumulate (3dNow!).
- void pfacc(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFAcc, &dst, &src); }
-
- //! @brief Packed SP-FP Accumulate (3dNow!).
- void pfacc(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFAcc, &dst, &src); }
-
- //! @brief Packed SP-FP Addition (3dNow!).
- void pfadd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFAdd, &dst, &src); }
-
- //! @brief Packed SP-FP Addition (3dNow!).
- void pfadd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFAdd, &dst, &src); }
-
- //! @brief Packed SP-FP Compare - dst == src (3dNow!).
- void pfcmpeq(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFCmpEQ, &dst, &src); }
-
- //! @brief Packed SP-FP Compare - dst == src (3dNow!).
- void pfcmpeq(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFCmpEQ, &dst, &src); }
-
- //! @brief Packed SP-FP Compare - dst >= src (3dNow!).
- void pfcmpge(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFCmpGE, &dst, &src); }
-
- //! @brief Packed SP-FP Compare - dst >= src (3dNow!).
- void pfcmpge(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFCmpGE, &dst, &src); }
-
- //! @brief Packed SP-FP Compare - dst > src (3dNow!).
- void pfcmpgt(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFCmpGT, &dst, &src); }
-
- //! @brief Packed SP-FP Compare - dst > src (3dNow!).
- void pfcmpgt(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFCmpGT, &dst, &src); }
-
- //! @brief Packed SP-FP Maximum (3dNow!).
- void pfmax(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFMax, &dst, &src); }
-
- //! @brief Packed SP-FP Maximum (3dNow!).
- void pfmax(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFMax, &dst, &src); }
-
- //! @brief Packed SP-FP Minimum (3dNow!).
- void pfmin(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFMin, &dst, &src); }
-
- //! @brief Packed SP-FP Minimum (3dNow!).
- void pfmin(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFMin, &dst, &src); }
-
- //! @brief Packed SP-FP Multiply (3dNow!).
- void pfmul(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFMul, &dst, &src); }
-
- //! @brief Packed SP-FP Multiply (3dNow!).
- void pfmul(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFMul, &dst, &src); }
-
- //! @brief Packed SP-FP Negative Accumulate (3dNow!).
- void pfnacc(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFNAcc, &dst, &src); }
-
- //! @brief Packed SP-FP Negative Accumulate (3dNow!).
- void pfnacc(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFNAcc, &dst, &src); }
-
- //! @brief Packed SP-FP Mixed Accumulate (3dNow!).
- void pfpnacc(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFPNAcc, &dst, &src); }
-
- //! @brief Packed SP-FP Mixed Accumulate (3dNow!).
- void pfpnacc(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFPNAcc, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal Approximation (3dNow!).
- void pfrcp(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFRcp, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal Approximation (3dNow!).
- void pfrcp(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFRcp, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal, First Iteration Step (3dNow!).
- void pfrcpit1(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFRcpIt1, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal, First Iteration Step (3dNow!).
- void pfrcpit1(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFRcpIt1, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal, Second Iteration Step (3dNow!).
- void pfrcpit2(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFRcpIt2, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal, Second Iteration Step (3dNow!).
- void pfrcpit2(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFRcpIt2, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal Square Root, First Iteration Step (3dNow!).
- void pfrsqit1(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFRSqIt1, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal Square Root, First Iteration Step (3dNow!).
- void pfrsqit1(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFRSqIt1, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal Square Root Approximation (3dNow!).
- void pfrsqrt(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFRSqrt, &dst, &src); }
-
- //! @brief Packed SP-FP Reciprocal Square Root Approximation (3dNow!).
- void pfrsqrt(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFRSqrt, &dst, &src); }
-
- //! @brief Packed SP-FP Subtract (3dNow!).
- void pfsub(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFSub, &dst, &src); }
-
- //! @brief Packed SP-FP Subtract (3dNow!).
- void pfsub(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFSub, &dst, &src); }
-
- //! @brief Packed SP-FP Reverse Subtract (3dNow!).
- void pfsubr(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPFSubR, &dst, &src); }
-
- //! @brief Packed SP-FP Reverse Subtract (3dNow!).
- void pfsubr(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPFSubR, &dst, &src); }
-
- //! @brief Packed DWords to SP-FP (3dNow!).
- void pi2fd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPI2FD, &dst, &src); }
-
- //! @brief Packed DWords to SP-FP (3dNow!).
- void pi2fd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPI2FD, &dst, &src); }
-
- //! @brief Packed Words to SP-FP (3dNow!).
- void pi2fw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPI2FW, &dst, &src); }
-
- //! @brief Packed Words to SP-FP (3dNow!).
- void pi2fw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPI2FW, &dst, &src); }
-
- //! @brief Packed swap DWord (3dNow!)
- void pswapd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSwapD, &dst, &src); }
-
- //! @brief Packed swap DWord (3dNow!)
- void pswapd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSwapD, &dst, &src); }
-
- // --------------------------------------------------------------------------
- // [SSE]
- // --------------------------------------------------------------------------
-
- //! @brief Packed SP-FP Add (SSE).
- void addps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstAddPS, &dst, &src); }
- //! @brief Packed SP-FP Add (SSE).
- void addps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstAddPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Add (SSE).
- void addss(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstAddSS, &dst, &src); }
- //! @brief Scalar SP-FP Add (SSE).
- void addss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstAddSS, &dst, &src); }
-
- //! @brief Bit-wise Logical And Not For SP-FP (SSE).
- void andnps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstAndnPS, &dst, &src); }
- //! @brief Bit-wise Logical And Not For SP-FP (SSE).
- void andnps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstAndnPS, &dst, &src); }
-
- //! @brief Bit-wise Logical And For SP-FP (SSE).
- void andps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstAndPS, &dst, &src); }
- //! @brief Bit-wise Logical And For SP-FP (SSE).
- void andps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstAndPS, &dst, &src); }
-
- //! @brief Packed SP-FP Compare (SSE).
- void cmpps(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstCmpPS, &dst, &src, &imm8); }
- //! @brief Packed SP-FP Compare (SSE).
- void cmpps(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstCmpPS, &dst, &src, &imm8); }
-
- //! @brief Compare Scalar SP-FP Values (SSE).
- void cmpss(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstCmpSS, &dst, &src, &imm8); }
- //! @brief Compare Scalar SP-FP Values (SSE).
- void cmpss(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstCmpSS, &dst, &src, &imm8); }
-
- //! @brief Scalar Ordered SP-FP Compare and Set EFLAGS (SSE).
- void comiss(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstComISS, &dst, &src); }
- //! @brief Scalar Ordered SP-FP Compare and Set EFLAGS (SSE).
- void comiss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstComISS, &dst, &src); }
-
- //! @brief Packed Signed INT32 to Packed SP-FP Conversion (SSE).
- void cvtpi2ps(const XmmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstCvtPI2PS, &dst, &src); }
- //! @brief Packed Signed INT32 to Packed SP-FP Conversion (SSE).
- void cvtpi2ps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtPI2PS, &dst, &src); }
-
- //! @brief Packed SP-FP to Packed INT32 Conversion (SSE).
- void cvtps2pi(const MmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvtPS2PI, &dst, &src); }
- //! @brief Packed SP-FP to Packed INT32 Conversion (SSE).
- void cvtps2pi(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtPS2PI, &dst, &src); }
-
- //! @brief Scalar Signed INT32 to SP-FP Conversion (SSE).
- void cvtsi2ss(const XmmVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCvtSI2SS, &dst, &src); }
- //! @brief Scalar Signed INT32 to SP-FP Conversion (SSE).
- void cvtsi2ss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtSI2SS, &dst, &src); }
-
- //! @brief Scalar SP-FP to Signed INT32 Conversion (SSE).
- void cvtss2si(const GpVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvtSS2SI, &dst, &src); }
- //! @brief Scalar SP-FP to Signed INT32 Conversion (SSE).
- void cvtss2si(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtSS2SI, &dst, &src); }
-
- //! @brief Packed SP-FP to Packed INT32 Conversion (truncate) (SSE).
- void cvttps2pi(const MmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvttPS2PI, &dst, &src); }
- //! @brief Packed SP-FP to Packed INT32 Conversion (truncate) (SSE).
- void cvttps2pi(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvttPS2PI, &dst, &src); }
-
- //! @brief Scalar SP-FP to Signed INT32 Conversion (truncate) (SSE).
- void cvttss2si(const GpVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvttSS2SI, &dst, &src); }
- //! @brief Scalar SP-FP to Signed INT32 Conversion (truncate) (SSE).
- void cvttss2si(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvttSS2SI, &dst, &src); }
-
- //! @brief Packed SP-FP Divide (SSE).
- void divps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstDivPS, &dst, &src); }
- //! @brief Packed SP-FP Divide (SSE).
- void divps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstDivPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Divide (SSE).
- void divss(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstDivSS, &dst, &src); }
- //! @brief Scalar SP-FP Divide (SSE).
- void divss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstDivSS, &dst, &src); }
-
- //! @brief Load Streaming SIMD Extension Control/Status (SSE).
- void ldmxcsr(const Mem &src) { this->_emitInstruction(kX86InstLdMXCSR, &src); }
-
- //! @brief Byte Mask Write (SSE).
- //!
- //! @note The default memory location is specified by DS:EDI.
- void maskmovq(const GpVar &dst_ptr, const MmVar &data, const MmVar &mask) { this->_emitInstruction(kX86InstMaskMovQ, &dst_ptr, &data, &mask); }
-
- //! @brief Packed SP-FP Maximum (SSE).
- void maxps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMaxPS, &dst, &src); }
- //! @brief Packed SP-FP Maximum (SSE).
- void maxps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMaxPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Maximum (SSE).
- void maxss(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMaxSS, &dst, &src); }
- //! @brief Scalar SP-FP Maximum (SSE).
- void maxss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMaxSS, &dst, &src); }
-
- //! @brief Packed SP-FP Minimum (SSE).
- void minps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMinPS, &dst, &src); }
- //! @brief Packed SP-FP Minimum (SSE).
- void minps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMinPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Minimum (SSE).
- void minss(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMinSS, &dst, &src); }
- //! @brief Scalar SP-FP Minimum (SSE).
- void minss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMinSS, &dst, &src); }
-
- //! @brief Move Aligned Packed SP-FP Values (SSE).
- void movaps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovAPS, &dst, &src); }
- //! @brief Move Aligned Packed SP-FP Values (SSE).
- void movaps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovAPS, &dst, &src); }
-
- //! @brief Move Aligned Packed SP-FP Values (SSE).
- void movaps(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovAPS, &dst, &src); }
-
- //! @brief Move DWord.
- void movd(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovD, &dst, &src); }
- //! @brief Move DWord.
- void movd(const GpVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovD, &dst, &src); }
- //! @brief Move DWord.
- void movd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovD, &dst, &src); }
- //! @brief Move DWord.
- void movd(const XmmVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstMovD, &dst, &src); }
-
- //! @brief Move QWord (SSE).
- void movq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovQ, &dst, &src); }
- //! @brief Move QWord (SSE).
- void movq(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovQ, &dst, &src); }
-#ifdef ASMJIT_X64
- //! @brief Move QWord (SSE).
- void movq(const GpVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovQ, &dst, &src); }
-#endif // ASMJIT_X64
- //! @brief Move QWord (SSE).
- void movq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovQ, &dst, &src); }
-#ifdef ASMJIT_X64
- //! @brief Move QWord (SSE).
- void movq(const XmmVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstMovQ, &dst, &src); }
-#endif // ASMJIT_X64
-
- //! @brief Move 64 Bits Non Temporal (SSE).
- void movntq(const Mem &dst, const MmVar &src) { this->_emitInstruction(kX86InstMovNTQ, &dst, &src); }
-
- //! @brief High to Low Packed SP-FP (SSE).
- void movhlps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovHLPS, &dst, &src); }
-
- //! @brief Move High Packed SP-FP (SSE).
- void movhps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovHPS, &dst, &src); }
-
- //! @brief Move High Packed SP-FP (SSE).
- void movhps(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovHPS, &dst, &src); }
-
- //! @brief Move Low to High Packed SP-FP (SSE).
- void movlhps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovLHPS, &dst, &src); }
-
- //! @brief Move Low Packed SP-FP (SSE).
- void movlps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovLPS, &dst, &src); }
-
- //! @brief Move Low Packed SP-FP (SSE).
- void movlps(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovLPS, &dst, &src); }
-
- //! @brief Move Aligned Four Packed SP-FP Non Temporal (SSE).
- void movntps(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovNTPS, &dst, &src); }
-
- //! @brief Move Scalar SP-FP (SSE).
- void movss(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovSS, &dst, &src); }
-
- //! @brief Move Scalar SP-FP (SSE).
- void movss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovSS, &dst, &src); }
-
- //! @brief Move Scalar SP-FP (SSE).
- void movss(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovSS, &dst, &src); }
-
- //! @brief Move Unaligned Packed SP-FP Values (SSE).
- void movups(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovUPS, &dst, &src); }
- //! @brief Move Unaligned Packed SP-FP Values (SSE).
- void movups(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovUPS, &dst, &src); }
-
- //! @brief Move Unaligned Packed SP-FP Values (SSE).
- void movups(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovUPS, &dst, &src); }
-
- //! @brief Packed SP-FP Multiply (SSE).
- void mulps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMulPS, &dst, &src); }
- //! @brief Packed SP-FP Multiply (SSE).
- void mulps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMulPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Multiply (SSE).
- void mulss(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMulSS, &dst, &src); }
- //! @brief Scalar SP-FP Multiply (SSE).
- void mulss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMulSS, &dst, &src); }
-
- //! @brief Bit-wise Logical OR for SP-FP Data (SSE).
- void orps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstOrPS, &dst, &src); }
- //! @brief Bit-wise Logical OR for SP-FP Data (SSE).
- void orps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstOrPS, &dst, &src); }
-
- //! @brief Packed Average (SSE).
- void pavgb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAvgB, &dst, &src); }
- //! @brief Packed Average (SSE).
- void pavgb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAvgB, &dst, &src); }
-
- //! @brief Packed Average (SSE).
- void pavgw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAvgW, &dst, &src); }
- //! @brief Packed Average (SSE).
- void pavgw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAvgW, &dst, &src); }
-
- //! @brief Extract Word (SSE).
- void pextrw(const GpVar &dst, const MmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPExtrW, &dst, &src, &imm8); }
-
- //! @brief Insert Word (SSE).
- void pinsrw(const MmVar &dst, const GpVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPInsRW, &dst, &src, &imm8); }
- //! @brief Insert Word (SSE).
- void pinsrw(const MmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPInsRW, &dst, &src, &imm8); }
-
- //! @brief Packed Signed Integer Word Maximum (SSE).
- void pmaxsw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPMaxSW, &dst, &src); }
- //! @brief Packed Signed Integer Word Maximum (SSE).
- void pmaxsw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMaxSW, &dst, &src); }
-
- //! @brief Packed Unsigned Integer Byte Maximum (SSE).
- void pmaxub(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPMaxUB, &dst, &src); }
- //! @brief Packed Unsigned Integer Byte Maximum (SSE).
- void pmaxub(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMaxUB, &dst, &src); }
-
- //! @brief Packed Signed Integer Word Minimum (SSE).
- void pminsw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPMinSW, &dst, &src); }
- //! @brief Packed Signed Integer Word Minimum (SSE).
- void pminsw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMinSW, &dst, &src); }
-
- //! @brief Packed Unsigned Integer Byte Minimum (SSE).
- void pminub(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPMinUB, &dst, &src); }
- //! @brief Packed Unsigned Integer Byte Minimum (SSE).
- void pminub(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMinUB, &dst, &src); }
-
- //! @brief Move Byte Mask To Integer (SSE).
- void pmovmskb(const GpVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPMovMskB, &dst, &src); }
-
- //! @brief Packed Multiply High Unsigned (SSE).
- void pmulhuw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPMulHUW, &dst, &src); }
- //! @brief Packed Multiply High Unsigned (SSE).
- void pmulhuw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMulHUW, &dst, &src); }
-
- //! @brief Packed Sum of Absolute Differences (SSE).
- void psadbw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSADBW, &dst, &src); }
- //! @brief Packed Sum of Absolute Differences (SSE).
- void psadbw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSADBW, &dst, &src); }
-
- //! @brief Packed Shuffle word (SSE).
- void pshufw(const MmVar &dst, const MmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPShufW, &dst, &src, &imm8); }
- //! @brief Packed Shuffle word (SSE).
- void pshufw(const MmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPShufW, &dst, &src, &imm8); }
-
- //! @brief Packed SP-FP Reciprocal (SSE).
- void rcpps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstRcpPS, &dst, &src); }
- //! @brief Packed SP-FP Reciprocal (SSE).
- void rcpps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstRcpPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Reciprocal (SSE).
- void rcpss(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstRcpSS, &dst, &src); }
- //! @brief Scalar SP-FP Reciprocal (SSE).
- void rcpss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstRcpSS, &dst, &src); }
-
- //! @brief Prefetch (SSE).
- void prefetch(const Mem &mem, const Imm &hint) { this->_emitInstruction(kX86InstPrefetch, &mem, &hint); }
-
- //! @brief Compute Sum of Absolute Differences (SSE).
- void psadbw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSADBW, &dst, &src); }
- //! @brief Compute Sum of Absolute Differences (SSE).
- void psadbw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSADBW, &dst, &src); }
-
- //! @brief Packed SP-FP Square Root Reciprocal (SSE).
- void rsqrtps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstSqrtPS, &dst, &src); }
- //! @brief Packed SP-FP Square Root Reciprocal (SSE).
- void rsqrtps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstSqrtPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Square Root Reciprocal (SSE).
- void rsqrtss(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstSqrtSS, &dst, &src); }
- //! @brief Scalar SP-FP Square Root Reciprocal (SSE).
- void rsqrtss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstSqrtSS, &dst, &src); }
-
- //! @brief Store fence (SSE).
- void sfence() { this->_emitInstruction(kX86InstSFence); }
-
- //! @brief Shuffle SP-FP (SSE).
- void shufps(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstShufPS, &dst, &src, &imm8); }
- //! @brief Shuffle SP-FP (SSE).
- void shufps(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstShufPS, &dst, &src, &imm8); }
-
- //! @brief Packed SP-FP Square Root (SSE).
- void sqrtps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstSqrtPS, &dst, &src); }
- //! @brief Packed SP-FP Square Root (SSE).
- void sqrtps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstSqrtPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Square Root (SSE).
- void sqrtss(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstSqrtSS, &dst, &src); }
- //! @brief Scalar SP-FP Square Root (SSE).
- void sqrtss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstSqrtSS, &dst, &src); }
-
- //! @brief Store Streaming SIMD Extension Control/Status (SSE).
- void stmxcsr(const Mem &dst) { this->_emitInstruction(kX86InstStMXCSR, &dst); }
-
- //! @brief Packed SP-FP Subtract (SSE).
- void subps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstSubPS, &dst, &src); }
- //! @brief Packed SP-FP Subtract (SSE).
- void subps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstSubPS, &dst, &src); }
-
- //! @brief Scalar SP-FP Subtract (SSE).
- void subss(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstSubSS, &dst, &src); }
- //! @brief Scalar SP-FP Subtract (SSE).
- void subss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstSubSS, &dst, &src); }
-
- //! @brief Unordered Scalar SP-FP compare and set EFLAGS (SSE).
- void ucomiss(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstUComISS, &dst, &src); }
- //! @brief Unordered Scalar SP-FP compare and set EFLAGS (SSE).
- void ucomiss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstUComISS, &dst, &src); }
-
- //! @brief Unpack High Packed SP-FP Data (SSE).
- void unpckhps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstUnpckHPS, &dst, &src); }
- //! @brief Unpack High Packed SP-FP Data (SSE).
- void unpckhps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstUnpckHPS, &dst, &src); }
-
- //! @brief Unpack Low Packed SP-FP Data (SSE).
- void unpcklps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstUnpckLPS, &dst, &src); }
- //! @brief Unpack Low Packed SP-FP Data (SSE).
- void unpcklps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstUnpckLPS, &dst, &src); }
-
- //! @brief Bit-wise Logical Xor for SP-FP Data (SSE).
- void xorps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstXorPS, &dst, &src); }
- //! @brief Bit-wise Logical Xor for SP-FP Data (SSE).
- void xorps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstXorPS, &dst, &src); }
-
- // --------------------------------------------------------------------------
- // [SSE2]
- // --------------------------------------------------------------------------
-
- //! @brief Packed DP-FP Add (SSE2).
- void addpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstAddPD, &dst, &src); }
- //! @brief Packed DP-FP Add (SSE2).
- void addpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstAddPD, &dst, &src); }
-
- //! @brief Scalar DP-FP Add (SSE2).
- void addsd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstAddSD, &dst, &src); }
- //! @brief Scalar DP-FP Add (SSE2).
- void addsd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstAddSD, &dst, &src); }
-
- //! @brief Bit-wise Logical And Not For DP-FP (SSE2).
- void andnpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstAndnPD, &dst, &src); }
- //! @brief Bit-wise Logical And Not For DP-FP (SSE2).
- void andnpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstAndnPD, &dst, &src); }
-
- //! @brief Bit-wise Logical And For DP-FP (SSE2).
- void andpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstAndPD, &dst, &src); }
- //! @brief Bit-wise Logical And For DP-FP (SSE2).
- void andpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstAndPD, &dst, &src); }
-
- //! @brief Flush Cache Line (SSE2).
- void clflush(const Mem &mem) { this->_emitInstruction(kX86InstClFlush, &mem); }
-
- //! @brief Packed DP-FP Compare (SSE2).
- void cmppd(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstCmpPD, &dst, &src, &imm8); }
- //! @brief Packed DP-FP Compare (SSE2).
- void cmppd(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstCmpPD, &dst, &src, &imm8); }
-
- //! @brief Compare Scalar SP-FP Values (SSE2).
- void cmpsd(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstCmpSD, &dst, &src, &imm8); }
- //! @brief Compare Scalar SP-FP Values (SSE2).
- void cmpsd(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstCmpSD, &dst, &src, &imm8); }
-
- //! @brief Scalar Ordered DP-FP Compare and Set EFLAGS (SSE2).
- void comisd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstComISD, &dst, &src); }
- //! @brief Scalar Ordered DP-FP Compare and Set EFLAGS (SSE2).
- void comisd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstComISD, &dst, &src); }
-
- //! @brief Convert Packed Dword Integers to Packed DP-FP Values (SSE2).
- void cvtdq2pd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvtDQ2PD, &dst, &src); }
- //! @brief Convert Packed Dword Integers to Packed DP-FP Values (SSE2).
- void cvtdq2pd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtDQ2PD, &dst, &src); }
-
- //! @brief Convert Packed Dword Integers to Packed SP-FP Values (SSE2).
- void cvtdq2ps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvtDQ2PS, &dst, &src); }
- //! @brief Convert Packed Dword Integers to Packed SP-FP Values (SSE2).
- void cvtdq2ps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtDQ2PS, &dst, &src); }
-
- //! @brief Convert Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvtpd2dq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvtPD2DQ, &dst, &src); }
- //! @brief Convert Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvtpd2dq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtPD2DQ, &dst, &src); }
-
- //! @brief Convert Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvtpd2pi(const MmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvtPD2PI, &dst, &src); }
- //! @brief Convert Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvtpd2pi(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtPD2PI, &dst, &src); }
-
- //! @brief Convert Packed DP-FP Values to Packed SP-FP Values (SSE2).
- void cvtpd2ps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvtPD2PS, &dst, &src); }
- //! @brief Convert Packed DP-FP Values to Packed SP-FP Values (SSE2).
- void cvtpd2ps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtPD2PS, &dst, &src); }
-
- //! @brief Convert Packed Dword Integers to Packed DP-FP Values (SSE2).
- void cvtpi2pd(const XmmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstCvtPI2PD, &dst, &src); }
- //! @brief Convert Packed Dword Integers to Packed DP-FP Values (SSE2).
- void cvtpi2pd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtPI2PD, &dst, &src); }
-
- //! @brief Convert Packed SP-FP Values to Packed Dword Integers (SSE2).
- void cvtps2dq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvtPS2DQ, &dst, &src); }
- //! @brief Convert Packed SP-FP Values to Packed Dword Integers (SSE2).
- void cvtps2dq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtPS2DQ, &dst, &src); }
-
- //! @brief Convert Packed SP-FP Values to Packed DP-FP Values (SSE2).
- void cvtps2pd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvtPS2PD, &dst, &src); }
- //! @brief Convert Packed SP-FP Values to Packed DP-FP Values (SSE2).
- void cvtps2pd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtPS2PD, &dst, &src); }
-
- //! @brief Convert Scalar DP-FP Value to Dword Integer (SSE2).
- void cvtsd2si(const GpVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvtSD2SI, &dst, &src); }
- //! @brief Convert Scalar DP-FP Value to Dword Integer (SSE2).
- void cvtsd2si(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtSD2SI, &dst, &src); }
-
- //! @brief Convert Scalar DP-FP Value to Scalar SP-FP Value (SSE2).
- void cvtsd2ss(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvtSD2SS, &dst, &src); }
- //! @brief Convert Scalar DP-FP Value to Scalar SP-FP Value (SSE2).
- void cvtsd2ss(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtSD2SS, &dst, &src); }
-
- //! @brief Convert Dword Integer to Scalar DP-FP Value (SSE2).
- void cvtsi2sd(const XmmVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCvtSI2SD, &dst, &src); }
- //! @brief Convert Dword Integer to Scalar DP-FP Value (SSE2).
- void cvtsi2sd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtSI2SD, &dst, &src); }
-
- //! @brief Convert Scalar SP-FP Value to Scalar DP-FP Value (SSE2).
- void cvtss2sd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvtSS2SD, &dst, &src); }
- //! @brief Convert Scalar SP-FP Value to Scalar DP-FP Value (SSE2).
- void cvtss2sd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvtSS2SD, &dst, &src); }
-
- //! @brief Convert with Truncation Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvttpd2pi(const MmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvttPD2PI, &dst, &src); }
- //! @brief Convert with Truncation Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvttpd2pi(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvttPD2PI, &dst, &src); }
-
- //! @brief Convert with Truncation Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvttpd2dq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvttPD2DQ, &dst, &src); }
- //! @brief Convert with Truncation Packed DP-FP Values to Packed Dword Integers (SSE2).
- void cvttpd2dq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvttPD2DQ, &dst, &src); }
-
- //! @brief Convert with Truncation Packed SP-FP Values to Packed Dword Integers (SSE2).
- void cvttps2dq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvttPS2DQ, &dst, &src); }
- //! @brief Convert with Truncation Packed SP-FP Values to Packed Dword Integers (SSE2).
- void cvttps2dq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvttPS2DQ, &dst, &src); }
-
- //! @brief Convert with Truncation Scalar DP-FP Value to Signed Dword Integer (SSE2).
- void cvttsd2si(const GpVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstCvttSD2SI, &dst, &src); }
- //! @brief Convert with Truncation Scalar DP-FP Value to Signed Dword Integer (SSE2).
- void cvttsd2si(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCvttSD2SI, &dst, &src); }
-
- //! @brief Packed DP-FP Divide (SSE2).
- void divpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstDivPD, &dst, &src); }
- //! @brief Packed DP-FP Divide (SSE2).
- void divpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstDivPD, &dst, &src); }
-
- //! @brief Scalar DP-FP Divide (SSE2).
- void divsd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstDivSD, &dst, &src); }
- //! @brief Scalar DP-FP Divide (SSE2).
- void divsd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstDivSD, &dst, &src); }
-
- //! @brief Load Fence (SSE2).
- void lfence() { this->_emitInstruction(kX86InstLFence); }
-
- //! @brief Store Selected Bytes of Double Quadword (SSE2).
- //!
- //! @note Target is DS:EDI.
- void maskmovdqu(const GpVar &dst_ptr, const XmmVar &src, const XmmVar &mask) { this->_emitInstruction(kX86InstMaskMovDQU, &dst_ptr, &src, &mask); }
-
- //! @brief Return Maximum Packed Double-Precision FP Values (SSE2).
- void maxpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMaxPD, &dst, &src); }
- //! @brief Return Maximum Packed Double-Precision FP Values (SSE2).
- void maxpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMaxPD, &dst, &src); }
-
- //! @brief Return Maximum Scalar Double-Precision FP Value (SSE2).
- void maxsd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMaxSD, &dst, &src); }
- //! @brief Return Maximum Scalar Double-Precision FP Value (SSE2).
- void maxsd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMaxSD, &dst, &src); }
-
- //! @brief Memory Fence (SSE2).
- void mfence() { this->_emitInstruction(kX86InstMFence); }
-
- //! @brief Return Minimum Packed DP-FP Values (SSE2).
- void minpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMinPD, &dst, &src); }
- //! @brief Return Minimum Packed DP-FP Values (SSE2).
- void minpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMinPD, &dst, &src); }
-
- //! @brief Return Minimum Scalar DP-FP Value (SSE2).
- void minsd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMinSD, &dst, &src); }
- //! @brief Return Minimum Scalar DP-FP Value (SSE2).
- void minsd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMinSD, &dst, &src); }
-
- //! @brief Move Aligned DQWord (SSE2).
- void movdqa(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovDQA, &dst, &src); }
- //! @brief Move Aligned DQWord (SSE2).
- void movdqa(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovDQA, &dst, &src); }
-
- //! @brief Move Aligned DQWord (SSE2).
- void movdqa(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovDQA, &dst, &src); }
-
- //! @brief Move Unaligned Double Quadword (SSE2).
- void movdqu(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovDQU, &dst, &src); }
- //! @brief Move Unaligned Double Quadword (SSE2).
- void movdqu(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovDQU, &dst, &src); }
-
- //! @brief Move Unaligned Double Quadword (SSE2).
- void movdqu(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovDQU, &dst, &src); }
-
- //! @brief Extract Packed SP-FP Sign Mask (SSE2).
- void movmskps(const GpVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovMskPS, &dst, &src); }
-
- //! @brief Extract Packed DP-FP Sign Mask (SSE2).
- void movmskpd(const GpVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovMskPD, &dst, &src); }
-
- //! @brief Move Scalar Double-Precision FP Value (SSE2).
- void movsd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovSD, &dst, &src); }
- //! @brief Move Scalar Double-Precision FP Value (SSE2).
- void movsd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovSD, &dst, &src); }
-
- //! @brief Move Scalar Double-Precision FP Value (SSE2).
- void movsd(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovSD, &dst, &src); }
-
- //! @brief Move Aligned Packed Double-Precision FP Values (SSE2).
- void movapd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovAPD, &dst, &src); }
-
- //! @brief Move Aligned Packed Double-Precision FP Values (SSE2).
- void movapd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovAPD, &dst, &src); }
-
- //! @brief Move Aligned Packed Double-Precision FP Values (SSE2).
- void movapd(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovAPD, &dst, &src); }
-
- //! @brief Move Quadword from XMM to MMX Technology Register (SSE2).
- void movdq2q(const MmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovDQ2Q, &dst, &src); }
-
- //! @brief Move Quadword from MMX Technology to XMM Register (SSE2).
- void movq2dq(const XmmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstMovQ2DQ, &dst, &src); }
-
- //! @brief Move High Packed Double-Precision FP Value (SSE2).
- void movhpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovHPD, &dst, &src); }
-
- //! @brief Move High Packed Double-Precision FP Value (SSE2).
- void movhpd(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovHPD, &dst, &src); }
-
- //! @brief Move Low Packed Double-Precision FP Value (SSE2).
- void movlpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovLPD, &dst, &src); }
-
- //! @brief Move Low Packed Double-Precision FP Value (SSE2).
- void movlpd(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovLPD, &dst, &src); }
-
- //! @brief Store Double Quadword Using Non-Temporal Hint (SSE2).
- void movntdq(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovNTDQ, &dst, &src); }
-
- //! @brief Store Store DWORD Using Non-Temporal Hint (SSE2).
- void movnti(const Mem &dst, const GpVar &src) { this->_emitInstruction(kX86InstMovNTI, &dst, &src); }
-
- //! @brief Store Packed Double-Precision FP Values Using Non-Temporal Hint (SSE2).
- void movntpd(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovNTPD, &dst, &src); }
-
- //! @brief Move Unaligned Packed Double-Precision FP Values (SSE2).
- void movupd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovUPD, &dst, &src); }
-
- //! @brief Move Unaligned Packed Double-Precision FP Values (SSE2).
- void movupd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovUPD, &dst, &src); }
-
- //! @brief Move Unaligned Packed Double-Precision FP Values (SSE2).
- void movupd(const Mem &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovUPD, &dst, &src); }
-
- //! @brief Packed DP-FP Multiply (SSE2).
- void mulpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMulPD, &dst, &src); }
- //! @brief Packed DP-FP Multiply (SSE2).
- void mulpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMulPD, &dst, &src); }
-
- //! @brief Scalar DP-FP Multiply (SSE2).
- void mulsd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMulSD, &dst, &src); }
- //! @brief Scalar DP-FP Multiply (SSE2).
- void mulsd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMulSD, &dst, &src); }
-
- //! @brief Bit-wise Logical OR for DP-FP Data (SSE2).
- void orpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstOrPD, &dst, &src); }
- //! @brief Bit-wise Logical OR for DP-FP Data (SSE2).
- void orpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstOrPD, &dst, &src); }
-
- //! @brief Pack with Signed Saturation (SSE2).
- void packsswb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPackSSWB, &dst, &src); }
- //! @brief Pack with Signed Saturation (SSE2).
- void packsswb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPackSSWB, &dst, &src); }
-
- //! @brief Pack with Signed Saturation (SSE2).
- void packssdw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPackSSDW, &dst, &src); }
- //! @brief Pack with Signed Saturation (SSE2).
- void packssdw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPackSSDW, &dst, &src); }
-
- //! @brief Pack with Unsigned Saturation (SSE2).
- void packuswb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPackUSWB, &dst, &src); }
- //! @brief Pack with Unsigned Saturation (SSE2).
- void packuswb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPackUSWB, &dst, &src); }
-
- //! @brief Packed BYTE Add (SSE2).
- void paddb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAddB, &dst, &src); }
- //! @brief Packed BYTE Add (SSE2).
- void paddb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddB, &dst, &src); }
-
- //! @brief Packed WORD Add (SSE2).
- void paddw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAddW, &dst, &src); }
- //! @brief Packed WORD Add (SSE2).
- void paddw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddW, &dst, &src); }
-
- //! @brief Packed DWORD Add (SSE2).
- void paddd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAddD, &dst, &src); }
- //! @brief Packed DWORD Add (SSE2).
- void paddd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddD, &dst, &src); }
-
- //! @brief Packed QWORD Add (SSE2).
- void paddq(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAddQ, &dst, &src); }
- //! @brief Packed QWORD Add (SSE2).
- void paddq(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddQ, &dst, &src); }
-
- //! @brief Packed QWORD Add (SSE2).
- void paddq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAddQ, &dst, &src); }
- //! @brief Packed QWORD Add (SSE2).
- void paddq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddQ, &dst, &src); }
-
- //! @brief Packed Add with Saturation (SSE2).
- void paddsb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAddSB, &dst, &src); }
- //! @brief Packed Add with Saturation (SSE2).
- void paddsb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddSB, &dst, &src); }
-
- //! @brief Packed Add with Saturation (SSE2).
- void paddsw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAddSW, &dst, &src); }
- //! @brief Packed Add with Saturation (SSE2).
- void paddsw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddSW, &dst, &src); }
-
- //! @brief Packed Add Unsigned with Saturation (SSE2).
- void paddusb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAddUSB, &dst, &src); }
- //! @brief Packed Add Unsigned with Saturation (SSE2).
- void paddusb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddUSB, &dst, &src); }
-
- //! @brief Packed Add Unsigned with Saturation (SSE2).
- void paddusw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAddUSW, &dst, &src); }
- //! @brief Packed Add Unsigned with Saturation (SSE2).
- void paddusw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAddUSW, &dst, &src); }
-
- //! @brief Logical AND (SSE2).
- void pand(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAnd, &dst, &src); }
- //! @brief Logical AND (SSE2).
- void pand(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAnd, &dst, &src); }
-
- //! @brief Logical AND Not (SSE2).
- void pandn(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAndN, &dst, &src); }
- //! @brief Logical AND Not (SSE2).
- void pandn(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAndN, &dst, &src); }
-
- //! @brief Spin Loop Hint (SSE2).
- void pause() { this->_emitInstruction(kX86InstPause); }
-
- //! @brief Packed Average (SSE2).
- void pavgb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAvgB, &dst, &src); }
- //! @brief Packed Average (SSE2).
- void pavgb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAvgB, &dst, &src); }
-
- //! @brief Packed Average (SSE2).
- void pavgw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAvgW, &dst, &src); }
- //! @brief Packed Average (SSE2).
- void pavgw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAvgW, &dst, &src); }
-
- //! @brief Packed Compare for Equal (BYTES) (SSE2).
- void pcmpeqb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPCmpEqB, &dst, &src); }
- //! @brief Packed Compare for Equal (BYTES) (SSE2).
- void pcmpeqb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpEqB, &dst, &src); }
-
- //! @brief Packed Compare for Equal (WORDS) (SSE2).
- void pcmpeqw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPCmpEqW, &dst, &src); }
- //! @brief Packed Compare for Equal (WORDS) (SSE2).
- void pcmpeqw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpEqW, &dst, &src); }
-
- //! @brief Packed Compare for Equal (DWORDS) (SSE2).
- void pcmpeqd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPCmpEqD, &dst, &src); }
- //! @brief Packed Compare for Equal (DWORDS) (SSE2).
- void pcmpeqd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpEqD, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (BYTES) (SSE2).
- void pcmpgtb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPCmpGtB, &dst, &src); }
- //! @brief Packed Compare for Greater Than (BYTES) (SSE2).
- void pcmpgtb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpGtB, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (WORDS) (SSE2).
- void pcmpgtw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPCmpGtW, &dst, &src); }
- //! @brief Packed Compare for Greater Than (WORDS) (SSE2).
- void pcmpgtw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpGtW, &dst, &src); }
-
- //! @brief Packed Compare for Greater Than (DWORDS) (SSE2).
- void pcmpgtd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPCmpGtD, &dst, &src); }
- //! @brief Packed Compare for Greater Than (DWORDS) (SSE2).
- void pcmpgtd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpGtD, &dst, &src); }
-
- //! @brief Extract Word (SSE2).
- void pextrw(const GpVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPExtrW, &dst, &src, &imm8); }
- //! @brief Extract Word (SSE2).
- void pextrw(const Mem &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPExtrW, &dst, &src, &imm8); }
-
- //! @brief Packed Signed Integer Word Maximum (SSE2).
- void pmaxsw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMaxSW, &dst, &src); }
- //! @brief Packed Signed Integer Word Maximum (SSE2).
- void pmaxsw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMaxSW, &dst, &src); }
-
- //! @brief Packed Unsigned Integer Byte Maximum (SSE2).
- void pmaxub(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMaxUB, &dst, &src); }
- //! @brief Packed Unsigned Integer Byte Maximum (SSE2).
- void pmaxub(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMaxUB, &dst, &src); }
-
- //! @brief Packed Signed Integer Word Minimum (SSE2).
- void pminsw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMinSW, &dst, &src); }
- //! @brief Packed Signed Integer Word Minimum (SSE2).
- void pminsw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMinSW, &dst, &src); }
-
- //! @brief Packed Unsigned Integer Byte Minimum (SSE2).
- void pminub(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMinUB, &dst, &src); }
- //! @brief Packed Unsigned Integer Byte Minimum (SSE2).
- void pminub(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMinUB, &dst, &src); }
-
- //! @brief Move Byte Mask (SSE2).
- void pmovmskb(const GpVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMovMskB, &dst, &src); }
-
- //! @brief Packed Multiply High (SSE2).
- void pmulhw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMulHW, &dst, &src); }
- //! @brief Packed Multiply High (SSE2).
- void pmulhw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMulHW, &dst, &src); }
-
- //! @brief Packed Multiply High Unsigned (SSE2).
- void pmulhuw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMulHUW, &dst, &src); }
- //! @brief Packed Multiply High Unsigned (SSE2).
- void pmulhuw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMulHUW, &dst, &src); }
-
- //! @brief Packed Multiply Low (SSE2).
- void pmullw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMulLW, &dst, &src); }
- //! @brief Packed Multiply Low (SSE2).
- void pmullw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMulLW, &dst, &src); }
-
- //! @brief Packed Multiply to QWORD (SSE2).
- void pmuludq(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPMulUDQ, &dst, &src); }
- //! @brief Packed Multiply to QWORD (SSE2).
- void pmuludq(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMulUDQ, &dst, &src); }
-
- //! @brief Packed Multiply to QWORD (SSE2).
- void pmuludq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMulUDQ, &dst, &src); }
- //! @brief Packed Multiply to QWORD (SSE2).
- void pmuludq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMulUDQ, &dst, &src); }
-
- //! @brief Bitwise Logical OR (SSE2).
- void por(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPOr, &dst, &src); }
- //! @brief Bitwise Logical OR (SSE2).
- void por(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPOr, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (SSE2).
- void pslld(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSllD, &dst, &src); }
- //! @brief Packed Shift Left Logical (SSE2).
- void pslld(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSllD, &dst, &src); }
- //! @brief Packed Shift Left Logical (SSE2).
- void pslld(const XmmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSllD, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (SSE2).
- void psllq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSllQ, &dst, &src); }
- //! @brief Packed Shift Left Logical (SSE2).
- void psllq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSllQ, &dst, &src); }
- //! @brief Packed Shift Left Logical (SSE2).
- void psllq(const XmmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSllQ, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (SSE2).
- void psllw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSllW, &dst, &src); }
- //! @brief Packed Shift Left Logical (SSE2).
- void psllw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSllW, &dst, &src); }
- //! @brief Packed Shift Left Logical (SSE2).
- void psllw(const XmmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSllW, &dst, &src); }
-
- //! @brief Packed Shift Left Logical (SSE2).
- void pslldq(const XmmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSllDQ, &dst, &src); }
-
- //! @brief Packed Shift Right Arithmetic (SSE2).
- void psrad(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSraD, &dst, &src); }
- //! @brief Packed Shift Right Arithmetic (SSE2).
- void psrad(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSraD, &dst, &src); }
- //! @brief Packed Shift Right Arithmetic (SSE2).
- void psrad(const XmmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSraD, &dst, &src); }
-
- //! @brief Packed Shift Right Arithmetic (SSE2).
- void psraw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSraW, &dst, &src); }
- //! @brief Packed Shift Right Arithmetic (SSE2).
- void psraw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSraW, &dst, &src); }
- //! @brief Packed Shift Right Arithmetic (SSE2).
- void psraw(const XmmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSraW, &dst, &src); }
-
- //! @brief Packed Subtract (SSE2).
- void psubb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSubB, &dst, &src); }
- //! @brief Packed Subtract (SSE2).
- void psubb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubB, &dst, &src); }
-
- //! @brief Packed Subtract (SSE2).
- void psubw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSubW, &dst, &src); }
- //! @brief Packed Subtract (SSE2).
- void psubw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubW, &dst, &src); }
-
- //! @brief Packed Subtract (SSE2).
- void psubd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSubD, &dst, &src); }
- //! @brief Packed Subtract (SSE2).
- void psubd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubD, &dst, &src); }
-
- //! @brief Packed Subtract (SSE2).
- void psubq(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSubQ, &dst, &src); }
- //! @brief Packed Subtract (SSE2).
- void psubq(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubQ, &dst, &src); }
-
- //! @brief Packed Subtract (SSE2).
- void psubq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSubQ, &dst, &src); }
- //! @brief Packed Subtract (SSE2).
- void psubq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubQ, &dst, &src); }
-
- //! @brief Packed Multiply and Add (SSE2).
- void pmaddwd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMAddWD, &dst, &src); }
- //! @brief Packed Multiply and Add (SSE2).
- void pmaddwd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMAddWD, &dst, &src); }
-
- //! @brief Shuffle Packed DWORDs (SSE2).
- void pshufd(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPShufD, &dst, &src, &imm8); }
- //! @brief Shuffle Packed DWORDs (SSE2).
- void pshufd(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPShufD, &dst, &src, &imm8); }
-
- //! @brief Shuffle Packed High Words (SSE2).
- void pshufhw(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPShufHW, &dst, &src, &imm8); }
- //! @brief Shuffle Packed High Words (SSE2).
- void pshufhw(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPShufHW, &dst, &src, &imm8); }
-
- //! @brief Shuffle Packed Low Words (SSE2).
- void pshuflw(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPShufLW, &dst, &src, &imm8); }
- //! @brief Shuffle Packed Low Words (SSE2).
- void pshuflw(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPShufLW, &dst, &src, &imm8); }
-
- //! @brief Packed Shift Right Logical (SSE2).
- void psrld(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSrlD, &dst, &src); }
- //! @brief Packed Shift Right Logical (SSE2).
- void psrld(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSrlD, &dst, &src); }
- //! @brief Packed Shift Right Logical (SSE2).
- void psrld(const XmmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSrlD, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (SSE2).
- void psrlq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSrlQ, &dst, &src); }
- //! @brief Packed Shift Right Logical (SSE2).
- void psrlq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSrlQ, &dst, &src); }
- //! @brief Packed Shift Right Logical (SSE2).
- void psrlq(const XmmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSrlQ, &dst, &src); }
-
- //! @brief DQWord Shift Right Logical (MMX).
- void psrldq(const XmmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSrlDQ, &dst, &src); }
-
- //! @brief Packed Shift Right Logical (SSE2).
- void psrlw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSrlW, &dst, &src); }
- //! @brief Packed Shift Right Logical (SSE2).
- void psrlw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSrlW, &dst, &src); }
- //! @brief Packed Shift Right Logical (SSE2).
- void psrlw(const XmmVar &dst, const Imm &src) { this->_emitInstruction(kX86InstPSrlW, &dst, &src); }
-
- //! @brief Packed Subtract with Saturation (SSE2).
- void psubsb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSubSB, &dst, &src); }
- //! @brief Packed Subtract with Saturation (SSE2).
- void psubsb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubSB, &dst, &src); }
-
- //! @brief Packed Subtract with Saturation (SSE2).
- void psubsw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSubSW, &dst, &src); }
- //! @brief Packed Subtract with Saturation (SSE2).
- void psubsw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubSW, &dst, &src); }
-
- //! @brief Packed Subtract with Unsigned Saturation (SSE2).
- void psubusb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSubUSB, &dst, &src); }
- //! @brief Packed Subtract with Unsigned Saturation (SSE2).
- void psubusb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubUSB, &dst, &src); }
-
- //! @brief Packed Subtract with Unsigned Saturation (SSE2).
- void psubusw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSubUSW, &dst, &src); }
- //! @brief Packed Subtract with Unsigned Saturation (SSE2).
- void psubusw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSubUSW, &dst, &src); }
-
- //! @brief Unpack High Data (SSE2).
- void punpckhbw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPunpckHBW, &dst, &src); }
- //! @brief Unpack High Data (SSE2).
- void punpckhbw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckHBW, &dst, &src); }
-
- //! @brief Unpack High Data (SSE2).
- void punpckhwd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPunpckHWD, &dst, &src); }
- //! @brief Unpack High Data (SSE2).
- void punpckhwd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckHWD, &dst, &src); }
-
- //! @brief Unpack High Data (SSE2).
- void punpckhdq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPunpckHDQ, &dst, &src); }
- //! @brief Unpack High Data (SSE2).
- void punpckhdq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckHDQ, &dst, &src); }
-
- //! @brief Unpack High Data (SSE2).
- void punpckhqdq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPunpckHQDQ, &dst, &src); }
- //! @brief Unpack High Data (SSE2).
- void punpckhqdq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckHQDQ, &dst, &src); }
-
- //! @brief Unpack Low Data (SSE2).
- void punpcklbw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPunpckLBW, &dst, &src); }
- //! @brief Unpack Low Data (SSE2).
- void punpcklbw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckLBW, &dst, &src); }
-
- //! @brief Unpack Low Data (SSE2).
- void punpcklwd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPunpckLWD, &dst, &src); }
- //! @brief Unpack Low Data (SSE2).
- void punpcklwd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckLWD, &dst, &src); }
-
- //! @brief Unpack Low Data (SSE2).
- void punpckldq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPunpckLDQ, &dst, &src); }
- //! @brief Unpack Low Data (SSE2).
- void punpckldq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckLDQ, &dst, &src); }
-
- //! @brief Unpack Low Data (SSE2).
- void punpcklqdq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPunpckLQDQ, &dst, &src); }
- //! @brief Unpack Low Data (SSE2).
- void punpcklqdq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPunpckLQDQ, &dst, &src); }
-
- //! @brief Bitwise Exclusive OR (SSE2).
- void pxor(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPXor, &dst, &src); }
- //! @brief Bitwise Exclusive OR (SSE2).
- void pxor(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPXor, &dst, &src); }
-
- //! @brief Shuffle DP-FP (SSE2).
- void shufpd(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstShufPD, &dst, &src, &imm8); }
- //! @brief Shuffle DP-FP (SSE2).
- void shufpd(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstShufPD, &dst, &src, &imm8); }
-
- //! @brief Compute Square Roots of Packed DP-FP Values (SSE2).
- void sqrtpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstSqrtPD, &dst, &src); }
- //! @brief Compute Square Roots of Packed DP-FP Values (SSE2).
- void sqrtpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstSqrtPD, &dst, &src); }
-
- //! @brief Compute Square Root of Scalar DP-FP Value (SSE2).
- void sqrtsd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstSqrtSD, &dst, &src); }
- //! @brief Compute Square Root of Scalar DP-FP Value (SSE2).
- void sqrtsd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstSqrtSD, &dst, &src); }
-
- //! @brief Packed DP-FP Subtract (SSE2).
- void subpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstSubPD, &dst, &src); }
- //! @brief Packed DP-FP Subtract (SSE2).
- void subpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstSubPD, &dst, &src); }
-
- //! @brief Scalar DP-FP Subtract (SSE2).
- void subsd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstSubSD, &dst, &src); }
- //! @brief Scalar DP-FP Subtract (SSE2).
- void subsd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstSubSD, &dst, &src); }
-
- //! @brief Scalar Unordered DP-FP Compare and Set EFLAGS (SSE2).
- void ucomisd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstUComISD, &dst, &src); }
- //! @brief Scalar Unordered DP-FP Compare and Set EFLAGS (SSE2).
- void ucomisd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstUComISD, &dst, &src); }
-
- //! @brief Unpack and Interleave High Packed Double-Precision FP Values (SSE2).
- void unpckhpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstUnpckHPD, &dst, &src); }
- //! @brief Unpack and Interleave High Packed Double-Precision FP Values (SSE2).
- void unpckhpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstUnpckHPD, &dst, &src); }
-
- //! @brief Unpack and Interleave Low Packed Double-Precision FP Values (SSE2).
- void unpcklpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstUnpckLPD, &dst, &src); }
- //! @brief Unpack and Interleave Low Packed Double-Precision FP Values (SSE2).
- void unpcklpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstUnpckLPD, &dst, &src); }
-
- //! @brief Bit-wise Logical OR for DP-FP Data (SSE2).
- void xorpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstXorPD, &dst, &src); }
- //! @brief Bit-wise Logical OR for DP-FP Data (SSE2).
- void xorpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstXorPD, &dst, &src); }
-
- // --------------------------------------------------------------------------
- // [SSE3]
- // --------------------------------------------------------------------------
-
- //! @brief Packed DP-FP Add/Subtract (SSE3).
- void addsubpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstAddSubPD, &dst, &src); }
- //! @brief Packed DP-FP Add/Subtract (SSE3).
- void addsubpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstAddSubPD, &dst, &src); }
-
- //! @brief Packed SP-FP Add/Subtract (SSE3).
- void addsubps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstAddSubPS, &dst, &src); }
- //! @brief Packed SP-FP Add/Subtract (SSE3).
- void addsubps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstAddSubPS, &dst, &src); }
-
-#if ASMJIT_NOT_SUPPORTED_BY_COMPILER
- // TODO: NOT IMPLEMENTED BY THE COMPILER.
- //! @brief Store Integer with Truncation (SSE3).
- void fisttp(const Mem &dst) { this->_emitInstruction(kX86InstFISttP, &dst); }
-#endif // ASMJIT_NOT_SUPPORTED_BY_COMPILER
-
- //! @brief Packed DP-FP Horizontal Add (SSE3).
- void haddpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstHAddPD, &dst, &src); }
- //! @brief Packed DP-FP Horizontal Add (SSE3).
- void haddpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstHAddPD, &dst, &src); }
-
- //! @brief Packed SP-FP Horizontal Add (SSE3).
- void haddps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstHAddPS, &dst, &src); }
- //! @brief Packed SP-FP Horizontal Add (SSE3).
- void haddps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstHAddPS, &dst, &src); }
-
- //! @brief Packed DP-FP Horizontal Subtract (SSE3).
- void hsubpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstHSubPD, &dst, &src); }
- //! @brief Packed DP-FP Horizontal Subtract (SSE3).
- void hsubpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstHSubPD, &dst, &src); }
-
- //! @brief Packed SP-FP Horizontal Subtract (SSE3).
- void hsubps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstHSubPS, &dst, &src); }
- //! @brief Packed SP-FP Horizontal Subtract (SSE3).
- void hsubps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstHSubPS, &dst, &src); }
-
- //! @brief Load Unaligned Integer 128 Bits (SSE3).
- void lddqu(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstLdDQU, &dst, &src); }
-
-#if ASMJIT_NOT_SUPPORTED_BY_COMPILER
- //! @brief Set Up Monitor Address (SSE3).
- void monitor() { this->_emitInstruction(kX86InstMonitor); }
-#endif // ASMJIT_NOT_SUPPORTED_BY_COMPILER
-
- //! @brief Move One DP-FP and Duplicate (SSE3).
- void movddup(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovDDup, &dst, &src); }
- //! @brief Move One DP-FP and Duplicate (SSE3).
- void movddup(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovDDup, &dst, &src); }
-
- //! @brief Move Packed SP-FP High and Duplicate (SSE3).
- void movshdup(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovSHDup, &dst, &src); }
- //! @brief Move Packed SP-FP High and Duplicate (SSE3).
- void movshdup(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovSHDup, &dst, &src); }
-
- //! @brief Move Packed SP-FP Low and Duplicate (SSE3).
- void movsldup(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstMovSLDup, &dst, &src); }
- //! @brief Move Packed SP-FP Low and Duplicate (SSE3).
- void movsldup(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovSLDup, &dst, &src); }
-
-#if ASMJIT_NOT_SUPPORTED_BY_COMPILER
- //! @brief Monitor Wait (SSE3).
- void mwait() { this->_emitInstruction(kX86InstMWait); }
-#endif // ASMJIT_NOT_SUPPORTED_BY_COMPILER
-
- // --------------------------------------------------------------------------
- // [SSSE3]
- // --------------------------------------------------------------------------
-
- //! @brief Packed SIGN (SSSE3).
- void psignb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSignB, &dst, &src); }
- //! @brief Packed SIGN (SSSE3).
- void psignb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSignB, &dst, &src); }
-
- //! @brief Packed SIGN (SSSE3).
- void psignb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSignB, &dst, &src); }
- //! @brief Packed SIGN (SSSE3).
- void psignb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSignB, &dst, &src); }
-
- //! @brief Packed SIGN (SSSE3).
- void psignw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSignW, &dst, &src); }
- //! @brief Packed SIGN (SSSE3).
- void psignw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSignW, &dst, &src); }
-
- //! @brief Packed SIGN (SSSE3).
- void psignw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSignW, &dst, &src); }
- //! @brief Packed SIGN (SSSE3).
- void psignw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSignW, &dst, &src); }
-
- //! @brief Packed SIGN (SSSE3).
- void psignd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPSignD, &dst, &src); }
- //! @brief Packed SIGN (SSSE3).
- void psignd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSignD, &dst, &src); }
-
- //! @brief Packed SIGN (SSSE3).
- void psignd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPSignD, &dst, &src); }
- //! @brief Packed SIGN (SSSE3).
- void psignd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPSignD, &dst, &src); }
-
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPHAddW, &dst, &src); }
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPHAddW, &dst, &src); }
-
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPHAddW, &dst, &src); }
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPHAddW, &dst, &src); }
-
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPHAddD, &dst, &src); }
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPHAddD, &dst, &src); }
-
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPHAddD, &dst, &src); }
- //! @brief Packed Horizontal Add (SSSE3).
- void phaddd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPHAddD, &dst, &src); }
-
- //! @brief Packed Horizontal Add and Saturate (SSSE3).
- void phaddsw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPHAddSW, &dst, &src); }
- //! @brief Packed Horizontal Add and Saturate (SSSE3).
- void phaddsw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPHAddSW, &dst, &src); }
-
- //! @brief Packed Horizontal Add and Saturate (SSSE3).
- void phaddsw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPHAddSW, &dst, &src); }
- //! @brief Packed Horizontal Add and Saturate (SSSE3).
- void phaddsw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPHAddSW, &dst, &src); }
-
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPHSubW, &dst, &src); }
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPHSubW, &dst, &src); }
-
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPHSubW, &dst, &src); }
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPHSubW, &dst, &src); }
-
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPHSubD, &dst, &src); }
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPHSubD, &dst, &src); }
-
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPHSubD, &dst, &src); }
- //! @brief Packed Horizontal Subtract (SSSE3).
- void phsubd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPHSubD, &dst, &src); }
-
- //! @brief Packed Horizontal Subtract and Saturate (SSSE3).
- void phsubsw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPHSubSW, &dst, &src); }
- //! @brief Packed Horizontal Subtract and Saturate (SSSE3).
- void phsubsw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPHSubSW, &dst, &src); }
-
- //! @brief Packed Horizontal Subtract and Saturate (SSSE3).
- void phsubsw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPHSubSW, &dst, &src); }
- //! @brief Packed Horizontal Subtract and Saturate (SSSE3).
- void phsubsw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPHSubSW, &dst, &src); }
-
- //! @brief Multiply and Add Packed Signed and Unsigned Bytes (SSSE3).
- void pmaddubsw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPMAddUBSW, &dst, &src); }
- //! @brief Multiply and Add Packed Signed and Unsigned Bytes (SSSE3).
- void pmaddubsw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMAddUBSW, &dst, &src); }
-
- //! @brief Multiply and Add Packed Signed and Unsigned Bytes (SSSE3).
- void pmaddubsw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMAddUBSW, &dst, &src); }
- //! @brief Multiply and Add Packed Signed and Unsigned Bytes (SSSE3).
- void pmaddubsw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMAddUBSW, &dst, &src); }
-
- //! @brief Packed Absolute Value (SSSE3).
- void pabsb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAbsB, &dst, &src); }
- //! @brief Packed Absolute Value (SSSE3).
- void pabsb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAbsB, &dst, &src); }
-
- //! @brief Packed Absolute Value (SSSE3).
- void pabsb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAbsB, &dst, &src); }
- //! @brief Packed Absolute Value (SSSE3).
- void pabsb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAbsB, &dst, &src); }
-
- //! @brief Packed Absolute Value (SSSE3).
- void pabsw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAbsW, &dst, &src); }
- //! @brief Packed Absolute Value (SSSE3).
- void pabsw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAbsW, &dst, &src); }
-
- //! @brief Packed Absolute Value (SSSE3).
- void pabsw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAbsW, &dst, &src); }
- //! @brief Packed Absolute Value (SSSE3).
- void pabsw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAbsW, &dst, &src); }
-
- //! @brief Packed Absolute Value (SSSE3).
- void pabsd(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPAbsD, &dst, &src); }
- //! @brief Packed Absolute Value (SSSE3).
- void pabsd(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAbsD, &dst, &src); }
-
- //! @brief Packed Absolute Value (SSSE3).
- void pabsd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPAbsD, &dst, &src); }
- //! @brief Packed Absolute Value (SSSE3).
- void pabsd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPAbsD, &dst, &src); }
-
- //! @brief Packed Multiply High with Round and Scale (SSSE3).
- void pmulhrsw(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPMulHRSW, &dst, &src); }
- //! @brief Packed Multiply High with Round and Scale (SSSE3).
- void pmulhrsw(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMulHRSW, &dst, &src); }
-
- //! @brief Packed Multiply High with Round and Scale (SSSE3).
- void pmulhrsw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMulHRSW, &dst, &src); }
- //! @brief Packed Multiply High with Round and Scale (SSSE3).
- void pmulhrsw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMulHRSW, &dst, &src); }
-
- //! @brief Packed Shuffle Bytes (SSSE3).
- void pshufb(const MmVar &dst, const MmVar &src) { this->_emitInstruction(kX86InstPShufB, &dst, &src); }
- //! @brief Packed Shuffle Bytes (SSSE3).
- void pshufb(const MmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPShufB, &dst, &src); }
-
- //! @brief Packed Shuffle Bytes (SSSE3).
- void pshufb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPShufB, &dst, &src); }
- //! @brief Packed Shuffle Bytes (SSSE3).
- void pshufb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPShufB, &dst, &src); }
-
- //! @brief Packed Shuffle Bytes (SSSE3).
- void palignr(const MmVar &dst, const MmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPAlignR, &dst, &src, &imm8); }
- //! @brief Packed Shuffle Bytes (SSSE3).
- void palignr(const MmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPAlignR, &dst, &src, &imm8); }
-
- //! @brief Packed Shuffle Bytes (SSSE3).
- void palignr(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPAlignR, &dst, &src, &imm8); }
- //! @brief Packed Shuffle Bytes (SSSE3).
- void palignr(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPAlignR, &dst, &src, &imm8); }
-
- // --------------------------------------------------------------------------
- // [SSE4.1]
- // --------------------------------------------------------------------------
-
- //! @brief Blend Packed DP-FP Values (SSE4.1).
- void blendpd(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstBlendPD, &dst, &src, &imm8); }
- //! @brief Blend Packed DP-FP Values (SSE4.1).
- void blendpd(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstBlendPD, &dst, &src, &imm8); }
-
- //! @brief Blend Packed SP-FP Values (SSE4.1).
- void blendps(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstBlendPS, &dst, &src, &imm8); }
- //! @brief Blend Packed SP-FP Values (SSE4.1).
- void blendps(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstBlendPS, &dst, &src, &imm8); }
-
- //! @brief Variable Blend Packed DP-FP Values (SSE4.1).
- void blendvpd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstBlendVPD, &dst, &src); }
- //! @brief Variable Blend Packed DP-FP Values (SSE4.1).
- void blendvpd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstBlendVPD, &dst, &src); }
-
- //! @brief Variable Blend Packed SP-FP Values (SSE4.1).
- void blendvps(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstBlendVPS, &dst, &src); }
- //! @brief Variable Blend Packed SP-FP Values (SSE4.1).
- void blendvps(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstBlendVPS, &dst, &src); }
-
- //! @brief Dot Product of Packed DP-FP Values (SSE4.1).
- void dppd(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstDpPD, &dst, &src, &imm8); }
- //! @brief Dot Product of Packed DP-FP Values (SSE4.1).
- void dppd(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstDpPD, &dst, &src, &imm8); }
-
- //! @brief Dot Product of Packed SP-FP Values (SSE4.1).
- void dpps(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstDpPS, &dst, &src, &imm8); }
- //! @brief Dot Product of Packed SP-FP Values (SSE4.1).
- void dpps(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstDpPS, &dst, &src, &imm8); }
-
- //! @brief Extract Packed SP-FP Value (SSE4.1).
- void extractps(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstExtractPS, &dst, &src, &imm8); }
- //! @brief Extract Packed SP-FP Value (SSE4.1).
- void extractps(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstExtractPS, &dst, &src, &imm8); }
-
- //! @brief Load Double Quadword Non-Temporal Aligned Hint (SSE4.1).
- void movntdqa(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstMovNTDQA, &dst, &src); }
-
- //! @brief Compute Multiple Packed Sums of Absolute Difference (SSE4.1).
- void mpsadbw(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstMPSADBW, &dst, &src, &imm8); }
- //! @brief Compute Multiple Packed Sums of Absolute Difference (SSE4.1).
- void mpsadbw(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstMPSADBW, &dst, &src, &imm8); }
-
- //! @brief Pack with Unsigned Saturation (SSE4.1).
- void packusdw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPackUSDW, &dst, &src); }
- //! @brief Pack with Unsigned Saturation (SSE4.1).
- void packusdw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPackUSDW, &dst, &src); }
-
- //! @brief Variable Blend Packed Bytes (SSE4.1).
- void pblendvb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPBlendVB, &dst, &src); }
- //! @brief Variable Blend Packed Bytes (SSE4.1).
- void pblendvb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPBlendVB, &dst, &src); }
-
- //! @brief Blend Packed Words (SSE4.1).
- void pblendw(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPBlendW, &dst, &src, &imm8); }
- //! @brief Blend Packed Words (SSE4.1).
- void pblendw(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPBlendW, &dst, &src, &imm8); }
-
- //! @brief Compare Packed Qword Data for Equal (SSE4.1).
- void pcmpeqq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPCmpEqQ, &dst, &src); }
- //! @brief Compare Packed Qword Data for Equal (SSE4.1).
- void pcmpeqq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpEqQ, &dst, &src); }
-
- //! @brief Extract Byte (SSE4.1).
- void pextrb(const GpVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPExtrB, &dst, &src, &imm8); }
- //! @brief Extract Byte (SSE4.1).
- void pextrb(const Mem &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPExtrB, &dst, &src, &imm8); }
-
- //! @brief Extract Dword (SSE4.1).
- void pextrd(const GpVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPExtrD, &dst, &src, &imm8); }
- //! @brief Extract Dword (SSE4.1).
- void pextrd(const Mem &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPExtrD, &dst, &src, &imm8); }
-
- //! @brief Extract Dword (SSE4.1).
- void pextrq(const GpVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPExtrQ, &dst, &src, &imm8); }
- //! @brief Extract Dword (SSE4.1).
- void pextrq(const Mem &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPExtrQ, &dst, &src, &imm8); }
-
- //! @brief Packed Horizontal Word Minimum (SSE4.1).
- void phminposuw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPHMinPOSUW, &dst, &src); }
- //! @brief Packed Horizontal Word Minimum (SSE4.1).
- void phminposuw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPHMinPOSUW, &dst, &src); }
-
- //! @brief Insert Byte (SSE4.1).
- void pinsrb(const XmmVar &dst, const GpVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPInsRB, &dst, &src, &imm8); }
- //! @brief Insert Byte (SSE4.1).
- void pinsrb(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPInsRB, &dst, &src, &imm8); }
-
- //! @brief Insert Dword (SSE4.1).
- void pinsrd(const XmmVar &dst, const GpVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPInsRD, &dst, &src, &imm8); }
- //! @brief Insert Dword (SSE4.1).
- void pinsrd(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPInsRD, &dst, &src, &imm8); }
-
- //! @brief Insert Dword (SSE4.1).
- void pinsrq(const XmmVar &dst, const GpVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPInsRQ, &dst, &src, &imm8); }
- //! @brief Insert Dword (SSE4.1).
- void pinsrq(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPInsRQ, &dst, &src, &imm8); }
-
- //! @brief Insert Word (SSE2).
- void pinsrw(const XmmVar &dst, const GpVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPInsRW, &dst, &src, &imm8); }
- //! @brief Insert Word (SSE2).
- void pinsrw(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPInsRW, &dst, &src, &imm8); }
-
- //! @brief Maximum of Packed Word Integers (SSE4.1).
- void pmaxuw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMaxUW, &dst, &src); }
- //! @brief Maximum of Packed Word Integers (SSE4.1).
- void pmaxuw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMaxUW, &dst, &src); }
-
- //! @brief Maximum of Packed Signed Byte Integers (SSE4.1).
- void pmaxsb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMaxSB, &dst, &src); }
- //! @brief Maximum of Packed Signed Byte Integers (SSE4.1).
- void pmaxsb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMaxSB, &dst, &src); }
-
- //! @brief Maximum of Packed Signed Dword Integers (SSE4.1).
- void pmaxsd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMaxSD, &dst, &src); }
- //! @brief Maximum of Packed Signed Dword Integers (SSE4.1).
- void pmaxsd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMaxSD, &dst, &src); }
-
- //! @brief Maximum of Packed Unsigned Dword Integers (SSE4.1).
- void pmaxud(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMaxUD, &dst, &src); }
- //! @brief Maximum of Packed Unsigned Dword Integers (SSE4.1).
- void pmaxud(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMaxUD, &dst, &src); }
-
- //! @brief Minimum of Packed Signed Byte Integers (SSE4.1).
- void pminsb(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMinSB, &dst, &src); }
- //! @brief Minimum of Packed Signed Byte Integers (SSE4.1).
- void pminsb(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMinSB, &dst, &src); }
-
- //! @brief Minimum of Packed Word Integers (SSE4.1).
- void pminuw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMinUW, &dst, &src); }
- //! @brief Minimum of Packed Word Integers (SSE4.1).
- void pminuw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMinUW, &dst, &src); }
-
- //! @brief Minimum of Packed Dword Integers (SSE4.1).
- void pminud(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMinUD, &dst, &src); }
- //! @brief Minimum of Packed Dword Integers (SSE4.1).
- void pminud(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMinUD, &dst, &src); }
-
- //! @brief Minimum of Packed Dword Integers (SSE4.1).
- void pminsd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMinSD, &dst, &src); }
- //! @brief Minimum of Packed Dword Integers (SSE4.1).
- void pminsd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMinSD, &dst, &src); }
-
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxbw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMovSXBW, &dst, &src); }
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxbw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMovSXBW, &dst, &src); }
-
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxbd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMovSXBD, &dst, &src); }
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxbd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMovSXBD, &dst, &src); }
-
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxbq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMovSXBQ, &dst, &src); }
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxbq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMovSXBQ, &dst, &src); }
-
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxwd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMovSXWD, &dst, &src); }
- //! @brief Packed Move with Sign Extend (SSE4.1).
- void pmovsxwd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMovSXWD, &dst, &src); }
-
- //! @brief (SSE4.1).
- void pmovsxwq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMovSXWQ, &dst, &src); }
- //! @brief (SSE4.1).
- void pmovsxwq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMovSXWQ, &dst, &src); }
-
- //! @brief (SSE4.1).
- void pmovsxdq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMovSXDQ, &dst, &src); }
- //! @brief (SSE4.1).
- void pmovsxdq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMovSXDQ, &dst, &src); }
-
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxbw(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMovZXBW, &dst, &src); }
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxbw(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMovZXBW, &dst, &src); }
-
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxbd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMovZXBD, &dst, &src); }
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxbd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMovZXBD, &dst, &src); }
-
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxbq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMovZXBQ, &dst, &src); }
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxbq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMovZXBQ, &dst, &src); }
-
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxwd(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMovZXWD, &dst, &src); }
- //! @brief Packed Move with Zero Extend (SSE4.1).
- void pmovzxwd(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMovZXWD, &dst, &src); }
-
- //! @brief (SSE4.1).
- void pmovzxwq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMovZXWQ, &dst, &src); }
- //! @brief (SSE4.1).
- void pmovzxwq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMovZXWQ, &dst, &src); }
-
- //! @brief (SSE4.1).
- void pmovzxdq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMovZXDQ, &dst, &src); }
- //! @brief (SSE4.1).
- void pmovzxdq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMovZXDQ, &dst, &src); }
-
- //! @brief Multiply Packed Signed Dword Integers (SSE4.1).
- void pmuldq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMulDQ, &dst, &src); }
- //! @brief Multiply Packed Signed Dword Integers (SSE4.1).
- void pmuldq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMulDQ, &dst, &src); }
-
- //! @brief Multiply Packed Signed Integers and Store Low Result (SSE4.1).
- void pmulld(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPMulLD, &dst, &src); }
- //! @brief Multiply Packed Signed Integers and Store Low Result (SSE4.1).
- void pmulld(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPMulLD, &dst, &src); }
-
- //! @brief Logical Compare (SSE4.1).
- void ptest(const XmmVar &op1, const XmmVar &op2) { this->_emitInstruction(kX86InstPTest, &op1, &op2); }
- //! @brief Logical Compare (SSE4.1).
- void ptest(const XmmVar &op1, const Mem &op2) { this->_emitInstruction(kX86InstPTest, &op1, &op2); }
-
- //! Round Packed SP-FP Values @brief (SSE4.1).
- void roundps(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstRoundPS, &dst, &src, &imm8); }
- //! Round Packed SP-FP Values @brief (SSE4.1).
- void roundps(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstRoundPS, &dst, &src, &imm8); }
-
- //! @brief Round Scalar SP-FP Values (SSE4.1).
- void roundss(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstRoundSS, &dst, &src, &imm8); }
- //! @brief Round Scalar SP-FP Values (SSE4.1).
- void roundss(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstRoundSS, &dst, &src, &imm8); }
-
- //! @brief Round Packed DP-FP Values (SSE4.1).
- void roundpd(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstRoundPD, &dst, &src, &imm8); }
- //! @brief Round Packed DP-FP Values (SSE4.1).
- void roundpd(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstRoundPD, &dst, &src, &imm8); }
-
- //! @brief Round Scalar DP-FP Values (SSE4.1).
- void roundsd(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstRoundSD, &dst, &src, &imm8); }
- //! @brief Round Scalar DP-FP Values (SSE4.1).
- void roundsd(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstRoundSD, &dst, &src, &imm8); }
-
- // --------------------------------------------------------------------------
- // [SSE4.2]
- // --------------------------------------------------------------------------
-
- //! @brief Accumulate CRC32 Value (polynomial 0x11EDC6F41) (SSE4.2).
- void crc32(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstCrc32, &dst, &src); }
- //! @brief Accumulate CRC32 Value (polynomial 0x11EDC6F41) (SSE4.2).
- void crc32(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstCrc32, &dst, &src); }
-
- //! @brief Packed Compare Explicit Length Strings, Return Index (SSE4.2).
- void pcmpestri(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPCmpEStrI, &dst, &src, &imm8); }
- //! @brief Packed Compare Explicit Length Strings, Return Index (SSE4.2).
- void pcmpestri(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPCmpEStrI, &dst, &src, &imm8); }
-
- //! @brief Packed Compare Explicit Length Strings, Return Mask (SSE4.2).
- void pcmpestrm(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPCmpEStrM, &dst, &src, &imm8); }
- //! @brief Packed Compare Explicit Length Strings, Return Mask (SSE4.2).
- void pcmpestrm(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPCmpEStrM, &dst, &src, &imm8); }
-
- //! @brief Packed Compare Implicit Length Strings, Return Index (SSE4.2).
- void pcmpistri(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPCmpIStrI, &dst, &src, &imm8); }
- //! @brief Packed Compare Implicit Length Strings, Return Index (SSE4.2).
- void pcmpistri(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPCmpIStrI, &dst, &src, &imm8); }
-
- //! @brief Packed Compare Implicit Length Strings, Return Mask (SSE4.2).
- void pcmpistrm(const XmmVar &dst, const XmmVar &src, const Imm &imm8) { this->_emitInstruction(kX86InstPCmpIStrM, &dst, &src, &imm8); }
- //! @brief Packed Compare Implicit Length Strings, Return Mask (SSE4.2).
- void pcmpistrm(const XmmVar &dst, const Mem &src, const Imm &imm8) { this->_emitInstruction(kX86InstPCmpIStrM, &dst, &src, &imm8); }
-
- //! @brief Compare Packed Data for Greater Than (SSE4.2).
- void pcmpgtq(const XmmVar &dst, const XmmVar &src) { this->_emitInstruction(kX86InstPCmpGtQ, &dst, &src); }
- //! @brief Compare Packed Data for Greater Than (SSE4.2).
- void pcmpgtq(const XmmVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPCmpGtQ, &dst, &src); }
-
- //! @brief Return the Count of Number of Bits Set to 1 (SSE4.2).
- void popcnt(const GpVar &dst, const GpVar &src) { this->_emitInstruction(kX86InstPopCnt, &dst, &src); }
- //! @brief Return the Count of Number of Bits Set to 1 (SSE4.2).
- void popcnt(const GpVar &dst, const Mem &src) { this->_emitInstruction(kX86InstPopCnt, &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.
- void amd_prefetch(const Mem &mem) { this->_emitInstruction(kX86InstAmdPrefetch, &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).
- void amd_prefetchw(const Mem &mem) { this->_emitInstruction(kX86InstAmdPrefetchW, &mem); }
-
- // --------------------------------------------------------------------------
- // [Intel only]
- // --------------------------------------------------------------------------
-
- //! @brief Move Data After Swapping Bytes (SSE3 - Intel Atom).
- void movbe(const GpVar &dst, const Mem &src)
- {
- ASMJIT_ASSERT(!dst.isGpb());
- this->_emitInstruction(kX86InstMovBE, &dst, &src);
- }
-
- //! @brief Move Data After Swapping Bytes (SSE3 - Intel Atom).
- void movbe(const Mem &dst, const GpVar &src)
- {
- ASMJIT_ASSERT(!src.isGpb());
- this->_emitInstruction(kX86InstMovBE, &dst, &src);
- }
-
- // -------------------------------------------------------------------------
- // [Emit Options]
- // -------------------------------------------------------------------------
-
- //! @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.
- void lock() { this->_emitOptions |= kX86EmitOptionLock; }
-
- //! @brief Force REX prefix to be emitted.
- //!
- //! This option should be used carefully, because there are unencodable
- //! combinations. If you want to access ah, bh, ch or dh registers then you
- //! can't emit REX prefix and it will cause an illegal instruction error.
- //!
- //! @note REX prefix is only valid for X64/AMD64 platform.
- //!
- //! @sa @c kX86EmitOptionRex.
- void rex() { this->_emitOptions |= kX86EmitOptionRex; }
+//! status code to `kErrorUnknownInst`.
+struct ASMJIT_VCLASS X86Compiler : public Compiler {
+ ASMJIT_NO_COPY(X86Compiler)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a `X86Compiler` instance.
+ ASMJIT_API X86Compiler(Runtime* runtime, uint32_t arch
+#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
+ = kArchHost
+#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64
+ );
+ //! Destroy the `X86Compiler` instance.
+ ASMJIT_API ~X86Compiler();
+
+ // --------------------------------------------------------------------------
+ // [Arch]
+ // --------------------------------------------------------------------------
+
+ //! Get count of registers of the current architecture.
+ ASMJIT_INLINE const X86RegCount& getRegCount() const {
+ return _regCount;
+ }
+
+ //! Get Gpd or Gpq register depending on the current architecture.
+ ASMJIT_INLINE X86GpReg gpz(uint32_t index) const {
+ return X86GpReg(zax, index);
+ }
+
+ //! Create an architecture dependent intptr_t memory operand.
+ ASMJIT_INLINE X86Mem intptr_ptr(const X86GpReg& base, int32_t disp = 0) const {
+ return x86::ptr(base, disp, _regSize);
+ }
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) const {
+ return x86::ptr(base, index, shift, disp, _regSize);
+ }
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, int32_t disp = 0) const {
+ return x86::ptr(label, disp, _regSize);
+ }
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0) const {
+ return x86::ptr(label, index, shift, disp, _regSize);
+ }
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, int32_t disp = 0) const {
+ return x86::ptr_abs(pAbs, disp, _regSize);
+ }
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, const X86GpReg& index, uint32_t shift, int32_t disp = 0) const {
+ return x86::ptr_abs(pAbs, index, shift, disp, _regSize);
+ }
+
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr(const X86GpVar& base, int32_t disp = 0) {
+ return x86::ptr(base, disp, _regSize);
+ }
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr(const X86GpVar& base, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) {
+ return x86::ptr(base, index, shift, disp, _regSize);
+ }
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp = 0) {
+ return x86::ptr(label, index, shift, disp, _regSize);
+ }
+ //! \overload
+ ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, const X86GpVar& index, uint32_t shift, int32_t disp = 0) {
+ return x86::ptr_abs(pAbs, index, shift, disp, _regSize);
+ }
+
+ ASMJIT_API Error setArch(uint32_t arch);
+
+ // --------------------------------------------------------------------------
+ // [Inst / Emit]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `InstNode`.
+ ASMJIT_API InstNode* newInst(uint32_t code);
+ //! \overload
+ ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0);
+ //! \overload
+ ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0, const Operand& o1);
+ //! \overload
+ ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2);
+ //! \overload
+ ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3);
+ //! \overload
+ ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4);
+
+ //! Add a new `InstNode`.
+ ASMJIT_API InstNode* emit(uint32_t code);
+ //! \overload
+ ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0);
+ //! \overload
+ ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1);
+ //! \overload
+ ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2);
+ //! \overload
+ ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3);
+ //! \overload
+ ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4);
+
+ //! \overload
+ ASMJIT_API InstNode* emit(uint32_t code, int o0);
+ //! \overload
+ ASMJIT_API InstNode* emit(uint32_t code, uint64_t o0);
+ //! \overload
+ ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, int o1);
+ //! \overload
+ ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, uint64_t o1);
+ //! \overload
+ ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, int o2);
+ //! \overload
+ ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2);
+
+ // --------------------------------------------------------------------------
+ // [Func]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `X86FuncNode`.
+ ASMJIT_API X86FuncNode* newFunc(uint32_t conv, const FuncPrototype& p);
+
+ //! Add a new function.
+ //!
+ //! \param conv Calling convention to use (see \ref kFuncConv enum)
+ //! \param params Function arguments prototype.
+ //!
+ //! This method is usually used as a first step when generating functions
+ //! by `Compiler`. First parameter `cconv` specifies function calling
+ //! convention to use. Second parameter `params` specifies function
+ //! arguments. To create function arguments are used templates
+ //! `FuncBuilder0<...>`, `FuncBuilder1<...>`, `FuncBuilder2<...>`, etc...
+ //!
+ //! Templates with FuncBuilder 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.
+ //!
+ //! ~~~
+ //! // Building function using asmjit::Compiler example.
+ //!
+ //! // Compiler instance
+ //! Compiler c;
+ //!
+ //! // Begin of function, also emits function prolog.
+ //! c.addFunc(
+ //! // Default calling convention (32-bit cdecl or 64-bit for host OS)
+ //! kFuncConvHost,
+ //! // Using function builder to generate arguments list
+ //! FuncBuilder2<Void, int, int>());
+ //!
+ //! // End of function, also emits function epilog.
+ //! c.endFunc();
+ //! ~~~
+ //!
+ //! 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 `asmjit::Function::getArg()` method. Arguments
+ //! are indexed from 0 (like everything in C).
+ //!
+ //! ~~~
+ //! // Accessing function arguments through asmjit::Function example.
+ //!
+ //! // Compiler instance
+ //! Compiler c;
+ //! X86GpVar a0(c, kVarTypeInt32);
+ //! X86GpVar a1(c, kVarTypeInt32);
+ //!
+ //! // Begin of function (also emits function prolog)
+ //! c.addFunc(
+ //! // Default calling convention (32-bit cdecl or 64-bit for host OS)
+ //! kFuncConvHost,
+ //! // Using function builder to generate arguments list
+ //! FuncBuilder2<Void, int, int>());
+ //!
+ //! c.setArg(0, a0);
+ //! c.setArg(1, a1);
+ //!
+ //! // Use them.
+ //! c.add(a0, a1);
+ //!
+ //! // End of function - emits function epilog and return instruction.
+ //! c.endFunc();
+ //! ~~~
+ //!
+ //! Arguments are like variables. How to manipulate with variables is
+ //! documented in `Compiler`, variables section.
+ //!
+ //! \note To get current function use `getFunc()` method or save pointer to
+ //! `FuncNode` returned by `Compiler::addFunc<>` method. The recommended way
+ //! is saving the pointer and using it to specify function arguments and
+ //! return value.
+ //!
+ //! \sa FuncBuilder0, FuncBuilder1, FuncBuilder2, ...
+ ASMJIT_API X86FuncNode* addFunc(uint32_t conv, const FuncPrototype& p);
+
+ //! End of current function.
+ ASMJIT_API EndNode* endFunc();
+
+ //! Get current function as `X86FuncNode`.
+ //!
+ //! This method can be called within `addFunc()` and `endFunc()` block to get
+ //! current function you are working with. It's recommended to store `FuncNode`
+ //! pointer returned by `addFunc<>` method, because this allows you in future
+ //! implement function sections outside of function itself.
+ ASMJIT_INLINE X86FuncNode* getFunc() const {
+ return static_cast<X86FuncNode*>(_func);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Ret]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `RetNode`.
+ ASMJIT_API RetNode* newRet(const Operand& o0, const Operand& o1);
+ //! Add a new `RetNode`.
+ ASMJIT_API RetNode* addRet(const Operand& o0, const Operand& o1);
+
+ // --------------------------------------------------------------------------
+ // [Call]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `X86CallNode`.
+ ASMJIT_API X86CallNode* newCall(const Operand& o0, uint32_t conv, const FuncPrototype& p);
+ //! Add a new `X86CallNode`.
+ ASMJIT_API X86CallNode* addCall(const Operand& o0, uint32_t conv, const FuncPrototype& p);
+
+ // --------------------------------------------------------------------------
+ // [Vars]
+ // --------------------------------------------------------------------------
+
+ //! Set function argument to `var`.
+ ASMJIT_API Error setArg(uint32_t argIndex, Var& var);
+
+ ASMJIT_API virtual Error _newVar(Var* var, uint32_t type, const char* name);
+
+ //! Create a new Gp variable.
+ ASMJIT_INLINE X86GpVar newGpVar(uint32_t vType = kVarTypeIntPtr, const char* name = nullptr) {
+ ASMJIT_ASSERT(vType < kX86VarTypeCount);
+ ASMJIT_ASSERT(IntUtil::inInterval<uint32_t>(vType, _kVarTypeIntStart, _kVarTypeIntEnd));
+
+ X86GpVar var(NoInit);
+ _newVar(&var, vType, name);
+ return var;
+ }
+
+ //! Create a new Mm variable.
+ ASMJIT_INLINE X86MmVar newMmVar(uint32_t vType = kX86VarTypeMm, const char* name = nullptr) {
+ ASMJIT_ASSERT(vType < kX86VarTypeCount);
+ ASMJIT_ASSERT(IntUtil::inInterval<uint32_t>(vType, _kX86VarTypeMmStart, _kX86VarTypeMmEnd));
+
+ X86MmVar var(NoInit);
+ _newVar(&var, vType, name);
+ return var;
+ }
+
+ //! Create a new Xmm variable.
+ ASMJIT_INLINE X86XmmVar newXmmVar(uint32_t vType = kX86VarTypeXmm, const char* name = nullptr) {
+ ASMJIT_ASSERT(vType < kX86VarTypeCount);
+ ASMJIT_ASSERT(IntUtil::inInterval<uint32_t>(vType, _kX86VarTypeXmmStart, _kX86VarTypeXmmEnd));
+
+ X86XmmVar var(NoInit);
+ _newVar(&var, vType, name);
+ return var;
+ }
+
+ //! Create a new Ymm variable.
+ ASMJIT_INLINE X86YmmVar newYmmVar(uint32_t vType = kX86VarTypeYmm, const char* name = nullptr) {
+ ASMJIT_ASSERT(vType < kX86VarTypeCount);
+ ASMJIT_ASSERT(IntUtil::inInterval<uint32_t>(vType, _kX86VarTypeYmmStart, _kX86VarTypeYmmEnd));
+
+ X86YmmVar var(NoInit);
+ _newVar(&var, vType, name);
+ return var;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Stack]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual Error _newStack(BaseMem* mem, uint32_t size, uint32_t alignment, const char* name);
+
+ //! Create a new memory chunk allocated on the current function's stack.
+ ASMJIT_INLINE X86Mem newStack(uint32_t size, uint32_t alignment, const char* name = nullptr) {
+ X86Mem m(NoInit);
+ _newStack(&m, size, alignment, name);
+ return m;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Const]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual Error _newConst(BaseMem* mem, uint32_t scope, const void* data, size_t size);
+
+ //! Put data to a constant-pool and get a memory reference to it.
+ ASMJIT_INLINE X86Mem newConst(uint32_t scope, const void* data, size_t size) {
+ X86Mem m(NoInit);
+ _newConst(&m, scope, data, size);
+ return m;
+ }
+
+ //! Put a BYTE `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newByteConst(uint32_t scope, uint8_t val) { return newConst(scope, &val, 1); }
+ //! Put a WORD `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newWordConst(uint32_t scope, uint16_t val) { return newConst(scope, &val, 2); }
+ //! Put a DWORD `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newDWordConst(uint32_t scope, uint32_t val) { return newConst(scope, &val, 4); }
+ //! Put a QWORD `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newQWordConst(uint32_t scope, uint64_t val) { return newConst(scope, &val, 8); }
+
+ //! Put a WORD `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newInt16Const(uint32_t scope, int16_t val) { return newConst(scope, &val, 2); }
+ //! Put a WORD `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newUInt16Const(uint32_t scope, uint16_t val) { return newConst(scope, &val, 2); }
+ //! Put a DWORD `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newInt32Const(uint32_t scope, int32_t val) { return newConst(scope, &val, 4); }
+ //! Put a DWORD `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newUInt32Const(uint32_t scope, uint32_t val) { return newConst(scope, &val, 4); }
+ //! Put a QWORD `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newInt64Const(uint32_t scope, int64_t val) { return newConst(scope, &val, 8); }
+ //! Put a QWORD `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newUInt64Const(uint32_t scope, uint64_t val) { return newConst(scope, &val, 8); }
+
+ //! Put a SP-FP `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newFloatConst(uint32_t scope, float val) { return newConst(scope, &val, 4); }
+ //! Put a DP-FP `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newDoubleConst(uint32_t scope, double val) { return newConst(scope, &val, 8); }
+
+ //! Put a MMX `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newMmConst(uint32_t scope, const Vec64& val) { return newConst(scope, &val, 8); }
+ //! Put a XMM `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newXmmConst(uint32_t scope, const Vec128& val) { return newConst(scope, &val, 16); }
+ //! Put a YMM `val` to a constant-pool.
+ ASMJIT_INLINE X86Mem newYmmConst(uint32_t scope, const Vec256& val) { return newConst(scope, &val, 32); }
+
+ // --------------------------------------------------------------------------
+ // [Embed]
+ // --------------------------------------------------------------------------
+
+ //! Add 8-bit integer data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* db(uint8_t x) { return embed(&x, 1); }
+ //! Add 16-bit integer data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* dw(uint16_t x) { return embed(&x, 2); }
+ //! Add 32-bit integer data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* dd(uint32_t x) { return embed(&x, 4); }
+ //! Add 64-bit integer data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* dq(uint64_t x) { return embed(&x, 8); }
+
+ //! Add 8-bit integer data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* dint8(int8_t x) { return embed(&x, static_cast<uint32_t>(sizeof(int8_t))); }
+ //! Add 8-bit integer data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* duint8(uint8_t x) { return embed(&x, static_cast<uint32_t>(sizeof(uint8_t))); }
+
+ //! Add 16-bit integer data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* dint16(int16_t x) { return embed(&x, static_cast<uint32_t>(sizeof(int16_t))); }
+ //! Add 16-bit integer data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* duint16(uint16_t x) { return embed(&x, static_cast<uint32_t>(sizeof(uint16_t))); }
+
+ //! Add 32-bit integer data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* dint32(int32_t x) { return embed(&x, static_cast<uint32_t>(sizeof(int32_t))); }
+ //! Add 32-bit integer data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* duint32(uint32_t x) { return embed(&x, static_cast<uint32_t>(sizeof(uint32_t))); }
+
+ //! Add 64-bit integer data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* dint64(int64_t x) { return embed(&x, static_cast<uint32_t>(sizeof(int64_t))); }
+ //! Add 64-bit integer data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* duint64(uint64_t x) { return embed(&x, static_cast<uint32_t>(sizeof(uint64_t))); }
+
+ //! Add float data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* dfloat(float x) { return embed(&x, static_cast<uint32_t>(sizeof(float))); }
+ //! Add double data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* ddouble(double x) { return embed(&x, static_cast<uint32_t>(sizeof(double))); }
+
+ //! Add Mm data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* dmm(const Vec64& x) { return embed(&x, static_cast<uint32_t>(sizeof(Vec64))); }
+ //! Add Xmm data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* dxmm(const Vec128& x) { return embed(&x, static_cast<uint32_t>(sizeof(Vec128))); }
+ //! Add Ymm data to the instruction stream.
+ ASMJIT_INLINE EmbedNode* dymm(const Vec256& x) { return embed(&x, static_cast<uint32_t>(sizeof(Vec256))); }
+
+ //! Add data in a given structure instance to the instruction stream.
+ template<typename T>
+ ASMJIT_INLINE EmbedNode* dstruct(const T& x) { return embed(&x, static_cast<uint32_t>(sizeof(T))); }
+
+ // --------------------------------------------------------------------------
+ // [Make]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual void* make();
+
+ // -------------------------------------------------------------------------
+ // [Assembler]
+ // -------------------------------------------------------------------------
+
+ ASMJIT_API virtual Assembler* _newAssembler();
+
+ // -------------------------------------------------------------------------
+ // [Serialize]
+ // -------------------------------------------------------------------------
+
+ ASMJIT_API virtual Error serialize(Assembler* assembler);
+
+ // -------------------------------------------------------------------------
+ // [Options]
+ // -------------------------------------------------------------------------
+
+ ASMJIT_X86_EMIT_OPTIONS(X86Compiler)
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Count of registers depending on the current architecture.
+ X86RegCount _regCount;
+
+ //! EAX or RAX register depending on the current architecture.
+ X86GpReg zax;
+ //! ECX or RCX register depending on the current architecture.
+ X86GpReg zcx;
+ //! EDX or RDX register depending on the current architecture.
+ X86GpReg zdx;
+ //! EBX or RBX register depending on the current architecture.
+ X86GpReg zbx;
+ //! ESP or RSP register depending on the current architecture.
+ X86GpReg zsp;
+ //! EBP or RBP register depending on the current architecture.
+ X86GpReg zbp;
+ //! ESI or RSI register depending on the current architecture.
+ X86GpReg zsi;
+ //! EDI or RDI register depending on the current architecture.
+ X86GpReg zdi;
+
+ // --------------------------------------------------------------------------
+ // [X86 Instructions]
+ // --------------------------------------------------------------------------
+
+#define INST_0x(_Inst_, _Code_) \
+ ASMJIT_INLINE InstNode* _Inst_() { \
+ return emit(_Code_); \
+ }
+
+#define INST_1x(_Inst_, _Code_, _Op0_) \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0) { \
+ return emit(_Code_, o0); \
+ }
+
+#define INST_1x_(_Inst_, _Code_, _Op0_, _Cond_) \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0) { \
+ ASMJIT_ASSERT(_Cond_); \
+ return emit(_Code_, o0); \
+ }
+
+#define INST_1i(_Inst_, _Code_, _Op0_) \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0) { \
+ return emit(_Code_, o0); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(int o0) { \
+ return emit(_Code_, o0); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(unsigned int o0) { \
+ return emit(_Code_, static_cast<uint64_t>(o0)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(int64_t o0) { \
+ return emit(_Code_, static_cast<uint64_t>(o0)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(uint64_t o0) { \
+ return emit(_Code_, o0); \
+ }
+
+#define INST_1cc(_Inst_, _Code_, _Translate_, _Op0_) \
+ ASMJIT_INLINE InstNode* _Inst_(uint32_t cc, const _Op0_& o0) { \
+ return emit(_Translate_(cc), o0); \
+ } \
+ \
+ ASMJIT_INLINE InstNode* _Inst_##a(const _Op0_& o0) { return emit(_Code_##a, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##ae(const _Op0_& o0) { return emit(_Code_##ae, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##b(const _Op0_& o0) { return emit(_Code_##b, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##be(const _Op0_& o0) { return emit(_Code_##be, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##c(const _Op0_& o0) { return emit(_Code_##c, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##e(const _Op0_& o0) { return emit(_Code_##e, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##g(const _Op0_& o0) { return emit(_Code_##g, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##ge(const _Op0_& o0) { return emit(_Code_##ge, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##l(const _Op0_& o0) { return emit(_Code_##l, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##le(const _Op0_& o0) { return emit(_Code_##le, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##na(const _Op0_& o0) { return emit(_Code_##na, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##nae(const _Op0_& o0) { return emit(_Code_##nae, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##nb(const _Op0_& o0) { return emit(_Code_##nb, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##nbe(const _Op0_& o0) { return emit(_Code_##nbe, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##nc(const _Op0_& o0) { return emit(_Code_##nc, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##ne(const _Op0_& o0) { return emit(_Code_##ne, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##ng(const _Op0_& o0) { return emit(_Code_##ng, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##nge(const _Op0_& o0) { return emit(_Code_##nge, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##nl(const _Op0_& o0) { return emit(_Code_##nl, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##nle(const _Op0_& o0) { return emit(_Code_##nle, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##no(const _Op0_& o0) { return emit(_Code_##no, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##np(const _Op0_& o0) { return emit(_Code_##np, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##ns(const _Op0_& o0) { return emit(_Code_##ns, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##nz(const _Op0_& o0) { return emit(_Code_##nz, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##o(const _Op0_& o0) { return emit(_Code_##o, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##p(const _Op0_& o0) { return emit(_Code_##p, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##pe(const _Op0_& o0) { return emit(_Code_##pe, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##po(const _Op0_& o0) { return emit(_Code_##po, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##s(const _Op0_& o0) { return emit(_Code_##s, o0); } \
+ ASMJIT_INLINE InstNode* _Inst_##z(const _Op0_& o0) { return emit(_Code_##z, o0); }
+
+#define INST_2x(_Inst_, _Code_, _Op0_, _Op1_) \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1) { \
+ return emit(_Code_, o0, o1); \
+ }
+
+#define INST_2x_(_Inst_, _Code_, _Op0_, _Op1_, _Cond_) \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1) { \
+ ASMJIT_ASSERT(_Cond_); \
+ return emit(_Code_, o0, o1); \
+ }
+
+#define INST_2i(_Inst_, _Code_, _Op0_, _Op1_) \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1) { \
+ return emit(_Code_, o0, o1); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, int o1) { \
+ return emit(_Code_, o0, o1); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, unsigned int o1) { \
+ return emit(_Code_, o0, static_cast<uint64_t>(o1)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, int64_t o1) { \
+ return emit(_Code_, o0, static_cast<uint64_t>(o1)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, uint64_t o1) { \
+ return emit(_Code_, o0, o1); \
+ }
+
+#define INST_2cc(_Inst_, _Code_, _Translate_, _Op0_, _Op1_) \
+ ASMJIT_INLINE InstNode* _Inst_(uint32_t cc, const _Op0_& o0, const _Op1_& o1) { \
+ return emit(_Translate_(cc), o0, o1); \
+ } \
+ \
+ ASMJIT_INLINE InstNode* _Inst_##a(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##a, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##ae(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ae, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##b(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##b, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##be(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##be, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##c(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##c, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##e(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##e, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##g(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##g, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##ge(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ge, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##l(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##l, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##le(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##le, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##na(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##na, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##nae(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nae, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##nb(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nb, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##nbe(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nbe, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##nc(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nc, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##ne(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ne, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##ng(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ng, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##nge(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nge, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##nl(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nl, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##nle(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nle, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##no(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##no, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##np(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##np, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##ns(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ns, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##nz(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nz, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##o(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##o, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##p(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##p, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##pe(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##pe, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##po(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##po, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##s(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##s, o0, o1); } \
+ ASMJIT_INLINE InstNode* _Inst_##z(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##z, o0, o1); }
+
+#define INST_3x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \
+ return emit(_Code_, o0, o1, o2); \
+ }
+
+#define INST_3x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Cond_) \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \
+ ASMJIT_ASSERT(_Cond_); \
+ return emit(_Code_, o0, o1, o2); \
+ }
+
+#define INST_3i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \
+ return emit(_Code_, o0, o1, o2); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, int o2) { \
+ return emit(_Code_, o0, o1, o2); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, unsigned int o2) { \
+ return emit(_Code_, o0, o1, static_cast<uint64_t>(o2)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, int64_t o2) { \
+ return emit(_Code_, o0, o1, static_cast<uint64_t>(o2)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, uint64_t o2) { \
+ return emit(_Code_, o0, o1, o2); \
+ }
+
+#define INST_4x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \
+ return emit(_Code_, o0, o1, o2, o3); \
+ }
+
+#define INST_4x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Cond_) \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \
+ ASMJIT_ASSERT(_Cond_); \
+ return emit(_Code_, o0, o1, o2, o3); \
+ }
+
+#define INST_4i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \
+ return emit(_Code_, o0, o1, o2, o3); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int o3) { \
+ return emit(_Code_, o0, o1, o2, o3); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, unsigned int o3) { \
+ return emit(_Code_, o0, o1, o2, static_cast<uint64_t>(o3)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int64_t o3) { \
+ return emit(_Code_, o0, o1, o2, static_cast<uint64_t>(o3)); \
+ } \
+ /*! \overload */ \
+ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, uint64_t o3) { \
+ return emit(_Code_, o0, o1, o2, o3); \
+ }
+
+ //! Add with carry.
+ INST_2x(adc, kX86InstIdAdc, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(adc, kX86InstIdAdc, X86GpVar, X86Mem)
+ //! \overload
+ INST_2i(adc, kX86InstIdAdc, X86GpVar, Imm)
+ //! \overload
+ INST_2x(adc, kX86InstIdAdc, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(adc, kX86InstIdAdc, X86Mem, Imm)
+
+ //! Add.
+ INST_2x(add, kX86InstIdAdd, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(add, kX86InstIdAdd, X86GpVar, X86Mem)
+ //! \overload
+ INST_2i(add, kX86InstIdAdd, X86GpVar, Imm)
+ //! \overload
+ INST_2x(add, kX86InstIdAdd, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(add, kX86InstIdAdd, X86Mem, Imm)
+
+ //! And.
+ INST_2x(and_, kX86InstIdAnd, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(and_, kX86InstIdAnd, X86GpVar, X86Mem)
+ //! \overload
+ INST_2i(and_, kX86InstIdAnd, X86GpVar, Imm)
+ //! \overload
+ INST_2x(and_, kX86InstIdAnd, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(and_, kX86InstIdAnd, X86Mem, Imm)
+
+ //! Bit scan forward.
+ INST_2x_(bsf, kX86InstIdBsf, X86GpVar, X86GpVar, !o0.isGpb())
+ //! \overload
+ INST_2x_(bsf, kX86InstIdBsf, X86GpVar, X86Mem, !o0.isGpb())
+
+ //! Bit scan reverse.
+ INST_2x_(bsr, kX86InstIdBsr, X86GpVar, X86GpVar, !o0.isGpb())
+ //! \overload
+ INST_2x_(bsr, kX86InstIdBsr, X86GpVar, X86Mem, !o0.isGpb())
+
+ //! Byte swap (32-bit or 64-bit registers only) (i486).
+ INST_1x_(bswap, kX86InstIdBswap, X86GpVar, o0.getSize() >= 4)
+
+ //! Bit test.
+ INST_2x(bt, kX86InstIdBt, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2i(bt, kX86InstIdBt, X86GpVar, Imm)
+ //! \overload
+ INST_2x(bt, kX86InstIdBt, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(bt, kX86InstIdBt, X86Mem, Imm)
+
+ //! Bit test and complement.
+ INST_2x(btc, kX86InstIdBtc, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2i(btc, kX86InstIdBtc, X86GpVar, Imm)
+ //! \overload
+ INST_2x(btc, kX86InstIdBtc, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(btc, kX86InstIdBtc, X86Mem, Imm)
+
+ //! Bit test and reset.
+ INST_2x(btr, kX86InstIdBtr, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2i(btr, kX86InstIdBtr, X86GpVar, Imm)
+ //! \overload
+ INST_2x(btr, kX86InstIdBtr, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(btr, kX86InstIdBtr, X86Mem, Imm)
+
+ //! Bit test and set.
+ INST_2x(bts, kX86InstIdBts, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2i(bts, kX86InstIdBts, X86GpVar, Imm)
+ //! \overload
+ INST_2x(bts, kX86InstIdBts, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(bts, kX86InstIdBts, X86Mem, Imm)
+
+ //! Call a function.
+ ASMJIT_INLINE X86CallNode* call(const X86GpVar& dst, uint32_t conv, const FuncPrototype& p) {
+ return addCall(dst, conv, p);
+ }
+ //! \overload
+ ASMJIT_INLINE X86CallNode* call(const X86Mem& dst, uint32_t conv, const FuncPrototype& p) {
+ return addCall(dst, conv, p);
+ }
+ //! \overload
+ ASMJIT_INLINE X86CallNode* call(const Label& label, uint32_t conv, const FuncPrototype& p) {
+ return addCall(label, conv, p);
+ }
+ //! \overload
+ ASMJIT_INLINE X86CallNode* call(const Imm& dst, uint32_t conv, const FuncPrototype& p) {
+ return addCall(dst, conv, p);
+ }
+ //! \overload
+ ASMJIT_INLINE X86CallNode* call(Ptr dst, uint32_t conv, const FuncPrototype& p) {
+ return addCall(Imm(dst), conv, p);
+ }
+
+ //! Clear carry flag
+ INST_0x(clc, kX86InstIdClc)
+ //! Clear direction flag
+ INST_0x(cld, kX86InstIdCld)
+ //! Complement carry Flag.
+ INST_0x(cmc, kX86InstIdCmc)
+
+ //! Convert BYTE to WORD (AX <- Sign Extend AL).
+ INST_1x(cbw, kX86InstIdCbw, X86GpVar /* al */)
+ //! Convert DWORD to QWORD (EDX:EAX <- Sign Extend EAX).
+ INST_2x(cdq, kX86InstIdCdq, X86GpVar /* edx */, X86GpVar /* eax */)
+ //! Convert DWORD to QWORD (RAX <- Sign Extend EAX) (X64 Only).
+ INST_1x(cdqe, kX86InstIdCdqe, X86GpVar /* eax */)
+ //! Convert QWORD to OWORD (RDX:RAX <- Sign Extend RAX) (X64 Only).
+ INST_2x(cqo, kX86InstIdCdq, X86GpVar /* rdx */, X86GpVar /* rax */)
+ //! Convert WORD to DWORD (DX:AX <- Sign Extend AX).
+ INST_2x(cwd, kX86InstIdCwd, X86GpVar /* dx */, X86GpVar /* ax */)
+ //! Convert WORD to DWORD (EAX <- Sign Extend AX).
+ INST_1x(cwde, kX86InstIdCwde, X86GpVar /* eax */)
+
+ //! Conditional move.
+ INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpVar, X86GpVar)
+ //! Conditional move.
+ INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpVar, X86Mem)
+
+ //! Compare two operands.
+ INST_2x(cmp, kX86InstIdCmp, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(cmp, kX86InstIdCmp, X86GpVar, X86Mem)
+ //! \overload
+ INST_2i(cmp, kX86InstIdCmp, X86GpVar, Imm)
+ //! \overload
+ INST_2x(cmp, kX86InstIdCmp, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(cmp, kX86InstIdCmp, X86Mem, Imm)
+
+ //! Compare BYTE in ES:`o0` and DS:`o1`.
+ INST_2x(cmpsb, kX86InstIdCmpsB, X86GpVar, X86GpVar)
+ //! Compare DWORD in ES:`o0` and DS:`o1`.
+ INST_2x(cmpsd, kX86InstIdCmpsD, X86GpVar, X86GpVar)
+ //! Compare QWORD in ES:`o0` and DS:`o1` (X64 Only).
+ INST_2x(cmpsq, kX86InstIdCmpsQ, X86GpVar, X86GpVar)
+ //! Compare WORD in ES:`o0` and DS:`o1`.
+ INST_2x(cmpsw, kX86InstIdCmpsW, X86GpVar, X86GpVar)
+
+ //! Compare and exchange (i486).
+ INST_3x(cmpxchg, kX86InstIdCmpxchg, X86GpVar /* eax */, X86GpVar, X86GpVar)
+ //! \overload
+ INST_3x(cmpxchg, kX86InstIdCmpxchg, X86GpVar /* eax */, X86Mem, X86GpVar)
+
+ //! Compare and exchange 128-bit value in RDX:RAX with `x_mem` (X64 Only).
+ ASMJIT_INLINE InstNode* cmpxchg16b(
+ const X86GpVar& r_edx, const X86GpVar& r_eax,
+ const X86GpVar& r_ecx, const X86GpVar& r_ebx,
+ const X86Mem& x_mem) {
+
+ return emit(kX86InstIdCmpxchg16b, r_edx, r_eax, r_ecx, r_ebx, x_mem);
+ }
+
+ //! Compare and exchange 64-bit value in EDX:EAX with `x_mem` (Pentium).
+ ASMJIT_INLINE InstNode* cmpxchg8b(
+ const X86GpVar& r_edx, const X86GpVar& r_eax,
+ const X86GpVar& r_ecx, const X86GpVar& r_ebx,
+ const X86Mem& x_mem) {
+
+ return emit(kX86InstIdCmpxchg8b, r_edx, r_eax, r_ecx, r_ebx, x_mem);
+ }
+
+ //! CPU identification (i486).
+ ASMJIT_INLINE InstNode* cpuid(
+ const X86GpVar& x_eax,
+ const X86GpVar& w_ebx,
+ const X86GpVar& x_ecx,
+ const X86GpVar& w_edx) {
+
+ // Destination variables must be different.
+ ASMJIT_ASSERT(x_eax.getId() != w_ebx.getId() &&
+ w_ebx.getId() != x_ecx.getId() &&
+ x_ecx.getId() != w_edx.getId());
+
+ return emit(kX86InstIdCpuid, x_eax, w_ebx, x_ecx, w_edx);
+ }
+
+ //! Accumulate crc32 value (polynomial 0x11EDC6F41) (SSE4.2).
+ INST_2x_(crc32, kX86InstIdCrc32, X86GpVar, X86GpVar, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq))
+ //! \overload
+ INST_2x_(crc32, kX86InstIdCrc32, X86GpVar, X86Mem, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq))
+
+ //! Decimal adjust AL after addition (X86 Only).
+ INST_1x(daa, kX86InstIdDaa, X86GpVar)
+ //! Decimal adjust AL after subtraction (X86 Only).
+ INST_1x(das, kX86InstIdDas, X86GpVar)
+
+ //! Decrement by 1.
+ INST_1x(dec, kX86InstIdDec, X86GpVar)
+ //! \overload
+ INST_1x(dec, kX86InstIdDec, X86Mem)
+
+ //! Unsigned divide (o0:o1 <- o0:o1 / o2).
+ //!
+ //! Remainder is stored in `o0`, quotient is stored in `o1`.
+ INST_3x_(div, kX86InstIdDiv, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId())
+ //! \overload
+ INST_3x_(div, kX86InstIdDiv, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId())
+
+ //! Signed divide (o0:o1 <- o0:o1 / o2).
+ //!
+ //! Remainder is stored in `o0`, quotient is stored in `o1`.
+ INST_3x_(idiv, kX86InstIdIdiv, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId())
+ //! \overload
+ INST_3x_(idiv, kX86InstIdIdiv, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId())
+
+ //! Signed multiply (o0:o1 <- o1 * o2).
+ //!
+ //! Hi value is stored in `o0`, lo value is stored in `o1`.
+ INST_3x_(imul, kX86InstIdImul, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId())
+ //! \overload
+ INST_3x_(imul, kX86InstIdImul, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId())
+
+ //! Signed multiply.
+ INST_2x(imul, kX86InstIdImul, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(imul, kX86InstIdImul, X86GpVar, X86Mem)
+ //! \overload
+ INST_2i(imul, kX86InstIdImul, X86GpVar, Imm)
+
+ //! Signed multiply.
+ INST_3i(imul, kX86InstIdImul, X86GpVar, X86GpVar, Imm)
+ //! \overload
+ INST_3i(imul, kX86InstIdImul, X86GpVar, X86Mem, Imm)
+
+ //! Increment by 1.
+ INST_1x(inc, kX86InstIdInc, X86GpVar)
+ //! \overload
+ INST_1x(inc, kX86InstIdInc, X86Mem)
+
+ //! Interrupt.
+ INST_1i(int_, kX86InstIdInt, Imm)
+ //! Interrupt 3 - trap to debugger.
+ ASMJIT_INLINE InstNode* int3() { return int_(3); }
+
+ //! Jump to label `label` if condition `cc` is met.
+ INST_1cc(j, kX86InstIdJ, X86Util::condToJcc, Label)
+
+ //! Short jump if CX/ECX/RCX is zero.
+ INST_2x(jecxz, kX86InstIdJecxz, X86GpVar, Label)
+
+ //! Jump.
+ INST_1x(jmp, kX86InstIdJmp, X86GpVar)
+ //! \overload
+ INST_1x(jmp, kX86InstIdJmp, X86Mem)
+ //! \overload
+ INST_1x(jmp, kX86InstIdJmp, Label)
+ //! \overload
+ INST_1x(jmp, kX86InstIdJmp, Imm)
+ //! \overload
+ ASMJIT_INLINE InstNode* jmp(Ptr dst) { return jmp(Imm(dst)); }
+
+ //! Load AH from flags.
+ INST_1x(lahf, kX86InstIdLahf, X86GpVar)
+
+ //! Load effective address
+ INST_2x(lea, kX86InstIdLea, X86GpVar, X86Mem)
+
+ //! Load BYTE from DS:`o1` to `o0`.
+ INST_2x(lodsb, kX86InstIdLodsB, X86GpVar, X86GpVar)
+ //! Load DWORD from DS:`o1` to `o0`.
+ INST_2x(lodsd, kX86InstIdLodsD, X86GpVar, X86GpVar)
+ //! Load QWORD from DS:`o1` to `o0` (X64 Only).
+ INST_2x(lodsq, kX86InstIdLodsQ, X86GpVar, X86GpVar)
+ //! Load WORD from DS:`o1` to `o0`.
+ INST_2x(lodsw, kX86InstIdLodsW, X86GpVar, X86GpVar)
+
+ //! Move.
+ INST_2x(mov, kX86InstIdMov, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(mov, kX86InstIdMov, X86GpVar, X86Mem)
+ //! \overload
+ INST_2i(mov, kX86InstIdMov, X86GpVar, Imm)
+ //! \overload
+ INST_2x(mov, kX86InstIdMov, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(mov, kX86InstIdMov, X86Mem, Imm)
+
+ //! Move from segment register.
+ INST_2x(mov, kX86InstIdMov, X86GpVar, X86SegReg)
+ //! \overload
+ INST_2x(mov, kX86InstIdMov, X86Mem, X86SegReg)
+ //! Move to segment register.
+ INST_2x(mov, kX86InstIdMov, X86SegReg, X86GpVar)
+ //! \overload
+ INST_2x(mov, kX86InstIdMov, X86SegReg, X86Mem)
+
+ //! Move (AL|AX|EAX|RAX <- absolute address in immediate).
+ INST_2x(mov_ptr, kX86InstIdMovPtr, X86GpReg, Imm);
+ //! \overload
+ ASMJIT_INLINE InstNode* mov_ptr(const X86GpReg& o0, Ptr o1) {
+ ASMJIT_ASSERT(o0.getRegIndex() == 0);
+ return emit(kX86InstIdMovPtr, o0, Imm(o1));
+ }
+
+ //! Move (absolute address in immediate <- AL|AX|EAX|RAX).
+ INST_2x(mov_ptr, kX86InstIdMovPtr, Imm, X86GpReg);
+ //! \overload
+ ASMJIT_INLINE InstNode* mov_ptr(Ptr o0, const X86GpReg& o1) {
+ ASMJIT_ASSERT(o1.getRegIndex() == 0);
+ return emit(kX86InstIdMovPtr, Imm(o0), o1);
+ }
+
+ //! Move data after swapping bytes (SSE3 - Atom).
+ INST_2x_(movbe, kX86InstIdMovbe, X86GpVar, X86Mem, !o0.isGpb());
+ //! \overload
+ INST_2x_(movbe, kX86InstIdMovbe, X86Mem, X86GpVar, !o1.isGpb());
+
+ //! Load BYTE from DS:`o1` to ES:`o0`.
+ INST_2x(movsb, kX86InstIdMovsB, X86GpVar, X86GpVar)
+ //! Load DWORD from DS:`o1` to ES:`o0`.
+ INST_2x(movsd, kX86InstIdMovsD, X86GpVar, X86GpVar)
+ //! Load QWORD from DS:`o1` to ES:`o0` (X64 Only).
+ INST_2x(movsq, kX86InstIdMovsQ, X86GpVar, X86GpVar)
+ //! Load WORD from DS:`o1` to ES:`o0`.
+ INST_2x(movsw, kX86InstIdMovsW, X86GpVar, X86GpVar)
+
+ //! Move with sign-extension.
+ INST_2x(movsx, kX86InstIdMovsx, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(movsx, kX86InstIdMovsx, X86GpVar, X86Mem)
+
+ //! Move DWORD to QWORD with sign-extension (X64 Only).
+ INST_2x(movsxd, kX86InstIdMovsxd, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(movsxd, kX86InstIdMovsxd, X86GpVar, X86Mem)
+
+ //! Move with zero-extension.
+ INST_2x(movzx, kX86InstIdMovzx, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(movzx, kX86InstIdMovzx, X86GpVar, X86Mem)
+
+ //! Unsigned multiply (o0:o1 <- o1 * o2).
+ INST_3x_(mul, kX86InstIdMul, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId())
+ //! \overload
+ INST_3x_(mul, kX86InstIdMul, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId())
+
+ //! Two's complement negation.
+ INST_1x(neg, kX86InstIdNeg, X86GpVar)
+ //! \overload
+ INST_1x(neg, kX86InstIdNeg, X86Mem)
+
+ //! No operation.
+ INST_0x(nop, kX86InstIdNop)
+
+ //! One's complement negation.
+ INST_1x(not_, kX86InstIdNot, X86GpVar)
+ //! \overload
+ INST_1x(not_, kX86InstIdNot, X86Mem)
+
+ //! Or.
+ INST_2x(or_, kX86InstIdOr, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(or_, kX86InstIdOr, X86GpVar, X86Mem)
+ //! \overload
+ INST_2i(or_, kX86InstIdOr, X86GpVar, Imm)
+ //! \overload
+ INST_2x(or_, kX86InstIdOr, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(or_, kX86InstIdOr, X86Mem, Imm)
+
+ //! Pop a value from the stack.
+ INST_1x_(pop, kX86InstIdPop, X86GpVar, o0.getSize() == 2 || o0.getSize() == _regSize)
+ //! \overload
+ INST_1x_(pop, kX86InstIdPop, X86Mem, o0.getSize() == 2 || o0.getSize() == _regSize)
+
+ //! Pop stack into EFLAGS Register (32-bit or 64-bit).
+ INST_0x(popf, kX86InstIdPopf)
+
+ //! Return the count of number of bits set to 1 (SSE4.2).
+ INST_2x_(popcnt, kX86InstIdPopcnt, X86GpVar, X86GpVar, !o0.isGpb() && o0.getSize() == o1.getSize())
+ //! \overload
+ INST_2x_(popcnt, kX86InstIdPopcnt, X86GpVar, X86Mem, !o0.isGpb())
+
+ //! Push WORD or DWORD/QWORD on the stack.
+ INST_1x_(push, kX86InstIdPush, X86GpVar, o0.getSize() == 2 || o0.getSize() == _regSize)
+ //! Push WORD or DWORD/QWORD on the stack.
+ INST_1x_(push, kX86InstIdPush, X86Mem,o0.getSize() == 2 || o0.getSize() == _regSize)
+ //! Push segment register on the stack.
+ INST_1x(push, kX86InstIdPush, X86SegReg)
+ //! Push WORD or DWORD/QWORD on the stack.
+ INST_1i(push, kX86InstIdPush, Imm)
+
+ //! Push EFLAGS register (32-bit or 64-bit) on the stack.
+ INST_0x(pushf, kX86InstIdPushf)
+
+ //! Rotate bits left.
+ INST_2x(rcl, kX86InstIdRcl, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(rcl, kX86InstIdRcl, X86Mem, X86GpVar)
+ //! Rotate bits left.
+ INST_2i(rcl, kX86InstIdRcl, X86GpVar, Imm)
+ //! \overload
+ INST_2i(rcl, kX86InstIdRcl, X86Mem, Imm)
+
+ //! Rotate bits right.
+ INST_2x(rcr, kX86InstIdRcr, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(rcr, kX86InstIdRcr, X86Mem, X86GpVar)
+ //! Rotate bits right.
+ INST_2i(rcr, kX86InstIdRcr, X86GpVar, Imm)
+ //! \overload
+ INST_2i(rcr, kX86InstIdRcr, X86Mem, Imm)
+
+ //! Read time-stamp counter (Pentium).
+ INST_2x_(rdtsc, kX86InstIdRdtsc, X86GpVar, X86GpVar, o0.getId() != o1.getId())
+ //! Read time-stamp counter and processor id (Pentium).
+ INST_3x_(rdtscp, kX86InstIdRdtscp, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+
+ //! Repeated load ECX/RCX BYTEs from DS:[ESI/RSI] to AL.
+ INST_3x_(rep_lodsb, kX86InstIdRepLodsB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated load ECX/RCX DWORDs from DS:[ESI/RSI] to AL.
+ INST_3x_(rep_lodsd, kX86InstIdRepLodsD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated load ECX/RCX QWORDs from DS:[RSI] to RAX (X64 Only).
+ INST_3x_(rep_lodsq, kX86InstIdRepLodsQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated load ECX/RCX WORDs from DS:[ESI/RSI] to AX.
+ INST_3x_(rep_lodsw, kX86InstIdRepLodsW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+
+ //! Repeated move ECX/RCX BYTEs from DS:[ESI/RSI] to ES:[EDI/RDI].
+ INST_3x_(rep_movsb, kX86InstIdRepMovsB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated move ECX/RCX DWORDs from DS:[ESI/RSI] to ES:[EDI/RDI].
+ INST_3x_(rep_movsd, kX86InstIdRepMovsD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated move ECX/RCX QWORDs from DS:[RSI] to ES:[RDI] (X64 Only).
+ INST_3x_(rep_movsq, kX86InstIdRepMovsQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated move ECX/RCX DWORDs from DS:[ESI/RSI] to ES:[EDI/RDI].
+ INST_3x_(rep_movsw, kX86InstIdRepMovsW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+
+ //! Repeated fill ECX/RCX BYTEs at ES:[EDI/RDI] with AL.
+ INST_3x_(rep_stosb, kX86InstIdRepStosB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated fill ECX/RCX DWORDs at ES:[EDI/RDI] with EAX.
+ INST_3x_(rep_stosd, kX86InstIdRepStosD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated fill ECX/RCX QWORDs at ES:[RDI] with RAX (X64 Only).
+ INST_3x_(rep_stosq, kX86InstIdRepStosQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated fill ECX/RCX WORDs at ES:[EDI/RDI] with AX.
+ INST_3x_(rep_stosw, kX86InstIdRepStosW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+
+ //! Repeated find non-AL BYTEs in ES:[EDI/RDI] and DS:[ESI/RDI].
+ INST_3x_(repe_cmpsb, kX86InstIdRepeCmpsB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated find non-EAX DWORDs in ES:[EDI/RDI] and DS:[ESI/RDI].
+ INST_3x_(repe_cmpsd, kX86InstIdRepeCmpsD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated find non-RAX QWORDs in ES:[RDI] and DS:[RDI] (X64 Only).
+ INST_3x_(repe_cmpsq, kX86InstIdRepeCmpsQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated find non-AX WORDs in ES:[EDI/RDI] and DS:[ESI/RDI].
+ INST_3x_(repe_cmpsw, kX86InstIdRepeCmpsW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+
+ //! Repeated find non-AL BYTE starting at ES:[EDI/RDI].
+ INST_3x_(repe_scasb, kX86InstIdRepeScasB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated find non-EAX DWORD starting at ES:[EDI/RDI].
+ INST_3x_(repe_scasd, kX86InstIdRepeScasD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated find non-RAX QWORD starting at ES:[RDI] (X64 Only).
+ INST_3x_(repe_scasq, kX86InstIdRepeScasQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated find non-AX WORD starting at ES:[EDI/RDI].
+ INST_3x_(repe_scasw, kX86InstIdRepeScasW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+
+ //! Repeated find AL BYTEs in [RDI] and [RSI].
+ INST_3x_(repne_cmpsb, kX86InstIdRepneCmpsB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated find EAX DWORDs in [RDI] and [RSI].
+ INST_3x_(repne_cmpsd, kX86InstIdRepneCmpsD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated find RAX QWORDs in [RDI] and [RSI] (X64 Only).
+ INST_3x_(repne_cmpsq, kX86InstIdRepneCmpsQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated find AX WORDs in [RDI] and [RSI].
+ INST_3x_(repne_cmpsw, kX86InstIdRepneCmpsW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+
+ //! Repeated Find AL BYTEs, starting at ES:[EDI/RDI].
+ INST_3x_(repne_scasb, kX86InstIdRepneScasB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated find EAX DWORDs, starting at ES:[EDI/RDI].
+ INST_3x_(repne_scasd, kX86InstIdRepneScasD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated find RAX QWORDs, starting at ES:[RDI] (X64 Only).
+ INST_3x_(repne_scasq, kX86InstIdRepneScasQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+ //! Repeated find AX WORDs, starting at ES:[EDI/RDI].
+ INST_3x_(repne_scasw, kX86InstIdRepneScasW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId())
+
+ //! Return.
+ ASMJIT_INLINE RetNode* ret() { return addRet(noOperand, noOperand); }
+ //! \overload
+ ASMJIT_INLINE RetNode* ret(const X86GpVar& o0) { return addRet(o0, noOperand); }
+ //! \overload
+ ASMJIT_INLINE RetNode* ret(const X86GpVar& o0, const X86GpVar& o1) { return addRet(o0, o1); }
+ //! \overload
+ ASMJIT_INLINE RetNode* ret(const X86XmmVar& o0) { return addRet(o0, noOperand); }
+ //! \overload
+ ASMJIT_INLINE RetNode* ret(const X86XmmVar& o0, const X86XmmVar& o1) { return addRet(o0, o1); }
+
+ //! Rotate bits left.
+ INST_2x(rol, kX86InstIdRol, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(rol, kX86InstIdRol, X86Mem, X86GpVar)
+ //! Rotate bits left.
+ INST_2i(rol, kX86InstIdRol, X86GpVar, Imm)
+ //! \overload
+ INST_2i(rol, kX86InstIdRol, X86Mem, Imm)
+
+ //! Rotate bits right.
+ INST_2x(ror, kX86InstIdRor, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(ror, kX86InstIdRor, X86Mem, X86GpVar)
+ //! Rotate bits right.
+ INST_2i(ror, kX86InstIdRor, X86GpVar, Imm)
+ //! \overload
+ INST_2i(ror, kX86InstIdRor, X86Mem, Imm)
+
+ //! Store `a` (allocated in AH/AX/EAX/RAX) into Flags.
+ INST_1x(sahf, kX86InstIdSahf, X86GpVar)
+
+ //! Integer subtraction with borrow.
+ INST_2x(sbb, kX86InstIdSbb, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(sbb, kX86InstIdSbb, X86GpVar, X86Mem)
+ //! \overload
+ INST_2i(sbb, kX86InstIdSbb, X86GpVar, Imm)
+ //! \overload
+ INST_2x(sbb, kX86InstIdSbb, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(sbb, kX86InstIdSbb, X86Mem, Imm)
+
+ //! Shift bits left.
+ INST_2x(sal, kX86InstIdSal, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(sal, kX86InstIdSal, X86Mem, X86GpVar)
+ //! Shift bits left.
+ INST_2i(sal, kX86InstIdSal, X86GpVar, Imm)
+ //! \overload
+ INST_2i(sal, kX86InstIdSal, X86Mem, Imm)
+
+ //! Shift bits right.
+ INST_2x(sar, kX86InstIdSar, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(sar, kX86InstIdSar, X86Mem, X86GpVar)
+ //! Shift bits right.
+ INST_2i(sar, kX86InstIdSar, X86GpVar, Imm)
+ //! \overload
+ INST_2i(sar, kX86InstIdSar, X86Mem, Imm)
+
+ //! Find non `o1` BYTE starting at ES:`o0`.
+ INST_2x(scasb, kX86InstIdScasB, X86GpVar, X86GpVar)
+ //! Find non `o1` DWORD starting at ES:`o0`.
+ INST_2x(scasd, kX86InstIdScasD, X86GpVar, X86GpVar)
+ //! Find non `o1` QWORD starting at ES:`o0` (X64 Only).
+ INST_2x(scasq, kX86InstIdScasQ, X86GpVar, X86GpVar)
+ //! Find non `o1` WORD starting at ES:`o0`.
+ INST_2x(scasw, kX86InstIdScasW, X86GpVar, X86GpVar)
+
+ //! Set byte on condition.
+ INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86GpVar)
+ //! Set byte on condition.
+ INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86Mem)
+
+ //! Shift bits left.
+ INST_2x(shl, kX86InstIdShl, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(shl, kX86InstIdShl, X86Mem, X86GpVar)
+ //! Shift bits left.
+ INST_2i(shl, kX86InstIdShl, X86GpVar, Imm)
+ //! \overload
+ INST_2i(shl, kX86InstIdShl, X86Mem, Imm)
+
+ //! Shift bits right.
+ INST_2x(shr, kX86InstIdShr, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(shr, kX86InstIdShr, X86Mem, X86GpVar)
+ //! Shift bits right.
+ INST_2i(shr, kX86InstIdShr, X86GpVar, Imm)
+ //! \overload
+ INST_2i(shr, kX86InstIdShr, X86Mem, Imm)
+
+ //! Double precision shift left.
+ INST_3x(shld, kX86InstIdShld, X86GpVar, X86GpVar, X86GpVar)
+ //! \overload
+ INST_3x(shld, kX86InstIdShld, X86Mem, X86GpVar, X86GpVar)
+ //! Double precision shift left.
+ INST_3i(shld, kX86InstIdShld, X86GpVar, X86GpVar, Imm)
+ //! \overload
+ INST_3i(shld, kX86InstIdShld, X86Mem, X86GpVar, Imm)
+
+ //! Double precision shift right.
+ INST_3x(shrd, kX86InstIdShrd, X86GpVar, X86GpVar, X86GpVar)
+ //! \overload
+ INST_3x(shrd, kX86InstIdShrd, X86Mem, X86GpVar, X86GpVar)
+ //! Double precision shift right.
+ INST_3i(shrd, kX86InstIdShrd, X86GpVar, X86GpVar, Imm)
+ //! \overload
+ INST_3i(shrd, kX86InstIdShrd, X86Mem, X86GpVar, Imm)
+
+ //! Set carry flag to 1.
+ INST_0x(stc, kX86InstIdStc)
+ //! Set direction flag to 1.
+ INST_0x(std, kX86InstIdStd)
+
+ //! Fill BYTE at ES:`o0` with `o1`.
+ INST_2x(stosb, kX86InstIdStosB, X86GpVar, X86GpVar)
+ //! Fill DWORD at ES:`o0` with `o1`.
+ INST_2x(stosd, kX86InstIdStosD, X86GpVar, X86GpVar)
+ //! Fill QWORD at ES:`o0` with `o1` (X64 Only).
+ INST_2x(stosq, kX86InstIdStosQ, X86GpVar, X86GpVar)
+ //! Fill WORD at ES:`o0` with `o1`.
+ INST_2x(stosw, kX86InstIdStosW, X86GpVar, X86GpVar)
+
+ //! Subtract.
+ INST_2x(sub, kX86InstIdSub, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(sub, kX86InstIdSub, X86GpVar, X86Mem)
+ //! \overload
+ INST_2i(sub, kX86InstIdSub, X86GpVar, Imm)
+ //! \overload
+ INST_2x(sub, kX86InstIdSub, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(sub, kX86InstIdSub, X86Mem, Imm)
+
+ //! Logical compare.
+ INST_2x(test, kX86InstIdTest, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2i(test, kX86InstIdTest, X86GpVar, Imm)
+ //! \overload
+ INST_2x(test, kX86InstIdTest, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(test, kX86InstIdTest, X86Mem, Imm)
+
+ //! Undefined instruction - Raise #UD exception.
+ INST_0x(ud2, kX86InstIdUd2)
+
+ //! Exchange and add.
+ INST_2x(xadd, kX86InstIdXadd, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(xadd, kX86InstIdXadd, X86Mem, X86GpVar)
+
+ //! Exchange register/memory with register.
+ INST_2x(xchg, kX86InstIdXchg, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(xchg, kX86InstIdXchg, X86Mem, X86GpVar)
+ //! \overload
+ INST_2x(xchg, kX86InstIdXchg, X86GpVar, X86Mem)
+
+ //! Xor.
+ INST_2x(xor_, kX86InstIdXor, X86GpVar, X86GpVar)
+ //! \overload
+ INST_2x(xor_, kX86InstIdXor, X86GpVar, X86Mem)
+ //! \overload
+ INST_2i(xor_, kX86InstIdXor, X86GpVar, Imm)
+ //! \overload
+ INST_2x(xor_, kX86InstIdXor, X86Mem, X86GpVar)
+ //! \overload
+ INST_2i(xor_, kX86InstIdXor, X86Mem, Imm)
+
+ // --------------------------------------------------------------------------
+ // [Fpu]
+ // --------------------------------------------------------------------------
+
+ //! Compute 2^x - 1 (FPU).
+ INST_0x(f2xm1, kX86InstIdF2xm1)
+ //! Absolute value of fp0 (FPU).
+ INST_0x(fabs, kX86InstIdFabs)
+
+ //! Add `o1` to `o0` (one has to be `fp0`) and store result in `o0` (FPU).
+ INST_2x_(fadd, kX86InstIdFadd, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0)
+ //! Add 4-byte or 8-byte FP `o0` to fp0 and store result in fp0 (FPU).
+ INST_1x(fadd, kX86InstIdFadd, X86Mem)
+ //! Add fp0 to `o0` and pop the FPU stack (FPU).
+ INST_1x(faddp, kX86InstIdFaddp, X86FpReg)
+ //! \overload
+ INST_0x(faddp, kX86InstIdFaddp)
+
+ //! Load binary coded decimal (FPU).
+ INST_1x(fbld, kX86InstIdFbld, X86Mem)
+ //! Store BCD integer and Pop (FPU).
+ INST_1x(fbstp, kX86InstIdFbstp, X86Mem)
+ //! Change fp0 sign (FPU).
+ INST_0x(fchs, kX86InstIdFchs)
+ //! Clear exceptions (FPU).
+ INST_0x(fclex, kX86InstIdFclex)
+
+ //! Conditional move (FPU).
+ INST_1x(fcmovb, kX86InstIdFcmovb, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmovbe, kX86InstIdFcmovbe, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmove, kX86InstIdFcmove, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmovnb, kX86InstIdFcmovnb, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmovnbe, kX86InstIdFcmovnbe, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmovne, kX86InstIdFcmovne, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmovnu, kX86InstIdFcmovnu, X86FpReg)
+ //! Conditional move (FPU).
+ INST_1x(fcmovu, kX86InstIdFcmovu, X86FpReg)
+
+ //! Compare fp0 with `o0` (FPU).
+ INST_1x(fcom, kX86InstIdFcom, X86FpReg)
+ //! Compare fp0 with fp1 (FPU).
+ INST_0x(fcom, kX86InstIdFcom)
+ //! Compare fp0 with 4-byte or 8-byte FP at `src` (FPU).
+ INST_1x(fcom, kX86InstIdFcom, X86Mem)
+ //! Compare fp0 with `o0` and pop the FPU stack (FPU).
+ INST_1x(fcomp, kX86InstIdFcomp, X86FpReg)
+ //! Compare fp0 with fp1 and pop the FPU stack (FPU).
+ INST_0x(fcomp, kX86InstIdFcomp)
+ //! Compare fp0 with 4-byte or 8-byte FP at `adr` and pop the FPU stack (FPU).
+ INST_1x(fcomp, kX86InstIdFcomp, X86Mem)
+ //! Compare fp0 with fp1 and pop the FPU stack twice (FPU).
+ INST_0x(fcompp, kX86InstIdFcompp)
+ //! Compare fp0 and `o0` and Set EFLAGS (FPU).
+ INST_1x(fcomi, kX86InstIdFcomi, X86FpReg)
+ //! Compare fp0 and `o0` and Set EFLAGS and pop the FPU stack (FPU).
+ INST_1x(fcomip, kX86InstIdFcomip, X86FpReg)
+
+ //! Calculate cosine of fp0 and store result in fp0 (FPU).
+ INST_0x(fcos, kX86InstIdFcos)
+ //! Decrement FPU stack-top pointer (FPU).
+ INST_0x(fdecstp, kX86InstIdFdecstp)
+
+ //! Divide `o0` by `o1` (one has to be `fp0`) (FPU).
+ INST_2x_(fdiv, kX86InstIdFdiv, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0)
+ //! Divide fp0 by 32-bit or 64-bit FP value (FPU).
+ INST_1x(fdiv, kX86InstIdFdiv, X86Mem)
+ //! Divide `o0` by fp0 (FPU).
+ INST_1x(fdivp, kX86InstIdFdivp, X86FpReg)
+ //! \overload
+ INST_0x(fdivp, kX86InstIdFdivp)
+
+ //! Reverse divide `o0` by `o1` (one has to be `fp0`) (FPU).
+ INST_2x_(fdivr, kX86InstIdFdivr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0)
+ //! Reverse divide fp0 by 32-bit or 64-bit FP value (FPU).
+ INST_1x(fdivr, kX86InstIdFdivr, X86Mem)
+ //! Reverse divide `o0` by fp0 (FPU).
+ INST_1x(fdivrp, kX86InstIdFdivrp, X86FpReg)
+ //! \overload
+ INST_0x(fdivrp, kX86InstIdFdivrp)
+
+ //! Free FP register (FPU).
+ INST_1x(ffree, kX86InstIdFfree, X86FpReg)
+
+ //! Add 16-bit or 32-bit integer to fp0 (FPU).
+ INST_1x_(fiadd, kX86InstIdFiadd, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+ //! Compare fp0 with 16-bit or 32-bit Integer (FPU).
+ INST_1x_(ficom, kX86InstIdFicom, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+ //! Compare fp0 with 16-bit or 32-bit Integer and pop the FPU stack (FPU).
+ INST_1x_(ficomp, kX86InstIdFicomp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+ //! Divide fp0 by 32-bit or 16-bit integer (`src`) (FPU).
+ INST_1x_(fidiv, kX86InstIdFidiv, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+ //! Reverse divide fp0 by 32-bit or 16-bit integer (`src`) (FPU).
+ INST_1x_(fidivr, kX86InstIdFidivr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+
+ //! Load 16-bit, 32-bit or 64-bit Integer and push it to the FPU stack (FPU).
+ INST_1x_(fild, kX86InstIdFild, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8)
+ //! Multiply fp0 by 16-bit or 32-bit integer and store it to fp0 (FPU).
+ INST_1x_(fimul, kX86InstIdFimul, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+
+ //! Increment FPU stack-top pointer (FPU).
+ INST_0x(fincstp, kX86InstIdFincstp)
+ //! Initialize FPU (FPU).
+ INST_0x(finit, kX86InstIdFinit)
+
+ //! Subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU).
+ INST_1x_(fisub, kX86InstIdFisub, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+ //! Reverse subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU).
+ INST_1x_(fisubr, kX86InstIdFisubr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+
+ //! Initialize FPU without checking for pending unmasked exceptions (FPU).
+ INST_0x(fninit, kX86InstIdFninit)
+
+ //! Store fp0 as 16-bit or 32-bit Integer to `o0` (FPU).
+ INST_1x_(fist, kX86InstIdFist, X86Mem, o0.getSize() == 2 || o0.getSize() == 4)
+ //! Store fp0 as 16-bit, 32-bit or 64-bit Integer to `o0` and pop the FPU stack (FPU).
+ INST_1x_(fistp, kX86InstIdFistp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8)
+ //! Push 32-bit, 64-bit or 80-bit floating point value on the FPU stack (FPU).
+ INST_1x_(fld, kX86InstIdFld, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10)
+ //! Push `o0` on the FPU stack (FPU).
+ INST_1x(fld, kX86InstIdFld, X86FpReg)
+
+ //! Push +1.0 on the FPU stack (FPU).
+ INST_0x(fld1, kX86InstIdFld1)
+ //! Push log2(10) on the FPU stack (FPU).
+ INST_0x(fldl2t, kX86InstIdFldl2t)
+ //! Push log2(e) on the FPU stack (FPU).
+ INST_0x(fldl2e, kX86InstIdFldl2e)
+ //! Push pi on the FPU stack (FPU).
+ INST_0x(fldpi, kX86InstIdFldpi)
+ //! Push log10(2) on the FPU stack (FPU).
+ INST_0x(fldlg2, kX86InstIdFldlg2)
+ //! Push ln(2) on the FPU stack (FPU).
+ INST_0x(fldln2, kX86InstIdFldln2)
+ //! Push +0.0 on the FPU stack (FPU).
+ INST_0x(fldz, kX86InstIdFldz)
+
+ //! Load x87 FPU control word (2 bytes) (FPU).
+ INST_1x(fldcw, kX86InstIdFldcw, X86Mem)
+ //! Load x87 FPU environment (14 or 28 bytes) (FPU).
+ INST_1x(fldenv, kX86InstIdFldenv, X86Mem)
+
+ //! Multiply `o0` by `o1` (one has to be `fp0`) and store result in `o0` (FPU).
+ INST_2x_(fmul, kX86InstIdFmul, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0)
+ //! Multiply fp0 by 32-bit or 64-bit `o0` and store result in fp0 (FPU).
+ INST_1x(fmul, kX86InstIdFmul, X86Mem)
+ //! Multiply fp0 by `o0` and pop the FPU stack (FPU).
+ INST_1x(fmulp, kX86InstIdFmulp, X86FpReg)
+ //! \overload
+ INST_0x(fmulp, kX86InstIdFmulp)
+
+ //! Clear exceptions (FPU).
+ INST_0x(fnclex, kX86InstIdFnclex)
+ //! No operation (FPU).
+ INST_0x(fnop, kX86InstIdFnop)
+ //! Save FPU state (FPU).
+ INST_1x(fnsave, kX86InstIdFnsave, X86Mem)
+ //! Store x87 FPU environment (FPU).
+ INST_1x(fnstenv, kX86InstIdFnstenv, X86Mem)
+ //! Store x87 FPU control word (FPU).
+ INST_1x(fnstcw, kX86InstIdFnstcw, X86Mem)
+
+ //! Store x87 FPU status word to `o0` (AX) (FPU).
+ INST_1x_(fnstsw, kX86InstIdFnstsw, X86GpReg, o0.isRegCode(kX86RegTypeGpw, kX86RegIndexAx))
+ //! Store x87 FPU status word to `o0` (2 bytes) (FPU).
+ INST_1x(fnstsw, kX86InstIdFnstsw, X86Mem)
+
+ //! Arctan(`fp1` / `fp0`) and pop the FPU stack (FPU).
+ INST_0x(fpatan, kX86InstIdFpatan)
+ //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU).
+ INST_0x(fprem, kX86InstIdFprem)
+ //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU).
+ INST_0x(fprem1, kX86InstIdFprem1)
+ //! Arctan(`fp0`) and pop the FPU stack (FPU).
+ INST_0x(fptan, kX86InstIdFptan)
+ //! Round `fp0` to Integer (FPU).
+ INST_0x(frndint, kX86InstIdFrndint)
+
+ //! Restore FPU state from `o0` (94 or 108 bytes) (FPU).
+ INST_1x(frstor, kX86InstIdFrstor, X86Mem)
+ //! Save FPU state to `o0` (94 or 108 bytes) (FPU).
+ INST_1x(fsave, kX86InstIdFsave, X86Mem)
+
+ //! Scale `fp0` by `fp1` (FPU).
+ INST_0x(fscale, kX86InstIdFscale)
+ //! Sine of `fp0` and store result in `fp0` (FPU).
+ INST_0x(fsin, kX86InstIdFsin)
+ //! Sine and cosine of `fp0`, store sine in `fp0` and push cosine on the FPU stack (FPU).
+ INST_0x(fsincos, kX86InstIdFsincos)
+ //! Square root of `fp0` and store it in `fp0` (FPU).
+ INST_0x(fsqrt, kX86InstIdFsqrt)
+
+ //! Store floating point value to 32-bit or 64-bit memory location (FPU).
+ INST_1x_(fst, kX86InstIdFst, X86Mem, o0.getSize() == 4 || o0.getSize() == 8)
+ //! Store floating point value to `o0` (FPU).
+ INST_1x(fst, kX86InstIdFst, X86FpReg)
+ //! Store floating point value to 32-bit or 64-bit memory location and pop the FPU stack (FPU).
+ INST_1x_(fstp, kX86InstIdFstp, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10)
+ //! Store floating point value to `o0` and pop the FPU stack (FPU).
+ INST_1x(fstp, kX86InstIdFstp, X86FpReg)
+
+ //! Store x87 FPU control word to `o0` (2 bytes) (FPU).
+ INST_1x(fstcw, kX86InstIdFstcw, X86Mem)
+ //! Store x87 FPU environment to `o0` (14 or 28 bytes) (FPU).
+ INST_1x(fstenv, kX86InstIdFstenv, X86Mem)
+ //! Store x87 FPU status word to `o0` (allocated in AX) (FPU).
+ INST_1x(fstsw, kX86InstIdFstsw, X86GpVar)
+ //! Store x87 FPU status word (2 bytes) (FPU).
+ INST_1x(fstsw, kX86InstIdFstsw, X86Mem)
+
+ //! Subtract `o0` from `o0` (one has to be `fp0`) and store result in `o0` (FPU).
+ INST_2x_(fsub, kX86InstIdFsub, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0)
+ //! Subtract 32-bit or 64-bit `o0` from fp0 and store result in fp0 (FPU).
+ INST_1x_(fsub, kX86InstIdFsub, X86Mem, o0.getSize() == 4 || o0.getSize() == 8)
+ //! Subtract fp0 from `o0` and pop FPU stack (FPU).
+ INST_1x(fsubp, kX86InstIdFsubp, X86FpReg)
+ //! \overload
+ INST_0x(fsubp, kX86InstIdFsubp)
+
+ //! Reverse subtract `o1` from `o0` (one has to be `fp0`) and store result in `o0` (FPU).
+ INST_2x_(fsubr, kX86InstIdFsubr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0)
+ //! Reverse subtract 32-bit or 64-bit `o0` from `fp0` and store result in `fp0` (FPU).
+ INST_1x_(fsubr, kX86InstIdFsubr, X86Mem, o0.getSize() == 4 || o0.getSize() == 8)
+ //! Reverse subtract `fp0` from `o0` and pop FPU stack (FPU).
+ INST_1x(fsubrp, kX86InstIdFsubrp, X86FpReg)
+ //! \overload
+ INST_0x(fsubrp, kX86InstIdFsubrp)
+
+ //! Floating point test - Compare `fp0` with 0.0. (FPU).
+ INST_0x(ftst, kX86InstIdFtst)
+
+ //! Unordered compare `fp0` with `o0` (FPU).
+ INST_1x(fucom, kX86InstIdFucom, X86FpReg)
+ //! Unordered compare `fp0` with `fp1` (FPU).
+ INST_0x(fucom, kX86InstIdFucom)
+ //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS (FPU).
+ INST_1x(fucomi, kX86InstIdFucomi, X86FpReg)
+ //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS and pop the FPU stack (FPU).
+ INST_1x(fucomip, kX86InstIdFucomip, X86FpReg)
+ //! Unordered compare `fp0` with `o0` and pop the FPU stack (FPU).
+ INST_1x(fucomp, kX86InstIdFucomp, X86FpReg)
+ //! Unordered compare `fp0` with `fp1` and pop the FPU stack (FPU).
+ INST_0x(fucomp, kX86InstIdFucomp)
+ //! Unordered compare `fp0` with `fp1` and pop the FPU stack twice (FPU).
+ INST_0x(fucompp, kX86InstIdFucompp)
+
+ INST_0x(fwait, kX86InstIdFwait)
+
+ //! Examine fp0 (FPU).
+ INST_0x(fxam, kX86InstIdFxam)
+ //! Exchange content of fp0 with `o0` (FPU).
+ INST_1x(fxch, kX86InstIdFxch, X86FpReg)
+
+ //! Restore FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE).
+ INST_1x(fxrstor, kX86InstIdFxrstor, X86Mem)
+ //! Store FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE).
+ INST_1x(fxsave, kX86InstIdFxsave, X86Mem)
+ //! Extract exponent and store to `fp0` and push significand on the FPU stack (FPU).
+ INST_0x(fxtract, kX86InstIdFxtract)
+
+ //! Compute `fp1 * log2(fp0)`, pop the FPU stack and store result in `fp0` (FPU).
+ INST_0x(fyl2x, kX86InstIdFyl2x)
+ //! Compute `fp1 * log2(fp0 + 1)`, pop the FPU stack and store result in `fp0` (FPU).
+ INST_0x(fyl2xp1, kX86InstIdFyl2xp1)
+
+ // --------------------------------------------------------------------------
+ // [MMX]
+ // --------------------------------------------------------------------------
+
+ //! Move DWORD (MMX).
+ INST_2x(movd, kX86InstIdMovd, X86Mem, X86MmVar)
+ //! \overload
+ INST_2x(movd, kX86InstIdMovd, X86GpVar, X86MmVar)
+ //! \overload
+ INST_2x(movd, kX86InstIdMovd, X86MmVar, X86Mem)
+ //! \overload
+ INST_2x(movd, kX86InstIdMovd, X86MmVar, X86GpVar)
+
+ //! Move QWORD (MMX).
+ INST_2x(movq, kX86InstIdMovq, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(movq, kX86InstIdMovq, X86Mem, X86MmVar)
+ //! \overload
+ INST_2x(movq, kX86InstIdMovq, X86MmVar, X86Mem)
+
+ //! Move QWORD (X64 Only).
+ INST_2x(movq, kX86InstIdMovq, X86GpVar, X86MmVar)
+ //! \overload
+ INST_2x(movq, kX86InstIdMovq, X86MmVar, X86GpVar)
+
+ //! Pack DWORDs to WORDs with signed saturation (MMX).
+ INST_2x(packssdw, kX86InstIdPackssdw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(packssdw, kX86InstIdPackssdw, X86MmVar, X86Mem)
+
+ //! Pack WORDs to BYTEs with signed saturation (MMX).
+ INST_2x(packsswb, kX86InstIdPacksswb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(packsswb, kX86InstIdPacksswb, X86MmVar, X86Mem)
+
+ //! Pack WORDs to BYTEs with unsigned saturation (MMX).
+ INST_2x(packuswb, kX86InstIdPackuswb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(packuswb, kX86InstIdPackuswb, X86MmVar, X86Mem)
+
+ //! Packed BYTE add (MMX).
+ INST_2x(paddb, kX86InstIdPaddb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(paddb, kX86InstIdPaddb, X86MmVar, X86Mem)
+
+ //! Packed DWORD add (MMX).
+ INST_2x(paddd, kX86InstIdPaddd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(paddd, kX86InstIdPaddd, X86MmVar, X86Mem)
+
+ //! Packed BYTE add with saturation (MMX).
+ INST_2x(paddsb, kX86InstIdPaddsb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(paddsb, kX86InstIdPaddsb, X86MmVar, X86Mem)
+
+ //! Packed WORD add with saturation (MMX).
+ INST_2x(paddsw, kX86InstIdPaddsw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(paddsw, kX86InstIdPaddsw, X86MmVar, X86Mem)
+
+ //! Packed BYTE add with unsigned saturation (MMX).
+ INST_2x(paddusb, kX86InstIdPaddusb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(paddusb, kX86InstIdPaddusb, X86MmVar, X86Mem)
+
+ //! Packed WORD add with unsigned saturation (MMX).
+ INST_2x(paddusw, kX86InstIdPaddusw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(paddusw, kX86InstIdPaddusw, X86MmVar, X86Mem)
+
+ //! Packed WORD add (MMX).
+ INST_2x(paddw, kX86InstIdPaddw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(paddw, kX86InstIdPaddw, X86MmVar, X86Mem)
+
+ //! Packed and (MMX).
+ INST_2x(pand, kX86InstIdPand, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pand, kX86InstIdPand, X86MmVar, X86Mem)
+
+ //! Packed and-not (MMX).
+ INST_2x(pandn, kX86InstIdPandn, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pandn, kX86InstIdPandn, X86MmVar, X86Mem)
+
+ //! Packed BYTEs compare for equality (MMX).
+ INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmVar, X86Mem)
+
+ //! Packed DWORDs compare for equality (MMX).
+ INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmVar, X86Mem)
+
+ //! Packed WORDs compare for equality (MMX).
+ INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmVar, X86Mem)
+
+ //! Packed BYTEs compare if greater than (MMX).
+ INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmVar, X86Mem)
+
+ //! Packed DWORDs compare if greater than (MMX).
+ INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmVar, X86Mem)
+
+ //! Packed WORDs compare if greater than (MMX).
+ INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmVar, X86Mem)
+
+ //! Packed WORD multiply high (MMX).
+ INST_2x(pmulhw, kX86InstIdPmulhw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pmulhw, kX86InstIdPmulhw, X86MmVar, X86Mem)
+
+ //! Packed WORD multiply low (MMX).
+ INST_2x(pmullw, kX86InstIdPmullw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pmullw, kX86InstIdPmullw, X86MmVar, X86Mem)
+
+ //! Packed bitwise or (MMX).
+ INST_2x(por, kX86InstIdPor, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(por, kX86InstIdPor, X86MmVar, X86Mem)
+
+ //! Packed WORD multiply and add to packed DWORD (MMX).
+ INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmVar, X86Mem)
+
+ //! Packed DWORD shift left logical (MMX).
+ INST_2x(pslld, kX86InstIdPslld, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pslld, kX86InstIdPslld, X86MmVar, X86Mem)
+ //! \overload
+ INST_2i(pslld, kX86InstIdPslld, X86MmVar, Imm)
+
+ //! Packed QWORD shift left logical (MMX).
+ INST_2x(psllq, kX86InstIdPsllq, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psllq, kX86InstIdPsllq, X86MmVar, X86Mem)
+ //! \overload
+ INST_2i(psllq, kX86InstIdPsllq, X86MmVar, Imm)
+
+ //! Packed WORD shift left logical (MMX).
+ INST_2x(psllw, kX86InstIdPsllw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psllw, kX86InstIdPsllw, X86MmVar, X86Mem)
+ //! \overload
+ INST_2i(psllw, kX86InstIdPsllw, X86MmVar, Imm)
+
+ //! Packed DWORD shift right arithmetic (MMX).
+ INST_2x(psrad, kX86InstIdPsrad, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psrad, kX86InstIdPsrad, X86MmVar, X86Mem)
+ //! \overload
+ INST_2i(psrad, kX86InstIdPsrad, X86MmVar, Imm)
+
+ //! Packed WORD shift right arithmetic (MMX).
+ INST_2x(psraw, kX86InstIdPsraw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psraw, kX86InstIdPsraw, X86MmVar, X86Mem)
+ //! \overload
+ INST_2i(psraw, kX86InstIdPsraw, X86MmVar, Imm)
+
+ //! Packed DWORD shift right logical (MMX).
+ INST_2x(psrld, kX86InstIdPsrld, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psrld, kX86InstIdPsrld, X86MmVar, X86Mem)
+ //! \overload
+ INST_2i(psrld, kX86InstIdPsrld, X86MmVar, Imm)
+
+ //! Packed QWORD shift right logical (MMX).
+ INST_2x(psrlq, kX86InstIdPsrlq, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psrlq, kX86InstIdPsrlq, X86MmVar, X86Mem)
+ //! \overload
+ INST_2i(psrlq, kX86InstIdPsrlq, X86MmVar, Imm)
+
+ //! Packed WORD shift right logical (MMX).
+ INST_2x(psrlw, kX86InstIdPsrlw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psrlw, kX86InstIdPsrlw, X86MmVar, X86Mem)
+ //! \overload
+ INST_2i(psrlw, kX86InstIdPsrlw, X86MmVar, Imm)
+
+ //! Packed BYTE subtract (MMX).
+ INST_2x(psubb, kX86InstIdPsubb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psubb, kX86InstIdPsubb, X86MmVar, X86Mem)
+
+ //! Packed DWORD subtract (MMX).
+ INST_2x(psubd, kX86InstIdPsubd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psubd, kX86InstIdPsubd, X86MmVar, X86Mem)
+
+ //! Packed BYTE subtract with saturation (MMX).
+ INST_2x(psubsb, kX86InstIdPsubsb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psubsb, kX86InstIdPsubsb, X86MmVar, X86Mem)
+
+ //! Packed WORD subtract with saturation (MMX).
+ INST_2x(psubsw, kX86InstIdPsubsw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psubsw, kX86InstIdPsubsw, X86MmVar, X86Mem)
+
+ //! Packed BYTE subtract with unsigned saturation (MMX).
+ INST_2x(psubusb, kX86InstIdPsubusb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psubusb, kX86InstIdPsubusb, X86MmVar, X86Mem)
+
+ //! Packed WORD subtract with unsigned saturation (MMX).
+ INST_2x(psubusw, kX86InstIdPsubusw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psubusw, kX86InstIdPsubusw, X86MmVar, X86Mem)
+
+ //! Packed WORD subtract (MMX).
+ INST_2x(psubw, kX86InstIdPsubw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psubw, kX86InstIdPsubw, X86MmVar, X86Mem)
+
+ //! Unpack high packed BYTEs to WORDs (MMX).
+ INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmVar, X86Mem)
+
+ //! Unpack high packed DWORDs to QWORDs (MMX).
+ INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmVar, X86Mem)
+
+ //! Unpack high packed WORDs to DWORDs (MMX).
+ INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmVar, X86Mem)
+
+ //! Unpack low packed BYTEs to WORDs (MMX).
+ INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmVar, X86Mem)
+
+ //! Unpack low packed DWORDs to QWORDs (MMX).
+ INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmVar, X86Mem)
+
+ //! Unpack low packed WORDs to DWORDs (MMX).
+ INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmVar, X86Mem)
+
+ //! Packed bitwise xor (MMX).
+ INST_2x(pxor, kX86InstIdPxor, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pxor, kX86InstIdPxor, X86MmVar, X86Mem)
+
+ //! Empty MMX state.
+ INST_0x(emms, kX86InstIdEmms)
+
+ // --------------------------------------------------------------------------
+ // [3dNow]
+ // --------------------------------------------------------------------------
+
+ //! Packed SP-FP to DWORD convert (3dNow!).
+ INST_2x(pf2id, kX86InstIdPf2id, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pf2id, kX86InstIdPf2id, X86MmVar, X86Mem)
+
+ //! Packed SP-FP to WORD convert (3dNow!).
+ INST_2x(pf2iw, kX86InstIdPf2iw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pf2iw, kX86InstIdPf2iw, X86MmVar, X86Mem)
+
+ //! Packed SP-FP accumulate (3dNow!).
+ INST_2x(pfacc, kX86InstIdPfacc, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfacc, kX86InstIdPfacc, X86MmVar, X86Mem)
+
+ //! Packed SP-FP addition (3dNow!).
+ INST_2x(pfadd, kX86InstIdPfadd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfadd, kX86InstIdPfadd, X86MmVar, X86Mem)
+
+ //! Packed SP-FP compare - dst == src (3dNow!).
+ INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmVar, X86Mem)
+
+ //! Packed SP-FP compare - dst >= src (3dNow!).
+ INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmVar, X86Mem)
+
+ //! Packed SP-FP compare - dst > src (3dNow!).
+ INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmVar, X86Mem)
+
+ //! Packed SP-FP maximum (3dNow!).
+ INST_2x(pfmax, kX86InstIdPfmax, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfmax, kX86InstIdPfmax, X86MmVar, X86Mem)
+
+ //! Packed SP-FP minimum (3dNow!).
+ INST_2x(pfmin, kX86InstIdPfmin, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfmin, kX86InstIdPfmin, X86MmVar, X86Mem)
+
+ //! Packed SP-FP multiply (3dNow!).
+ INST_2x(pfmul, kX86InstIdPfmul, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfmul, kX86InstIdPfmul, X86MmVar, X86Mem)
+
+ //! Packed SP-FP negative accumulate (3dNow!).
+ INST_2x(pfnacc, kX86InstIdPfnacc, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfnacc, kX86InstIdPfnacc, X86MmVar, X86Mem)
+
+ //! Packed SP-FP mixed accumulate (3dNow!).
+ INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmVar, X86Mem)
+
+ //! Packed SP-FP reciprocal approximation (3dNow!).
+ INST_2x(pfrcp, kX86InstIdPfrcp, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfrcp, kX86InstIdPfrcp, X86MmVar, X86Mem)
+
+ //! Packed SP-FP reciprocal, first iteration step (3dNow!).
+ INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmVar, X86Mem)
+
+ //! Packed SP-FP reciprocal, second iteration step (3dNow!).
+ INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmVar, X86Mem)
+
+ //! Packed SP-FP reciprocal square root, first iteration step (3dNow!).
+ INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmVar, X86Mem)
+
+ //! Packed SP-FP reciprocal square root approximation (3dNow!).
+ INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmVar, X86Mem)
+
+ //! Packed SP-FP subtract (3dNow!).
+ INST_2x(pfsub, kX86InstIdPfsub, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfsub, kX86InstIdPfsub, X86MmVar, X86Mem)
+
+ //! Packed SP-FP reverse subtract (3dNow!).
+ INST_2x(pfsubr, kX86InstIdPfsubr, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pfsubr, kX86InstIdPfsubr, X86MmVar, X86Mem)
+
+ //! Packed DWORDs to SP-FP (3dNow!).
+ INST_2x(pi2fd, kX86InstIdPi2fd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pi2fd, kX86InstIdPi2fd, X86MmVar, X86Mem)
+
+ //! Packed WORDs to SP-FP (3dNow!).
+ INST_2x(pi2fw, kX86InstIdPi2fw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pi2fw, kX86InstIdPi2fw, X86MmVar, X86Mem)
+
+ //! Packed swap DWORDs (3dNow!)
+ INST_2x(pswapd, kX86InstIdPswapd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pswapd, kX86InstIdPswapd, X86MmVar, X86Mem)
+
+ //! Prefetch (3dNow!).
+ INST_1x(prefetch_3dnow, kX86InstIdPrefetch3dNow, X86Mem)
+
+ //! Prefetch and set cache to modified (3dNow!).
+ INST_1x(prefetchw_3dnow, kX86InstIdPrefetchw3dNow, X86Mem)
+
+ //! Faster EMMS (3dNow!).
+ INST_0x(femms, kX86InstIdFemms)
+
+ // --------------------------------------------------------------------------
+ // [SSE]
+ // --------------------------------------------------------------------------
+
+ //! Packed SP-FP add (SSE).
+ INST_2x(addps, kX86InstIdAddps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(addps, kX86InstIdAddps, X86XmmVar, X86Mem)
+
+ //! Scalar SP-FP add (SSE).
+ INST_2x(addss, kX86InstIdAddss, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(addss, kX86InstIdAddss, X86XmmVar, X86Mem)
+
+ //! Packed SP-FP bitwise and-not (SSE).
+ INST_2x(andnps, kX86InstIdAndnps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(andnps, kX86InstIdAndnps, X86XmmVar, X86Mem)
+
+ //! Packed SP-FP bitwise and (SSE).
+ INST_2x(andps, kX86InstIdAndps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(andps, kX86InstIdAndps, X86XmmVar, X86Mem)
+
+ //! Packed SP-FP compare (SSE).
+ INST_3i(cmpps, kX86InstIdCmpps, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(cmpps, kX86InstIdCmpps, X86XmmVar, X86Mem, Imm)
+
+ //! Compare scalar SP-FP Values (SSE).
+ INST_3i(cmpss, kX86InstIdCmpss, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(cmpss, kX86InstIdCmpss, X86XmmVar, X86Mem, Imm)
+
+ //! Scalar ordered SP-FP compare and set EFLAGS (SSE).
+ INST_2x(comiss, kX86InstIdComiss, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(comiss, kX86InstIdComiss, X86XmmVar, X86Mem)
+
+ //! Packed signed INT32 to packed SP-FP conversion (SSE).
+ INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmVar, X86MmVar)
+ //! \overload
+ INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmVar, X86Mem)
+
+ //! Packed SP-FP to packed INT32 conversion (SSE).
+ INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmVar, X86Mem)
+
+ //! Convert scalar INT32 to SP-FP (SSE).
+ INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmVar, X86GpVar)
+ //! \overload
+ INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmVar, X86Mem)
+
+ //! Convert scalar SP-FP to INT32 (SSE).
+ INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpVar, X86Mem)
+
+ //! Convert with truncation packed SP-FP to packed INT32 (SSE).
+ INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmVar, X86Mem)
+
+ //! Convert with truncation scalar SP-FP to INT32 (SSE).
+ INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpVar, X86Mem)
+
+ //! Packed SP-FP divide (SSE).
+ INST_2x(divps, kX86InstIdDivps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(divps, kX86InstIdDivps, X86XmmVar, X86Mem)
+
+ //! Scalar SP-FP divide (SSE).
+ INST_2x(divss, kX86InstIdDivss, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(divss, kX86InstIdDivss, X86XmmVar, X86Mem)
+
+ //! Load streaming SIMD extension control/status (SSE).
+ INST_1x(ldmxcsr, kX86InstIdLdmxcsr, X86Mem)
+
+ //! Byte mask write (SSE).
+ INST_3x(maskmovq, kX86InstIdMaskmovq, X86GpVar /* zdi */, X86MmVar, X86MmVar)
+
+ //! Packed SP-FP maximum (SSE).
+ INST_2x(maxps, kX86InstIdMaxps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(maxps, kX86InstIdMaxps, X86XmmVar, X86Mem)
+
+ //! Scalar SP-FP maximum (SSE).
+ INST_2x(maxss, kX86InstIdMaxss, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(maxss, kX86InstIdMaxss, X86XmmVar, X86Mem)
+
+ //! Packed SP-FP minimum (SSE).
+ INST_2x(minps, kX86InstIdMinps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(minps, kX86InstIdMinps, X86XmmVar, X86Mem)
+
+ //! Scalar SP-FP minimum (SSE).
+ INST_2x(minss, kX86InstIdMinss, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(minss, kX86InstIdMinss, X86XmmVar, X86Mem)
+
+ //! Move aligned packed SP-FP (SSE).
+ INST_2x(movaps, kX86InstIdMovaps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(movaps, kX86InstIdMovaps, X86XmmVar, X86Mem)
+ //! Move aligned packed SP-FP (SSE).
+ INST_2x(movaps, kX86InstIdMovaps, X86Mem, X86XmmVar)
+
+ //! Move DWORD.
+ INST_2x(movd, kX86InstIdMovd, X86Mem, X86XmmVar)
+ //! \overload
+ INST_2x(movd, kX86InstIdMovd, X86GpVar, X86XmmVar)
+ //! \overload
+ INST_2x(movd, kX86InstIdMovd, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2x(movd, kX86InstIdMovd, X86XmmVar, X86GpVar)
+
+ //! Move QWORD (SSE).
+ INST_2x(movq, kX86InstIdMovq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(movq, kX86InstIdMovq, X86Mem, X86XmmVar)
+ //! \overload
+ INST_2x(movq, kX86InstIdMovq, X86XmmVar, X86Mem)
+
+ //! Move QWORD (X64 Only).
+ INST_2x(movq, kX86InstIdMovq, X86GpVar, X86XmmVar)
+ //! \overload
+ INST_2x(movq, kX86InstIdMovq, X86XmmVar, X86GpVar)
+
+ //! Move QWORD using NT hint (SSE).
+ INST_2x(movntq, kX86InstIdMovntq, X86Mem, X86MmVar)
+
+ //! Move high to low packed SP-FP (SSE).
+ INST_2x(movhlps, kX86InstIdMovhlps, X86XmmVar, X86XmmVar)
+
+ //! Move high packed SP-FP (SSE).
+ INST_2x(movhps, kX86InstIdMovhps, X86XmmVar, X86Mem)
+ //! Move high packed SP-FP (SSE).
+ INST_2x(movhps, kX86InstIdMovhps, X86Mem, X86XmmVar)
+
+ //! Move low to high packed SP-FP (SSE).
+ INST_2x(movlhps, kX86InstIdMovlhps, X86XmmVar, X86XmmVar)
+
+ //! Move low packed SP-FP (SSE).
+ INST_2x(movlps, kX86InstIdMovlps, X86XmmVar, X86Mem)
+ //! Move low packed SP-FP (SSE).
+ INST_2x(movlps, kX86InstIdMovlps, X86Mem, X86XmmVar)
+
+ //! Move aligned packed SP-FP using NT hint (SSE).
+ INST_2x(movntps, kX86InstIdMovntps, X86Mem, X86XmmVar)
+
+ //! Move scalar SP-FP (SSE).
+ INST_2x(movss, kX86InstIdMovss, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(movss, kX86InstIdMovss, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2x(movss, kX86InstIdMovss, X86Mem, X86XmmVar)
+
+ //! Move unaligned packed SP-FP (SSE).
+ INST_2x(movups, kX86InstIdMovups, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(movups, kX86InstIdMovups, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2x(movups, kX86InstIdMovups, X86Mem, X86XmmVar)
+
+ //! Packed SP-FP multiply (SSE).
+ INST_2x(mulps, kX86InstIdMulps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(mulps, kX86InstIdMulps, X86XmmVar, X86Mem)
+
+ //! Scalar SP-FP multiply (SSE).
+ INST_2x(mulss, kX86InstIdMulss, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(mulss, kX86InstIdMulss, X86XmmVar, X86Mem)
+
+ //! Packed SP-FP bitwise or (SSE).
+ INST_2x(orps, kX86InstIdOrps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(orps, kX86InstIdOrps, X86XmmVar, X86Mem)
+
+ //! Packed BYTE average (SSE).
+ INST_2x(pavgb, kX86InstIdPavgb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pavgb, kX86InstIdPavgb, X86MmVar, X86Mem)
+
+ //! Packed WORD average (SSE).
+ INST_2x(pavgw, kX86InstIdPavgw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pavgw, kX86InstIdPavgw, X86MmVar, X86Mem)
+
+ //! Extract WORD based on selector (SSE).
+ INST_3i(pextrw, kX86InstIdPextrw, X86GpVar, X86MmVar, Imm)
+
+ //! Insert WORD based on selector (SSE).
+ INST_3i(pinsrw, kX86InstIdPinsrw, X86MmVar, X86GpVar, Imm)
+ //! \overload
+ INST_3i(pinsrw, kX86InstIdPinsrw, X86MmVar, X86Mem, Imm)
+
+ //! Packed WORD maximum (SSE).
+ INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmVar, X86Mem)
+
+ //! Packed BYTE unsigned maximum (SSE).
+ INST_2x(pmaxub, kX86InstIdPmaxub, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pmaxub, kX86InstIdPmaxub, X86MmVar, X86Mem)
+
+ //! Packed WORD minimum (SSE).
+ INST_2x(pminsw, kX86InstIdPminsw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pminsw, kX86InstIdPminsw, X86MmVar, X86Mem)
+
+ //! Packed BYTE unsigned minimum (SSE).
+ INST_2x(pminub, kX86InstIdPminub, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pminub, kX86InstIdPminub, X86MmVar, X86Mem)
+
+ //! Move byte mask to integer (SSE).
+ INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpVar, X86MmVar)
+
+ //! Packed WORD unsigned multiply high (SSE).
+ INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmVar, X86Mem)
+
+ //! Packed WORD sum of absolute differences (SSE).
+ INST_2x(psadbw, kX86InstIdPsadbw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psadbw, kX86InstIdPsadbw, X86MmVar, X86Mem)
+
+ //! Packed WORD shuffle (SSE).
+ INST_3i(pshufw, kX86InstIdPshufw, X86MmVar, X86MmVar, Imm)
+ //! \overload
+ INST_3i(pshufw, kX86InstIdPshufw, X86MmVar, X86Mem, Imm)
+
+ //! Packed SP-FP reciprocal (SSE).
+ INST_2x(rcpps, kX86InstIdRcpps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(rcpps, kX86InstIdRcpps, X86XmmVar, X86Mem)
+
+ //! Scalar SP-FP reciprocal (SSE).
+ INST_2x(rcpss, kX86InstIdRcpss, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(rcpss, kX86InstIdRcpss, X86XmmVar, X86Mem)
+
+ //! Prefetch (SSE).
+ INST_2i(prefetch, kX86InstIdPrefetch, X86Mem, Imm)
+
+ //! Packed WORD sum of absolute differences (SSE).
+ INST_2x(psadbw, kX86InstIdPsadbw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psadbw, kX86InstIdPsadbw, X86XmmVar, X86Mem)
+
+ //! Packed SP-FP Square root reciprocal (SSE).
+ INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmVar, X86Mem)
+
+ //! Scalar SP-FP Square root reciprocal (SSE).
+ INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmVar, X86Mem)
+
+ //! Store fence (SSE).
+ INST_0x(sfence, kX86InstIdSfence)
+
+ //! Shuffle SP-FP (SSE).
+ INST_3i(shufps, kX86InstIdShufps, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(shufps, kX86InstIdShufps, X86XmmVar, X86Mem, Imm)
+
+ //! Packed SP-FP square root (SSE).
+ INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmVar, X86Mem)
+
+ //! Scalar SP-FP square root (SSE).
+ INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmVar, X86Mem)
+
+ //! Store streaming SIMD extension control/status (SSE).
+ INST_1x(stmxcsr, kX86InstIdStmxcsr, X86Mem)
+
+ //! Packed SP-FP subtract (SSE).
+ INST_2x(subps, kX86InstIdSubps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(subps, kX86InstIdSubps, X86XmmVar, X86Mem)
+
+ //! Scalar SP-FP subtract (SSE).
+ INST_2x(subss, kX86InstIdSubss, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(subss, kX86InstIdSubss, X86XmmVar, X86Mem)
+
+ //! Unordered scalar SP-FP compare and set EFLAGS (SSE).
+ INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmVar, X86Mem)
+
+ //! Unpack high packed SP-FP data (SSE).
+ INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmVar, X86Mem)
+
+ //! Unpack low packed SP-FP data (SSE).
+ INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmVar, X86Mem)
+
+ //! Packed SP-FP bitwise xor (SSE).
+ INST_2x(xorps, kX86InstIdXorps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(xorps, kX86InstIdXorps, X86XmmVar, X86Mem)
+
+ // --------------------------------------------------------------------------
+ // [SSE2]
+ // --------------------------------------------------------------------------
+
+ //! Packed DP-FP add (SSE2).
+ INST_2x(addpd, kX86InstIdAddpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(addpd, kX86InstIdAddpd, X86XmmVar, X86Mem)
+
+ //! Scalar DP-FP add (SSE2).
+ INST_2x(addsd, kX86InstIdAddsd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(addsd, kX86InstIdAddsd, X86XmmVar, X86Mem)
+
+ //! Packed DP-FP bitwise and-not (SSE2).
+ INST_2x(andnpd, kX86InstIdAndnpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(andnpd, kX86InstIdAndnpd, X86XmmVar, X86Mem)
+
+ //! Packed DP-FP bitwise and (SSE2).
+ INST_2x(andpd, kX86InstIdAndpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(andpd, kX86InstIdAndpd, X86XmmVar, X86Mem)
+
+ //! Flush cache line (SSE2).
+ INST_1x(clflush, kX86InstIdClflush, X86Mem)
+
+ //! Packed DP-FP compare (SSE2).
+ INST_3i(cmppd, kX86InstIdCmppd, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(cmppd, kX86InstIdCmppd, X86XmmVar, X86Mem, Imm)
+
+ //! Scalar SP-FP compare (SSE2).
+ INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmVar, X86Mem, Imm)
+
+ //! Scalar ordered DP-FP compare and set EFLAGS (SSE2).
+ INST_2x(comisd, kX86InstIdComisd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(comisd, kX86InstIdComisd, X86XmmVar, X86Mem)
+
+ //! Convert packed DWORD integers to packed DP-FP (SSE2).
+ INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmVar, X86Mem)
+
+ //! Convert packed DWORD integers to packed SP-FP (SSE2).
+ INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmVar, X86Mem)
+
+ //! Convert packed DP-FP to packed DWORDs (SSE2).
+ INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmVar, X86Mem)
+
+ //! Convert packed DP-FP to packed DWORDs (SSE2).
+ INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmVar, X86Mem)
+
+ //! Convert packed DP-FP to packed SP-FP (SSE2).
+ INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmVar, X86Mem)
+
+ //! Convert packed DWORDs to packed DP-FP (SSE2).
+ INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmVar, X86MmVar)
+ //! \overload
+ INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmVar, X86Mem)
+
+ //! Convert packed SP-FP to packed DWORDs (SSE2).
+ INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmVar, X86Mem)
+
+ //! Convert packed SP-FP to packed DP-FP (SSE2).
+ INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmVar, X86Mem)
+
+ //! Convert scalar DP-FP to DWORD (SSE2).
+ INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpVar, X86Mem)
+
+ //! Convert scalar DP-FP to scalar SP-FP (SSE2).
+ INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmVar, X86Mem)
+
+ //! Convert DWORD to scalar DP-FP (SSE2).
+ INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmVar, X86GpVar)
+ //! \overload
+ INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmVar, X86Mem)
+
+ //! Convert scalar SP-FP to DP-FP (SSE2).
+ INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmVar, X86Mem)
+
+ //! Convert with truncation packed DP-FP to packed DWORDs (SSE2).
+ INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmVar, X86Mem)
+
+ //! Convert with truncation packed DP-FP to packed QWORDs (SSE2).
+ INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmVar, X86Mem)
+
+ //! Convert with truncation packed SP-FP to packed QWORDs (SSE2).
+ INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmVar, X86Mem)
+
+ //! Convert with truncation scalar DP-FP to DWORD (SSE2).
+ INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpVar, X86XmmVar)
+ //! \overload
+ INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpVar, X86Mem)
+
+ //! Packed DP-FP divide (SSE2).
+ INST_2x(divpd, kX86InstIdDivpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(divpd, kX86InstIdDivpd, X86XmmVar, X86Mem)
+
+ //! Scalar DP-FP divide (SSE2).
+ INST_2x(divsd, kX86InstIdDivsd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(divsd, kX86InstIdDivsd, X86XmmVar, X86Mem)
+
+ //! Load fence (SSE2).
+ INST_0x(lfence, kX86InstIdLfence)
+
+ //! Store selected bytes of OWORD (SSE2).
+ INST_3x(maskmovdqu, kX86InstIdMaskmovdqu, X86GpVar /* zdi */, X86XmmVar, X86XmmVar)
+
+ //! Packed DP-FP maximum (SSE2).
+ INST_2x(maxpd, kX86InstIdMaxpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(maxpd, kX86InstIdMaxpd, X86XmmVar, X86Mem)
+
+ //! Scalar DP-FP maximum (SSE2).
+ INST_2x(maxsd, kX86InstIdMaxsd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(maxsd, kX86InstIdMaxsd, X86XmmVar, X86Mem)
+
+ //! Memory fence (SSE2).
+ INST_0x(mfence, kX86InstIdMfence)
+
+ //! Packed DP-FP minimum (SSE2).
+ INST_2x(minpd, kX86InstIdMinpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(minpd, kX86InstIdMinpd, X86XmmVar, X86Mem)
+
+ //! Scalar DP-FP minimum (SSE2).
+ INST_2x(minsd, kX86InstIdMinsd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(minsd, kX86InstIdMinsd, X86XmmVar, X86Mem)
+
+ //! Move aligned OWORD (SSE2).
+ INST_2x(movdqa, kX86InstIdMovdqa, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(movdqa, kX86InstIdMovdqa, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2x(movdqa, kX86InstIdMovdqa, X86Mem, X86XmmVar)
+
+ //! Move unaligned OWORD (SSE2).
+ INST_2x(movdqu, kX86InstIdMovdqu, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(movdqu, kX86InstIdMovdqu, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2x(movdqu, kX86InstIdMovdqu, X86Mem, X86XmmVar)
+
+ //! Extract packed SP-FP sign mask (SSE2).
+ INST_2x(movmskps, kX86InstIdMovmskps, X86GpVar, X86XmmVar)
+
+ //! Extract packed DP-FP sign mask (SSE2).
+ INST_2x(movmskpd, kX86InstIdMovmskpd, X86GpVar, X86XmmVar)
+
+ //! Move scalar DP-FP (SSE2).
+ INST_2x(movsd, kX86InstIdMovsd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(movsd, kX86InstIdMovsd, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2x(movsd, kX86InstIdMovsd, X86Mem, X86XmmVar)
+
+ //! Move aligned packed DP-FP (SSE2).
+ INST_2x(movapd, kX86InstIdMovapd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(movapd, kX86InstIdMovapd, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2x(movapd, kX86InstIdMovapd, X86Mem, X86XmmVar)
+
+ //! Move QWORD from Xmm to Mm register (SSE2).
+ INST_2x(movdq2q, kX86InstIdMovdq2q, X86MmVar, X86XmmVar)
+
+ //! Move QWORD from Mm to Xmm register (SSE2).
+ INST_2x(movq2dq, kX86InstIdMovq2dq, X86XmmVar, X86MmVar)
+
+ //! Move high packed DP-FP (SSE2).
+ INST_2x(movhpd, kX86InstIdMovhpd, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2x(movhpd, kX86InstIdMovhpd, X86Mem, X86XmmVar)
+
+ //! Move low packed DP-FP (SSE2).
+ INST_2x(movlpd, kX86InstIdMovlpd, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2x(movlpd, kX86InstIdMovlpd, X86Mem, X86XmmVar)
+
+ //! Store OWORD using NT hint (SSE2).
+ INST_2x(movntdq, kX86InstIdMovntdq, X86Mem, X86XmmVar)
+
+ //! Store DWORD using NT hint (SSE2).
+ INST_2x(movnti, kX86InstIdMovnti, X86Mem, X86GpVar)
+
+ //! Store packed DP-FP using NT hint (SSE2).
+ INST_2x(movntpd, kX86InstIdMovntpd, X86Mem, X86XmmVar)
+
+ //! Move unaligned packed DP-FP (SSE2).
+ INST_2x(movupd, kX86InstIdMovupd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(movupd, kX86InstIdMovupd, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2x(movupd, kX86InstIdMovupd, X86Mem, X86XmmVar)
+
+ //! Packed DP-FP multiply (SSE2).
+ INST_2x(mulpd, kX86InstIdMulpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(mulpd, kX86InstIdMulpd, X86XmmVar, X86Mem)
+
+ //! Scalar DP-FP multiply (SSE2).
+ INST_2x(mulsd, kX86InstIdMulsd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(mulsd, kX86InstIdMulsd, X86XmmVar, X86Mem)
+
+ //! Packed DP-FP bitwise or (SSE2).
+ INST_2x(orpd, kX86InstIdOrpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(orpd, kX86InstIdOrpd, X86XmmVar, X86Mem)
+
+ //! Pack WORDs to BYTEs with signed saturation (SSE2).
+ INST_2x(packsswb, kX86InstIdPacksswb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(packsswb, kX86InstIdPacksswb, X86XmmVar, X86Mem)
+
+ //! Pack DWORDs to WORDs with signed saturation (SSE2).
+ INST_2x(packssdw, kX86InstIdPackssdw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(packssdw, kX86InstIdPackssdw, X86XmmVar, X86Mem)
+
+ //! Pack WORDs to BYTEs with unsigned saturation (SSE2).
+ INST_2x(packuswb, kX86InstIdPackuswb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(packuswb, kX86InstIdPackuswb, X86XmmVar, X86Mem)
+
+ //! Packed BYTE add (SSE2).
+ INST_2x(paddb, kX86InstIdPaddb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(paddb, kX86InstIdPaddb, X86XmmVar, X86Mem)
+
+ //! Packed WORD add (SSE2).
+ INST_2x(paddw, kX86InstIdPaddw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(paddw, kX86InstIdPaddw, X86XmmVar, X86Mem)
+
+ //! Packed DWORD add (SSE2).
+ INST_2x(paddd, kX86InstIdPaddd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(paddd, kX86InstIdPaddd, X86XmmVar, X86Mem)
+
+ //! Packed QWORD add (SSE2).
+ INST_2x(paddq, kX86InstIdPaddq, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(paddq, kX86InstIdPaddq, X86MmVar, X86Mem)
+
+ //! Packed QWORD add (SSE2).
+ INST_2x(paddq, kX86InstIdPaddq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(paddq, kX86InstIdPaddq, X86XmmVar, X86Mem)
+
+ //! Packed BYTE add with saturation (SSE2).
+ INST_2x(paddsb, kX86InstIdPaddsb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(paddsb, kX86InstIdPaddsb, X86XmmVar, X86Mem)
+
+ //! Packed WORD add with saturation (SSE2).
+ INST_2x(paddsw, kX86InstIdPaddsw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(paddsw, kX86InstIdPaddsw, X86XmmVar, X86Mem)
+
+ //! Packed BYTE add with unsigned saturation (SSE2).
+ INST_2x(paddusb, kX86InstIdPaddusb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(paddusb, kX86InstIdPaddusb, X86XmmVar, X86Mem)
+
+ //! Packed WORD add with unsigned saturation (SSE2).
+ INST_2x(paddusw, kX86InstIdPaddusw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(paddusw, kX86InstIdPaddusw, X86XmmVar, X86Mem)
+
+ //! Packed bitwise and (SSE2).
+ INST_2x(pand, kX86InstIdPand, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pand, kX86InstIdPand, X86XmmVar, X86Mem)
+
+ //! Packed bitwise and-not (SSE2).
+ INST_2x(pandn, kX86InstIdPandn, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pandn, kX86InstIdPandn, X86XmmVar, X86Mem)
+
+ //! Spin loop hint (SSE2).
+ INST_0x(pause, kX86InstIdPause)
+
+ //! Packed BYTE average (SSE2).
+ INST_2x(pavgb, kX86InstIdPavgb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pavgb, kX86InstIdPavgb, X86XmmVar, X86Mem)
+
+ //! Packed WORD average (SSE2).
+ INST_2x(pavgw, kX86InstIdPavgw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pavgw, kX86InstIdPavgw, X86XmmVar, X86Mem)
+
+ //! Packed BYTE compare for equality (SSE2).
+ INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmVar, X86Mem)
+
+ //! Packed WROD compare for equality (SSE2).
+ INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmVar, X86Mem)
+
+ //! Packed DWORD compare for equality (SSE2).
+ INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmVar, X86Mem)
+
+ //! Packed BYTE compare if greater than (SSE2).
+ INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmVar, X86Mem)
+
+ //! Packed WORD compare if greater than (SSE2).
+ INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmVar, X86Mem)
+
+ //! Packed DWORD compare if greater than (SSE2).
+ INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmVar, X86Mem)
+
+ //! Extract WORD based on selector (SSE2).
+ INST_3i(pextrw, kX86InstIdPextrw, X86GpVar, X86XmmVar, Imm)
+
+ //! Insert WORD based on selector (SSE2).
+ INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmVar, X86GpVar, Imm)
+ //! \overload
+ INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmVar, X86Mem, Imm)
+
+ //! Packed WORD maximum (SSE2).
+ INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmVar, X86Mem)
+
+ //! Packed BYTE unsigned maximum (SSE2).
+ INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmVar, X86Mem)
+
+ //! Packed WORD minimum (SSE2).
+ INST_2x(pminsw, kX86InstIdPminsw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pminsw, kX86InstIdPminsw, X86XmmVar, X86Mem)
+
+ //! Packed BYTE unsigned minimum (SSE2).
+ INST_2x(pminub, kX86InstIdPminub, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pminub, kX86InstIdPminub, X86XmmVar, X86Mem)
+
+ //! Move BYTE mask (SSE2).
+ INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpVar, X86XmmVar)
+
+ //! Packed WORD multiply high (SSE2).
+ INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmVar, X86Mem)
+
+ //! Packed WORD unsigned multiply high (SSE2).
+ INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmVar, X86Mem)
+
+ //! Packed WORD multiply low (SSE2).
+ INST_2x(pmullw, kX86InstIdPmullw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmullw, kX86InstIdPmullw, X86XmmVar, X86Mem)
+
+ //! Packed DWORD multiply to QWORD (SSE2).
+ INST_2x(pmuludq, kX86InstIdPmuludq, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pmuludq, kX86InstIdPmuludq, X86MmVar, X86Mem)
+
+ //! Packed DWORD multiply to QWORD (SSE2).
+ INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmVar, X86Mem)
+
+ //! Packed bitwise or (SSE2).
+ INST_2x(por, kX86InstIdPor, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(por, kX86InstIdPor, X86XmmVar, X86Mem)
+
+ //! Packed DWORD shift left logical (SSE2).
+ INST_2x(pslld, kX86InstIdPslld, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pslld, kX86InstIdPslld, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2i(pslld, kX86InstIdPslld, X86XmmVar, Imm)
+
+ //! Packed QWORD shift left logical (SSE2).
+ INST_2x(psllq, kX86InstIdPsllq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psllq, kX86InstIdPsllq, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2i(psllq, kX86InstIdPsllq, X86XmmVar, Imm)
+
+ //! Packed WORD shift left logical (SSE2).
+ INST_2x(psllw, kX86InstIdPsllw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psllw, kX86InstIdPsllw, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2i(psllw, kX86InstIdPsllw, X86XmmVar, Imm)
+
+ //! Packed OWORD shift left logical (SSE2).
+ INST_2i(pslldq, kX86InstIdPslldq, X86XmmVar, Imm)
+
+ //! Packed DWORD shift right arithmetic (SSE2).
+ INST_2x(psrad, kX86InstIdPsrad, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psrad, kX86InstIdPsrad, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2i(psrad, kX86InstIdPsrad, X86XmmVar, Imm)
+
+ //! Packed WORD shift right arithmetic (SSE2).
+ INST_2x(psraw, kX86InstIdPsraw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psraw, kX86InstIdPsraw, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2i(psraw, kX86InstIdPsraw, X86XmmVar, Imm)
+
+ //! Packed BYTE subtract (SSE2).
+ INST_2x(psubb, kX86InstIdPsubb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psubb, kX86InstIdPsubb, X86XmmVar, X86Mem)
+
+ //! Packed DWORD subtract (SSE2).
+ INST_2x(psubd, kX86InstIdPsubd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psubd, kX86InstIdPsubd, X86XmmVar, X86Mem)
+
+ //! Packed QWORD subtract (SSE2).
+ INST_2x(psubq, kX86InstIdPsubq, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psubq, kX86InstIdPsubq, X86MmVar, X86Mem)
+
+ //! Packed QWORD subtract (SSE2).
+ INST_2x(psubq, kX86InstIdPsubq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psubq, kX86InstIdPsubq, X86XmmVar, X86Mem)
+
+ //! Packed WORD subtract (SSE2).
+ INST_2x(psubw, kX86InstIdPsubw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psubw, kX86InstIdPsubw, X86XmmVar, X86Mem)
+
+ //! Packed WORD to DWORD multiply and add (SSE2).
+ INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmVar, X86Mem)
+
+ //! Packed DWORD shuffle (SSE2).
+ INST_3i(pshufd, kX86InstIdPshufd, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(pshufd, kX86InstIdPshufd, X86XmmVar, X86Mem, Imm)
+
+ //! Packed WORD shuffle high (SSE2).
+ INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmVar, X86Mem, Imm)
+
+ //! Packed WORD shuffle low (SSE2).
+ INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmVar, X86Mem, Imm)
+
+ //! Packed DWORD shift right logical (SSE2).
+ INST_2x(psrld, kX86InstIdPsrld, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psrld, kX86InstIdPsrld, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2i(psrld, kX86InstIdPsrld, X86XmmVar, Imm)
+
+ //! Packed QWORD shift right logical (SSE2).
+ INST_2x(psrlq, kX86InstIdPsrlq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psrlq, kX86InstIdPsrlq, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2i(psrlq, kX86InstIdPsrlq, X86XmmVar, Imm)
+
+ //! Scalar OWORD shift right logical (SSE2).
+ INST_2i(psrldq, kX86InstIdPsrldq, X86XmmVar, Imm)
+
+ //! Packed WORD shift right logical (SSE2).
+ INST_2x(psrlw, kX86InstIdPsrlw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psrlw, kX86InstIdPsrlw, X86XmmVar, X86Mem)
+ //! \overload
+ INST_2i(psrlw, kX86InstIdPsrlw, X86XmmVar, Imm)
+
+ //! Packed BYTE subtract with saturation (SSE2).
+ INST_2x(psubsb, kX86InstIdPsubsb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psubsb, kX86InstIdPsubsb, X86XmmVar, X86Mem)
+
+ //! Packed WORD subtract with saturation (SSE2).
+ INST_2x(psubsw, kX86InstIdPsubsw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psubsw, kX86InstIdPsubsw, X86XmmVar, X86Mem)
+
+ //! Packed BYTE subtract with unsigned saturation (SSE2).
+ INST_2x(psubusb, kX86InstIdPsubusb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psubusb, kX86InstIdPsubusb, X86XmmVar, X86Mem)
+
+ //! Packed WORD subtract with unsigned saturation (SSE2).
+ INST_2x(psubusw, kX86InstIdPsubusw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psubusw, kX86InstIdPsubusw, X86XmmVar, X86Mem)
+
+ //! Unpack high packed BYTEs to WORDs (SSE2).
+ INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmVar, X86Mem)
+
+ //! Unpack high packed DWORDs to QWORDs (SSE2).
+ INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmVar, X86Mem)
+
+ //! Unpack high packed QWORDs to OWORD (SSE2).
+ INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmVar, X86Mem)
+
+ //! Unpack high packed WORDs to DWORDs (SSE2).
+ INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmVar, X86Mem)
+
+ //! Unpack low packed BYTEs to WORDs (SSE2).
+ INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmVar, X86Mem)
+
+ //! Unpack low packed DWORDs to QWORDs (SSE2).
+ INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmVar, X86Mem)
+
+ //! Unpack low packed QWORDs to OWORD (SSE2).
+ INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmVar, X86Mem)
+
+ //! Unpack low packed WORDs to DWORDs (SSE2).
+ INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmVar, X86Mem)
+
+ //! Packed bitwise xor (SSE2).
+ INST_2x(pxor, kX86InstIdPxor, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pxor, kX86InstIdPxor, X86XmmVar, X86Mem)
+
+ //! Shuffle DP-FP (SSE2).
+ INST_3i(shufpd, kX86InstIdShufpd, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(shufpd, kX86InstIdShufpd, X86XmmVar, X86Mem, Imm)
+
+ //! Packed DP-FP square root (SSE2).
+ INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmVar, X86Mem)
+
+ //! Scalar DP-FP square root (SSE2).
+ INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmVar, X86Mem)
+
+ //! Packed DP-FP subtract (SSE2).
+ INST_2x(subpd, kX86InstIdSubpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(subpd, kX86InstIdSubpd, X86XmmVar, X86Mem)
+
+ //! Scalar DP-FP subtract (SSE2).
+ INST_2x(subsd, kX86InstIdSubsd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(subsd, kX86InstIdSubsd, X86XmmVar, X86Mem)
+
+ //! Scalar DP-FP unordered compare and set EFLAGS (SSE2).
+ INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmVar, X86Mem)
+
+ //! Unpack and interleave high packed DP-FP (SSE2).
+ INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmVar, X86Mem)
+
+ //! Unpack and interleave low packed DP-FP (SSE2).
+ INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmVar, X86Mem)
+
+ //! Packed DP-FP bitwise xor (SSE2).
+ INST_2x(xorpd, kX86InstIdXorpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(xorpd, kX86InstIdXorpd, X86XmmVar, X86Mem)
+
+ // --------------------------------------------------------------------------
+ // [SSE3]
+ // --------------------------------------------------------------------------
+
+ //! Packed DP-FP add/subtract (SSE3).
+ INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmVar, X86Mem)
+
+ //! Packed SP-FP add/subtract (SSE3).
+ INST_2x(addsubps, kX86InstIdAddsubps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(addsubps, kX86InstIdAddsubps, X86XmmVar, X86Mem)
+
+ //! Store truncated `fp0` as 16-bit, 32-bit or 64-bit integer to `o0` and pop
+ //! the FPU stack (FPU / SSE3).
+ INST_1x(fisttp, kX86InstIdFisttp, X86Mem)
+
+ //! Packed DP-FP horizontal add (SSE3).
+ INST_2x(haddpd, kX86InstIdHaddpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(haddpd, kX86InstIdHaddpd, X86XmmVar, X86Mem)
+
+ //! Packed SP-FP horizontal add (SSE3).
+ INST_2x(haddps, kX86InstIdHaddps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(haddps, kX86InstIdHaddps, X86XmmVar, X86Mem)
+
+ //! Packed DP-FP horizontal subtract (SSE3).
+ INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmVar, X86Mem)
+
+ //! Packed SP-FP horizontal subtract (SSE3).
+ INST_2x(hsubps, kX86InstIdHsubps, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(hsubps, kX86InstIdHsubps, X86XmmVar, X86Mem)
+
+ //! Load 128-bits unaligned (SSE3).
+ INST_2x(lddqu, kX86InstIdLddqu, X86XmmVar, X86Mem)
+
+ // //! Setup monitor address (SSE3).
+ // INST_0x(monitor, kX86InstIdMonitor)
+
+ //! Move one DP-FP and duplicate (SSE3).
+ INST_2x(movddup, kX86InstIdMovddup, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(movddup, kX86InstIdMovddup, X86XmmVar, X86Mem)
+
+ //! Move packed SP-FP high and duplicate (SSE3).
+ INST_2x(movshdup, kX86InstIdMovshdup, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(movshdup, kX86InstIdMovshdup, X86XmmVar, X86Mem)
+
+ //! Move packed SP-FP low and duplicate (SSE3).
+ INST_2x(movsldup, kX86InstIdMovsldup, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(movsldup, kX86InstIdMovsldup, X86XmmVar, X86Mem)
+
+ // //! Monitor wait (SSE3).
+ // INST_0x(mwait, kX86InstIdMwait)
+
+ // --------------------------------------------------------------------------
+ // [SSSE3]
+ // --------------------------------------------------------------------------
+
+ //! Packed BYTE sign (SSSE3).
+ INST_2x(psignb, kX86InstIdPsignb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psignb, kX86InstIdPsignb, X86MmVar, X86Mem)
+
+ //! PackedBYTE sign (SSSE3).
+ INST_2x(psignb, kX86InstIdPsignb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psignb, kX86InstIdPsignb, X86XmmVar, X86Mem)
+
+ //! Packed DWORD sign (SSSE3).
+ INST_2x(psignd, kX86InstIdPsignd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psignd, kX86InstIdPsignd, X86MmVar, X86Mem)
+
+ //! Packed DWORD sign (SSSE3).
+ INST_2x(psignd, kX86InstIdPsignd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psignd, kX86InstIdPsignd, X86XmmVar, X86Mem)
+
+ //! Packed WORD sign (SSSE3).
+ INST_2x(psignw, kX86InstIdPsignw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(psignw, kX86InstIdPsignw, X86MmVar, X86Mem)
+
+ //! Packed WORD sign (SSSE3).
+ INST_2x(psignw, kX86InstIdPsignw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(psignw, kX86InstIdPsignw, X86XmmVar, X86Mem)
+
+ //! Packed DWORD horizontal add (SSSE3).
+ INST_2x(phaddd, kX86InstIdPhaddd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(phaddd, kX86InstIdPhaddd, X86MmVar, X86Mem)
+
+ //! Packed DWORD horizontal add (SSSE3).
+ INST_2x(phaddd, kX86InstIdPhaddd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(phaddd, kX86InstIdPhaddd, X86XmmVar, X86Mem)
+
+ //! Packed WORD horizontal add with saturation (SSSE3).
+ INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmVar, X86Mem)
+
+ //! Packed WORD horizontal add with with saturation (SSSE3).
+ INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmVar, X86Mem)
+
+ //! Packed WORD horizontal add (SSSE3).
+ INST_2x(phaddw, kX86InstIdPhaddw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(phaddw, kX86InstIdPhaddw, X86MmVar, X86Mem)
+
+ //! Packed WORD horizontal add (SSSE3).
+ INST_2x(phaddw, kX86InstIdPhaddw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(phaddw, kX86InstIdPhaddw, X86XmmVar, X86Mem)
+
+ //! Packed DWORD horizontal subtract (SSSE3).
+ INST_2x(phsubd, kX86InstIdPhsubd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(phsubd, kX86InstIdPhsubd, X86MmVar, X86Mem)
+
+ //! Packed DWORD horizontal subtract (SSSE3).
+ INST_2x(phsubd, kX86InstIdPhsubd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(phsubd, kX86InstIdPhsubd, X86XmmVar, X86Mem)
+
+ //! Packed WORD horizontal subtract with saturation (SSSE3).
+ INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmVar, X86Mem)
+
+ //! Packed WORD horizontal subtract with saturation (SSSE3).
+ INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmVar, X86Mem)
+
+ //! Packed WORD horizontal subtract (SSSE3).
+ INST_2x(phsubw, kX86InstIdPhsubw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(phsubw, kX86InstIdPhsubw, X86MmVar, X86Mem)
+
+ //! Packed WORD horizontal subtract (SSSE3).
+ INST_2x(phsubw, kX86InstIdPhsubw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(phsubw, kX86InstIdPhsubw, X86XmmVar, X86Mem)
+
+ //! Packed multiply and add signed and unsigned bytes (SSSE3).
+ INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmVar, X86Mem)
+
+ //! Packed multiply and add signed and unsigned bytes (SSSE3).
+ INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmVar, X86Mem)
+
+ //! Packed BYTE absolute value (SSSE3).
+ INST_2x(pabsb, kX86InstIdPabsb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pabsb, kX86InstIdPabsb, X86MmVar, X86Mem)
+
+ //! Packed BYTE absolute value (SSSE3).
+ INST_2x(pabsb, kX86InstIdPabsb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pabsb, kX86InstIdPabsb, X86XmmVar, X86Mem)
+
+ //! Packed DWORD absolute value (SSSE3).
+ INST_2x(pabsd, kX86InstIdPabsd, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pabsd, kX86InstIdPabsd, X86MmVar, X86Mem)
+
+ //! Packed DWORD absolute value (SSSE3).
+ INST_2x(pabsd, kX86InstIdPabsd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pabsd, kX86InstIdPabsd, X86XmmVar, X86Mem)
+
+ //! Packed WORD absolute value (SSSE3).
+ INST_2x(pabsw, kX86InstIdPabsw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pabsw, kX86InstIdPabsw, X86MmVar, X86Mem)
+
+ //! Packed WORD absolute value (SSSE3).
+ INST_2x(pabsw, kX86InstIdPabsw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pabsw, kX86InstIdPabsw, X86XmmVar, X86Mem)
+
+ //! Packed WORD multiply high, round and scale (SSSE3).
+ INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmVar, X86Mem)
+
+ //! Packed WORD multiply high, round and scale (SSSE3).
+ INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmVar, X86Mem)
+
+ //! Packed BYTE shuffle (SSSE3).
+ INST_2x(pshufb, kX86InstIdPshufb, X86MmVar, X86MmVar)
+ //! \overload
+ INST_2x(pshufb, kX86InstIdPshufb, X86MmVar, X86Mem)
+
+ //! Packed BYTE shuffle (SSSE3).
+ INST_2x(pshufb, kX86InstIdPshufb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pshufb, kX86InstIdPshufb, X86XmmVar, X86Mem)
+
+ //! Packed align right (SSSE3).
+ INST_3i(palignr, kX86InstIdPalignr, X86MmVar, X86MmVar, Imm)
+ //! \overload
+ INST_3i(palignr, kX86InstIdPalignr, X86MmVar, X86Mem, Imm)
+
+ //! Packed align right (SSSE3).
+ INST_3i(palignr, kX86InstIdPalignr, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(palignr, kX86InstIdPalignr, X86XmmVar, X86Mem, Imm)
+
+ // --------------------------------------------------------------------------
+ // [SSE4.1]
+ // --------------------------------------------------------------------------
+
+ //! Packed DP-FP blend (SSE4.1).
+ INST_3i(blendpd, kX86InstIdBlendpd, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(blendpd, kX86InstIdBlendpd, X86XmmVar, X86Mem, Imm)
+
+ //! Packed SP-FP blend (SSE4.1).
+ INST_3i(blendps, kX86InstIdBlendps, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(blendps, kX86InstIdBlendps, X86XmmVar, X86Mem, Imm)
+
+ //! Packed DP-FP variable blend (SSE4.1).
+ INST_3x(blendvpd, kX86InstIdBlendvpd, X86XmmVar, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_3x(blendvpd, kX86InstIdBlendvpd, X86XmmVar, X86Mem, X86XmmVar)
+
+ //! Packed SP-FP variable blend (SSE4.1).
+ INST_3x(blendvps, kX86InstIdBlendvps, X86XmmVar, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_3x(blendvps, kX86InstIdBlendvps, X86XmmVar, X86Mem, X86XmmVar)
+
+ //! Packed DP-FP dot product (SSE4.1).
+ INST_3i(dppd, kX86InstIdDppd, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(dppd, kX86InstIdDppd, X86XmmVar, X86Mem, Imm)
+
+ //! Packed SP-FP dot product (SSE4.1).
+ INST_3i(dpps, kX86InstIdDpps, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(dpps, kX86InstIdDpps, X86XmmVar, X86Mem, Imm)
+
+ //! Extract SP-FP based on selector (SSE4.1).
+ INST_3i(extractps, kX86InstIdExtractps, X86GpVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(extractps, kX86InstIdExtractps, X86Mem, X86XmmVar, Imm)
+
+ //! Insert SP-FP based on selector (SSE4.1).
+ INST_3i(insertps, kX86InstIdInsertps, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(insertps, kX86InstIdInsertps, X86XmmVar, X86Mem, Imm)
+
+ //! Load OWORD aligned using NT hint (SSE4.1).
+ INST_2x(movntdqa, kX86InstIdMovntdqa, X86XmmVar, X86Mem)
+
+ //! Packed WORD sums of absolute difference (SSE4.1).
+ INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmVar, X86Mem, Imm)
+
+ //! Pack DWORDs to WORDs with unsigned saturation (SSE4.1).
+ INST_2x(packusdw, kX86InstIdPackusdw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(packusdw, kX86InstIdPackusdw, X86XmmVar, X86Mem)
+
+ //! Packed BYTE variable blend (SSE4.1).
+ INST_3x(pblendvb, kX86InstIdPblendvb, X86XmmVar, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_3x(pblendvb, kX86InstIdPblendvb, X86XmmVar, X86Mem, X86XmmVar)
+
+ //! Packed WORD blend (SSE4.1).
+ INST_3i(pblendw, kX86InstIdPblendw, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(pblendw, kX86InstIdPblendw, X86XmmVar, X86Mem, Imm)
+
+ //! Packed QWORD compare for equality (SSE4.1).
+ INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmVar, X86Mem)
+
+ //! Extract BYTE based on selector (SSE4.1).
+ INST_3i(pextrb, kX86InstIdPextrb, X86GpVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(pextrb, kX86InstIdPextrb, X86Mem, X86XmmVar, Imm)
+
+ //! Extract DWORD based on selector (SSE4.1).
+ INST_3i(pextrd, kX86InstIdPextrd, X86GpVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(pextrd, kX86InstIdPextrd, X86Mem, X86XmmVar, Imm)
+
+ //! Extract QWORD based on selector (SSE4.1).
+ INST_3i(pextrq, kX86InstIdPextrq, X86GpVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(pextrq, kX86InstIdPextrq, X86Mem, X86XmmVar, Imm)
+
+ //! Extract WORD based on selector (SSE4.1).
+ INST_3i(pextrw, kX86InstIdPextrw, X86Mem, X86XmmVar, Imm)
+
+ //! Packed WORD horizontal minimum (SSE4.1).
+ INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmVar, X86Mem)
+
+ //! Insert BYTE based on selector (SSE4.1).
+ INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmVar, X86GpVar, Imm)
+ //! \overload
+ INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmVar, X86Mem, Imm)
+
+ //! Insert DWORD based on selector (SSE4.1).
+ INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmVar, X86GpVar, Imm)
+ //! \overload
+ INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmVar, X86Mem, Imm)
+
+ //! Insert QWORD based on selector (SSE4.1).
+ INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmVar, X86GpVar, Imm)
+ //! \overload
+ INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmVar, X86Mem, Imm)
+
+ //! Packed BYTE maximum (SSE4.1).
+ INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmVar, X86Mem)
+
+ //! Packed DWORD maximum (SSE4.1).
+ INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmVar, X86Mem)
+
+ //! Packed DWORD unsigned maximum (SSE4.1).
+ INST_2x(pmaxud, kX86InstIdPmaxud, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmaxud,kX86InstIdPmaxud , X86XmmVar, X86Mem)
+
+ //! Packed WORD unsigned maximum (SSE4.1).
+ INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmVar, X86Mem)
+
+ //! Packed BYTE minimum (SSE4.1).
+ INST_2x(pminsb, kX86InstIdPminsb, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pminsb, kX86InstIdPminsb, X86XmmVar, X86Mem)
+
+ //! Packed DWORD minimum (SSE4.1).
+ INST_2x(pminsd, kX86InstIdPminsd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pminsd, kX86InstIdPminsd, X86XmmVar, X86Mem)
+
+ //! Packed WORD unsigned minimum (SSE4.1).
+ INST_2x(pminuw, kX86InstIdPminuw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pminuw, kX86InstIdPminuw, X86XmmVar, X86Mem)
+
+ //! Packed DWORD unsigned minimum (SSE4.1).
+ INST_2x(pminud, kX86InstIdPminud, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pminud, kX86InstIdPminud, X86XmmVar, X86Mem)
+
+ //! Packed BYTE to DWORD with sign extend (SSE4.1).
+ INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmVar, X86Mem)
+
+ //! Packed BYTE to QWORD with sign extend (SSE4.1).
+ INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmVar, X86Mem)
+
+ //! Packed BYTE to WORD with sign extend (SSE4.1).
+ INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmVar, X86Mem)
+
+ //! Packed DWORD to QWORD with sign extend (SSE4.1).
+ INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmVar, X86Mem)
+
+ //! Packed WORD to DWORD with sign extend (SSE4.1).
+ INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmVar, X86Mem)
+
+ //! Packed WORD to QWORD with sign extend (SSE4.1).
+ INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmVar, X86Mem)
+
+ //! BYTE to DWORD with zero extend (SSE4.1).
+ INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmVar, X86Mem)
+
+ //! Packed BYTE to QWORD with zero extend (SSE4.1).
+ INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmVar, X86Mem)
+
+ //! BYTE to WORD with zero extend (SSE4.1).
+ INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmVar, X86Mem)
+
+ //! Packed DWORD to QWORD with zero extend (SSE4.1).
+ INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmVar, X86Mem)
+
+ //! Packed WORD to DWORD with zero extend (SSE4.1).
+ INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmVar, X86Mem)
+
+ //! Packed WORD to QWORD with zero extend (SSE4.1).
+ INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmVar, X86Mem)
+
+ //! Packed DWORD to QWORD multiply (SSE4.1).
+ INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmVar, X86Mem)
+
+ //! Packed DWORD multiply low (SSE4.1).
+ INST_2x(pmulld, kX86InstIdPmulld, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pmulld, kX86InstIdPmulld, X86XmmVar, X86Mem)
+
+ //! Logical compare (SSE4.1).
+ INST_2x(ptest, kX86InstIdPtest, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(ptest, kX86InstIdPtest, X86XmmVar, X86Mem)
+
+ //! Packed DP-FP round (SSE4.1).
+ INST_3i(roundpd, kX86InstIdRoundpd, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(roundpd, kX86InstIdRoundpd, X86XmmVar, X86Mem, Imm)
+
+ //! Packed SP-FP round (SSE4.1).
+ INST_3i(roundps, kX86InstIdRoundps, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(roundps, kX86InstIdRoundps, X86XmmVar, X86Mem, Imm)
+
+ //! Scalar DP-FP round (SSE4.1).
+ INST_3i(roundsd, kX86InstIdRoundsd, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(roundsd, kX86InstIdRoundsd, X86XmmVar, X86Mem, Imm)
+
+ //! Scalar SP-FP round (SSE4.1).
+ INST_3i(roundss, kX86InstIdRoundss, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(roundss, kX86InstIdRoundss, X86XmmVar, X86Mem, Imm)
+
+ // --------------------------------------------------------------------------
+ // [SSE4.2]
+ // --------------------------------------------------------------------------
+
+ //! Packed compare explicit length strings, return index (SSE4.2).
+ INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmVar, X86Mem, Imm)
+
+ //! Packed compare explicit length strings, return mask (SSE4.2).
+ INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmVar, X86Mem, Imm)
+
+ //! Packed compare implicit length strings, return index (SSE4.2).
+ INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmVar, X86Mem, Imm)
+
+ //! Packed compare implicit length strings, return mask (SSE4.2).
+ INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmVar, X86Mem, Imm)
+
+ //! Packed QWORD compare if greater than (SSE4.2).
+ INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmVar, X86Mem)
+
+ // --------------------------------------------------------------------------
+ // [AESNI]
+ // --------------------------------------------------------------------------
+
+ //! Perform a single round of the AES decryption flow.
+ INST_2x(aesdec, kX86InstIdAesdec, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(aesdec, kX86InstIdAesdec, X86XmmVar, X86Mem)
+
+ //! Perform the last round of the AES decryption flow.
+ INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmVar, X86Mem)
+
+ //! Perform a single round of the AES encryption flow.
+ INST_2x(aesenc, kX86InstIdAesenc, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(aesenc, kX86InstIdAesenc, X86XmmVar, X86Mem)
+
+ //! Perform the last round of the AES encryption flow.
+ INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmVar, X86Mem)
+
+ //! Perform the InvMixColumns transformation.
+ INST_2x(aesimc, kX86InstIdAesimc, X86XmmVar, X86XmmVar)
+ //! \overload
+ INST_2x(aesimc, kX86InstIdAesimc, X86XmmVar, X86Mem)
+
+ //! Assist in expanding the AES cipher key.
+ INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmVar, X86XmmVar, Imm)
+ //! \overload
+ INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmVar, X86Mem, Imm)
+
+ // --------------------------------------------------------------------------
+ // [PCLMULQDQ]
+ // --------------------------------------------------------------------------
+
+ //! Packed QWORD to OWORD carry-less multiply (PCLMULQDQ).
+ INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmVar, X86XmmVar, Imm);
+ //! \overload
+ INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmVar, X86Mem, Imm);
+
+#undef INST_0x
+
+#undef INST_1x
+#undef INST_1x_
+#undef INST_1i
+#undef INST_1cc
+
+#undef INST_2x
+#undef INST_2x_
+#undef INST_2i
+#undef INST_2cc
+
+#undef INST_3x
+#undef INST_3x_
+#undef INST_3i
+
+#undef INST_4x
+#undef INST_4x_
+#undef INST_4i
};
-//! @}
-
-} // AsmJit namespace
-
-#undef ASMJIT_NOT_SUPPORTED_BY_COMPILER
+//! \}
+
+} // asmjit namespace
// [Api-End]
-#include "../core/apiend.h"
-
+#include "../apiend.h"
+
+#endif // !ASMJIT_DISABLE_COMPILER
+
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86compilercontext.cpp
+++ /dev/null
@@ -1,1879 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/intutil.h"
-#include "../core/stringutil.h"
-
-#include "../x86/x86assembler.h"
-#include "../x86/x86compiler.h"
-#include "../x86/x86compilercontext.h"
-#include "../x86/x86compilerfunc.h"
-#include "../x86/x86compileritem.h"
-#include "../x86/x86util.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::CompilerContext - Construction / Destruction]
-// ============================================================================
-
-X86CompilerContext::X86CompilerContext(X86Compiler *x86Compiler) : CompilerContext(x86Compiler)
-{
- this->_state = &_x86State;
-
- this->_clear();
- this->_emitComments = !!x86Compiler->getLogger();
-}
-
-X86CompilerContext::~X86CompilerContext()
-{
-}
-
-// ============================================================================
-// [AsmJit::CompilerContext - Clear]
-// ============================================================================
-
-void X86CompilerContext::_clear()
-{
- this->_zoneMemory.clear();
- this->_func = nullptr;
-
- this->_start = nullptr;
- this->_stop = nullptr;
-
- this->_x86State.clear();
- this->_active = nullptr;
-
- this->_forwardJumps = nullptr;
-
- this->_currentOffset = 0;
- this->_isUnreachable = 0;
-
- this->_modifiedGpRegisters = 0;
- this->_modifiedMmRegisters = 0;
- this->_modifiedXmmRegisters = 0;
-
- this->_allocableEBP = false;
-
- this->_adjustESP = 0;
-
- this->_argumentsBaseReg = kRegIndexInvalid; // Used by patcher.
- this->_argumentsBaseOffset = 0; // Used by patcher.
- this->_argumentsActualDisp = 0; // Used by translate().
-
- this->_variablesBaseReg = kRegIndexInvalid; // Used by patcher.
- this->_variablesBaseOffset = 0; // Used by patcher.
- this->_variablesActualDisp = 0; // Used by translate()
-
- this->_memUsed = nullptr;
- this->_memFree = nullptr;
-
- this->_mem4BlocksCount = 0;
- this->_mem8BlocksCount = 0;
- this->_mem16BlocksCount = 0;
-
- this->_memBytesTotal = 0;
-
- this->_backCode.clear();
- this->_backPos = 0;
-}
-
-// ============================================================================
-// [AsmJit::CompilerContext - Construction / Destruction]
-// ============================================================================
-
-void X86CompilerContext::allocVar(X86CompilerVar *var, uint32_t regMask, uint32_t vflags)
-{
- switch (var->getType())
- {
- case kX86VarTypeGpd:
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
-#endif // ASMJIT_X64
- this->allocGpVar(var, regMask, vflags);
- break;
-
- case kX86VarTypeX87:
- case kX86VarTypeX87SS:
- case kX86VarTypeX87SD:
- // TODO: X87 Support.
- break;
-
- case kX86VarTypeMm:
- this->allocMmVar(var, regMask, vflags);
- break;
-
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- this->allocXmmVar(var, regMask, vflags);
- }
-
- this->_postAlloc(var, vflags);
-}
-
-void X86CompilerContext::saveVar(X86CompilerVar *var)
-{
- switch (var->getType())
- {
- case kX86VarTypeGpd:
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
-#endif // ASMJIT_X64
- this->saveGpVar(var);
- break;
-
- case kX86VarTypeX87:
- case kX86VarTypeX87SS:
- case kX86VarTypeX87SD:
- // TODO: X87 Support.
- break;
-
- case kX86VarTypeMm:
- this->saveMmVar(var);
- break;
-
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- this->saveXmmVar(var);
- }
-}
-
-void X86CompilerContext::spillVar(X86CompilerVar *var)
-{
- switch (var->getType())
- {
- case kX86VarTypeGpd:
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
-#endif // ASMJIT_X64
- this->spillGpVar(var);
- break;
-
- case kX86VarTypeX87:
- case kX86VarTypeX87SS:
- case kX86VarTypeX87SD:
- // TODO: X87 Support.
- break;
-
- case kX86VarTypeMm:
- this->spillMmVar(var);
- break;
-
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- this->spillXmmVar(var);
- }
-}
-
-void X86CompilerContext::unuseVar(X86CompilerVar *var, uint32_t toState)
-{
- ASMJIT_ASSERT(toState != kVarStateReg);
-
- if (var->state == kVarStateReg)
- {
- uint32_t regIndex = var->regIndex;
- switch (var->getType())
- {
- case kX86VarTypeGpd:
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
-#endif // ASMJIT_X64
- this->_x86State.gp[regIndex] = nullptr;
- this->_freedGpRegister(regIndex);
- break;
-
- case kX86VarTypeX87:
- case kX86VarTypeX87SS:
- case kX86VarTypeX87SD:
- // TODO: X87 Support.
- break;
-
- case kX86VarTypeMm:
- this->_x86State.mm[regIndex] = nullptr;
- this->_freedMmRegister(regIndex);
- break;
-
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- this->_x86State.xmm[regIndex] = nullptr;
- this->_freedXmmRegister(regIndex);
- }
- }
-
- var->state = toState;
- var->changed = false;
- var->regIndex = kRegIndexInvalid;
-}
-
-void X86CompilerContext::allocGpVar(X86CompilerVar *var, uint32_t regMask, uint32_t vflags)
-{
- uint32_t fullMask = IntUtil::maskUpToIndex(kX86RegNumGp) & ~IntUtil::maskFromIndex(kX86RegIndexEsp);
- if (!this->_allocableEBP)
- fullMask &= ~IntUtil::maskFromIndex(kX86RegIndexEbp);
-
- // Fix the regMask (0 or full bit-array means that any register may be used).
- if (!regMask)
- regMask = 0xFFFFFFFF;
- regMask &= fullMask;
-
- // Working variables.
- uint32_t i;
- uint32_t mask;
-
- // Last register code (aka home).
- uint32_t home = var->homeRegisterIndex;
- // New register code.
- uint32_t idx = kRegIndexInvalid;
-
- // Preserved GP variables.
- uint32_t preservedGP = var->funcScope->getDecl()->getGpPreservedMask();
-
- // Spill candidate.
- X86CompilerVar *spillCandidate = nullptr;
-
- // Whether to alloc the non-preserved variables first.
- bool nonPreservedFirst = true;
-
- if (getFunc()->isCaller())
- nonPreservedFirst = !var->funcCall || var->funcCall->getOffset() >= var->lastItem->getOffset();
-
- // --------------------------------------------------------------------------
- // [Already Allocated]
- // --------------------------------------------------------------------------
-
- // Go away if variable is already allocated.
- if (var->state == kVarStateReg)
- {
- uint32_t oldIndex = var->regIndex;
-
- // Already allocated in the right register.
- if (IntUtil::maskFromIndex(oldIndex) & regMask)
- return;
-
- // Try to find unallocated register first.
- mask = regMask & ~_x86State.usedGP;
- if (mask)
- idx = IntUtil::findFirstBit(nonPreservedFirst && (mask & ~preservedGP) ? mask & ~preservedGP : mask);
- // Then find the allocated and exchange later.
- else
- idx = IntUtil::findFirstBit(regMask & _x86State.usedGP);
- ASMJIT_ASSERT(idx != kRegIndexInvalid);
-
- X86CompilerVar *other = this->_x86State.gp[idx];
- this->emitExchangeVar(var, idx, vflags, other);
-
- this->_x86State.gp[oldIndex] = other;
- this->_x86State.gp[idx] = var;
-
- if (other)
- other->regIndex = oldIndex;
- else
- this->_freedGpRegister(oldIndex);
-
- // Update X86CompilerVar.
- var->state = kVarStateReg;
- var->regIndex = idx;
- var->homeRegisterIndex = idx;
-
- this->_allocatedGpRegister(idx);
- return;
- }
-
- // --------------------------------------------------------------------------
- // [Find Unused GP]
- // --------------------------------------------------------------------------
-
- // Home register code.
- if (idx == kRegIndexInvalid && home != kRegIndexInvalid && (regMask & IntUtil::maskFromIndex(home)) && !(_x86State.usedGP & IntUtil::maskFromIndex(home)))
- {
- idx = home;
- goto _Alloc;
- }
-
- // We start from 1, because EAX/RAX register is sometimes explicitly
- // needed. So we trying to prevent reallocation in near future.
- if (idx == kRegIndexInvalid)
- {
- for (i = 1, mask = (1 << i); i < kX86RegNumGp; ++i, mask <<= 1)
- {
- if ((regMask & mask) && !(_x86State.usedGP & mask))
- {
- // Convenience to alloc non-preserved first or non-preserved last.
- if (nonPreservedFirst)
- {
- if (idx != kRegIndexInvalid && (preservedGP & mask))
- continue;
-
- idx = i;
- // If current register is preserved, we should try to find different
- // one that is not. This can save one push / pop in prolog / epilog.
- if (!(preservedGP & mask))
- break;
- }
- else
- {
- if (idx != kRegIndexInvalid && !(preservedGP & mask))
- continue;
-
- idx = i;
- // The opposite.
- if (preservedGP & mask)
- break;
- }
- }
- }
- }
-
- // If not found, try EAX/RAX.
- if (idx == kRegIndexInvalid && (regMask & IntUtil::maskFromIndex(kX86RegIndexEax)) && !(_x86State.usedGP & IntUtil::maskFromIndex(kX86RegIndexEax)))
- {
- idx = kX86RegIndexEax;
- goto _Alloc;
- }
-
- // If regMask contains restricted registers which may be used then everything
- // is handled inside this block.
- if (idx == kRegIndexInvalid && regMask != fullMask)
- {
- // Try to find unallocated register first.
- mask = regMask & ~this->_x86State.usedGP;
- if (mask)
- {
- idx = IntUtil::findFirstBit(nonPreservedFirst && (mask & ~preservedGP) ? (mask & ~preservedGP) : mask);
- ASMJIT_ASSERT(idx != kRegIndexInvalid);
- }
- // Then find the allocated and spill later.
- else
- {
- idx = IntUtil::findFirstBit(regMask & _x86State.usedGP);
- ASMJIT_ASSERT(idx != kRegIndexInvalid);
-
- // Spill register we need.
- spillCandidate = this->_x86State.gp[idx];
-
- // Jump to spill part of allocation.
- goto L_Spill;
- }
- }
-
- // --------------------------------------------------------------------------
- // [Spill]
- // --------------------------------------------------------------------------
-
- // If register is still not found, spill other variable.
- if (idx == kRegIndexInvalid)
- {
- if (!spillCandidate)
- spillCandidate = this->_getSpillCandidateGP();
-
- // Spill candidate not found?
- if (!spillCandidate)
- {
- this->_compiler->setError(kErrorNoRegisters);
- return;
- }
-
- L_Spill:
- // Prevented variables can't be spilled. _getSpillCandidate() never returns
- // prevented variables, but when jumping to L_Spill it could happen.
- if (spillCandidate->workOffset == this->_currentOffset)
- {
- this->_compiler->setError(kErrorOverlappedRegisters);
- return;
- }
-
- idx = spillCandidate->regIndex;
- this->spillGpVar(spillCandidate);
- }
-
- // --------------------------------------------------------------------------
- // [Alloc]
- // --------------------------------------------------------------------------
-
-_Alloc:
- if (var->state == kVarStateMem && (vflags & kVarAllocRead))
- this->emitLoadVar(var, idx);
-
- // Update X86CompilerVar.
- var->state = kVarStateReg;
- var->regIndex = idx;
- var->homeRegisterIndex = idx;
-
- // Update CompilerState.
- this->_allocatedVariable(var);
-}
-
-void X86CompilerContext::saveGpVar(X86CompilerVar *var)
-{
- // Can't save variable that isn't allocated.
- ASMJIT_ASSERT(var->state == kVarStateReg);
- ASMJIT_ASSERT(var->regIndex != kRegIndexInvalid);
-
- uint32_t idx = var->regIndex;
- this->emitSaveVar(var, idx);
-
- // Update X86CompilerVar.
- var->changed = false;
-}
-
-void X86CompilerContext::spillGpVar(X86CompilerVar *var)
-{
- // Can't spill variable that isn't allocated.
- ASMJIT_ASSERT(var->state == kVarStateReg);
- ASMJIT_ASSERT(var->regIndex != kRegIndexInvalid);
-
- uint32_t idx = var->regIndex;
-
- if (var->changed)
- this->emitSaveVar(var, idx);
-
- // Update X86CompilerVar.
- var->regIndex = kRegIndexInvalid;
- var->state = kVarStateMem;
- var->changed = false;
-
- // Update CompilerState.
- this->_x86State.gp[idx] = nullptr;
- this->_freedGpRegister(idx);
-}
-
-void X86CompilerContext::allocMmVar(X86CompilerVar *var, uint32_t regMask, uint32_t vflags)
-{
- // Fix the regMask (0 or full bit-array means that any register may be used).
- if (!regMask)
- regMask = IntUtil::maskUpToIndex(kX86RegNumMm);
- regMask &= IntUtil::maskUpToIndex(kX86RegNumMm);
-
- // Working variables.
- uint32_t i;
- uint32_t mask;
-
- // Last register code (aka home).
- uint32_t home = var->homeRegisterIndex;
- // New register code.
- uint32_t idx = kRegIndexInvalid;
-
- // Preserved MM variables.
- //
- // NOTE: Currently MM variables are not preserved and there is no calling
- // convention known to me that does that. But on the other side it's possible
- // to write such calling convention.
- uint32_t preservedMM = var->funcScope->getDecl()->getMmPreservedMask();
-
- // Spill candidate.
- X86CompilerVar *spillCandidate = nullptr;
-
- // Whether to alloc non-preserved first or last.
- bool nonPreservedFirst = true;
- if (this->getFunc()->isCaller())
- nonPreservedFirst = !var->funcCall || var->funcCall->getOffset() >= var->lastItem->getOffset();
-
- // --------------------------------------------------------------------------
- // [Already Allocated]
- // --------------------------------------------------------------------------
-
- // Go away if variable is already allocated.
- if (var->state == kVarStateReg)
- {
- uint32_t oldIndex = var->regIndex;
-
- // Already allocated in the right register.
- if (IntUtil::maskFromIndex(oldIndex) & regMask)
- return;
-
- // Try to find unallocated register first.
- mask = regMask & ~this->_x86State.usedMM;
- if (mask)
- idx = IntUtil::findFirstBit(nonPreservedFirst && (mask & ~preservedMM) ? mask & ~preservedMM : mask);
- // Then find the allocated and exchange later.
- else
- idx = IntUtil::findFirstBit(regMask & this->_x86State.usedMM);
- ASMJIT_ASSERT(idx != kRegIndexInvalid);
-
- X86CompilerVar *other = this->_x86State.mm[idx];
- if (other)
- this->spillMmVar(other);
-
- this->emitMoveVar(var, idx, vflags);
- this->_freedMmRegister(oldIndex);
- this->_x86State.mm[idx] = var;
-
- // Update X86CompilerVar.
- var->state = kVarStateReg;
- var->regIndex = idx;
- var->homeRegisterIndex = idx;
-
- this->_allocatedMmRegister(idx);
- return;
- }
-
- // --------------------------------------------------------------------------
- // [Find Unused MM]
- // --------------------------------------------------------------------------
-
- // If regMask contains restricted registers which may be used then everything
- // is handled in this block.
- if (regMask != IntUtil::maskUpToIndex(kX86RegNumMm))
- {
- // Try to find unallocated register first.
- mask = regMask & ~this->_x86State.usedMM;
- if (mask)
- {
- idx = IntUtil::findFirstBit(nonPreservedFirst && (mask & ~preservedMM) ? mask & ~preservedMM : mask);
- ASMJIT_ASSERT(idx != kRegIndexInvalid);
- }
- // Then find the allocated and spill later.
- else
- {
- idx = IntUtil::findFirstBit(regMask & this->_x86State.usedMM);
- ASMJIT_ASSERT(idx != kRegIndexInvalid);
-
- // Spill register we need.
- spillCandidate = this->_x86State.mm[idx];
-
- // Jump to spill part of allocation.
- goto L_Spill;
- }
- }
-
- // Home register code.
- if (idx == kRegIndexInvalid && home != kRegIndexInvalid)
- {
- if (!(_x86State.usedMM & (1U << home)))
- idx = home;
- }
-
- if (idx == kRegIndexInvalid)
- {
- for (i = 0, mask = (1 << i); i < kX86RegNumMm; ++i, mask <<= 1)
- {
- if (!(this->_x86State.usedMM & mask))
- {
- // Convenience to alloc non-preserved first or non-preserved last.
- if (nonPreservedFirst)
- {
- if (idx != kRegIndexInvalid && (preservedMM & mask))
- continue;
- idx = i;
- // If current register is preserved, we should try to find different
- // one that is not. This can save one push / pop in prolog / epilog.
- if (!(preservedMM & mask))
- break;
- }
- else
- {
- if (idx != kRegIndexInvalid && !(preservedMM & mask))
- continue;
- idx = i;
- // The opposite.
- if (preservedMM & mask)
- break;
- }
- }
- }
- }
-
- // --------------------------------------------------------------------------
- // [Spill]
- // --------------------------------------------------------------------------
-
- // If register is still not found, spill other variable.
- if (idx == kRegIndexInvalid)
- {
- if (!spillCandidate)
- spillCandidate = this->_getSpillCandidateMM();
-
- // Spill candidate not found?
- if (!spillCandidate)
- {
- this->_compiler->setError(kErrorNoRegisters);
- return;
- }
-
- L_Spill:
-
- // Prevented variables can't be spilled. _getSpillCandidate() never returns
- // prevented variables, but when jumping to L_spill it can happen.
- if (spillCandidate->workOffset == this->_currentOffset)
- {
- this->_compiler->setError(kErrorOverlappedRegisters);
- return;
- }
-
- idx = spillCandidate->regIndex;
- this->spillMmVar(spillCandidate);
- }
-
- // --------------------------------------------------------------------------
- // [Alloc]
- // --------------------------------------------------------------------------
-
- if (var->state == kVarStateMem && (vflags & kVarAllocRead))
- this->emitLoadVar(var, idx);
-
- // Update X86CompilerVar.
- var->state = kVarStateReg;
- var->regIndex = idx;
- var->homeRegisterIndex = idx;
-
- // Update CompilerState.
- this->_allocatedVariable(var);
-}
-
-void X86CompilerContext::saveMmVar(X86CompilerVar *var)
-{
- // Can't save variable that isn't allocated.
- ASMJIT_ASSERT(var->state == kVarStateReg);
- ASMJIT_ASSERT(var->regIndex != kRegIndexInvalid);
-
- uint32_t idx = var->regIndex;
- this->emitSaveVar(var, idx);
-
- // Update X86CompilerVar.
- var->changed = false;
-}
-
-void X86CompilerContext::spillMmVar(X86CompilerVar *var)
-{
- // Can't spill variable that isn't allocated.
- ASMJIT_ASSERT(var->state == kVarStateReg);
- ASMJIT_ASSERT(var->regIndex != kRegIndexInvalid);
-
- uint32_t idx = var->regIndex;
-
- if (var->changed)
- this->emitSaveVar(var, idx);
-
- // Update X86CompilerVar.
- var->regIndex = kRegIndexInvalid;
- var->state = kVarStateMem;
- var->changed = false;
-
- // Update CompilerState.
- this->_x86State.mm[idx] = nullptr;
- this->_freedMmRegister(idx);
-}
-
-void X86CompilerContext::allocXmmVar(X86CompilerVar *var, uint32_t regMask, uint32_t vflags)
-{
- // Fix the regMask (0 or full bit-array means that any register may be used).
- if (!regMask)
- regMask = IntUtil::maskUpToIndex(kX86RegNumXmm);
- regMask &= IntUtil::maskUpToIndex(kX86RegNumXmm);
-
- // Working variables.
- uint32_t i;
- uint32_t mask;
-
- // Last register code (aka home).
- uint32_t home = var->homeRegisterIndex;
- // New register code.
- uint32_t idx = kRegIndexInvalid;
-
- // Preserved XMM variables.
- uint32_t preservedXMM = var->funcScope->getDecl()->getXmmPreservedMask();
-
- // Spill candidate.
- X86CompilerVar *spillCandidate = nullptr;
-
- // Whether to alloc non-preserved first or last.
- bool nonPreservedFirst = true;
-
- if (this->getFunc()->isCaller())
- nonPreservedFirst = !var->funcCall || var->funcCall->getOffset() >= var->lastItem->getOffset();
-
- // --------------------------------------------------------------------------
- // [Already Allocated]
- // --------------------------------------------------------------------------
-
- // Go away if variable is already allocated.
- if (var->state == kVarStateReg)
- {
- uint32_t oldIndex = var->regIndex;
-
- // Already allocated in the right register.
- if (IntUtil::maskFromIndex(oldIndex) & regMask)
- return;
-
- // Try to find unallocated register first.
- mask = regMask & ~this->_x86State.usedXMM;
- if (mask)
- idx = IntUtil::findFirstBit(nonPreservedFirst && (mask & ~preservedXMM) ? mask & ~preservedXMM : mask);
- // Then find the allocated and exchange later.
- else
- idx = IntUtil::findFirstBit(regMask & this->_x86State.usedXMM);
- ASMJIT_ASSERT(idx != kRegIndexInvalid);
-
- X86CompilerVar *other = this->_x86State.xmm[idx];
- if (other)
- this->spillXmmVar(other);
-
- this->emitMoveVar(var, idx, vflags);
- this->_freedXmmRegister(oldIndex);
- this->_x86State.xmm[idx] = var;
-
- // Update X86CompilerVar.
- var->state = kVarStateReg;
- var->regIndex = idx;
- var->homeRegisterIndex = idx;
-
- this->_allocatedXmmRegister(idx);
- return;
- }
-
- // --------------------------------------------------------------------------
- // [Find Unused XMM]
- // --------------------------------------------------------------------------
-
- // If regMask contains restricted registers which may be used then everything
- // is handled in this block.
- if (regMask != IntUtil::maskUpToIndex(kX86RegNumXmm))
- {
- // Try to find unallocated register first.
- mask = regMask & ~this->_x86State.usedXMM;
- if (mask)
- {
- idx = IntUtil::findFirstBit(nonPreservedFirst && (mask & ~preservedXMM) ? mask & ~preservedXMM : mask);
- ASMJIT_ASSERT(idx != kRegIndexInvalid);
- }
- // Then find the allocated and spill later.
- else
- {
- idx = IntUtil::findFirstBit(regMask & this->_x86State.usedXMM);
- ASMJIT_ASSERT(idx != kRegIndexInvalid);
-
- // Spill register we need.
- spillCandidate = this->_x86State.xmm[idx];
-
- // Jump to spill part of allocation.
- goto L_Spill;
- }
- }
-
- // Home register code.
- if (idx == kRegIndexInvalid && home != kRegIndexInvalid)
- {
- if (!(_x86State.usedXMM & (1U << home)))
- idx = home;
- }
-
- if (idx == kRegIndexInvalid)
- {
- for (i = 0, mask = (1 << i); i < kX86RegNumXmm; ++i, mask <<= 1)
- {
- if (!(this->_x86State.usedXMM & mask))
- {
- // Convenience to alloc non-preserved first or non-preserved last.
- if (nonPreservedFirst)
- {
- if (idx != kRegIndexInvalid && (preservedXMM & mask))
- continue;
- idx = i;
- // If current register is preserved, we should try to find different
- // one that is not. This can save one push / pop in prolog / epilog.
- if (!(preservedXMM & mask))
- break;
- }
- else
- {
- if (idx != kRegIndexInvalid && !(preservedXMM & mask))
- continue;
- idx = i;
- // The opposite.
- if (preservedXMM & mask)
- break;
- }
- }
- }
- }
-
- // --------------------------------------------------------------------------
- // [Spill]
- // --------------------------------------------------------------------------
-
- // If register is still not found, spill other variable.
- if (idx == kRegIndexInvalid)
- {
- if (!spillCandidate)
- spillCandidate = this->_getSpillCandidateXMM();
-
- // Spill candidate not found?
- if (!spillCandidate)
- {
- this->_compiler->setError(kErrorNoRegisters);
- return;
- }
-
- L_Spill:
-
- // Prevented variables can't be spilled. _getSpillCandidate() never returns
- // prevented variables, but when jumping to L_spill it can happen.
- if (spillCandidate->workOffset == this->_currentOffset)
- {
- this->_compiler->setError(kErrorOverlappedRegisters);
- return;
- }
-
- idx = spillCandidate->regIndex;
- this->spillXmmVar(spillCandidate);
- }
-
- // --------------------------------------------------------------------------
- // [Alloc]
- // --------------------------------------------------------------------------
-
- if (var->state == kVarStateMem && (vflags & kVarAllocRead))
- this->emitLoadVar(var, idx);
-
- // Update X86CompilerVar.
- var->state = kVarStateReg;
- var->regIndex = idx;
- var->homeRegisterIndex = idx;
-
- // Update CompilerState.
- this->_allocatedVariable(var);
-}
-
-void X86CompilerContext::saveXmmVar(X86CompilerVar *var)
-{
- // Can't save variable that isn't allocated.
- ASMJIT_ASSERT(var->state == kVarStateReg);
- ASMJIT_ASSERT(var->regIndex != kRegIndexInvalid);
-
- uint32_t idx = var->regIndex;
- this->emitSaveVar(var, idx);
-
- // Update X86CompilerVar.
- var->changed = false;
-}
-
-void X86CompilerContext::spillXmmVar(X86CompilerVar *var)
-{
- // Can't spill variable that isn't allocated.
- ASMJIT_ASSERT(var->state == kVarStateReg);
- ASMJIT_ASSERT(var->regIndex != kRegIndexInvalid);
-
- uint32_t idx = var->regIndex;
-
- if (var->changed)
- this->emitSaveVar(var, idx);
-
- // Update CompilerVar.
- var->regIndex = kRegIndexInvalid;
- var->state = kVarStateMem;
- var->changed = false;
-
- // Update CompilerState.
- this->_x86State.xmm[idx] = nullptr;
- this->_freedXmmRegister(idx);
-}
-
-void X86CompilerContext::emitLoadVar(X86CompilerVar *var, uint32_t regIndex)
-{
- X86Compiler *x86Compiler = this->getCompiler();
- Mem m = this->_getVarMem(var);
-
- switch (var->getType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstMov, gpd(regIndex), m);
- if (this->_emitComments)
- goto _AddComment;
- break;
-
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- x86Compiler->emit(kX86InstMov, gpq(regIndex), m);
- if (this->_emitComments)
- goto _AddComment;
- break;
-#endif // ASMJIT_X64
-
- case kX86VarTypeX87:
- case kX86VarTypeX87SS:
- case kX86VarTypeX87SD:
- // TODO: X87 Support.
- break;
-
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, mm(regIndex), m);
- if (this->_emitComments)
- goto _AddComment;
- break;
-
- case kX86VarTypeXmm:
- x86Compiler->emit(kX86InstMovDQA, xmm(regIndex), m);
- if (this->_emitComments)
- goto _AddComment;
- break;
-
- case kX86VarTypeXmmSS:
- x86Compiler->emit(kX86InstMovSS, xmm(regIndex), m);
- if (this->_emitComments)
- goto _AddComment;
- break;
-
- case kX86VarTypeXmmSD:
- x86Compiler->emit(kX86InstMovSD, xmm(regIndex), m);
- if (this->_emitComments)
- goto _AddComment;
- break;
-
- case kX86VarTypeXmmPS:
- x86Compiler->emit(kX86InstMovAPS, xmm(regIndex), m);
- if (this->_emitComments)
- goto _AddComment;
- break;
-
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstMovAPD, xmm(regIndex), m);
- if (this->_emitComments)
- goto _AddComment;
- }
- return;
-
-_AddComment:
- x86Compiler->getCurrentItem()->formatComment("Alloc %s", var->getName());
-}
-
-void X86CompilerContext::emitSaveVar(X86CompilerVar *var, uint32_t regIndex)
-{
- // Caller must ensure that variable is allocated.
- ASMJIT_ASSERT(regIndex != kRegIndexInvalid);
-
- X86Compiler *x86Compiler = this->getCompiler();
- Mem m = this->_getVarMem(var);
-
- switch (var->getType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstMov, m, gpd(regIndex));
- if (this->_emitComments)
- goto _AddComment;
- break;
-
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- x86Compiler->emit(kX86InstMov, m, gpq(regIndex));
- if (this->_emitComments)
- goto _AddComment;
- break;
-#endif // ASMJIT_X64
-
- case kX86VarTypeX87:
- case kX86VarTypeX87SS:
- case kX86VarTypeX87SD:
- // TODO: X87 Support.
- break;
-
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, m, mm(regIndex));
- if (this->_emitComments)
- goto _AddComment;
- break;
-
- case kX86VarTypeXmm:
- x86Compiler->emit(kX86InstMovDQA, m, xmm(regIndex));
- if (this->_emitComments)
- goto _AddComment;
- break;
-
- case kX86VarTypeXmmSS:
- x86Compiler->emit(kX86InstMovSS, m, xmm(regIndex));
- if (this->_emitComments)
- goto _AddComment;
- break;
-
- case kX86VarTypeXmmSD:
- x86Compiler->emit(kX86InstMovSD, m, xmm(regIndex));
- if (this->_emitComments)
- goto _AddComment;
- break;
-
- case kX86VarTypeXmmPS:
- x86Compiler->emit(kX86InstMovAPS, m, xmm(regIndex));
- if (this->_emitComments)
- goto _AddComment;
- break;
-
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstMovAPD, m, xmm(regIndex));
- if (this->_emitComments)
- goto _AddComment;
- }
- return;
-
-_AddComment:
- x86Compiler->getCurrentItem()->formatComment("Spill %s", var->getName());
-}
-
-void X86CompilerContext::emitMoveVar(X86CompilerVar *var, uint32_t regIndex, uint32_t vflags)
-{
- // Caller must ensure that the given variable is allocated.
- ASMJIT_ASSERT(var->regIndex != kRegIndexInvalid);
-
- X86Compiler *x86Compiler = this->getCompiler();
- if (!(vflags & kVarAllocRead))
- return;
-
- switch (var->getType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstMov, gpd(regIndex), gpd(var->regIndex));
- break;
-
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- x86Compiler->emit(kX86InstMov, gpq(regIndex), gpq(var->regIndex));
- break;
-#endif // ASMJIT_X64
-
- case kX86VarTypeX87:
- case kX86VarTypeX87SS:
- case kX86VarTypeX87SD:
- // TODO: X87 Support.
- break;
-
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, mm(regIndex), mm(var->regIndex));
- break;
-
- case kX86VarTypeXmm:
- x86Compiler->emit(kX86InstMovDQA, xmm(regIndex), xmm(var->regIndex));
- break;
-
- case kX86VarTypeXmmSS:
- x86Compiler->emit(kX86InstMovSS, xmm(regIndex), xmm(var->regIndex));
- break;
-
- case kX86VarTypeXmmSD:
- x86Compiler->emit(kX86InstMovSD, xmm(regIndex), xmm(var->regIndex));
- break;
-
- case kX86VarTypeXmmPS:
- x86Compiler->emit(kX86InstMovAPS, xmm(regIndex), xmm(var->regIndex));
- break;
-
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstMovAPD, xmm(regIndex), xmm(var->regIndex));
- }
-}
-
-void X86CompilerContext::emitExchangeVar(X86CompilerVar *var, uint32_t regIndex, uint32_t vflags, X86CompilerVar *other)
-{
- // Caller must ensure that the given variable is allocated.
- ASMJIT_ASSERT(var->regIndex != kRegIndexInvalid);
-
- X86Compiler *x86Compiler = this->getCompiler();
-
- // If other is not valid then we can just emit MOV (or other similar instruction).
- if (!other)
- {
- this->emitMoveVar(var, regIndex, vflags);
- return;
- }
-
- // If we need to alloc for write-only operation then we can move other
- // variable away instead of exchanging them.
- if (!(vflags & kVarAllocRead))
- {
- this->emitMoveVar(other, var->regIndex, kVarAllocRead);
- return;
- }
-
- switch (var->getType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstXchg, gpd(regIndex), gpd(var->regIndex));
- break;
-
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- x86Compiler->emit(kX86InstXchg, gpq(regIndex), gpq(var->regIndex));
- break;
-#endif // ASMJIT_X64
-
- case kX86VarTypeX87:
- case kX86VarTypeX87SS:
- case kX86VarTypeX87SD:
- // TODO: X87 Support.
- break;
-
- // NOTE: MM and XMM registers shoudln't be exchanged using this way, it's
- // correct, but instead of using one instruction we need three.
-
- case kX86VarTypeMm:
- {
- MmReg a = mm(regIndex);
- MmReg b = mm(var->regIndex);
-
- x86Compiler->emit(kX86InstPXor, a, b);
- x86Compiler->emit(kX86InstPXor, b, a);
- x86Compiler->emit(kX86InstPXor, a, b);
- break;
- }
-
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- {
- XmmReg a = xmm(regIndex);
- XmmReg b = xmm(var->regIndex);
-
- x86Compiler->emit(kX86InstXorPS, a, b);
- x86Compiler->emit(kX86InstXorPS, b, a);
- x86Compiler->emit(kX86InstXorPS, a, b);
- break;
- }
-
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- {
- XmmReg a = xmm(regIndex);
- XmmReg b = xmm(var->regIndex);
-
- x86Compiler->emit(kX86InstXorPD, a, b);
- x86Compiler->emit(kX86InstXorPD, b, a);
- x86Compiler->emit(kX86InstXorPD, a, b);
- break;
- }
-
- case kX86VarTypeXmm:
- {
- XmmReg a = xmm(regIndex);
- XmmReg b = xmm(var->regIndex);
-
- x86Compiler->emit(kX86InstPXor, a, b);
- x86Compiler->emit(kX86InstPXor, b, a);
- x86Compiler->emit(kX86InstPXor, a, b);
- }
- }
-}
-
-void X86CompilerContext::_postAlloc(X86CompilerVar *var, uint32_t vflags)
-{
- if (vflags & kVarAllocWrite)
- var->changed = true;
-}
-
-void X86CompilerContext::_markMemoryUsed(X86CompilerVar *var)
-{
- if (var->homeMemoryData)
- return;
-
- VarMemBlock *mem = this->_allocMemBlock(var->getSize());
- if (!mem)
- return;
-
- var->homeMemoryData = mem;
-}
-
-Mem X86CompilerContext::_getVarMem(X86CompilerVar *var)
-{
- Mem m;
- m._mem.id = var->getId();
-
- if (!var->isMemArgument())
- m._mem.displacement = this->_adjustESP;
-
- this->_markMemoryUsed(var);
- return m;
-}
-
-static int32_t getSpillScore(X86CompilerVar *var, uint32_t currentOffset)
-{
- int32_t score = 0;
-
- ASMJIT_ASSERT(var->lastItem);
- uint32_t lastOffset = var->lastItem->getOffset();
-
- if (lastOffset >= currentOffset)
- score += static_cast<int32_t>(lastOffset - currentOffset);
-
- // Each write access decreases probability of spill.
- score -= static_cast<int32_t>(var->regWriteCount) + static_cast<int32_t>(var->regRwCount);
- // Each read-only access increases probability of spill.
- score += static_cast<int32_t>(var->regReadCount);
-
- // Each memory access increases probability of spill.
- score += static_cast<int32_t>(var->memWriteCount) + static_cast<int32_t>(var->memRwCount);
- score += static_cast<int32_t>(var->memReadCount);
-
- return score;
-}
-
-X86CompilerVar *X86CompilerContext::_getSpillCandidateGP()
-{
- return this->_getSpillCandidateGeneric(_x86State.gp, kX86RegNumGp);
-}
-
-X86CompilerVar *X86CompilerContext::_getSpillCandidateMM()
-{
- return this->_getSpillCandidateGeneric(_x86State.mm, kX86RegNumMm);
-}
-
-X86CompilerVar *X86CompilerContext::_getSpillCandidateXMM()
-{
- return this->_getSpillCandidateGeneric(_x86State.xmm, kX86RegNumXmm);
-}
-
-X86CompilerVar *X86CompilerContext::_getSpillCandidateGeneric(X86CompilerVar **varArray, uint32_t count)
-{
- uint32_t i;
-
- X86CompilerVar *candidate = nullptr;
- uint32_t candidatePriority = 0;
- int32_t candidateScore = 0;
-
- uint32_t currentOffset = this->_compiler->getCurrentItem()->getOffset();
-
- for (i = 0; i < count; ++i)
- {
- // Get variable.
- X86CompilerVar *cv = varArray[i];
-
- // Never spill variables needed for next instruction.
- if (!cv || cv->workOffset == this->_currentOffset)
- continue;
-
- uint32_t variablePriority = cv->getPriority();
- int32_t variableScore = getSpillScore(cv, currentOffset);
-
- if (!candidate || variablePriority > candidatePriority || (variablePriority == candidatePriority && variableScore > candidateScore))
- {
- candidate = cv;
- candidatePriority = variablePriority;
- candidateScore = variableScore;
- }
- }
-
- return candidate;
-}
-
-void X86CompilerContext::_addActive(X86CompilerVar *var)
-{
- // Never call with variable that is already in active list.
- ASMJIT_ASSERT(!var->nextActive);
- ASMJIT_ASSERT(!var->prevActive);
-
- if (!this->_active)
- {
- var->nextActive = var;
- var->prevActive = var;
-
- this->_active = var;
- }
- else
- {
- X86CompilerVar *vlast = static_cast<X86CompilerVar *>(this->_active)->prevActive;
-
- vlast->nextActive = var;
- static_cast<X86CompilerVar *>(this->_active)->prevActive = var;
-
- var->nextActive = static_cast<X86CompilerVar *>(this->_active);
- var->prevActive = vlast;
- }
-}
-
-void X86CompilerContext::_freeActive(X86CompilerVar *var)
-{
- X86CompilerVar *next = var->nextActive;
- X86CompilerVar *prev = var->prevActive;
-
- if (prev == next)
- this->_active = nullptr;
- else
- {
- if (this->_active == var)
- this->_active = next;
-
- prev->nextActive = next;
- next->prevActive = prev;
- }
-
- var->nextActive = nullptr;
- var->prevActive = nullptr;
-}
-
-void X86CompilerContext::_freeAllActive()
-{
- if (!this->_active)
- return;
-
- X86CompilerVar *cur = static_cast<X86CompilerVar *>(this->_active);
- for (;;)
- {
- X86CompilerVar *next = cur->nextActive;
-
- cur->nextActive = nullptr;
- cur->prevActive = nullptr;
-
- if (next == this->_active)
- break;
- }
-
- this->_active = nullptr;
-}
-
-void X86CompilerContext::_allocatedVariable(X86CompilerVar *var)
-{
- uint32_t idx = var->regIndex;
-
- switch (var->getType())
- {
- case kX86VarTypeGpd:
- case kX86VarTypeGpq:
- this->_x86State.gp[idx] = var;
- this->_allocatedGpRegister(idx);
- break;
-
- case kX86VarTypeMm:
- this->_x86State.mm[idx] = var;
- this->_allocatedMmRegister(idx);
- break;
-
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- this->_x86State.xmm[idx] = var;
- this->_allocatedXmmRegister(idx);
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
-}
-
-void X86CompilerContext::translateOperands(Operand *operands, uint32_t count)
-{
- X86Compiler *x86Compiler = this->getCompiler();
- uint32_t i;
-
- // Translate variables to registers.
- for (i = 0; i < count; ++i)
- {
- Operand &o = operands[i];
-
- if (o.isVar())
- {
- X86CompilerVar *cv = x86Compiler->_getVar(o.getId());
- ASMJIT_ASSERT(cv);
-
- o._reg.op = kOperandReg;
- o._reg.code |= cv->regIndex;
- }
- else if (o.isMem())
- {
- if ((o.getId() & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- // Memory access. We just increment here actual displacement.
- X86CompilerVar *cv = x86Compiler->_getVar(o.getId());
- ASMJIT_ASSERT(cv);
-
- o._mem.displacement += cv->isMemArgument() ? _argumentsActualDisp : _variablesActualDisp;
- // NOTE: This is not enough, variable position will be patched later
- // by X86CompilerContext::_patchMemoryOperands().
- }
- else if ((o._mem.base & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *cv = x86Compiler->_getVar(o._mem.base);
- ASMJIT_ASSERT(cv);
-
- o._mem.base = cv->regIndex;
- }
-
- if ((o._mem.index & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *cv = x86Compiler->_getVar(o._mem.index);
- ASMJIT_ASSERT(cv);
-
- o._mem.index = cv->regIndex;
- }
- }
- }
-}
-
-void X86CompilerContext::addBackwardCode(X86CompilerJmpInst *from)
-{
- this->_backCode.append(from);
-}
-
-void X86CompilerContext::addForwardJump(X86CompilerJmpInst *inst)
-{
- ForwardJumpData *j = reinterpret_cast<ForwardJumpData *>(this->_zoneMemory.alloc(sizeof(ForwardJumpData)));
- if (!j)
- {
- this->_compiler->setError(kErrorNoHeapMemory);
- return;
- }
-
- j->inst = inst;
- j->state = this->_saveState();
- j->next = this->_forwardJumps;
- this->_forwardJumps = j;
-}
-
-X86CompilerState *X86CompilerContext::_saveState()
-{
- X86Compiler *x86Compiler = this->getCompiler();
-
- // Get count of variables stored in memory.
- uint32_t memVarsCount = 0;
- X86CompilerVar *cur = static_cast<X86CompilerVar *>(this->_active);
-
- if (cur)
- {
- do
- {
- if (cur->state == kVarStateMem)
- ++memVarsCount;
- cur = cur->nextActive;
- } while (cur != this->_active);
- }
-
- // Alloc X86CompilerState structure (using zone allocator) and copy current
- // state into it.
- X86CompilerState *state = x86Compiler->_newState(memVarsCount);
- memcpy(state, &this->_x86State, sizeof(X86CompilerState));
-
- // Clear changed flags.
- state->changedGP = 0;
- state->changedMM = 0;
- state->changedXMM = 0;
-
- unsigned i;
- unsigned mask;
-
- // Save variables stored in REGISTERs and CHANGE flag.
- for (i = 0, mask = 1; i < kX86RegNumGp; ++i, mask <<= 1)
- if (state->gp[i] && state->gp[i]->changed)
- state->changedGP |= mask;
-
- for (i = 0, mask = 1; i < kX86RegNumMm; ++i, mask <<= 1)
- if (state->mm[i] && state->mm[i]->changed)
- state->changedMM |= mask;
-
- for (i = 0, mask = 1; i < kX86RegNumXmm; ++i, mask <<= 1)
- if (state->xmm[i] && state->xmm[i]->changed)
- state->changedXMM |= mask;
-
- // Save variables stored in MEMORY.
- state->memVarsCount = memVarsCount;
- memVarsCount = 0;
-
- cur = static_cast<X86CompilerVar *>(this->_active);
- if (cur)
- {
- do
- {
- if (cur->state == kVarStateMem)
- state->memVarsData[memVarsCount++] = cur;
- cur = cur->nextActive;
- } while (cur != this->_active);
- }
-
- // Finished.
- return state;
-}
-
-void X86CompilerContext::_assignState(X86CompilerState *state)
-{
- memcpy(&this->_x86State, state, sizeof(X86CompilerState));
- this->_x86State.memVarsCount = 0;
-
- unsigned i, mask;
-
- // Unuse all variables first.
- X86CompilerVar *cv = static_cast<X86CompilerVar *>(this->_active);
- if (cv)
- {
- do
- {
- cv->state = kVarStateUnused;
- cv = cv->nextActive;
- } while (cv != this->_active);
- }
-
- // Assign variables stored in memory which are not unused.
- for (i = 0; i < state->memVarsCount; ++i)
- state->memVarsData[i]->state = kVarStateMem;
-
- // Assign allocated variables.
- for (i = 0, mask = 1; i < kX86RegNumGp; ++i, mask <<= 1)
- {
- if ((cv = this->_x86State.gp[i]))
- {
- cv->state = kVarStateReg;
- cv->regIndex = i;
- cv->changed = !!(this->_x86State.changedGP & mask);
- }
- }
-
- for (i = 0, mask = 1; i < kX86RegNumMm; ++i, mask <<= 1)
- {
- if ((cv = this->_x86State.mm[i]))
- {
- cv->state = kVarStateReg;
- cv->regIndex = i;
- cv->changed = !!(this->_x86State.changedMM & mask);
- }
- }
-
- for (i = 0, mask = 1; i < kX86RegNumXmm; ++i, mask <<= 1)
- {
- if ((cv = this->_x86State.xmm[i]))
- {
- cv->state = kVarStateReg;
- cv->regIndex = i;
- cv->changed = !!(this->_x86State.changedXMM & mask);
- }
- }
-}
-
-void X86CompilerContext::_restoreState(X86CompilerState *state, uint32_t targetOffset)
-{
- X86CompilerState *fromState = &this->_x86State;
- X86CompilerState *toState = state;
-
- // No change, rare...
- if (fromState == toState)
- return;
-
- unsigned base;
- unsigned i;
-
- // --------------------------------------------------------------------------
- // Set target state to all variables. cv->tInt is target state in this func.
- // --------------------------------------------------------------------------
-
- // UNUSED.
- X86CompilerVar *cv = static_cast<X86CompilerVar *>(this->_active);
- if (cv)
- {
- do
- {
- cv->tInt = kVarStateUnused;
- cv = cv->nextActive;
- } while (cv != this->_active);
- }
-
- // MEMORY.
- for (i = 0; i < toState->memVarsCount; ++i)
- toState->memVarsData[i]->tInt = kVarStateMem;
-
- // REGISTER.
- for (i = 0; i < X86CompilerState::kStateRegCount; ++i)
- if ((cv = toState->regs[i]))
- cv->tInt = kVarStateReg;
-
- // --------------------------------------------------------------------------
- // [GP-Registers Switch]
- // --------------------------------------------------------------------------
-
- // TODO.
-#if 0
- for (i = 0; i < kX86RegNumGp; ++i)
- {
- X86CompilerVar *fromVar = fromState->gp[i];
- X86CompilerVar *toVar = toState->gp[i];
-
- if (fromVar != toVar)
- {
- if (fromVar)
- {
- if (toVar)
- {
- if (fromState->gp[to
- }
- else
- {
- // It is possible that variable that was saved in state currently not
- // exists (tInt is target scope!).
- if (fromVar->tInt == kVarStateUnused)
- this->unuseVar(fromVar, kVarStateUnused);
- else
- this->spillVar(fromVar);
- }
- }
- }
- else if (fromVar)
- {
- uint32_t mask = IntUtil::maskFromIndex(i);
- // Variables are the same, we just need to compare changed flags.
- if ((fromState->changedGP & mask) && !(toState->changedGP & mask))
- this->saveVar(fromVar);
- }
- }
-#endif
-
- // Spill.
- for (base = 0, i = 0; i < X86CompilerState::kStateRegCount; ++i)
- {
- // Change the base offset (from base offset so the register index can be calculated).
- if (i == X86CompilerState::kStateRegMmBase || i == X86CompilerState::kStateRegXmmBase)
- base = i;
-
- uint32_t regIndex = i - base;
- X86CompilerVar *fromVar = fromState->regs[i];
- X86CompilerVar *toVar = toState->regs[i];
-
- if (fromVar != toVar)
- {
- // Spill the register.
- if (fromVar)
- {
- // It is possible that variable that was saved in state currently not
- // exists (tInt is target scope!).
- if (fromVar->tInt == kVarStateUnused)
- this->unuseVar(fromVar, kVarStateUnused);
- else
- this->spillVar(fromVar);
- }
- }
- else if (fromVar)
- {
- // Variables are the same, we just need to compare changed flags.
- uint32_t mask = IntUtil::maskFromIndex(regIndex);
-
- if ((fromState->changedGP & mask) && !(toState->changedGP & mask))
- this->saveVar(fromVar);
- }
- }
-
- // Alloc.
- for (base = 0, i = 0; i < X86CompilerState::kStateRegCount; ++i)
- {
- // Change the base offset (from base offset so the register index can be calculated).
- if (i == X86CompilerState::kStateRegMmBase || i == X86CompilerState::kStateRegXmmBase)
- base = i;
-
- X86CompilerVar *fromVar = fromState->regs[i];
- X86CompilerVar *toVar = toState->regs[i];
-
- if (fromVar != toVar)
- {
- // Alloc register.
- uint32_t regIndex = i - base;
-
- if (toVar)
- this->allocVar(toVar, IntUtil::maskFromIndex(regIndex), kVarAllocRead);
- }
-
- // TODO:
- //if (toVar)
- //toVar->changed = to->changed;
- }
-
- // --------------------------------------------------------------------------
- // Update used masks.
- // --------------------------------------------------------------------------
-
- this->_x86State.usedGP = state->usedGP;
- this->_x86State.usedMM = state->usedMM;
- this->_x86State.usedXMM = state->usedXMM;
-
- // --------------------------------------------------------------------------
- // Update changed masks and cleanup.
- // --------------------------------------------------------------------------
-
- cv = static_cast<X86CompilerVar *>(this->_active);
- if (cv)
- {
- do
- {
- if (cv->tInt != kVarStateReg)
- {
- cv->state = static_cast<int>(cv->tInt);
- cv->changed = false;
- }
-
- cv->tInt = 0;
- cv = cv->nextActive;
- } while (cv != this->_active);
- }
-}
-
-VarMemBlock *X86CompilerContext::_allocMemBlock(uint32_t size)
-{
- ASMJIT_ASSERT(size);
-
- // First try to find mem blocks.
- VarMemBlock *mem = this->_memFree;
- VarMemBlock *prev = nullptr;
-
- while (mem)
- {
- VarMemBlock *next = mem->nextFree;
-
- if (mem->size == size)
- {
- if (prev)
- prev->nextFree = next;
- else
- this->_memFree = next;
-
- mem->nextFree = nullptr;
- return mem;
- }
-
- prev = mem;
- mem = next;
- }
-
- // Never mind, create new.
- mem = reinterpret_cast<VarMemBlock *>(this->_zoneMemory.alloc(sizeof(VarMemBlock)));
- if (!mem)
- {
- this->_compiler->setError(kErrorNoHeapMemory);
- return nullptr;
- }
-
- mem->offset = 0;
- mem->size = size;
-
- mem->nextUsed = this->_memUsed;
- mem->nextFree = nullptr;
-
- this->_memUsed = mem;
-
- switch (size)
- {
- case 16:
- ++this->_mem16BlocksCount;
- break;
- case 8:
- ++this->_mem8BlocksCount;
- break;
- case 4:
- ++this->_mem4BlocksCount;
- }
-
- return mem;
-}
-
-void X86CompilerContext::_freeMemBlock(VarMemBlock *mem)
-{
- // Add mem to free blocks.
- mem->nextFree = this->_memFree;
- this->_memFree = mem;
-}
-
-void X86CompilerContext::_allocMemoryOperands()
-{
- VarMemBlock *mem;
-
- // Variables are allocated in this order:
- // 1. 16-byte variables.
- // 2. 8-byte variables.
- // 3. 4-byte variables.
- // 4. All others.
-
- uint32_t start16 = 0;
- uint32_t start8 = start16 + this->_mem16BlocksCount * 16;
- uint32_t start4 = start8 + this->_mem8BlocksCount * 8;
- uint32_t startX = IntUtil::align<uint32_t>(start4 + this->_mem4BlocksCount * 4, 16);
-
- for (mem = this->_memUsed; mem; mem = mem->nextUsed)
- {
- uint32_t size = mem->size;
- uint32_t offset;
-
- switch (size)
- {
- case 16:
- offset = start16;
- start16 += 16;
- break;
-
- case 8:
- offset = start8;
- start8 += 8;
- break;
-
- case 4:
- offset = start4;
- start4 += 4;
- break;
-
- default:
- // Align to 16 bytes if size is 16 or more.
- if (size >= 16)
- {
- size = IntUtil::align(size, 16u);
- startX = IntUtil::align(startX, 16u);
- }
-
- offset = startX;
- startX += size;
- }
-
- mem->offset = static_cast<int32_t>(offset);
- this->_memBytesTotal += size;
- }
-}
-
-void X86CompilerContext::_patchMemoryOperands(CompilerItem *start, CompilerItem *stop)
-{
- CompilerItem *cur;
-
- for (cur = start; ; cur = cur->getNext())
- {
- if (cur->getType() == kCompilerItemInst)
- {
- Mem *mem = reinterpret_cast<X86CompilerInst *>(cur)->_memOp;
-
- if (mem && (mem->_mem.id & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *cv = this->getCompiler()->_getVar(mem->_mem.id);
- ASMJIT_ASSERT(cv);
-
- if (cv->isMemArgument())
- {
- mem->_mem.base = this->_argumentsBaseReg;
- mem->_mem.displacement += cv->homeMemoryOffset;
- mem->_mem.displacement += this->_argumentsBaseOffset;
- }
- else
- {
- VarMemBlock *mb = reinterpret_cast<VarMemBlock *>(cv->homeMemoryData);
- ASMJIT_ASSERT(mb);
-
- mem->_mem.base = this->_variablesBaseReg;
- mem->_mem.displacement += mb->offset;
- mem->_mem.displacement += this->_variablesBaseOffset;
- }
- }
- }
- if (cur == stop)
- break;
- }
-}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86compilercontext.h
+++ /dev/null
@@ -1,309 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/intutil.h"
-#include "../core/podvector.h"
-
-#include "../x86/x86assembler.h"
-#include "../x86/x86compiler.h"
-#include "../x86/x86compilerfunc.h"
-#include "../x86/x86compileritem.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_X86
-//! @{
-
-// ============================================================================
-// [AsmJit::X86CompilerContext]
-// ============================================================================
-
-//! @internal
-//!
-//! @brief Compiler context is used by @ref X86Compiler.
-//!
-//! X86Compiler context is used during compilation and normally developer doesn't
-//! need access to it. The context is user per function (it's reset after each
-//! function is generated).
-struct X86CompilerContext : public CompilerContext
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref X86CompilerContext instance.
- ASMJIT_API X86CompilerContext(X86Compiler *x86Compiler);
- //! @brief Destroy the @ref X86CompilerContext instance.
- ASMJIT_API ~X86CompilerContext();
-
- // --------------------------------------------------------------------------
- // [Accessor]
- // --------------------------------------------------------------------------
-
- //! @brief Get compiler as @ref X86Compiler.
- X86Compiler *getCompiler() const { return reinterpret_cast<X86Compiler *>(this->_compiler); }
-
- //! @brief Get function as @ref X86CompilerFuncDecl.
- X86CompilerFuncDecl *getFunc() const { return reinterpret_cast<X86CompilerFuncDecl *>(this->_func); }
-
- // --------------------------------------------------------------------------
- // [Clear]
- // --------------------------------------------------------------------------
-
- //! @brief Clear context, preparing it for next function generation.
- ASMJIT_API void _clear();
-
- // --------------------------------------------------------------------------
- // [Register Allocator]
- // --------------------------------------------------------------------------
-
- //! @brief Allocate variable
- //!
- //! Calls @c allocGpVar, @c allocMmVar or @c allocXmmVar methods.
- ASMJIT_API void allocVar(X86CompilerVar *cv, uint32_t regMask, uint32_t vflags);
-
- //! @brief Save variable.
- //!
- //! Calls @c saveGpVar, @c saveMmVar or @c saveXmmVar methods.
- ASMJIT_API void saveVar(X86CompilerVar *cv);
-
- //! @brief Spill variable.
- //!
- //! Calls @c spillGpVar, @c spillMmVar or @c spillXmmVar methods.
- ASMJIT_API void spillVar(X86CompilerVar *cv);
-
- //! @brief Unuse variable (didn't spill, just forget about it).
- ASMJIT_API void unuseVar(X86CompilerVar *cv, uint32_t toState);
-
- //! @brief Helper method that is called for each variable per item.
- void _unuseVarOnEndOfScope(CompilerItem *item, X86CompilerVar *cv)
- {
- if (cv->lastItem == item)
- this->unuseVar(cv, kVarStateUnused);
- }
- //! @overload
- void _unuseVarOnEndOfScope(CompilerItem *item, VarAllocRecord *rec)
- {
- X86CompilerVar *cv = rec->vdata;
- if (cv->lastItem == item || (rec->vflags & kVarAllocUnuseAfterUse))
- this->unuseVar(cv, kVarStateUnused);
- }
- //! @overload
- void _unuseVarOnEndOfScope(CompilerItem *item, VarCallRecord *rec)
- {
- X86CompilerVar *v = rec->vdata;
- if (v->lastItem == item || (rec->flags & VarCallRecord::kFlagUnuseAfterUse))
- this->unuseVar(v, kVarStateUnused);
- }
-
- //! @brief Allocate variable (GP).
- ASMJIT_API void allocGpVar(X86CompilerVar *cv, uint32_t regMask, uint32_t vflags);
- //! @brief Save variable (GP).
- ASMJIT_API void saveGpVar(X86CompilerVar *cv);
- //! @brief Spill variable (GP).
- ASMJIT_API void spillGpVar(X86CompilerVar *cv);
-
- //! @brief Allocate variable (MM).
- ASMJIT_API void allocMmVar(X86CompilerVar *cv, uint32_t regMask, uint32_t vflags);
- //! @brief Save variable (MM).
- ASMJIT_API void saveMmVar(X86CompilerVar *cv);
- //! @brief Spill variable (MM).
- ASMJIT_API void spillMmVar(X86CompilerVar *cv);
-
- //! @brief Allocate variable (XMM).
- ASMJIT_API void allocXmmVar(X86CompilerVar *cv, uint32_t regMask, uint32_t vflags);
- //! @brief Save variable (XMM).
- ASMJIT_API void saveXmmVar(X86CompilerVar *cv);
- //! @brief Spill variable (XMM).
- ASMJIT_API void spillXmmVar(X86CompilerVar *cv);
-
- //! @brief Emit load variable instruction(s).
- ASMJIT_API void emitLoadVar(X86CompilerVar *cv, uint32_t regIndex);
- //! @brief Emit save variable instruction(s).
- ASMJIT_API void emitSaveVar(X86CompilerVar *cv, uint32_t regIndex);
-
- //! @brief Emit move variable instruction(s).
- ASMJIT_API void emitMoveVar(X86CompilerVar *cv, uint32_t regIndex, uint32_t vflags);
- //! @brief Emit exchange variable instruction(s).
- ASMJIT_API void emitExchangeVar(X86CompilerVar *cv, uint32_t regIndex, uint32_t vflags, X86CompilerVar *other);
-
- //! @brief Called each time a variable is alloceted.
- ASMJIT_API void _postAlloc(X86CompilerVar *cv, uint32_t vflags);
- //! @brief Marks variable home memory as used (must be called at least once
- //! for each variable that uses function local memory - stack).
- ASMJIT_API void _markMemoryUsed(X86CompilerVar *cv);
-
- ASMJIT_API Mem _getVarMem(X86CompilerVar *cv);
-
- ASMJIT_API X86CompilerVar *_getSpillCandidateGP();
- ASMJIT_API X86CompilerVar *_getSpillCandidateMM();
- ASMJIT_API X86CompilerVar *_getSpillCandidateXMM();
- ASMJIT_API X86CompilerVar *_getSpillCandidateGeneric(X86CompilerVar **varArray, uint32_t count);
-
- bool _isActive(X86CompilerVar *cv) { return !!cv->nextActive; }
-
- ASMJIT_API void _addActive(X86CompilerVar *cv);
- ASMJIT_API void _freeActive(X86CompilerVar *cv);
- ASMJIT_API void _freeAllActive();
-
- ASMJIT_API void _allocatedVariable(X86CompilerVar *cv);
-
- void _allocatedGpRegister(uint32_t index)
- {
- this->_x86State.usedGP |= IntUtil::maskFromIndex(index);
- this->_modifiedGpRegisters |= IntUtil::maskFromIndex(index);
- }
-
- void _allocatedMmRegister(uint32_t index)
- {
- this->_x86State.usedMM |= IntUtil::maskFromIndex(index);
- this->_modifiedMmRegisters |= IntUtil::maskFromIndex(index);
- }
-
- void _allocatedXmmRegister(uint32_t index)
- {
- this->_x86State.usedXMM |= IntUtil::maskFromIndex(index);
- this->_modifiedXmmRegisters |= IntUtil::maskFromIndex(index);
- }
-
- void _freedGpRegister(uint32_t index) { this->_x86State.usedGP &= ~IntUtil::maskFromIndex(index); }
-
- void _freedMmRegister(uint32_t index) { this->_x86State.usedMM &= ~IntUtil::maskFromIndex(index); }
-
- void _freedXmmRegister(uint32_t index) { this->_x86State.usedXMM &= ~IntUtil::maskFromIndex(index); }
-
- void _markGpRegisterModified(uint32_t index) { this->_modifiedGpRegisters |= IntUtil::maskFromIndex(index); }
-
- void _markMmRegisterModified(uint32_t index) { this->_modifiedMmRegisters |= IntUtil::maskFromIndex(index); }
-
- void _markXmmRegisterModified(uint32_t index) { this->_modifiedXmmRegisters |= IntUtil::maskFromIndex(index); }
-
- // TODO: Find code which uses this and improve.
- void _newRegisterHomeIndex(X86CompilerVar *cv, uint32_t idx)
- {
- if (cv->homeRegisterIndex == kRegIndexInvalid)
- cv->homeRegisterIndex = idx;
- cv->prefRegisterMask |= 1U << idx;
- }
-
- // TODO: Find code which uses this and improve.
- void _newRegisterHomeMask(X86CompilerVar *cv, uint32_t mask)
- {
- cv->prefRegisterMask |= mask;
- }
-
- // --------------------------------------------------------------------------
- // [Operand Patcher]
- // --------------------------------------------------------------------------
-
- ASMJIT_API void translateOperands(Operand *operands, uint32_t count);
-
- // --------------------------------------------------------------------------
- // [Backward Code]
- // --------------------------------------------------------------------------
-
- ASMJIT_API void addBackwardCode(X86CompilerJmpInst *from);
-
- // --------------------------------------------------------------------------
- // [Forward Jump]
- // --------------------------------------------------------------------------
-
- ASMJIT_API void addForwardJump(X86CompilerJmpInst *inst);
-
- // --------------------------------------------------------------------------
- // [State]
- // --------------------------------------------------------------------------
-
- ASMJIT_API X86CompilerState *_saveState();
- ASMJIT_API void _assignState(X86CompilerState *state);
- ASMJIT_API void _restoreState(X86CompilerState *state, uint32_t targetOffset = kInvalidValue);
-
- // --------------------------------------------------------------------------
- // [Memory Allocator]
- // --------------------------------------------------------------------------
-
- ASMJIT_API VarMemBlock *_allocMemBlock(uint32_t size);
- ASMJIT_API void _freeMemBlock(VarMemBlock *mem);
-
- ASMJIT_API void _allocMemoryOperands();
- ASMJIT_API void _patchMemoryOperands(CompilerItem *start, CompilerItem *stop);
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief X86 specific compiler state (linked with @ref _state).
- X86CompilerState _x86State;
-
- //! @brief Forward jumps (single linked list).
- ForwardJumpData *_forwardJumps;
-
- //! @brief Global modified GP registers mask (per function).
- uint32_t _modifiedGpRegisters;
- //! @brief Global modified MM registers mask (per function).
- uint32_t _modifiedMmRegisters;
- //! @brief Global modified XMM registers mask (per function).
- uint32_t _modifiedXmmRegisters;
-
- //! @brief Whether the EBP/RBP register can be used by register allocator.
- uint32_t _allocableEBP;
-
- //! @brief ESP adjust constant (changed during PUSH/POP or when using
- //! stack.
- int _adjustESP;
-
- //! @brief Function arguments base pointer (register).
- uint32_t _argumentsBaseReg;
- //! @brief Function arguments base offset.
- int32_t _argumentsBaseOffset;
- //! @brief Function arguments displacement.
- int32_t _argumentsActualDisp;
-
- //! @brief Function variables base pointer (register).
- uint32_t _variablesBaseReg;
- //! @brief Function variables base offset.
- int32_t _variablesBaseOffset;
- //! @brief Function variables displacement.
- int32_t _variablesActualDisp;
-
- //! @brief Used memory blocks (for variables, here is each created mem block
- //! that can be also in _memFree list).
- VarMemBlock *_memUsed;
- //! @brief Free memory blocks (freed, prepared for another allocation).
- VarMemBlock *_memFree;
- //! @brief Count of 4-byte memory blocks used by the function.
- uint32_t _mem4BlocksCount;
- //! @brief Count of 8-byte memory blocks used by the function.
- uint32_t _mem8BlocksCount;
- //! @brief Count of 16-byte memory blocks used by the function.
- uint32_t _mem16BlocksCount;
- //! @brief Count of total bytes of stack memory used by the function.
- uint32_t _memBytesTotal;
-
- //! @brief List of items which need to be translated. These items are filled
- //! by @c addBackwardCode().
- PodVector<X86CompilerJmpInst *> _backCode;
-
- //! @brief Backward code position (starts at 0).
- sysuint_t _backPos;
- //! @brief Whether to emit comments.
- bool _emitComments;
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86compilerfunc.cpp
+++ /dev/null
@@ -1,2796 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/intutil.h"
-#include "../core/stringutil.h"
-
-#include "../x86/x86compiler.h"
-#include "../x86/x86compilercontext.h"
-#include "../x86/x86compilerfunc.h"
-#include "../x86/x86compileritem.h"
-#include "../x86/x86cpuinfo.h"
-#include "../x86/x86util.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::X86Assembler - Logging]
-// ============================================================================
-
-// Defined in AsmJit/X86/X86Assembler.cpp.
-char *X86Assembler_dumpRegister(char *buf, uint32_t type, uint32_t index);
-char *X86Assembler_dumpOperand(char *buf, const Operand *op, uint32_t memRegType, uint32_t loggerFlags);
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncDecl - Construction / Destructioin]
-// ============================================================================
-
-X86CompilerFuncDecl::X86CompilerFuncDecl(X86Compiler *x86Compiler) : CompilerFuncDecl(x86Compiler), _gpModifiedAndPreserved(0), _mmModifiedAndPreserved(0), _xmmModifiedAndPreserved(0), _movDqInstCode(kInstNone),
- _pePushPopStackSize(0), _peMovStackSize(0), _peAdjustStackSize(0), _memStackSize(0), _memStackSize16(0)
-{
- this->_decl = &_x86Decl;
-
- // Just clear to safe defaults.
- this->_funcHints |= IntUtil::maskFromIndex(kX86FuncHintPushPop);
-
- // Stack is always aligned to 16-bytes when using 64-bit OS.
- if (CompilerUtil::isStack16ByteAligned())
- this->_funcHints |= IntUtil::maskFromIndex(kX86FuncHintAssume16ByteAlignment);
-
- this->_entryLabel = x86Compiler->newLabel();
- this->_exitLabel = x86Compiler->newLabel();
-
- this->_entryTarget = x86Compiler->_getTarget(this->_entryLabel.getId());
- this->_exitTarget = x86Compiler->_getTarget(this->_exitLabel.getId());
-
- this->_end = Compiler_newItem<X86CompilerFuncEnd>(x86Compiler, this);
-}
-
-X86CompilerFuncDecl::~X86CompilerFuncDecl()
-{
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncDecl - Interface]
-// ============================================================================
-
-void X86CompilerFuncDecl::prepare(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- this->_offset = x86Context._currentOffset++;
-
- this->_prepareVariables(this);
-}
-
-CompilerItem *X86CompilerFuncDecl::translate(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
-
- this->_allocVariables(x86Context);
- return this->translated();
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncDecl - Misc]
-// ============================================================================
-
-int X86CompilerFuncDecl::getMaxSize() const
-{
- // NOP.
- return 0;
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncDecl - Prototype]
-// ============================================================================
-
-void X86CompilerFuncDecl::setPrototype(uint32_t convention, uint32_t returnType, const uint32_t *arguments, uint32_t argumentsCount)
-{
- this->_x86Decl.setPrototype(convention, returnType, arguments, argumentsCount);
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncDecl - Helpers]
-// ============================================================================
-
-void X86CompilerFuncDecl::_createVariables()
-{
- X86Compiler *x86Compiler = this->getCompiler();
-
- uint32_t i, count = this->_x86Decl.getArgumentsCount();
- if (!count)
- return;
-
- this->_vars = reinterpret_cast<CompilerVar **>(x86Compiler->getZoneMemory().alloc(count * sizeof(void*)));
- if (!this->_vars)
- {
- x86Compiler->setError(kErrorNoHeapMemory);
- return;
- }
-
- char argNameStorage[64];
- char *argName = nullptr;
-
- bool debug = !!x86Compiler->getLogger();
- if (debug)
- argName = argNameStorage;
-
- for (i = 0; i < count; ++i)
- {
- FuncArg &arg = this->_x86Decl.getArgument(i);
-
- if (debug)
- snprintf(argName, ASMJIT_ARRAY_SIZE(argNameStorage), "arg_%u", i);
-
- uint32_t size = X86Util::getVarSizeFromVarType(arg.getVarType());
- X86CompilerVar *cv = x86Compiler->_newVar(argName, arg.getVarType(), size);
-
- if (arg.getRegIndex() != kRegIndexInvalid)
- {
- cv->_isRegArgument = true;
- cv->regIndex = arg.getRegIndex();
- }
-
- if (arg.getStackOffset() != kFuncStackInvalid)
- {
- cv->_isMemArgument = true;
- cv->homeMemoryOffset = arg.getStackOffset();
- }
-
- this->_vars[i] = cv;
- }
-}
-
-void X86CompilerFuncDecl::_prepareVariables(CompilerItem *first)
-{
- uint32_t count = this->_x86Decl.getArgumentsCount();
- if (!count)
- return;
-
- for (uint32_t i = 0; i < count; ++i)
- {
- X86CompilerVar *cv = this->getVar(i);
-
- // This is where variable scope starts.
- cv->firstItem = first;
- // If this will not be changed then it will be deallocated immediately.
- cv->lastItem = first;
- }
-}
-
-void X86CompilerFuncDecl::_allocVariables(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- uint32_t count = this->getDecl()->getArgumentsCount();
-
- if (!count)
- return;
-
- for (uint32_t i = 0; i < count; ++i)
- {
- X86CompilerVar *cv = this->getVar(i);
-
- if (cv->firstItem || cv->isArgument())
- {
- // Variable is used.
- if (cv->regIndex != kRegIndexInvalid)
- {
- cv->state = kVarStateReg;
- // If variable is in register -> mark it as changed so it will not be
- // lost by first spill.
- cv->changed = true;
- x86Context._allocatedVariable(cv);
- }
- else if (cv->isMemArgument())
- cv->state = kVarStateMem;
- }
- else
- // Variable is not used.
- cv->regIndex = kRegIndexInvalid;
- }
-}
-
-void X86CompilerFuncDecl::_preparePrologEpilog(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
-
- this->clearFuncFlag(kX86FuncFlagPushPop | kX86FuncFlagEmitEmms | kX86FuncFlagEmitSFence | kX86FuncFlagEmitLFence | kX86FuncFlagAssume16ByteAlignment | kX86FuncFlagPerform16ByteAlignment);
-
- uint32_t accessibleMemoryBelowStack = 0;
- if (this->getDecl()->getConvention() == kX86FuncConvX64U)
- accessibleMemoryBelowStack = 128;
-
- if (this->getHint(kX86FuncHintAssume16ByteAlignment))
- this->setFuncFlag(kX86FuncFlagAssume16ByteAlignment);
-
- if (this->getHint(kX86FuncHintPerform16ByteAlignment))
- this->setFuncFlag(kX86FuncFlagPerform16ByteAlignment);
-
- if (this->getHint(kFuncHintNaked))
- this->setFuncFlag(kFuncFlagIsNaked);
-
- if (this->isCaller() && (x86Context._memBytesTotal > 0 || this->isAssumed16ByteAlignment()))
- this->setFuncFlag(kX86FuncFlagIsEspAdjusted);
-
- if (x86Context._memBytesTotal > accessibleMemoryBelowStack)
- this->setFuncFlag(kX86FuncFlagIsEspAdjusted);
-
- if (this->getHint(kX86FuncHintPushPop))
- this->setFuncFlag(kX86FuncFlagPushPop);
-
- if (this->getHint(kX86FuncHintEmms))
- this->setFuncFlag(kX86FuncFlagEmitEmms);
-
- if (this->getHint(kX86FuncHintSFence))
- this->setFuncFlag(kX86FuncFlagEmitSFence);
-
- if (this->getHint(kX86FuncHintLFence))
- this->setFuncFlag(kX86FuncFlagEmitLFence);
-
- // Updated to respect comment from issue #47, align also when using MMX code.
- if (!this->isAssumed16ByteAlignment() && !this->isNaked() && (x86Context._mem16BlocksCount + (x86Context._mem8BlocksCount > 0)))
- // Have to align stack to 16-bytes.
- this->setFuncFlag(kX86FuncFlagIsEspAdjusted | kX86FuncFlagPerform16ByteAlignment);
-
- this->_gpModifiedAndPreserved = x86Context._modifiedGpRegisters & this->_x86Decl.getGpPreservedMask() & (~IntUtil::maskFromIndex(kX86RegIndexEsp));
- this->_mmModifiedAndPreserved = x86Context._modifiedMmRegisters & this->_x86Decl.getMmPreservedMask();
- this->_xmmModifiedAndPreserved = x86Context._modifiedXmmRegisters & this->_x86Decl.getXmmPreservedMask();
- this->_movDqInstCode = this->isAssumed16ByteAlignment() || this->isPerformed16ByteAlignment() ? kX86InstMovDQA : kX86InstMovDQU;
-
- // Prolog & Epilog stack size.
- int32_t memGpSize = IntUtil::bitCount(this->_gpModifiedAndPreserved) * sizeof(intptr_t);
- int32_t memMmSize = IntUtil::bitCount(this->_mmModifiedAndPreserved) * 8;
- int32_t memXmmSize = IntUtil::bitCount(this->_xmmModifiedAndPreserved) * 16;
-
- if (this->hasFuncFlag(kX86FuncFlagPushPop))
- {
- this->_pePushPopStackSize = memGpSize;
- this->_peMovStackSize = memXmmSize + IntUtil::align(memMmSize, 16);
- }
- else
- {
- this->_pePushPopStackSize = 0;
- this->_peMovStackSize = memXmmSize + IntUtil::align(memMmSize + memGpSize, 16);
- }
-
- if (this->isPerformed16ByteAlignment())
- this->_peAdjustStackSize += IntUtil::delta(this->_pePushPopStackSize, 16);
- else
- {
- int32_t v = 16 - sizeof(uintptr_t);
-
- if (!this->isNaked())
- v -= sizeof(uintptr_t);
-
- v -= this->_pePushPopStackSize & 15;
-
- if (v < 0)
- v += 16;
-
- this->_peAdjustStackSize = v;
-
- //this->_peAdjustStackSize += IntUtil::delta(this->_pePushPopStackSize + v, 16);
- }
-
- // Memory stack size.
- this->_memStackSize = x86Context._memBytesTotal;
- this->_memStackSize16 = IntUtil::align(this->_memStackSize, 16);
-
- if (this->isNaked())
- {
- x86Context._argumentsBaseReg = kX86RegIndexEsp;
- x86Context._argumentsBaseOffset = this->hasFuncFlag(kX86FuncFlagIsEspAdjusted) ?
- this->_funcCallStackSize + this->_memStackSize16 + this->_peMovStackSize + this->_pePushPopStackSize + this->_peAdjustStackSize : this->_pePushPopStackSize;
- }
- else
- {
- x86Context._argumentsBaseReg = kX86RegIndexEbp;
- x86Context._argumentsBaseOffset = sizeof(sysint_t);
- }
-
- x86Context._variablesBaseReg = kX86RegIndexEsp;
- x86Context._variablesBaseOffset = this->_funcCallStackSize;
-
- if (!this->hasFuncFlag(kX86FuncFlagIsEspAdjusted))
- x86Context._variablesBaseOffset = -this->_memStackSize16 - this->_peMovStackSize - this->_peAdjustStackSize;
-}
-
-void X86CompilerFuncDecl::_dumpFunction(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- X86Compiler *x86Compiler = this->getCompiler();
-
- Logger *logger = x86Compiler->getLogger();
- ASMJIT_ASSERT(logger);
-
- uint32_t i;
- char _buf[1024];
- char *p;
-
- // Log function prototype.
- uint32_t argumentsCount = this->_x86Decl.getArgumentsCount();
- bool first = true;
-
- logger->logString("; Function Prototype:\n");
- logger->logString(";\n");
-
- for (i = 0; i < argumentsCount; ++i)
- {
- const FuncArg &a = this->_x86Decl.getArgument(i);
- X86CompilerVar *cv = this->getVar(i);
-
- if (first)
- {
- logger->logString("; IDX| Type | Sz | Home |\n");
- logger->logString("; ---+----------+----+----------------+\n");
- }
-
- char *memHome = _buf;
-
- if (a.hasRegIndex())
- {
- Reg regOp(a.getRegIndex() | kX86RegTypeGpz, 0);
- X86Assembler_dumpOperand(memHome, ®Op, kX86RegTypeGpz, 0)[0] = 0;
- }
- else
- {
- Mem memOp;
- memOp._mem.base = kX86RegIndexEsp;
- memOp._mem.displacement = a.getStackOffset();
- X86Assembler_dumpOperand(memHome, &memOp, kX86RegTypeGpz, 0)[0] = 0;
- }
-
- logger->logFormat("; %-3u| %-9s| %-3u| %-15s|\n",
- // Argument index.
- i,
- // Argument type.
- cv->getType() < kX86VarTypeCount ? x86VarInfo[cv->getType()].getName() : "invalid",
- // Argument size.
- cv->getSize(),
- // Argument memory home.
- memHome
- );
-
- first = false;
- }
- logger->logString(";\n");
-
- // Log variables.
- uint32_t variablesCount = static_cast<uint32_t>(x86Compiler->_vars.getLength());
- first = true;
-
- logger->logString("; Variables:\n");
- logger->logString(";\n");
-
- for (i = 0; i < variablesCount; ++i)
- {
- X86CompilerVar *cv = static_cast<X86CompilerVar *>(x86Compiler->_vars[i]);
-
- // If this variable is not related to this function then skip it.
- if (cv->funcScope != this)
- continue;
-
- // Get some information about variable type.
- const X86VarInfo &vinfo = x86VarInfo[cv->getType()];
-
- if (first)
- {
- logger->logString("; ID | Type | Sz | Home | Register Access | Memory Access |\n");
- logger->logString("; ---+----------+----+----------------+-------------------+-------------------+\n");
- }
-
- char *memHome = const_cast<char *>("[None]");
- if (cv->homeMemoryData)
- {
- VarMemBlock *memBlock = reinterpret_cast<VarMemBlock *>(cv->homeMemoryData);
- memHome = _buf;
-
- Mem memOp;
- if (cv->isMemArgument())
- {
- const FuncArg &a = this->_x86Decl.getArgument(i);
-
- memOp._mem.base = x86Context._argumentsBaseReg;
- memOp._mem.displacement += x86Context._argumentsBaseOffset;
- memOp._mem.displacement += a.getStackOffset();
- }
- else
- {
- memOp._mem.base = x86Context._variablesBaseReg;
- memOp._mem.displacement += x86Context._variablesBaseOffset;
- memOp._mem.displacement += memBlock->offset;
- }
- X86Assembler_dumpOperand(memHome, &memOp, kX86RegTypeGpz, 0)[0] = 0;
- }
-
- logger->logFormat("; %-3u| %-9s| %-3u| %-15s| r=%-4uw=%-4ux=%-4u| r=%-4uw=%-4ux=%-4u|\n",
- // Variable id.
- static_cast<unsigned>(i & kOperandIdValueMask),
- // Variable type.
- cv->getType() < kX86VarTypeCount ? vinfo.getName() : "invalid",
- // Variable size.
- cv->getSize(),
- // Variable memory home.
- memHome,
- // Register access count.
- static_cast<unsigned>(cv->regReadCount),
- static_cast<unsigned>(cv->regWriteCount),
- static_cast<unsigned>(cv->regRwCount),
- // Memory access count.
- static_cast<unsigned>(cv->memReadCount),
- static_cast<unsigned>(cv->memWriteCount),
- static_cast<unsigned>(cv->memRwCount)
- );
- first = false;
- }
- logger->logString(";\n");
-
- // Log modified registers.
- p = _buf;
-
- uint32_t r;
- uint32_t modifiedRegisters = 0;
-
- for (r = 0; r < 3; ++r)
- {
- bool first = true;
- uint32_t regs = 0;
- uint32_t type = 0;
-
- switch (r)
- {
- case 0:
- regs = x86Context._modifiedGpRegisters;
- type = kX86RegTypeGpz;
- p = StringUtil::copy(p, "; GP : ");
- break;
- case 1:
- regs = x86Context._modifiedMmRegisters;
- type = kX86RegTypeMm;
- p = StringUtil::copy(p, "; MM : ");
- break;
- case 2:
- regs = x86Context._modifiedXmmRegisters;
- type = kX86RegTypeXmm;
- p = StringUtil::copy(p, "; XMM: ");
- break;
- default:
- ASMJIT_ASSERT(0);
- }
-
- for (i = 0; i < kX86RegNumBase; ++i)
- {
- if (regs & IntUtil::maskFromIndex(i))
- {
- if (!first)
- {
- *p++ = ',';
- *p++ = ' ';
- }
- p = X86Assembler_dumpRegister(p, type, i);
- first = false;
- ++modifiedRegisters;
- }
- }
- *p++ = '\n';
- }
- *p = 0;
-
- logger->logFormat("; Modified registers (%u):\n", static_cast<unsigned>(modifiedRegisters));
- logger->logString(_buf);
-
- logger->logString("\n");
-}
-
-void X86CompilerFuncDecl::_emitProlog(CompilerContext &cc)
-{
- X86Compiler *x86Compiler = this->getCompiler();
-
- // --------------------------------------------------------------------------
- // [Init]
- // --------------------------------------------------------------------------
-
- uint32_t i, mask;
- uint32_t preservedGP = this->_gpModifiedAndPreserved;
- uint32_t preservedMM = this->_mmModifiedAndPreserved;
- uint32_t preservedXMM = this->_xmmModifiedAndPreserved;
-
- int32_t stackOffset = this->_getRequiredStackOffset();
- int32_t stackPos;
-
- // --------------------------------------------------------------------------
- // [Prolog]
- // --------------------------------------------------------------------------
-
- if (x86Compiler->getLogger())
- x86Compiler->comment("Prolog");
-
- // Emit standard prolog entry code (but don't do it if function is set to be
- // naked).
- //
- // Also see the _prologEpilogStackAdjust variable. If function is naked (so
- // prolog and epilog will not contain "push ebp" and "mov ebp, esp", we need
- // to adjust stack by 8 bytes in 64-bit mode (this will give us that stack
- // will remain aligned to 16 bytes).
- if (!this->isNaked())
- {
- x86Compiler->emit(kX86InstPush, zbp);
- x86Compiler->emit(kX86InstMov, zbp, zsp);
- }
-
- // Align manually stack-pointer to 16-bytes.
- if (this->isPerformed16ByteAlignment())
- {
- ASMJIT_ASSERT(!this->isNaked());
- x86Compiler->emit(kX86InstAnd, zsp, imm(-16));
- }
-
- // --------------------------------------------------------------------------
- // [Save Gp - Push/Pop]
- // --------------------------------------------------------------------------
-
- if (preservedGP && this->hasFuncFlag(kX86FuncFlagPushPop))
- {
- for (i = 0, mask = 1; i < kX86RegNumGp; ++i, mask <<= 1)
- if (preservedGP & mask)
- x86Compiler->emit(kX86InstPush, gpz(i));
- }
-
- // --------------------------------------------------------------------------
- // [Adjust Scack]
- // --------------------------------------------------------------------------
-
- if (this->isEspAdjusted())
- {
- stackPos = this->_memStackSize16 + this->_funcCallStackSize;
- if (stackOffset)
- x86Compiler->emit(kX86InstSub, zsp, imm(stackOffset));
- }
- else
- {
- stackPos = -(this->_peMovStackSize + this->_peAdjustStackSize);
- //if (this->_pePushPop)
- //stackPos += IntUtil::bitCount(preservedGP) * sizeof(sysint_t);
- }
-
- // --------------------------------------------------------------------------
- // [Save Xmm - MovDqa/MovDqu]
- // --------------------------------------------------------------------------
-
- if (preservedXMM)
- {
- for (i = 0, mask = 1; i < kX86RegNumXmm; ++i, mask <<= 1)
- {
- if (preservedXMM & mask)
- {
- x86Compiler->emit(_movDqInstCode, dqword_ptr(zsp, stackPos), xmm(i));
- stackPos += 16;
- }
- }
- }
-
- // --------------------------------------------------------------------------
- // [Save Mm - MovQ]
- // --------------------------------------------------------------------------
-
- if (preservedMM)
- {
- for (i = 0, mask = 1; i < 8; ++i, mask <<= 1)
- {
- if (preservedMM & mask)
- {
- x86Compiler->emit(kX86InstMovQ, qword_ptr(zsp, stackPos), mm(i));
- stackPos += 8;
- }
- }
- }
-
- // --------------------------------------------------------------------------
- // [Save Gp - Mov]
- // --------------------------------------------------------------------------
-
- if (preservedGP && !this->hasFuncFlag(kX86FuncFlagPushPop))
- {
- for (i = 0, mask = 1; i < kX86RegNumGp; ++i, mask <<= 1)
- {
- if (preservedGP & mask)
- {
- x86Compiler->emit(kX86InstMov, sysint_ptr(zsp, stackPos), gpz(i));
- stackPos += sizeof(sysint_t);
- }
- }
- }
-
- // --------------------------------------------------------------------------
- // [...]
- // --------------------------------------------------------------------------
-
- if (x86Compiler->getLogger())
- x86Compiler->comment("Body");
-}
-
-void X86CompilerFuncDecl::_emitEpilog(CompilerContext &cc)
-{
- X86Compiler *x86Compiler = this->getCompiler();
-
- const X86CpuInfo *cpuInfo = X86CpuInfo::getGlobal();
-
- // --------------------------------------------------------------------------
- // [Init]
- // --------------------------------------------------------------------------
-
- uint32_t i, mask;
- uint32_t preservedGP = this->_gpModifiedAndPreserved;
- uint32_t preservedMM = this->_mmModifiedAndPreserved;
- uint32_t preservedXMM = this->_xmmModifiedAndPreserved;
-
- int32_t stackOffset = this->_getRequiredStackOffset();
- int32_t stackPos;
-
- if (this->isEspAdjusted())
- stackPos = this->_memStackSize16 + this->_funcCallStackSize;
- else
- stackPos = -(this->_peMovStackSize + this->_peAdjustStackSize);
-
- // --------------------------------------------------------------------------
- // [Epilog]
- // --------------------------------------------------------------------------
-
- if (x86Compiler->getLogger())
- x86Compiler->comment("Epilog");
-
- // --------------------------------------------------------------------------
- // [Restore Xmm - MovDqa/ModDqu]
- // --------------------------------------------------------------------------
-
- if (preservedXMM)
- {
- for (i = 0, mask = 1; i < kX86RegNumXmm; ++i, mask <<= 1)
- {
- if (preservedXMM & mask)
- {
- x86Compiler->emit(_movDqInstCode, xmm(i), dqword_ptr(zsp, stackPos));
- stackPos += 16;
- }
- }
- }
-
- // --------------------------------------------------------------------------
- // [Restore Mm - MovQ]
- // --------------------------------------------------------------------------
-
- if (preservedMM)
- {
- for (i = 0, mask = 1; i < 8; ++i, mask <<= 1)
- {
- if (preservedMM & mask)
- {
- x86Compiler->emit(kX86InstMovQ, mm(i), qword_ptr(zsp, stackPos));
- stackPos += 8;
- }
- }
- }
-
- // --------------------------------------------------------------------------
- // [Restore Gp - Mov]
- // --------------------------------------------------------------------------
-
- if (preservedGP && !this->hasFuncFlag(kX86FuncFlagPushPop))
- {
- for (i = 0, mask = 1; i < kX86RegNumGp; ++i, mask <<= 1)
- {
- if (preservedGP & mask)
- {
- x86Compiler->emit(kX86InstMov, gpz(i), sysint_ptr(zsp, stackPos));
- stackPos += sizeof(sysint_t);
- }
- }
- }
-
- // --------------------------------------------------------------------------
- // [Adjust Stack]
- // --------------------------------------------------------------------------
-
- if (this->isEspAdjusted() && stackOffset)
- x86Compiler->emit(kX86InstAdd, zsp, imm(stackOffset));
-
- // --------------------------------------------------------------------------
- // [Restore Gp - Push/Pop]
- // --------------------------------------------------------------------------
-
- if (preservedGP && this->hasFuncFlag(kX86FuncFlagPushPop))
- {
- for (i = kX86RegNumGp - 1, mask = 1 << i; static_cast<int32_t>(i) >= 0; --i, mask >>= 1)
- if (preservedGP & mask)
- x86Compiler->emit(kX86InstPop, gpz(i));
- }
-
- // --------------------------------------------------------------------------
- // [Emms]
- // --------------------------------------------------------------------------
-
- if (this->hasFuncFlag(kX86FuncFlagEmitEmms))
- x86Compiler->emit(kX86InstEmms);
-
- // --------------------------------------------------------------------------
- // [MFence/SFence/LFence]
- // --------------------------------------------------------------------------
-
- if (this->hasFuncFlag(kX86FuncFlagEmitSFence) && this->hasFuncFlag(kX86FuncFlagEmitLFence))
- x86Compiler->emit(kX86InstMFence);
- else if (this->hasFuncFlag(kX86FuncFlagEmitSFence))
- x86Compiler->emit(kX86InstSFence);
- else if (this->hasFuncFlag(kX86FuncFlagEmitLFence))
- x86Compiler->emit(kX86InstLFence);
-
- // --------------------------------------------------------------------------
- // [Epilog]
- // --------------------------------------------------------------------------
-
- // Emit standard epilog leave code (if needed).
- if (!this->isNaked())
- {
- // AMD seems to prefer LEAVE instead of MOV/POP sequence.
- if (cpuInfo->getVendorId() == kCpuAmd)
- x86Compiler->emit(kX86InstLeave);
- else
- {
- x86Compiler->emit(kX86InstMov, zsp, zbp);
- x86Compiler->emit(kX86InstPop, zbp);
- }
- }
-
- // Emit return.
- if (this->_x86Decl.getCalleePopsStack())
- x86Compiler->emit(kX86InstRet, imm(static_cast<int16_t>(this->_x86Decl.getArgumentsStackSize())));
- else
- x86Compiler->emit(kX86InstRet);
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncDecl - Function-Call]
-// ============================================================================
-
-void X86CompilerFuncDecl::reserveStackForFunctionCall(int32_t size)
-{
- size = IntUtil::align(size, 16);
- if (size > this->_funcCallStackSize)
- this->_funcCallStackSize = size;
- this->setFuncFlag(kFuncFlagIsCaller);
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncEnd - Construction / Destruction]
-// ============================================================================
-
-X86CompilerFuncEnd::X86CompilerFuncEnd(X86Compiler *x86Compiler, X86CompilerFuncDecl *func) : CompilerFuncEnd(x86Compiler, func)
-{
-}
-
-X86CompilerFuncEnd::~X86CompilerFuncEnd()
-{
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncEnd - Interface]
-// ============================================================================
-
-void X86CompilerFuncEnd::prepare(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- this->_offset = x86Context._currentOffset++;
-}
-
-CompilerItem *X86CompilerFuncEnd::translate(CompilerContext &cc)
-{
- this->_isTranslated = true;
- return nullptr;
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncRet - Construction / Destruction]
-// ============================================================================
-
-X86CompilerFuncRet::X86CompilerFuncRet(X86Compiler *x86Compiler, X86CompilerFuncDecl *func, const Operand *first, const Operand *second) : CompilerFuncRet(x86Compiler, func, first, second)
-{
-/*
- // TODO:?
-
- // Check whether the return value is compatible.
- uint32_t retValType = function->_x86Decl.getReturnType();
- bool valid = false;
-
- switch (retValType)
- {
- case kX86VarTypeGpd:
- case kX86VarTypeGpq:
- if ((this->_ret[0].isVar() && reinterpret_cast<const Var &>(this->_ret[0]).isGpVar()) || this->_ret[0].isImm())
- valid = true;
- break;
-
- case kX86VarTypeX87:
- case kX86VarTypeX87SS:
- case kX86VarTypeX87SD:
- if (this->_ret[0].isVar() && (reinterpret_cast<const Var &>(this->_ret[0]).isX87Var() || reinterpret_cast<const Var &>(this->_ret[0]).isXmmVar()))
- valid = true;
- break;
-
- case kX86VarTypeMm:
- break;
-
- case kVarTypeInvalid:
- if (this->_ret[0].isNone() && this->_ret[1].isNone())
- valid = true;
- }
-
- // Incompatible return value.
- if (!valid)
- c->setError(kErrorIncompatibleReturnType);
-*/
-}
-
-X86CompilerFuncRet::~X86CompilerFuncRet()
-{
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncRet - Interface]
-// ============================================================================
-
-void X86CompilerFuncRet::prepare(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- X86Compiler *x86Compiler = x86Context.getCompiler();
-
- uint32_t retValType = this->getFunc()->_x86Decl.getReturnType();
- this->_offset = x86Context._currentOffset;
-
- if (retValType != kVarTypeInvalid)
- {
- uint32_t i;
- for (i = 0; i < 2; ++i)
- {
- Operand &o = this->_ret[i];
-
- if (o.isVar())
- {
- ASMJIT_ASSERT(o.getId() != kInvalidValue);
- X86CompilerVar *cv = x86Compiler->_getVar(o.getId());
- ASMJIT_ASSERT(cv);
-
- // First item (begin of variable scope).
- if (!cv->firstItem)
- cv->firstItem = this;
-
- // Last item (end of variable scope).
- cv->lastItem = this;
-
- if (cv->workOffset == _offset)
- continue;
- if (!x86Context._isActive(cv))
- x86Context._addActive(cv);
-
- cv->workOffset = this->_offset;
- ++cv->regReadCount;
-
- if (X86Util::isVarTypeInt(cv->getType()) && X86Util::isVarTypeInt(retValType))
- x86Context._newRegisterHomeIndex(cv, !i ? kX86RegIndexEax : kX86RegIndexEdx);
- }
- }
- }
-
- ++x86Context._currentOffset;
-}
-
-CompilerItem *X86CompilerFuncRet::translate(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- X86Compiler *x86Compiler = x86Context.getCompiler();
-
- // Check whether the return value is compatible.
- uint32_t retValType = this->getFunc()->getDecl()->getReturnType();
- uint32_t i;
-
- switch (retValType)
- {
- case kX86VarTypeGpd:
- case kX86VarTypeGpq:
- for (i = 0; i < 2; ++i)
- {
- uint32_t dstIndex = !i ? kX86RegIndexEax : kX86RegIndexEdx;
- uint32_t srcIndex;
-
- if (this->_ret[i].isVar())
- {
- if (reinterpret_cast<const Var &>(this->_ret[i]).isGpVar())
- {
- X86CompilerVar *cv = x86Compiler->_getVar(this->_ret[i].getId());
- ASMJIT_ASSERT(cv);
-
- srcIndex = cv->regIndex;
- if (srcIndex == kRegIndexInvalid)
- x86Compiler->emit(kX86InstMov, gpz(dstIndex), x86Context._getVarMem(cv));
- else if (dstIndex != srcIndex)
- x86Compiler->emit(kX86InstMov, gpz(dstIndex), gpz(srcIndex));
- }
- }
- else if (this->_ret[i].isImm())
- x86Compiler->emit(kX86InstMov, gpz(dstIndex), this->_ret[i]);
- }
- break;
-
- case kX86VarTypeX87:
- case kX86VarTypeX87SS:
- case kX86VarTypeX87SD:
- // There is case that we need to return two values (Unix-ABI specific):
- // - FLD #2
- //- FLD #1
- i = 2;
- do
- {
- --i;
- uint32_t srci;
-
- if (this->_ret[i].isVar())
- {
- if (reinterpret_cast<const Var &>(this->_ret[i]).isX87Var())
- {
- // TODO: X87 Support.
- }
- else if (reinterpret_cast<const Var &>(this->_ret[i]).isXmmVar())
- {
- X86CompilerVar *cv = x86Compiler->_getVar(this->_ret[i].getId());
- ASMJIT_ASSERT(cv);
-
- srci = cv->regIndex;
- if (srci != kRegIndexInvalid)
- x86Context.saveXmmVar(cv);
-
- switch (cv->getType())
- {
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- x86Compiler->emit(kX86InstFLd, _BaseVarMem(reinterpret_cast<Var &>(this->_ret[i]), 4));
- break;
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstFLd, _BaseVarMem(reinterpret_cast<Var &>(this->_ret[i]), 8));
- }
- }
- }
- } while (i);
- break;
-
- case kX86VarTypeMm:
- for (i = 0; i < 2; ++i)
- {
- uint32_t dsti = i;
- uint32_t srci;
-
- if (this->_ret[i].isVar())
- {
- if (reinterpret_cast<const Var &>(this->_ret[i]).isGpVar())
- {
- X86CompilerVar *cv = x86Compiler->_getVar(this->_ret[i].getId());
- ASMJIT_ASSERT(cv);
-
- srci = cv->regIndex;
- uint32_t inst = this->_ret[i].isRegType(kX86RegTypeGpq) ? kX86InstMovQ : kX86InstMovD;
-
- if (srci == kRegIndexInvalid)
- x86Compiler->emit(inst, mm(dsti), x86Context._getVarMem(cv));
- else
-#ifdef ASMJIT_X86
- x86Compiler->emit(inst, mm(dsti), gpd(srci));
-#else
- x86Compiler->emit(inst, mm(dsti), this->_ret[i].isRegType(kX86RegTypeGpq) ? gpq(srci) : gpd(srci));
-#endif
- }
- else if (reinterpret_cast<const Var &>(this->_ret[i]).isMmVar())
- {
- X86CompilerVar *cv = x86Compiler->_getVar(this->_ret[i].getId());
- ASMJIT_ASSERT(cv);
-
- srci = cv->regIndex;
- uint32_t inst = kX86InstMovQ;
-
- if (srci == kRegIndexInvalid)
- x86Compiler->emit(inst, mm(dsti), x86Context._getVarMem(cv));
- else if (dsti != srci)
- x86Compiler->emit(inst, mm(dsti), mm(srci));
- }
- else if (reinterpret_cast<const Var &>(this->_ret[i]).isXmmVar())
- {
- X86CompilerVar *cv = x86Compiler->_getVar(this->_ret[i].getId());
- ASMJIT_ASSERT(cv);
-
- srci = cv->regIndex;
- uint32_t inst = kX86InstMovQ;
- if (reinterpret_cast<const Var &>(this->_ret[i]).getVarType() == kX86VarTypeXmmSS)
- inst = kX86InstMovD;
-
- if (srci == kRegIndexInvalid)
- x86Compiler->emit(inst, mm(dsti), x86Context._getVarMem(cv));
- else
- x86Compiler->emit(inst, mm(dsti), xmm(srci));
- }
- }
- }
- break;
-
- case kX86VarTypeXmm:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmPD:
- for (i = 0; i < 2; ++i)
- {
- uint32_t dsti = i;
- uint32_t srci;
-
- if (this->_ret[i].isVar())
- {
- if (reinterpret_cast<const Var &>(this->_ret[i]).isGpVar())
- {
- X86CompilerVar *cv = x86Compiler->_getVar(this->_ret[i].getId());
- ASMJIT_ASSERT(cv);
-
- srci = cv->regIndex;
- uint32_t inst = this->_ret[i].isRegType(kX86RegTypeGpq) ? kX86InstMovQ : kX86InstMovD;
-
- if (srci == kRegIndexInvalid)
- x86Compiler->emit(inst, xmm(dsti), x86Context._getVarMem(cv));
- else
-#ifdef ASMJIT_X86
- x86Compiler->emit(inst, xmm(dsti), gpd(srci));
-#else
- x86Compiler->emit(inst, xmm(dsti), this->_ret[i].isRegType(kX86RegTypeGpq) ? gpq(srci) : gpd(srci));
-#endif
- }
- else if (reinterpret_cast<const Var &>(this->_ret[i]).isX87Var())
- {
- // TODO: X87 Support.
- }
- else if (reinterpret_cast<const Var &>(this->_ret[i]).isMmVar())
- {
- X86CompilerVar *cv = x86Compiler->_getVar(this->_ret[i].getId());
- ASMJIT_ASSERT(cv);
-
- srci = cv->regIndex;
- if (srci == kRegIndexInvalid)
- x86Compiler->emit(kX86InstMovQ, xmm(dsti), x86Context._getVarMem(cv));
- else
- x86Compiler->emit(kX86InstMovQ, xmm(dsti), mm(srci));
- }
- else if (reinterpret_cast<const Var &>(this->_ret[i]).isXmmVar())
- {
- X86CompilerVar *cv = x86Compiler->_getVar(this->_ret[i].getId());
- ASMJIT_ASSERT(cv);
-
- srci = cv->regIndex;
- if (srci == kRegIndexInvalid)
- x86Compiler->emit(kX86InstMovDQA, xmm(dsti), x86Context._getVarMem(cv));
- else if (dsti != srci)
- x86Compiler->emit(kX86InstMovDQA, xmm(dsti), xmm(srci));
- }
- }
- }
- break;
-
- case kX86VarTypeXmmSS:
- for (i = 0; i < 2; ++i)
- {
- uint32_t dsti = i;
- uint32_t srci;
-
- if (this->_ret[i].isVar())
- {
- if (reinterpret_cast<const Var &>(this->_ret[i]).isX87Var())
- {
- // TODO: X87 Support.
- }
- else if (reinterpret_cast<const Var &>(this->_ret[i]).isXmmVar())
- {
- X86CompilerVar *cv = x86Compiler->_getVar(this->_ret[i].getId());
- ASMJIT_ASSERT(cv);
-
- srci = cv->regIndex;
- switch (cv->getType())
- {
- case kX86VarTypeXmm:
- if (srci == kRegIndexInvalid)
- x86Compiler->emit(kX86InstMovDQA, xmm(dsti), x86Context._getVarMem(cv));
- else if (dsti != srci)
- x86Compiler->emit(kX86InstMovDQA, xmm(dsti), xmm(srci));
- break;
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- if (srci == kRegIndexInvalid)
- x86Compiler->emit(kX86InstMovSS, xmm(dsti), x86Context._getVarMem(cv));
- else
- x86Compiler->emit(kX86InstMovSS, xmm(dsti), xmm(srci));
- break;
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- if (srci == kRegIndexInvalid)
- x86Compiler->emit(kX86InstCvtSD2SS, xmm(dsti), x86Context._getVarMem(cv));
- else if (dsti != srci)
- x86Compiler->emit(kX86InstCvtSD2SS, xmm(dsti), xmm(srci));
- }
- }
- }
- }
- break;
-
- case kX86VarTypeXmmSD:
- for (i = 0; i < 2; ++i)
- {
- uint32_t dsti = i;
- uint32_t srci;
-
- if (this->_ret[i].isVar())
- {
- if (reinterpret_cast<const Var &>(this->_ret[i]).isX87Var())
- {
- // TODO: X87 Support.
- }
- else if (reinterpret_cast<const Var &>(this->_ret[i]).isXmmVar())
- {
- X86CompilerVar *cv = x86Compiler->_getVar(this->_ret[i].getId());
- ASMJIT_ASSERT(cv);
-
- srci = cv->regIndex;
- switch (cv->getType())
- {
- case kX86VarTypeXmm:
- if (srci == kRegIndexInvalid)
- x86Compiler->emit(kX86InstMovDQA, xmm(dsti), x86Context._getVarMem(cv));
- else if (dsti != srci)
- x86Compiler->emit(kX86InstMovDQA, xmm(dsti), xmm(srci));
- break;
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- if (srci == kRegIndexInvalid)
- x86Compiler->emit(kX86InstCvtSS2SD, xmm(dsti), x86Context._getVarMem(cv));
- else
- x86Compiler->emit(kX86InstCvtSS2SD, xmm(dsti), xmm(srci));
- break;
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- if (srci == kRegIndexInvalid)
- x86Compiler->emit(kX86InstMovSD, xmm(dsti), x86Context._getVarMem(cv));
- else
- x86Compiler->emit(kX86InstMovSD, xmm(dsti), xmm(srci));
- }
- }
- }
- }
- }
-
- if (this->mustEmitJump())
- x86Context._isUnreachable = 1;
-
- for (i = 0; i < 2; ++i)
- {
- if (this->_ret[i].isVar())
- {
- X86CompilerVar *cv = x86Compiler->_getVar(this->_ret[i].getId());
- x86Context._unuseVarOnEndOfScope(this, cv);
- }
- }
-
- return this->translated();
-}
-
-void X86CompilerFuncRet::emit(Assembler &a)
-{
- X86Assembler &x86Asm = static_cast<X86Assembler &>(a);
-
- if (this->mustEmitJump())
- x86Asm.jmp(this->getFunc()->getExitLabel());
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncRet - Misc]
-// ============================================================================
-
-int X86CompilerFuncRet::getMaxSize() const
-{
- return this->mustEmitJump() ? 15 : 0;
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncCall - Construction / Destruction]
-// ============================================================================
-
-X86CompilerFuncCall::X86CompilerFuncCall(X86Compiler *x86Compiler, X86CompilerFuncDecl *caller, const Operand *target) : CompilerFuncCall(x86Compiler, caller, target), _gpParams(0), _mmParams(0), _xmmParams(0),
- _variablesCount(0), _variables(nullptr)
-{
-}
-
-X86CompilerFuncCall::~X86CompilerFuncCall()
-{
- memset(this->_argumentToVarRecord, 0, sizeof(VarCallRecord *) * kFuncArgsMax);
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncCall - Interface]
-// ============================================================================
-
-void X86CompilerFuncCall::prepare(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- X86Compiler *x86Compiler = this->getCompiler();
-
- // Prepare is similar to X86CompilerInst::prepare(). We collect unique variables
- // and update statistics, but we don't use standard alloc/free register calls.
- //
- // The calling function is also unique in variable allocator point of view,
- // because we need to alloc some variables that may be destroyed be the
- // callee (okay, may not, but this is not guaranteed).
- this->_offset = x86Context._currentOffset;
-
- // Tell EFunction that another function will be called inside. It needs this
- // information to reserve stack for the call and to mark esp adjustable.
- this->getCaller()->reserveStackForFunctionCall(static_cast<int32_t>(this->_x86Decl.getArgumentsStackSize()));
-
- uint32_t i;
- uint32_t argumentsCount = this->_x86Decl.getArgumentsCount();
- uint32_t operandsCount = argumentsCount;
- uint32_t variablesCount = 0;
-
- // Create registers used as arguments mask.
- for (i = 0; i < argumentsCount; ++i)
- {
- const FuncArg &fArg = this->_x86Decl.getArguments()[i];
-
- if (fArg.hasRegIndex())
- {
- switch (fArg.getVarType())
- {
- case kX86VarTypeGpd:
- case kX86VarTypeGpq:
- this->_gpParams |= IntUtil::maskFromIndex(fArg.getRegIndex());
- break;
- case kX86VarTypeMm:
- this->_mmParams |= IntUtil::maskFromIndex(fArg.getRegIndex());
- break;
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- this->_xmmParams |= IntUtil::maskFromIndex(fArg.getRegIndex());
- break;
- default:
- ASMJIT_ASSERT(0);
- }
- }
- else
- x86Context.getFunc()->setFuncFlag(kX86FuncFlagIsEspAdjusted);
- }
-
- // Call address.
- ++operandsCount;
-
- // The first and the second return value.
- if (!this->_ret[0].isNone())
- ++operandsCount;
- if (!this->_ret[1].isNone())
- ++operandsCount;
-
-#define __GET_VARIABLE(__vardata__) \
-{ \
- X86CompilerVar *_candidate = __vardata__; \
-\
- for (var = cur; ; ) \
- { \
- if (var == _variables) \
- { \
- var = cur++; \
- var->vdata = _candidate; \
- break; \
- } \
-\
- --var; \
-\
- if (var->vdata == _candidate) \
- break; \
- } \
-\
- ASMJIT_ASSERT(var); \
-}
-
- for (i = 0; i < operandsCount; ++i)
- {
- Operand& o = (i < argumentsCount) ? this->_args[i] : (i == argumentsCount ? this->_target : this->_ret[i - argumentsCount - 1]);
-
- if (o.isVar())
- {
- ASMJIT_ASSERT(o.getId() != kInvalidValue);
- X86CompilerVar *cv = x86Compiler->_getVar(o.getId());
- ASMJIT_ASSERT(cv);
-
- if (cv->workOffset == this->_offset)
- continue;
- if (!x86Context._isActive(cv))
- x86Context._addActive(cv);
-
- cv->workOffset = this->_offset;
- ++variablesCount;
- }
- else if (o.isMem())
- {
- if ((o.getId() & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *cv = x86Compiler->_getVar(o.getId());
- ASMJIT_ASSERT(cv);
-
- x86Context._markMemoryUsed(cv);
- if (!x86Context._isActive(cv))
- x86Context._addActive(cv);
-
- continue;
- }
- else if ((o._mem.base & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *cv = x86Compiler->_getVar(o._mem.base);
- ASMJIT_ASSERT(cv);
-
- if (cv->workOffset == this->_offset)
- continue;
- if (!x86Context._isActive(cv))
- x86Context._addActive(cv);
-
- cv->workOffset = this->_offset;
- ++variablesCount;
- }
-
- if ((o._mem.index & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *cv = x86Compiler->_getVar(o._mem.index);
- ASMJIT_ASSERT(cv);
-
- if (cv->workOffset == this->_offset)
- continue;
- if (!x86Context._isActive(cv))
- x86Context._addActive(cv);
-
- cv->workOffset = this->_offset;
- ++variablesCount;
- }
- }
- }
-
- // Traverse all active variables and set their funcCall pointer to this
- // call. This information can be used to choose between the preserved-first
- // and preserved-last register allocation.
- if (x86Context._active)
- {
- X86CompilerVar *first = static_cast<X86CompilerVar *>(x86Context._active);
- X86CompilerVar *active = first;
- do
- {
- if (!active->funcCall)
- active->funcCall = this;
- active = active->nextActive;
- } while (active != first);
- }
-
- if (!variablesCount)
- {
- ++x86Context._currentOffset;
- return;
- }
-
- this->_variables = reinterpret_cast<VarCallRecord *>(x86Compiler->getZoneMemory().alloc(sizeof(VarCallRecord) * variablesCount));
- if (!this->_variables)
- {
- x86Compiler->setError(kErrorNoHeapMemory);
- ++x86Context._currentOffset;
- return;
- }
-
- this->_variablesCount = variablesCount;
- memset(this->_variables, 0, sizeof(VarCallRecord) * variablesCount);
-
- VarCallRecord *cur = this->_variables;
- VarCallRecord *var = nullptr;
-
- for (i = 0; i < operandsCount; ++i)
- {
- Operand &o = (i < argumentsCount) ? this->_args[i] : (i == argumentsCount ? this->_target : this->_ret[i - argumentsCount - 1]);
-
- if (o.isVar())
- {
- X86CompilerVar *cv = x86Compiler->_getVar(o.getId());
- ASMJIT_ASSERT(cv);
-
- __GET_VARIABLE(cv);
- this->_argumentToVarRecord[i] = var;
-
- if (i < argumentsCount)
- {
- const FuncArg &fArg = this->_x86Decl.getArgument(i);
-
- if (fArg.hasRegIndex())
- {
- x86Context._newRegisterHomeIndex(cv, fArg.getRegIndex());
-
- switch (fArg.getVarType())
- {
- case kX86VarTypeGpd:
- case kX86VarTypeGpq:
- var->flags |= VarCallRecord::kFlagInGp;
- ++var->inCount;
- break;
-
- case kX86VarTypeMm:
- var->flags |= VarCallRecord::kFlagInMm;
- ++var->inCount;
- break;
-
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- var->flags |= VarCallRecord::kFlagInXmm;
- ++var->inCount;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- }
- else
- ++var->inCount;
-
- ++cv->regReadCount;
- }
- else if (i == argumentsCount)
- {
- uint32_t mask = ~this->_x86Decl.getGpPreservedMask() & ~this->_x86Decl.getGpArgumentsMask() & IntUtil::maskUpToIndex(kX86RegNumGp);
-
- x86Context._newRegisterHomeIndex(cv, IntUtil::findFirstBit(mask));
- x86Context._newRegisterHomeMask(cv, mask);
-
- var->flags |= VarCallRecord::kFlagCallReg;
- ++cv->regReadCount;
- }
- else
- {
- switch (cv->getType())
- {
- case kX86VarTypeGpd:
- case kX86VarTypeGpq:
- if (i == argumentsCount+1)
- var->flags |= VarCallRecord::kFlagOutEax;
- else
- var->flags |= VarCallRecord::kFlagOutEdx;
- break;
-
- case kX86VarTypeX87:
- case kX86VarTypeX87SS:
- case kX86VarTypeX87SD:
-#ifdef ASMJIT_X86
- if (i == argumentsCount + 1)
- var->flags |= VarCallRecord::kFlagOutSt0;
- else
- var->flags |= VarCallRecord::kFlagOutSt1;
-#else
- if (i == argumentsCount + 1)
- var->flags |= VarCallRecord::kFlagOutXmm0;
- else
- var->flags |= VarCallRecord::kFlagOutXmm1;
-#endif
- break;
-
- case kX86VarTypeMm:
- var->flags |= VarCallRecord::kFlagOutMm0;
- break;
-
- case kX86VarTypeXmm:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmPD:
- if (i == argumentsCount+1)
- var->flags |= VarCallRecord::kFlagOutXmm0;
- else
- var->flags |= VarCallRecord::kFlagOutXmm1;
- break;
-
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmSD:
-#ifdef ASMJIT_X86
- if (i == argumentsCount + 1)
- var->flags |= VarCallRecord::kFlagOutSt0;
- else
- var->flags |= VarCallRecord::kFlagOutSt1;
-#else
- if (i == argumentsCount + 1)
- var->flags |= VarCallRecord::kFlagOutXmm0;
- else
- var->flags |= VarCallRecord::kFlagOutXmm1;
-#endif
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
-
- ++cv->regWriteCount;
- }
- }
- else if (o.isMem())
- {
- ASMJIT_ASSERT(i == argumentsCount);
-
- if ((o.getId() & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *cv = x86Compiler->_getVar(o.getId());
- ASMJIT_ASSERT(cv);
-
- ++cv->memReadCount;
- }
- else if ((o._mem.base & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *cv = x86Compiler->_getVar(reinterpret_cast<Mem &>(o).getBase());
- ASMJIT_ASSERT(cv);
-
- ++cv->regReadCount;
-
- __GET_VARIABLE(cv);
- var->flags |= VarCallRecord::kFlagCallReg | VarCallRecord::kFlagCallMem;
- }
-
- if ((o._mem.index & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *cv = x86Compiler->_getVar(reinterpret_cast<Mem &>(o).getIndex());
- ASMJIT_ASSERT(cv);
-
- ++cv->regReadCount;
-
- __GET_VARIABLE(cv);
- var->flags |= VarCallRecord::kFlagCallReg | VarCallRecord::kFlagCallMem;
- }
- }
- }
-
- // Traverse all variables and update firstItem / lastItem. This
- // function is called from iterator that scans items using forward
- // direction so we can use this knowledge to optimize the process.
- //
- // Same code is in X86CompilerInst::prepare().
- for (i = 0; i < this->_variablesCount; ++i)
- {
- X86CompilerVar *v = this->_variables[i].vdata;
-
- // First item (begin of variable scope).
- if (!v->firstItem)
- v->firstItem = this;
-
- // Last item (end of variable scope).
- v->lastItem = this;
- }
-
- ++x86Context._currentOffset;
-
-#undef __GET_VARIABLE
-}
-
-CompilerItem *X86CompilerFuncCall::translate(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- X86Compiler *x86Compiler = x86Context.getCompiler();
-
- uint32_t i;
- uint32_t preserved, mask;
-
- uint32_t temporaryGpReg;
- uint32_t temporaryXmmReg;
-
- uint32_t offset = x86Context._currentOffset;
-
- // Constants.
- const FuncArg *targs = this->_x86Decl.getArguments();
-
- uint32_t argumentsCount = this->_x86Decl.getArgumentsCount();
- uint32_t variablesCount = this->_variablesCount;
-
- // Processed arguments kFuncArgsMax.
- uint8_t processed[kFuncArgsMax] = { 0 };
-
- x86Compiler->comment("Call");
-
- // These variables are used by the instruction so we set current offset
- // to their work offsets -> The getSpillCandidate() method never returns
- // the variable used by this instruction.
- for (i = 0; i < variablesCount; ++i)
- {
- this->_variables[i].vdata->workOffset = offset;
-
- // Init back-reference to VarCallRecord.
- this->_variables[i].vdata->tPtr = &this->_variables[i];
- }
-
- // --------------------------------------------------------------------------
- // STEP 1:
- //
- // Spill variables which are not used by the function call and have to
- // be destroyed. These registers may be used by callee.
- // --------------------------------------------------------------------------
-
- preserved = this->_x86Decl.getGpPreservedMask();
- for (i = 0, mask = 1; i < kX86RegNumGp; ++i, mask <<= 1)
- {
- X86CompilerVar *cv = x86Context._x86State.gp[i];
- if (cv && cv->workOffset != offset && !(preserved & mask))
- x86Context.spillGpVar(cv);
- }
-
- preserved = this->_x86Decl.getMmPreservedMask();
- for (i = 0, mask = 1; i < kX86RegNumMm; ++i, mask <<= 1)
- {
- X86CompilerVar *cv = x86Context._x86State.mm[i];
- if (cv && cv->workOffset != offset && !(preserved & mask))
- x86Context.spillMmVar(cv);
- }
-
- preserved = this->_x86Decl.getXmmPreservedMask();
- for (i = 0, mask = 1; i < kX86RegNumXmm; ++i, mask <<= 1)
- {
- X86CompilerVar *cv = x86Context._x86State.xmm[i];
- if (cv && cv->workOffset != offset && !(preserved & mask))
- x86Context.spillXmmVar(cv);
- }
-
- // --------------------------------------------------------------------------
- // STEP 2:
- //
- // Move all arguments to the stack which all already in registers.
- // --------------------------------------------------------------------------
-
- for (i = 0; i < argumentsCount; ++i)
- {
- if (processed[i])
- continue;
-
- const FuncArg &argType = targs[i];
- if (argType.hasRegIndex())
- continue;
-
- Operand &operand = this->_args[i];
-
- if (operand.isVar())
- {
- VarCallRecord *rec = this->_argumentToVarRecord[i];
- X86CompilerVar *cv = x86Compiler->_getVar(operand.getId());
-
- if (cv->regIndex != kRegIndexInvalid)
- {
- this->_moveAllocatedVariableToStack(cc, cv, argType);
-
- ++rec->inDone;
- processed[i] = true;
- }
- }
- }
-
- // --------------------------------------------------------------------------
- // STEP 3:
- //
- // Spill all non-preserved variables we moved to stack in STEP #2.
- // --------------------------------------------------------------------------
-
- for (i = 0; i < argumentsCount; ++i)
- {
- VarCallRecord *rec = this->_argumentToVarRecord[i];
- if (!rec || processed[i])
- continue;
-
- if (rec->inDone >= rec->inCount)
- {
- X86CompilerVar *cv = rec->vdata;
- if (cv->regIndex == kRegIndexInvalid)
- continue;
-
- if (rec->outCount)
- // Variable will be rewritten by function return value, it's not needed
- // to spill it. It will be allocated again by X86CompilerFuncCall.
- x86Context.unuseVar(rec->vdata, kVarStateUnused);
- else
- {
- switch (cv->getType())
- {
- case kX86VarTypeGpd:
- case kX86VarTypeGpq:
- if (!(this->_x86Decl.getGpPreservedMask() & IntUtil::maskFromIndex(cv->regIndex)))
- x86Context.spillGpVar(cv);
- break;
- case kX86VarTypeMm:
- if (!(this->_x86Decl.getMmPreservedMask() & IntUtil::maskFromIndex(cv->regIndex)))
- x86Context.spillMmVar(cv);
- break;
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmPD:
- if (!(this->_x86Decl.getXmmPreservedMask() & IntUtil::maskFromIndex(cv->regIndex)))
- x86Context.spillXmmVar(cv);
- }
- }
- }
- }
-
- // --------------------------------------------------------------------------
- // STEP 4:
- //
- // Get temporary register that we can use to pass input function arguments.
- // Now it's safe to do, because the non-needed variables should be spilled.
- // --------------------------------------------------------------------------
-
- temporaryGpReg = this->_findTemporaryGpRegister(cc);
- temporaryXmmReg = this->_findTemporaryXmmRegister(cc);
-
- // If failed to get temporary register then we need just to pick one.
- if (temporaryGpReg == kRegIndexInvalid)
- {
- // TODO.
- }
- if (temporaryXmmReg == kRegIndexInvalid)
- {
- // TODO.
- }
-
- // --------------------------------------------------------------------------
- // STEP 5:
- //
- // Move all remaining arguments to the stack (we can use temporary register).
- // or allocate it to the primary register. Also move immediates.
- // --------------------------------------------------------------------------
-
- for (i = 0; i < argumentsCount; ++i)
- {
- if (processed[i])
- continue;
-
- const FuncArg &argType = targs[i];
-
- if (argType.hasRegIndex())
- continue;
-
- Operand &operand = this->_args[i];
-
- if (operand.isVar())
- {
- VarCallRecord *rec = this->_argumentToVarRecord[i];
- X86CompilerVar *cv = x86Compiler->_getVar(operand.getId());
-
- this->_moveSpilledVariableToStack(cc, cv, argType, temporaryGpReg, temporaryXmmReg);
-
- ++rec->inDone;
- processed[i] = true;
- }
- else if (operand.isImm())
- {
- // TODO.
- }
- }
-
- // --------------------------------------------------------------------------
- // STEP 6:
- //
- // Allocate arguments to registers.
- // --------------------------------------------------------------------------
-
- bool didWork;
-
- do
- {
- didWork = false;
-
- for (i = 0; i < argumentsCount; ++i)
- {
- if (processed[i])
- continue;
-
- VarCallRecord *rsrc = this->_argumentToVarRecord[i];
-
- Operand &osrc = this->_args[i];
- ASMJIT_ASSERT(osrc.isVar());
- X86CompilerVar *vsrc = x86Compiler->_getVar(osrc.getId());
-
- const FuncArg &srcArgType = targs[i];
- X86CompilerVar *vdst = this->_getOverlappingVariable(cc, srcArgType);
-
- if (vsrc == vdst)
- {
- ++rsrc->inDone;
- processed[i] = true;
-
- didWork = true;
- continue;
- }
- else if (vdst)
- {
- VarCallRecord *rdst = reinterpret_cast<VarCallRecord *>(vdst->tPtr);
-
- if (!rdst)
- {
- x86Context.spillVar(vdst);
- vdst = nullptr;
- }
- else if (rdst->inDone >= rdst->inCount && !(rdst->flags & VarCallRecord::kFlagCallReg))
- {
- // Safe to spill.
- if (rdst->outCount || vdst->lastItem == this)
- x86Context.unuseVar(vdst, kVarStateUnused);
- else
- x86Context.spillVar(vdst);
- vdst = nullptr;
- }
- else
- {
- uint32_t x = this->_x86Decl.findArgumentByRegCode(X86Util::getRegCodeFromVarType(vsrc->getType(), vsrc->regIndex));
- bool doSpill = true;
-
- if (vdst->getClass() & kX86VarClassGp)
- {
- // Try to emit mov to register which is possible for call() operand.
- if (x == kInvalidValue && (rdst->flags & VarCallRecord::kFlagCallReg))
- {
- uint32_t rIndex;
- uint32_t rBit;
-
- // The mask which contains registers which are not-preserved
- // (these that might be clobbered by the callee) and which are
- // not used to pass function arguments. Each register contained
- // in this mask is ideal to be used by call() instruction.
- uint32_t possibleMask = ~this->_x86Decl.getGpPreservedMask() & ~this->_x86Decl.getGpArgumentsMask() & IntUtil::maskUpToIndex(kX86RegNumGp);
-
- if (possibleMask)
- {
- for (rIndex = 0, rBit = 1; rIndex < kX86RegNumGp; ++rIndex, rBit <<= 1)
- {
- if (possibleMask & rBit)
- {
- if (!x86Context._x86State.gp[rIndex])
- // This is the best possible solution, the register is
- // free. We do not need to continue with this loop, the
- // rIndex will be used by the call().
- break;
- else
- {
- // Wait until the register is freed or try to find another.
- doSpill = false;
- didWork = true;
- }
- }
- }
- }
- else
- {
- // Try to find a register which is free and which is not used
- // to pass a function argument.
- possibleMask = this->_x86Decl.getGpPreservedMask();
-
- for (rIndex = 0, rBit = 1; rIndex < kX86RegNumGp; ++rIndex, rBit <<= 1)
- {
- if (possibleMask & rBit)
- {
- // Found one.
- if (!x86Context._x86State.gp[rIndex])
- break;
- }
- }
- }
-
- if (rIndex < kX86RegNumGp)
- {
- if (temporaryGpReg == vsrc->regIndex)
- temporaryGpReg = rIndex;
- x86Compiler->emit(kX86InstMov, gpz(rIndex), gpz(vsrc->regIndex));
-
- x86Context._x86State.gp[vsrc->regIndex] = nullptr;
- x86Context._x86State.gp[rIndex] = vsrc;
-
- vsrc->regIndex = rIndex;
- x86Context._allocatedGpRegister(rIndex);
-
- doSpill = false;
- didWork = true;
- }
- }
- // Emit xchg instead of spill/alloc if possible.
- else if (x != kInvalidValue)
- {
- const FuncArg &dstArgType = targs[x];
- if (X86Util::getVarClassFromVarType(dstArgType.getVarType()) == X86Util::getVarClassFromVarType(srcArgType.getVarType()))
- {
- uint32_t dstIndex = vdst->regIndex;
- uint32_t srcIndex = vsrc->regIndex;
-
- if (srcIndex == dstArgType.getRegIndex())
- {
-#ifdef ASMJIT_X64
- if (vdst->getType() != kX86VarTypeGpd || vsrc->getType() != kX86VarTypeGpd)
- x86Compiler->emit(kX86InstXchg, gpq(dstIndex), gpq(srcIndex));
- else
-#endif
- x86Compiler->emit(kX86InstXchg, gpd(dstIndex), gpd(srcIndex));
-
- x86Context._x86State.gp[srcIndex] = vdst;
- x86Context._x86State.gp[dstIndex] = vsrc;
-
- vdst->regIndex = srcIndex;
- vsrc->regIndex = dstIndex;
-
- ++rdst->inDone;
- ++rsrc->inDone;
-
- processed[i] = true;
- processed[x] = true;
-
- doSpill = false;
- }
- }
- }
- }
-
- if (doSpill)
- {
- x86Context.spillVar(vdst);
- vdst = nullptr;
- }
- }
- }
-
- if (!vdst)
- {
- VarCallRecord *rec = reinterpret_cast<VarCallRecord *>(vsrc->tPtr);
-
- this->_moveSrcVariableToRegister(cc, vsrc, srcArgType);
-
- switch (srcArgType.getVarType())
- {
- case kX86VarTypeGpd:
- case kX86VarTypeGpq:
- x86Context._markGpRegisterModified(srcArgType.getRegIndex());
- break;
- case kX86VarTypeMm:
- x86Context._markMmRegisterModified(srcArgType.getRegIndex());
- break;
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmPD:
- x86Context._markMmRegisterModified(srcArgType.getRegIndex());
- }
-
- ++rec->inDone;
- processed[i] = true;
- }
- }
- } while (didWork);
-
- // --------------------------------------------------------------------------
- // STEP 7:
- //
- // Allocate operand used by CALL instruction.
- // --------------------------------------------------------------------------
-
- for (i = 0; i < variablesCount; ++i)
- {
- VarCallRecord &r = this->_variables[i];
- if ((r.flags & VarCallRecord::kFlagCallReg) && r.vdata->regIndex == kRegIndexInvalid)
- {
- // If the register is not allocated and the call form is 'call reg' then
- // it's possible to keep it in memory.
- if (!(r.flags & VarCallRecord::kFlagCallMem))
- {
- this->_target = r.vdata->asGpVar().m();
- break;
- }
-
- if (temporaryGpReg == kRegIndexInvalid)
- temporaryGpReg = this->_findTemporaryGpRegister(cc);
-
- x86Context.allocGpVar(r.vdata, IntUtil::maskFromIndex(temporaryGpReg), kVarAllocRegister | kVarAllocRead);
- }
- }
-
- x86Context.translateOperands(&this->_target, 1);
-
- // --------------------------------------------------------------------------
- // STEP 8:
- //
- // Spill all preserved variables.
- // --------------------------------------------------------------------------
-
- preserved = this->_x86Decl.getGpPreservedMask();
- for (i = 0, mask = 1; i < kX86RegNumGp; ++i, mask <<= 1)
- {
- X86CompilerVar *vdata = x86Context._x86State.gp[i];
- if (vdata && !(preserved & mask))
- {
- VarCallRecord *rec = reinterpret_cast<VarCallRecord *>(vdata->tPtr);
- if (rec && (rec->outCount || rec->flags & VarCallRecord::kFlagUnuseAfterUse || vdata->lastItem == this))
- x86Context.unuseVar(vdata, kVarStateUnused);
- else
- x86Context.spillGpVar(vdata);
- }
- }
-
- preserved = this->_x86Decl.getMmPreservedMask();
- for (i = 0, mask = 1; i < kX86RegNumMm; ++i, mask <<= 1)
- {
- X86CompilerVar *vdata = x86Context._x86State.mm[i];
- if (vdata && !(preserved & mask))
- {
- VarCallRecord *rec = reinterpret_cast<VarCallRecord *>(vdata->tPtr);
- if (rec && (rec->outCount || vdata->lastItem == this))
- x86Context.unuseVar(vdata, kVarStateUnused);
- else
- x86Context.spillMmVar(vdata);
- }
- }
-
- preserved = this->_x86Decl.getXmmPreservedMask();
- for (i = 0, mask = 1; i < kX86RegNumXmm; ++i, mask <<= 1)
- {
- X86CompilerVar *vdata = x86Context._x86State.xmm[i];
- if (vdata && !(preserved & mask))
- {
- VarCallRecord *rec = reinterpret_cast<VarCallRecord *>(vdata->tPtr);
- if (rec && (rec->outCount || vdata->lastItem == this))
- x86Context.unuseVar(vdata, kVarStateUnused);
- else
- x86Context.spillXmmVar(vdata);
- }
- }
-
- // --------------------------------------------------------------------------
- // STEP 9:
- //
- // Emit CALL instruction.
- // --------------------------------------------------------------------------
-
- x86Compiler->emit(kX86InstCall, this->_target);
-
- // Restore the stack offset.
- if (this->_x86Decl.getCalleePopsStack())
- {
- int32_t s = static_cast<int32_t>(this->_x86Decl.getArgumentsStackSize());
-
- if (s)
- x86Compiler->emit(kX86InstSub, zsp, imm(s));
- }
-
- // --------------------------------------------------------------------------
- // STEP 10:
- //
- // Prepare others for return value(s) and cleanup.
- // --------------------------------------------------------------------------
-
- // Clear temp data, see AsmJit::X86CompilerVar::temp why it's needed.
- for (i = 0; i < variablesCount; ++i)
- {
- VarCallRecord *rec = &this->_variables[i];
- X86CompilerVar *vdata = rec->vdata;
-
- if (rec->flags & (VarCallRecord::kFlagOutEax | VarCallRecord::kFlagOutEdx))
- {
- if (vdata->getClass() & kX86VarClassGp)
- {
- x86Context.allocGpVar(vdata, IntUtil::maskFromIndex((rec->flags & VarCallRecord::kFlagOutEax) ? kX86RegIndexEax : kX86RegIndexEdx), kVarAllocRegister | kVarAllocWrite);
- vdata->changed = true;
- }
- }
-
- if (rec->flags & VarCallRecord::kFlagOutMm0)
- {
- if (vdata->getClass() & kX86VarClassMm)
- {
- x86Context.allocMmVar(vdata, IntUtil::maskFromIndex(kX86RegIndexMm0), kVarAllocRegister | kVarAllocWrite);
- vdata->changed = true;
- }
- }
-
- if (rec->flags & (VarCallRecord::kFlagOutXmm0 | VarCallRecord::kFlagOutXmm1))
- {
- if (vdata->getClass() & kX86VarClassXmm)
- {
- x86Context.allocXmmVar(vdata, IntUtil::maskFromIndex((rec->flags & VarCallRecord::kFlagOutXmm0) ? kX86RegIndexXmm0 : kX86RegIndexXmm1), kVarAllocRegister | kVarAllocWrite);
- vdata->changed = true;
- }
- }
-
- if (rec->flags & (VarCallRecord::kFlagOutSt0 | VarCallRecord::kFlagOutSt1))
- {
- if (vdata->getClass() & kX86VarClassXmm)
- {
- Mem mem(x86Context._getVarMem(vdata));
- x86Context.unuseVar(vdata, kVarStateMem);
-
- switch (vdata->getType())
- {
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- mem.setSize(4);
- x86Compiler->emit(kX86InstFStP, mem);
- break;
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- mem.setSize(8);
- x86Compiler->emit(kX86InstFStP, mem);
- break;
- default:
- x86Compiler->comment("*** WARNING: Can't convert float return value to untyped XMM\n");
- }
- }
- }
-
- // Cleanup.
- vdata->tPtr = nullptr;
- }
-
- for (i = 0; i < variablesCount; ++i)
- x86Context._unuseVarOnEndOfScope(this, &this->_variables[i]);
-
- return this->translated();
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncCall - Misc]
-// ============================================================================
-
-int X86CompilerFuncCall::getMaxSize() const
-{
- // TODO: Instruction max size.
- return 15;
-}
-
-bool X86CompilerFuncCall::_tryUnuseVar(CompilerVar *_v)
-{
- X86CompilerVar *cv = static_cast<X86CompilerVar *>(_v);
-
- for (uint32_t i = 0; i < this->_variablesCount; ++i)
- if (this->_variables[i].vdata == cv)
- {
- this->_variables[i].flags |= VarCallRecord::kFlagUnuseAfterUse;
- return true;
- }
-
- return false;
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncCall - Helpers]
-// ============================================================================
-
-uint32_t X86CompilerFuncCall::_findTemporaryGpRegister(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
-
- uint32_t i;
- uint32_t mask;
-
- uint32_t passedGP = this->_x86Decl.getGpArgumentsMask();
- uint32_t candidate = kRegIndexInvalid;
-
- // Find all registers used to pass function arguments. We shouldn't use these
- // if possible.
- for (i = 0, mask = 1; i < kX86RegNumGp; ++i, mask <<= 1)
- {
- if (!x86Context._x86State.gp[i])
- {
- // If this register is used to pass arguments to function, we will mark
- // it and use it only if there is no other one.
- if (passedGP & mask)
- candidate = i;
- else
- return i;
- }
- }
-
- return candidate;
-}
-
-uint32_t X86CompilerFuncCall::_findTemporaryXmmRegister(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
-
- uint32_t i;
- uint32_t mask;
-
- uint32_t passedXMM = this->_x86Decl.getXmmArgumentsMask();
- uint32_t candidate = kRegIndexInvalid;
-
- // Find all registers used to pass function arguments. We shouldn't use these
- // if possible.
- for (i = 0, mask = 1; i < kX86RegNumXmm; ++i, mask <<= 1)
- {
- if (!x86Context._x86State.xmm[i])
- {
- // If this register is used to pass arguments to function, we will mark
- // it and use it only if there is no other one.
- if (passedXMM & mask)
- candidate = i;
- else
- return i;
- }
- }
-
- return candidate;
-}
-
-X86CompilerVar *X86CompilerFuncCall::_getOverlappingVariable(CompilerContext &cc, const FuncArg &argType) const
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- ASMJIT_ASSERT(argType.getVarType() != kVarTypeInvalid);
-
- switch (argType.getVarType())
- {
- case kX86VarTypeGpd:
- case kX86VarTypeGpq:
- return x86Context._x86State.gp[argType.getRegIndex()];
- case kX86VarTypeMm:
- return x86Context._x86State.mm[argType.getRegIndex()];
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmPD:
- return x86Context._x86State.xmm[argType.getRegIndex()];
- }
-
- return nullptr;
-}
-
-void X86CompilerFuncCall::_moveAllocatedVariableToStack(CompilerContext &cc, X86CompilerVar *vdata, const FuncArg &argType)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- X86Compiler *x86Compiler = x86Context.getCompiler();
-
- ASMJIT_ASSERT(!argType.hasRegIndex());
- ASMJIT_ASSERT(vdata->regIndex != kRegIndexInvalid);
-
- uint32_t src = vdata->regIndex;
- Mem dst = ptr(zsp, -static_cast<int>(sizeof(uintptr_t)) + argType.getStackOffset());
-
- switch (vdata->getType())
- {
- case kX86VarTypeGpd:
- switch (argType.getVarType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstMov, dst, gpd(src));
- return;
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMov, dst, gpq(src));
- return;
-#endif // ASMJIT_X64
- }
- break;
-
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- switch (argType.getVarType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstMov, dst, gpd(src));
- return;
- case kX86VarTypeGpq:
- x86Compiler->emit(kX86InstMov, dst, gpq(src));
- return;
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, dst, gpq(src));
- return;
- }
- break;
-#endif // ASMJIT_X64
-
- case kX86VarTypeMm:
- switch (argType.getVarType())
- {
- case kX86VarTypeGpd:
- case kX86VarTypeX87SS:
- case kX86VarTypeXmmSS:
- x86Compiler->emit(kX86InstMovD, dst, mm(src));
- return;
- case kX86VarTypeGpq:
- case kX86VarTypeMm:
- case kX86VarTypeX87SD:
- case kX86VarTypeXmmSD:
- x86Compiler->emit(kX86InstMovQ, dst, mm(src));
- return;
- }
- break;
-
- // We allow incompatible types here, because the called can convert them
- // to correct format before function is called.
-
- case kX86VarTypeXmm:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmPD:
- switch (argType.getVarType())
- {
- case kX86VarTypeXmm:
- x86Compiler->emit(kX86InstMovDQU, dst, xmm(src));
- return;
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- x86Compiler->emit(kX86InstMovUPS, dst, xmm(src));
- return;
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstMovUPD, dst, xmm(src));
- return;
- }
- break;
-
- case kX86VarTypeXmmSS:
- switch (argType.getVarType())
- {
- case kX86VarTypeX87SS:
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstMovSS, dst, xmm(src));
- return;
- }
- break;
-
- case kX86VarTypeXmmSD:
- switch (argType.getVarType())
- {
- case kX86VarTypeX87SD:
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstMovSD, dst, xmm(src));
- return;
- }
- break;
- }
-
- x86Compiler->setError(kErrorIncompatibleArgumentType);
-}
-
-void X86CompilerFuncCall::_moveSpilledVariableToStack(CompilerContext &cc, X86CompilerVar *cv, const FuncArg &argType, uint32_t temporaryGpReg, uint32_t temporaryXmmReg)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- X86Compiler *x86Compiler = x86Context.getCompiler();
-
- ASMJIT_ASSERT(!argType.hasRegIndex());
- ASMJIT_ASSERT(cv->regIndex == kRegIndexInvalid);
-
- Mem src = x86Context._getVarMem(cv);
- Mem dst = ptr(zsp, -static_cast<int>(sizeof(sysint_t)) + argType.getStackOffset());
-
- switch (cv->getType())
- {
- case kX86VarTypeGpd:
- switch (argType.getVarType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstMov, gpd(temporaryGpReg), src);
- x86Compiler->emit(kX86InstMov, dst, gpd(temporaryGpReg));
- return;
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMov, gpd(temporaryGpReg), src);
- x86Compiler->emit(kX86InstMov, dst, gpq(temporaryGpReg));
- return;
-#endif // ASMJIT_X64
- }
- break;
-
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- switch (argType.getVarType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstMov, gpd(temporaryGpReg), src);
- x86Compiler->emit(kX86InstMov, dst, gpd(temporaryGpReg));
- return;
- case kX86VarTypeGpq:
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMov, gpq(temporaryGpReg), src);
- x86Compiler->emit(kX86InstMov, dst, gpq(temporaryGpReg));
- return;
- }
- break;
-#endif // ASMJIT_X64
-
- case kX86VarTypeMm:
- switch (argType.getVarType())
- {
- case kX86VarTypeGpd:
- case kX86VarTypeX87SS:
- case kX86VarTypeXmmSS:
- x86Compiler->emit(kX86InstMov, gpd(temporaryGpReg), src);
- x86Compiler->emit(kX86InstMov, dst, gpd(temporaryGpReg));
- return;
- case kX86VarTypeGpq:
- case kX86VarTypeMm:
- case kX86VarTypeX87SD:
- case kX86VarTypeXmmSD:
- // TODO
- return;
- }
- break;
-
- // We allow incompatible types here, because the caller can convert them
- // to correct format before function is called.
-
- case kX86VarTypeXmm:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmPD:
- switch (argType.getVarType())
- {
- case kX86VarTypeXmm:
- x86Compiler->emit(kX86InstMovDQU, xmm(temporaryXmmReg), src);
- x86Compiler->emit(kX86InstMovDQU, dst, xmm(temporaryXmmReg));
- return;
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- x86Compiler->emit(kX86InstMovUPS, xmm(temporaryXmmReg), src);
- x86Compiler->emit(kX86InstMovUPS, dst, xmm(temporaryXmmReg));
- return;
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstMovUPD, xmm(temporaryXmmReg), src);
- x86Compiler->emit(kX86InstMovUPD, dst, xmm(temporaryXmmReg));
- return;
- }
- break;
-
- case kX86VarTypeXmmSS:
- switch (argType.getVarType())
- {
- case kX86VarTypeX87SS:
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstMovSS, xmm(temporaryXmmReg), src);
- x86Compiler->emit(kX86InstMovSS, dst, xmm(temporaryXmmReg));
- return;
- }
- break;
-
- case kX86VarTypeXmmSD:
- switch (argType.getVarType())
- {
- case kX86VarTypeX87SD:
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstMovSD, xmm(temporaryXmmReg), src);
- x86Compiler->emit(kX86InstMovSD, dst, xmm(temporaryXmmReg));
- return;
- }
- break;
- }
-
- x86Compiler->setError(kErrorIncompatibleArgumentType);
-}
-
-void X86CompilerFuncCall::_moveSrcVariableToRegister(CompilerContext &cc, X86CompilerVar *cv, const FuncArg &argType)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- X86Compiler *x86Compiler = x86Context.getCompiler();
-
- uint32_t dst = argType.getRegIndex();
- uint32_t src = cv->regIndex;
-
- if (src != kRegIndexInvalid)
- {
- switch (argType.getVarType())
- {
- case kX86VarTypeGpd:
- switch (cv->getType())
- {
- case kX86VarTypeGpd:
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
-#endif // ASMJIT_X64
- x86Compiler->emit(kX86InstMov, gpd(dst), gpd(src));
- return;
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovD, gpd(dst), mm(src));
- return;
- }
- break;
-
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- switch (cv->getType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstMov, gpd(dst), gpd(src));
- return;
- case kX86VarTypeGpq:
- x86Compiler->emit(kX86InstMov, gpq(dst), gpq(src));
- return;
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, gpq(dst), mm(src));
- return;
- }
- break;
-#endif // ASMJIT_X64
-
- case kX86VarTypeMm:
- switch (cv->getType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstMovD, gpd(dst), gpd(src));
- return;
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- x86Compiler->emit(kX86InstMovQ, gpq(dst), gpq(src));
- return;
-#endif // ASMJIT_X64
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, mm(dst), mm(src));
- return;
- }
- break;
-
- case kX86VarTypeXmm:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmPD:
- switch (cv->getType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstMovD, xmm(dst), gpd(src));
- return;
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- x86Compiler->emit(kX86InstMovQ, xmm(dst), gpq(src));
- return;
-#endif // ASMJIT_X64
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, xmm(dst), mm(src));
- return;
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstMovDQA, xmm(dst), xmm(src));
- return;
- }
- break;
-
- case kX86VarTypeXmmSS:
- switch (cv->getType())
- {
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, xmm(dst), mm(src));
- return;
- case kX86VarTypeXmm:
- x86Compiler->emit(kX86InstMovDQA, xmm(dst), xmm(src));
- return;
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- x86Compiler->emit(kX86InstMovSS, xmm(dst), xmm(src));
- return;
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstCvtSD2SS, xmm(dst), xmm(src));
- return;
- }
- break;
-
- case kX86VarTypeXmmSD:
- switch (cv->getType())
- {
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, xmm(dst), mm(src));
- return;
- case kX86VarTypeXmm:
- x86Compiler->emit(kX86InstMovDQA, xmm(dst), xmm(src));
- return;
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- x86Compiler->emit(kX86InstCvtSS2SD, xmm(dst), xmm(src));
- return;
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstMovSD, xmm(dst), xmm(src));
- return;
- }
- break;
- }
- }
- else
- {
- Mem mem = x86Context._getVarMem(cv);
-
- switch (argType.getVarType())
- {
- case kX86VarTypeGpd:
- switch (cv->getType())
- {
- case kX86VarTypeGpd:
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
-#endif // ASMJIT_X64
- x86Compiler->emit(kX86InstMov, gpd(dst), mem);
- return;
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovD, gpd(dst), mem);
- return;
- }
- break;
-
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- switch (cv->getType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstMov, gpd(dst), mem);
- return;
- case kX86VarTypeGpq:
- x86Compiler->emit(kX86InstMov, gpq(dst), mem);
- return;
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, gpq(dst), mem);
- return;
- }
- break;
-#endif // ASMJIT_X64
-
- case kX86VarTypeMm:
- switch (cv->getType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstMovD, gpd(dst), mem);
- return;
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- x86Compiler->emit(kX86InstMovQ, gpq(dst), mem);
- return;
-#endif // ASMJIT_X64
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, mm(dst), mem);
- return;
- }
- break;
-
- case kX86VarTypeXmm:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmPD:
- switch (cv->getType())
- {
- case kX86VarTypeGpd:
- x86Compiler->emit(kX86InstMovD, xmm(dst), mem);
- return;
-#ifdef ASMJIT_X64
- case kX86VarTypeGpq:
- x86Compiler->emit(kX86InstMovQ, xmm(dst), mem);
- return;
-#endif // ASMJIT_X64
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, xmm(dst), mem);
- return;
- case kX86VarTypeXmm:
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstMovDQA, xmm(dst), mem);
- return;
- }
- break;
-
- case kX86VarTypeXmmSS:
- switch (cv->getType())
- {
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, xmm(dst), mem);
- return;
- case kX86VarTypeXmm:
- x86Compiler->emit(kX86InstMovDQA, xmm(dst), mem);
- return;
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- x86Compiler->emit(kX86InstMovSS, xmm(dst), mem);
- return;
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstCvtSD2SS, xmm(dst), mem);
- return;
- }
- break;
-
- case kX86VarTypeXmmSD:
- switch (cv->getType())
- {
- case kX86VarTypeMm:
- x86Compiler->emit(kX86InstMovQ, xmm(dst), mem);
- return;
- case kX86VarTypeXmm:
- x86Compiler->emit(kX86InstMovDQA, xmm(dst), mem);
- return;
- case kX86VarTypeXmmSS:
- case kX86VarTypeXmmPS:
- x86Compiler->emit(kX86InstCvtSS2SD, xmm(dst), mem);
- return;
- case kX86VarTypeXmmSD:
- case kX86VarTypeXmmPD:
- x86Compiler->emit(kX86InstMovSD, xmm(dst), mem);
- return;
- }
- break;
- }
- }
-
- x86Compiler->setError(kErrorIncompatibleArgumentType);
-}
-
-// Prototype & Arguments Management.
-void X86CompilerFuncCall::setPrototype(uint32_t callingConvention, uint32_t returnType, const uint32_t *arguments, uint32_t argumentsCount)
-{
- this->_x86Decl.setPrototype(callingConvention, returnType, arguments, argumentsCount);
- this->_args = reinterpret_cast<Operand *>(this->getCompiler()->getZoneMemory().alloc(sizeof(Operand) * argumentsCount));
- memset(this->_args, 0, sizeof(Operand) * argumentsCount);
-}
-
-bool X86CompilerFuncCall::setArgument(uint32_t i, const Var &var)
-{
- ASMJIT_ASSERT(i < this->_x86Decl.getArgumentsCount());
-
- if (i >= this->_x86Decl.getArgumentsCount())
- return false;
-
- this->_args[i] = var;
- return true;
-}
-
-bool X86CompilerFuncCall::setArgument(uint32_t i, const Imm &imm)
-{
- ASMJIT_ASSERT(i < this->_x86Decl.getArgumentsCount());
-
- if (i >= _x86Decl.getArgumentsCount())
- return false;
-
- this->_args[i] = imm;
- return true;
-}
-
-bool X86CompilerFuncCall::setReturn(const Operand &first, const Operand &second)
-{
- this->_ret[0] = first;
- this->_ret[1] = second;
-
- return true;
-}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86compilerfunc.h
+++ /dev/null
@@ -1,365 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../x86/x86assembler.h"
-#include "../x86/x86compiler.h"
-#include "../x86/x86compileritem.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit {
-
-//! @addtogroup AsmJit_X86
-//! @{
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncDecl]
-// ============================================================================
-
-//! @brief @ref X86Compiler specific function declaration item.
-struct X86CompilerFuncDecl : public CompilerFuncDecl
-{
- ASMJIT_NO_COPY(X86CompilerFuncDecl)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref X86CompilerFuncDecl instance.
- ASMJIT_API X86CompilerFuncDecl(X86Compiler* x86Compiler);
- //! @brief Destroy the @ref X86CompilerFuncDecl instance.
- ASMJIT_API virtual ~X86CompilerFuncDecl();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get compiler as @ref X86Compiler.
- X86Compiler* getCompiler() const
- { return reinterpret_cast<X86Compiler*>(_compiler); }
-
- //! @brief Get function end item as @ref X86CompilerFuncEnd.
- X86CompilerFuncEnd* getEnd() const
- { return reinterpret_cast<X86CompilerFuncEnd*>(_end); }
-
- //! @brief Get function declaration as @ref X86FuncDecl.
- X86FuncDecl* getDecl() const
- { return reinterpret_cast<X86FuncDecl*>(_decl); }
-
- //! @brief Get function arguments as variables as @ref X86CompilerVar.
- X86CompilerVar** getVars() const
- { return reinterpret_cast<X86CompilerVar**>(_vars); }
-
- //! @brief Get function argument at @a index.
- X86CompilerVar* getVar(uint32_t index) const
- {
- ASMJIT_ASSERT(index < _x86Decl.getArgumentsCount());
- return reinterpret_cast<X86CompilerVar**>(_vars)[index];
- }
-
- //! @brief Get whether it's assumed that stack is aligned to 16 bytes.
- bool isAssumed16ByteAlignment() const
- { return hasFuncFlag(kX86FuncFlagAssume16ByteAlignment); }
-
- //! @brief Get whether it's required to align stack to 16 bytes by function.
- bool isPerformed16ByteAlignment() const
- { return hasFuncFlag(kX86FuncFlagPerform16ByteAlignment); }
-
- //! @brief Get whether the ESP is adjusted.
- bool isEspAdjusted() const
- { return hasFuncFlag(kX86FuncFlagIsEspAdjusted); }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void prepare(CompilerContext& cc);
- ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
-
- // --------------------------------------------------------------------------
- // [Misc]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual int getMaxSize() const;
-
- // --------------------------------------------------------------------------
- // [Prototype]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void setPrototype(
- uint32_t convention,
- uint32_t returnType,
- const uint32_t* arguments,
- uint32_t argumentsCount);
-
- // --------------------------------------------------------------------------
- // [Helpers]
- // --------------------------------------------------------------------------
-
- //! @internal
- //!
- //! @brief Get required stack offset needed to subtract/add Esp/Rsp in
- //! prolog/epilog.
- int32_t _getRequiredStackOffset() const
- { return _funcCallStackSize + _memStackSize16 + _peMovStackSize + _peAdjustStackSize; }
-
- //! @brief Create variables from FunctionPrototype declaration. This is just
- //! parsing what FunctionPrototype generated for current function calling
- //! convention and arguments.
- ASMJIT_API void _createVariables();
-
- //! @brief Prepare variables (ids, names, scope, registers).
- ASMJIT_API void _prepareVariables(CompilerItem* first);
-
- //! @brief Allocate variables (setting correct state, changing masks, etc).
- ASMJIT_API void _allocVariables(CompilerContext& cc);
-
- ASMJIT_API void _preparePrologEpilog(CompilerContext& cc);
- ASMJIT_API void _dumpFunction(CompilerContext& cc);
- ASMJIT_API void _emitProlog(CompilerContext& cc);
- ASMJIT_API void _emitEpilog(CompilerContext& cc);
-
- // --------------------------------------------------------------------------
- // [Function-Call]
- // --------------------------------------------------------------------------
-
- //! @brief Reserve stack for calling other function and mark function as
- //! callee.
- ASMJIT_API void reserveStackForFunctionCall(int32_t size);
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief X86 function decl.
- X86FuncDecl _x86Decl;
-
- //! @brief Modified and preserved GP registers mask.
- uint32_t _gpModifiedAndPreserved;
- //! @brief Modified and preserved MM registers mask.
- uint32_t _mmModifiedAndPreserved;
- //! @brief Modified and preserved XMM registers mask.
- uint32_t _xmmModifiedAndPreserved;
-
- //! @brief Id of MovDQWord instruction (@c kX86InstMovDQA or @c kX86InstMovDQU).
- //!
- //! The value is based on stack alignment. If it's guaranteed that stack
- //! is aligned to 16-bytes then @c kX86InstMovDQA instruction is used, otherwise
- //! the @c kX86InstMovDQU instruction is used for 16-byte mov.
- uint32_t _movDqInstCode;
-
- //! @brief Prolog / epilog stack size for PUSH/POP sequences.
- int32_t _pePushPopStackSize;
- //! @brief Prolog / epilog stack size for MOV sequences.
- int32_t _peMovStackSize;
- //! @brief Prolog / epilog stack adjust size (to make it 16-byte aligned).
- int32_t _peAdjustStackSize;
-
- //! @brief Memory stack size (for all variables and temporary memory).
- int32_t _memStackSize;
- //! @brief Like @c _memStackSize, but aligned to 16-bytes.
- int32_t _memStackSize16;
-};
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncEnd]
-// ============================================================================
-
-//! @brief @ref X86Compiler function end item.
-struct X86CompilerFuncEnd : public CompilerFuncEnd
-{
- ASMJIT_NO_COPY(X86CompilerFuncEnd)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref X86CompilerFuncEnd instance.
- ASMJIT_API X86CompilerFuncEnd(X86Compiler* x86Compiler, X86CompilerFuncDecl* func);
- //! @brief Destroy the @ref X86CompilerFuncEnd instance.
- ASMJIT_API virtual ~X86CompilerFuncEnd();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get compiler as @ref X86Compiler.
- X86Compiler* getCompiler() const
- { return reinterpret_cast<X86Compiler*>(_compiler); }
-
- //! @brief Get related function as @ref X86CompilerFuncDecl.
- X86CompilerFuncDecl* getFunc() const
- { return reinterpret_cast<X86CompilerFuncDecl*>(_func); }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void prepare(CompilerContext& cc);
- ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
-};
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncRet]
-// ============================================================================
-
-//! @brief Function return.
-struct X86CompilerFuncRet : public CompilerFuncRet
-{
- ASMJIT_NO_COPY(X86CompilerFuncRet)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref X86CompilerFuncRet instance.
- ASMJIT_API X86CompilerFuncRet(X86Compiler* c, X86CompilerFuncDecl* func,
- const Operand* first, const Operand* second);
- //! @brief Destroy the @ref X86CompilerFuncRet instance.
- ASMJIT_API virtual ~X86CompilerFuncRet();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get compiler as @ref X86Compiler.
- X86Compiler* getCompiler() const
- { return reinterpret_cast<X86Compiler*>(_compiler); }
-
- //! @Brief Get related function as @ref X86CompilerFuncDecl.
- X86CompilerFuncDecl* getFunc() const
- { return reinterpret_cast<X86CompilerFuncDecl*>(_func); }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void prepare(CompilerContext& cc);
- ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
- ASMJIT_API virtual void emit(Assembler& a);
-
- // --------------------------------------------------------------------------
- // [Misc]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual int getMaxSize() const;
-};
-
-// ============================================================================
-// [AsmJit::X86CompilerFuncCall]
-// ============================================================================
-
-//! @brief Compiler function call item.
-struct X86CompilerFuncCall : public CompilerFuncCall
-{
- ASMJIT_NO_COPY(X86CompilerFuncCall)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref X86CompilerFuncCall instance.
- ASMJIT_API X86CompilerFuncCall(X86Compiler* x86Compiler, X86CompilerFuncDecl* caller, const Operand* target);
- //! @brief Destroy the @ref X86CompilerFuncCall instance.
- ASMJIT_API virtual ~X86CompilerFuncCall();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get compiler as @ref X86Compiler.
- X86Compiler* getCompiler() const
- { return reinterpret_cast<X86Compiler*>(_compiler); }
-
- //! @brief Get caller as @ref X86CompilerFuncDecl.
- X86CompilerFuncDecl* getCaller() const
- { return reinterpret_cast<X86CompilerFuncDecl*>(_caller); }
-
- //! @brief Get function prototype.
- const X86FuncDecl* getDecl() const
- { return reinterpret_cast<X86FuncDecl*>(_decl); }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void prepare(CompilerContext& cc);
- ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
-
- // --------------------------------------------------------------------------
- // [Misc]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual int getMaxSize() const;
- ASMJIT_API virtual bool _tryUnuseVar(CompilerVar* v);
-
- // --------------------------------------------------------------------------
- // [Prototype]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void setPrototype(uint32_t convention, uint32_t returnType, const uint32_t* arguments, uint32_t argumentsCount);
-
- //! @brief Set function prototype.
- void setPrototype(uint32_t convention, const FuncPrototype& func)
- { setPrototype(convention, func.getReturnType(), func.getArguments(), func.getArgumentsCount()); }
-
- //! @brief Set return value.
- ASMJIT_API bool setReturn(const Operand& first, const Operand& second = Operand());
-
- //! @brief Set function argument @a i to @a var.
- ASMJIT_API bool setArgument(uint32_t i, const Var& var);
- //! @brief Set function argument @a i to @a imm.
- ASMJIT_API bool setArgument(uint32_t i, const Imm& imm);
-
- // --------------------------------------------------------------------------
- // [Internal]
- // --------------------------------------------------------------------------
-
- ASMJIT_API uint32_t _findTemporaryGpRegister(CompilerContext& cc);
- ASMJIT_API uint32_t _findTemporaryXmmRegister(CompilerContext& cc);
-
- ASMJIT_API X86CompilerVar* _getOverlappingVariable(CompilerContext& cc, const FuncArg& argType) const;
-
- ASMJIT_API void _moveAllocatedVariableToStack(CompilerContext& cc, X86CompilerVar* vdata, const FuncArg& argType);
- ASMJIT_API void _moveSpilledVariableToStack(CompilerContext& cc, X86CompilerVar* vdata, const FuncArg& argType,
- uint32_t temporaryGpReg,
- uint32_t temporaryXmmReg);
- ASMJIT_API void _moveSrcVariableToRegister(CompilerContext& cc, X86CompilerVar* vdata, const FuncArg& argType);
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief X86 declaration.
- X86FuncDecl _x86Decl;
-
- //! @brief Mask of GP registers used as function arguments.
- uint32_t _gpParams;
- //! @brief Mask of MM registers used as function arguments.
- uint32_t _mmParams;
- //! @brief Mask of XMM registers used as function arguments.
- uint32_t _xmmParams;
-
- //! @brief Variables count.
- uint32_t _variablesCount;
-
- //! @brief Variables (extracted from operands).
- VarCallRecord* _variables;
- //! @brief Argument index to @c VarCallRecord.
- VarCallRecord* _argumentToVarRecord[kFuncArgsMax];
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86compileritem.cpp
+++ /dev/null
@@ -1,1788 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/intutil.h"
-#include "../core/stringutil.h"
-
-#include "../x86/x86compiler.h"
-#include "../x86/x86compilercontext.h"
-#include "../x86/x86compilerfunc.h"
-#include "../x86/x86compileritem.h"
-#include "../x86/x86util.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::X86CompilerAlign - Construction / Destruction]
-// ============================================================================
-
-X86CompilerAlign::X86CompilerAlign(X86Compiler *x86Compiler, uint32_t size) : CompilerAlign(x86Compiler, size)
-{
-}
-
-X86CompilerAlign::~X86CompilerAlign()
-{
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerAlign - Interface]
-// ============================================================================
-
-void X86CompilerAlign::emit(Assembler &a)
-{
- X86Assembler &x86Asm = static_cast<X86Assembler &>(a);
-
- x86Asm.align(_size);
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerTarget - Construction / Destruction]
-// ============================================================================
-
-X86CompilerTarget::X86CompilerTarget(X86Compiler *c, const Label &label) : CompilerTarget(c, label)
-{
-}
-
-X86CompilerTarget::~X86CompilerTarget()
-{
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerTarget - Interface]
-// ============================================================================
-
-static X86CompilerTarget *X86CompilerTarget_removeUnreachableItems(X86CompilerTarget *target)
-{
- CompilerItem *prev = target->getPrev();
- CompilerItem *item = target->getNext();
-
- ASMJIT_ASSERT(prev);
- ASMJIT_ASSERT(item);
-
- for (;;)
- {
- CompilerItem *next = item->getNext();
- ASMJIT_ASSERT(next);
-
- if (item->getType() == kCompilerItemTarget)
- break;
-
- item->_prev = nullptr;
- item->_next = nullptr;
- item->_isUnreachable = true;
-
- item = next;
- }
-
- target->_prev = nullptr;
- target->_next = nullptr;
- target->_isTranslated = true;
-
- prev->_next = item;
- item->_prev = prev;
-
- return static_cast<X86CompilerTarget *>(item);
-}
-
-void X86CompilerTarget::prepare(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- this->_offset = x86Context._currentOffset++;
-}
-
-CompilerItem *X86CompilerTarget::translate(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
-
- // If this X86CompilerTarget was already translated, it's needed to change
- // the current state and return NULL to tell CompilerContext to process next
- // untranslated item.
- if (this->_isTranslated)
- {
- x86Context._restoreState(this->getState());
- return nullptr;
- }
-
- if (x86Context._isUnreachable)
- {
- // If the context has "isUnreachable" flag set and there is no state then
- // it means that this code will be never called. This is a problem, because
- // we are unable to assign a state to current location so we can't allocate
- // registers for variables used inside. So instead of doing anything wrong
- // we remove the unreachable code.
- if (!this->_state)
- return X86CompilerTarget_removeUnreachableItems(this);
-
- // Assign state to the compiler context.
- x86Context._isUnreachable = 0;
- x86Context._assignState(this->getState());
- }
- else
- this->_state = x86Context._saveState();
-
- return this->translated();
-}
-
-void X86CompilerTarget::emit(Assembler &a)
-{
- X86Assembler &x86Asm = static_cast<X86Assembler &>(a);
- x86Asm.bind(this->_label);
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerHint - Construction / Destruction]
-// ============================================================================
-
-X86CompilerHint::X86CompilerHint(X86Compiler *compiler, X86CompilerVar *var, uint32_t hintId, uint32_t hintValue) : CompilerHint(compiler, var, hintId, hintValue)
-{
-}
-
-X86CompilerHint::~X86CompilerHint()
-{
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerHint - Interface]
-// ============================================================================
-
-void X86CompilerHint::prepare(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- X86CompilerVar *var = this->getVar();
-
- this->_offset = x86Context._currentOffset;
-
- // First item (begin of variable scope).
- if (!var->firstItem)
- var->firstItem = this;
-
- // Last item (end of variable scope).
- CompilerItem *oldLast = var->lastItem;
- var->lastItem = this;
-
- switch (this->_hintId)
- {
- case kVarHintAlloc:
- case kVarHintSpill:
- case kVarHintSave:
- if (!x86Context._isActive(var))
- x86Context._addActive(var);
- break;
-
- case kVarHintSaveAndUnuse:
- if (!x86Context._isActive(var))
- x86Context._addActive(var);
- break;
-
- case kVarHintUnuse:
- if (oldLast)
- oldLast->_tryUnuseVar(var);
- }
-}
-
-CompilerItem *X86CompilerHint::translate(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- X86CompilerVar *var = this->getVar();
-
- switch (this->_hintId)
- {
- case kVarHintAlloc:
- x86Context.allocVar(var, this->_hintValue, kVarAllocRead);
- break;
-
- case kVarHintSpill:
- if (var->state == kVarStateReg)
- x86Context.spillVar(var);
- break;
-
- case kVarHintSave:
- case kVarHintSaveAndUnuse:
- if (var->state == kVarStateReg && var->changed)
- {
- x86Context.emitSaveVar(var, var->regIndex);
- var->changed = false;
- }
- if (this->_hintId == kVarHintSaveAndUnuse)
- goto _Unuse;
- break;
-
- case kVarHintUnuse:
- _Unuse:
- x86Context.unuseVar(var, kVarStateUnused);
- goto _End;
- }
-
- x86Context._unuseVarOnEndOfScope(this, var);
-
-_End:
- return this->translated();
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerHint - Misc]
-// ============================================================================
-
-int X86CompilerHint::getMaxSize() const
-{
- // Compiler hint is NOP, but it can generate other items which can do
- // something - in such more items are added into the stream so we don't need
- // to worry about this.
- return 0;
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerInst - Construction / Destruction]
-// ============================================================================
-
-X86CompilerInst::X86CompilerInst(X86Compiler *x86Compiler, uint32_t code, Operand *opData, uint32_t opCount) : CompilerInst(x86Compiler, code, opData, opCount)
-{
- this->_memOp = nullptr;
- this->_vars = nullptr;
- this->_variablesCount = 0;
-
- for (uint32_t i = 0; i < opCount; ++i)
- {
- if (this->_operands[i].isMem())
- {
- this->_memOp = reinterpret_cast<Mem *>(&this->_operands[i]);
- break;
- }
- }
-
- const X86InstInfo *info = &x86InstInfo[this->_code];
-
- if (info->isSpecial())
- this->setInstFlag(kX86CompilerInstFlagIsSpecial);
- if (info->isFpu())
- this->setInstFlag(kX86CompilerInstFlagIsFpu);
-
- if (this->isSpecial())
- {
- // ${SPECIAL_INSTRUCTION_HANDLING_BEGIN}
- switch (this->_code)
- {
- case kX86InstCpuId:
- // Special...
- break;
-
- case kX86InstCbw:
- case kX86InstCdq:
- case kX86InstCdqe:
- case kX86InstCwd:
- case kX86InstCwde:
- case kX86InstCqo:
- // Special...
- break;
-
- case kX86InstCmpXCHG:
- case kX86InstCmpXCHG8B:
-#ifdef ASMJIT_X64
- case kX86InstCmpXCHG16B:
-#endif // ASMJIT_X64
- // Special...
- break;
-
-#ifdef ASMJIT_X86
- case kX86InstDaa:
- case kX86InstDas:
- // Special...
- break;
-#endif // ASMJIT_X86
-
- case kX86InstIMul:
- switch (this->_operandsCount)
- {
- case 2:
- // IMUL dst, src is not special instruction.
- this->clearInstFlag(kX86CompilerInstFlagIsSpecial);
- break;
- case 3:
- // Only IMUL dst_hi, dst_lo, reg/mem is special, all others don't.
- if (!(this->_operands[0].isVar() && this->_operands[1].isVar() && this->_operands[2].isVarMem()))
- this->clearInstFlag(kX86CompilerInstFlagIsSpecial);
- }
- break;
- case kX86InstMul:
- case kX86InstIDiv:
- case kX86InstDiv:
- // Special...
- break;
-
- case kX86InstMovPtr:
- // Special...
- break;
-
- case kX86InstLahf:
- case kX86InstSahf:
- // Special...
- break;
-
- case kX86InstMaskMovQ:
- case kX86InstMaskMovDQU:
- // Special...
- break;
-
- case kX86InstEnter:
- case kX86InstLeave:
- // Special...
- break;
-
- case kX86InstRet:
- // Special...
- break;
-
- case kX86InstMonitor:
- case kX86InstMWait:
- // Special...
- break;
-
- case kX86InstPop:
- case kX86InstPopAD:
- case kX86InstPopFD:
- case kX86InstPopFQ:
- // Special...
- break;
-
- case kX86InstPush:
- case kX86InstPushAD:
- case kX86InstPushFD:
- case kX86InstPushFQ:
- // Special...
- break;
-
- case kX86InstRcl:
- case kX86InstRcr:
- case kX86InstRol:
- case kX86InstRor:
- case kX86InstSal:
- case kX86InstSar:
- case kX86InstShl:
- case kX86InstShr:
- // Rot instruction is special only if last operand is variable (register).
- if (!this->_operands[1].isVar())
- this->clearInstFlag(kX86CompilerInstFlagIsSpecial);
- break;
-
- case kX86InstShld:
- case kX86InstShrd:
- // Shld/Shrd instruction is special only if last operand is variable (register).
- if (!this->_operands[2].isVar())
- this->clearInstFlag(kX86CompilerInstFlagIsSpecial);
- break;
-
- case kX86InstRdtsc:
- case kX86InstRdtscP:
- // Special...
- break;
-
- case kX86InstRepLodSB:
- case kX86InstRepLodSD:
- case kX86InstRepLodSQ:
- case kX86InstRepLodSW:
- case kX86InstRepMovSB:
- case kX86InstRepMovSD:
- case kX86InstRepMovSQ:
- case kX86InstRepMovSW:
- case kX86InstRepStoSB:
- case kX86InstRepStoSD:
- case kX86InstRepStoSQ:
- case kX86InstRepStoSW:
- case kX86InstRepECmpSB:
- case kX86InstRepECmpSD:
- case kX86InstRepECmpSQ:
- case kX86InstRepECmpSW:
- case kX86InstRepEScaSB:
- case kX86InstRepEScaSD:
- case kX86InstRepEScaSQ:
- case kX86InstRepEScaSW:
- case kX86InstRepNECmpSB:
- case kX86InstRepNECmpSD:
- case kX86InstRepNECmpSQ:
- case kX86InstRepNECmpSW:
- case kX86InstRepNEScaSB:
- case kX86InstRepNEScaSD:
- case kX86InstRepNEScaSQ:
- case kX86InstRepNEScaSW:
- // Special...
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- // ${SPECIAL_INSTRUCTION_HANDLING_END}
- }
-}
-
-X86CompilerInst::~X86CompilerInst()
-{
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerInst - Interface]
-// ============================================================================
-
-void X86CompilerInst::prepare(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- X86Compiler *x86Compiler = this->getCompiler();
-
-#define __GET_VARIABLE(__vardata__) \
-{ \
- X86CompilerVar *_candidate = __vardata__; \
-\
- for (var = cur; ; ) \
- { \
- if (var == this->_vars) \
- { \
- var = cur++; \
- var->vdata = _candidate; \
- var->vflags = 0; \
- var->regMask = 0xFFFFFFFF; \
- break; \
- } \
-\
- --var; \
-\
- if (var->vdata == _candidate) \
- break; \
- } \
-\
- ASMJIT_ASSERT(var); \
-}
-
- this->_offset = x86Context._currentOffset;
-
- const X86InstInfo *id = &x86InstInfo[this->_code];
-
- uint32_t i, len = _operandsCount;
- uint32_t variablesCount = 0;
-
- for (i = 0; i < len; ++i)
- {
- Operand &o = this->_operands[i];
-
- if (o.isVar())
- {
- ASMJIT_ASSERT(o.getId() != kInvalidValue);
- X86CompilerVar *vdata = x86Compiler->_getVar(o.getId());
- ASMJIT_ASSERT(vdata);
-
- if (reinterpret_cast<Var *>(&o)->isGpVar())
- {
- if (reinterpret_cast<GpVar *>(&o)->isGpbLo())
- {
- this->setInstFlag(kX86CompilerInstFlagIsGpbLoUsed);
- ++vdata->regGpbLoCount;
- }
- if (reinterpret_cast<GpVar *>(&o)->isGpbHi())
- {
- this->setInstFlag(kX86CompilerInstFlagIsGpbHiUsed);
- ++vdata->regGpbHiCount;
- }
- }
-
- if (vdata->workOffset != this->_offset)
- {
- if (!x86Context._isActive(vdata))
- x86Context._addActive(vdata);
-
- vdata->workOffset = this->_offset;
- ++variablesCount;
- }
- }
- else if (o.isMem())
- {
- if ((o.getId() & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *vdata = x86Compiler->_getVar(o.getId());
- ASMJIT_ASSERT(vdata);
-
- x86Context._markMemoryUsed(vdata);
-
- if (vdata->workOffset != this->_offset)
- {
- if (!x86Context._isActive(vdata))
- x86Context._addActive(vdata);
-
- vdata->workOffset = this->_offset;
- ++variablesCount;
- }
- }
- else if ((o._mem.base & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *vdata = x86Compiler->_getVar(o._mem.base);
- ASMJIT_ASSERT(vdata);
-
- if (vdata->workOffset != this->_offset)
- {
- if (!x86Context._isActive(vdata))
- x86Context._addActive(vdata);
-
- vdata->workOffset = this->_offset;
- ++variablesCount;
- }
- }
-
- if ((o._mem.index & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *vdata = x86Compiler->_getVar(o._mem.index);
- ASMJIT_ASSERT(vdata);
-
- if (vdata->workOffset != this->_offset)
- {
- if (!x86Context._isActive(vdata))
- x86Context._addActive(vdata);
-
- vdata->workOffset = this->_offset;
- ++variablesCount;
- }
- }
- }
- }
-
- if (!variablesCount)
- {
- ++x86Context._currentOffset;
- return;
- }
-
- this->_vars = reinterpret_cast<VarAllocRecord *>(x86Compiler->getZoneMemory().alloc(sizeof(VarAllocRecord) * variablesCount));
- if (!this->_vars)
- {
- x86Compiler->setError(kErrorNoHeapMemory);
- ++x86Context._currentOffset;
- return;
- }
-
- this->_variablesCount = variablesCount;
-
- VarAllocRecord *cur = this->_vars;
- VarAllocRecord *var = nullptr;
-
- bool _isGpbUsed = hasInstFlag(kX86CompilerInstFlagIsGpbLoUsed) | hasInstFlag(kX86CompilerInstFlagIsGpbHiUsed);
- uint32_t gpRestrictMask = IntUtil::maskUpToIndex(kX86RegNumGp);
-
-#ifdef ASMJIT_X64
- if (hasInstFlag(kX86CompilerInstFlagIsGpbHiUsed))
- gpRestrictMask &= IntUtil::maskFromIndex(kX86RegIndexEax) | IntUtil::maskFromIndex(kX86RegIndexEbx) | IntUtil::maskFromIndex(kX86RegIndexEcx) | IntUtil::maskFromIndex(kX86RegIndexEdx) |
- IntUtil::maskFromIndex(kX86RegIndexEbp) | IntUtil::maskFromIndex(kX86RegIndexEsi) | IntUtil::maskFromIndex(kX86RegIndexEdi);
-#endif // ASMJIT_X64
-
- for (i = 0; i < len; ++i)
- {
- Operand &o = this->_operands[i];
-
- if (o.isVar())
- {
- X86CompilerVar *vdata = x86Compiler->_getVar(o.getId());
- ASMJIT_ASSERT(vdata);
-
- __GET_VARIABLE(vdata)
- var->vflags |= kVarAllocRegister;
-
- if (_isGpbUsed)
- {
-#ifdef ASMJIT_X86
- if (reinterpret_cast<GpVar *>(&o)->isGpb())
- var->regMask &= IntUtil::maskFromIndex(kX86RegIndexEax) | IntUtil::maskFromIndex(kX86RegIndexEbx) | IntUtil::maskFromIndex(kX86RegIndexEcx) | IntUtil::maskFromIndex(kX86RegIndexEdx);
-#else
- // Restrict all BYTE registers to RAX/RBX/RCX/RDX if HI BYTE register
- // is used (REX prefix makes HI BYTE addressing unencodable).
- if (hasInstFlag(kX86CompilerInstFlagIsGpbHiUsed))
- {
- if (reinterpret_cast<GpVar *>(&o)->isGpb())
- var->regMask &= IntUtil::maskFromIndex(kX86RegIndexEax) | IntUtil::maskFromIndex(kX86RegIndexEbx) | IntUtil::maskFromIndex(kX86RegIndexEcx) | IntUtil::maskFromIndex(kX86RegIndexEdx);
- }
-#endif // ASMJIT_X86/X64
- }
-
- if (this->isSpecial())
- {
- // ${SPECIAL_INSTRUCTION_HANDLING_BEGIN}
- switch (this->_code)
- {
- case kX86InstCpuId:
- switch (i)
- {
- case 0:
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
- case 1:
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEbx);
- gpRestrictMask &= ~var->regMask;
- break;
- case 2:
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEcx);
- gpRestrictMask &= ~var->regMask;
- break;
- case 3:
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEdx);
- gpRestrictMask &= ~var->regMask;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
- case kX86InstCbw:
- case kX86InstCdqe:
- case kX86InstCwde:
- switch (i)
- {
- case 0:
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
- case kX86InstCdq:
- case kX86InstCwd:
- case kX86InstCqo:
- switch (i)
- {
- case 0:
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEdx);
- gpRestrictMask &= ~var->regMask;
- break;
- case 1:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
- case kX86InstCmpXCHG:
- switch (i)
- {
- case 0:
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
- case 1:
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite;
- break;
- case 2:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
- case kX86InstCmpXCHG8B:
-#ifdef ASMJIT_X64
- case kX86InstCmpXCHG16B:
-#endif // ASMJIT_X64
- switch (i)
- {
- case 0:
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEdx);
- gpRestrictMask &= ~var->regMask;
- break;
- case 1:
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
- case 2:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEcx);
- gpRestrictMask &= ~var->regMask;
- break;
- case 3:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEbx);
- gpRestrictMask &= ~var->regMask;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
-#ifdef ASMJIT_X86
- case kX86InstDaa:
- case kX86InstDas:
- ASMJIT_ASSERT(!i);
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
-#endif // ASMJIT_X86
-
- case kX86InstIMul:
- case kX86InstMul:
- case kX86InstIDiv:
- case kX86InstDiv:
- switch (i)
- {
- case 0:
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEdx);
- gpRestrictMask &= ~var->regMask;
- break;
- case 1:
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
- case 2:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
- case kX86InstMovPtr:
- switch (i)
- {
- case 0:
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
- case 1:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
- case kX86InstLahf:
- ASMJIT_ASSERT(!i);
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
-
- case kX86InstSahf:
- ASMJIT_ASSERT(!i);
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
-
- case kX86InstMaskMovQ:
- case kX86InstMaskMovDQU:
- switch (i)
- {
- case 0:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEdi);
- gpRestrictMask &= ~var->regMask;
- break;
- case 1:
- case 2:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead;
- }
- break;
-
- case kX86InstEnter:
- case kX86InstLeave:
- // TODO: SPECIAL INSTRUCTION.
- break;
-
- case kX86InstRet:
- // TODO: SPECIAL INSTRUCTION.
- break;
-
- case kX86InstMonitor:
- case kX86InstMWait:
- // TODO: MONITOR/MWAIT (COMPILER).
- break;
-
- case kX86InstPop:
- // TODO: SPECIAL INSTRUCTION.
- break;
-
- case kX86InstPopAD:
- case kX86InstPopFD:
- case kX86InstPopFQ:
- // TODO: SPECIAL INSTRUCTION.
- break;
-
- case kX86InstPush:
- // TODO: SPECIAL INSTRUCTION.
- break;
-
- case kX86InstPushAD:
- case kX86InstPushFD:
- case kX86InstPushFQ:
- // TODO: SPECIAL INSTRUCTION.
- break;
-
- case kX86InstRcl:
- case kX86InstRcr:
- case kX86InstRol:
- case kX86InstRor:
- case kX86InstSal:
- case kX86InstSar:
- case kX86InstShl:
- case kX86InstShr:
- switch (i)
- {
- case 0:
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite;
- break;
- case 1:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEcx);
- gpRestrictMask &= ~var->regMask;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
- case kX86InstShld:
- case kX86InstShrd:
- switch (i)
- {
- case 0:
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite;
- break;
- case 1:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead;
- break;
- case 2:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEcx);
- gpRestrictMask &= ~var->regMask;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
- case kX86InstRdtsc:
- case kX86InstRdtscP:
- switch (i)
- {
- case 0:
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEdx);
- gpRestrictMask &= ~var->regMask;
- break;
- case 1:
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
- case 2:
- ASMJIT_ASSERT(this->_code == kX86InstRdtscP);
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEcx);
- gpRestrictMask &= ~var->regMask;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
- case kX86InstRepLodSB:
- case kX86InstRepLodSD:
- case kX86InstRepLodSQ:
- case kX86InstRepLodSW:
- switch (i)
- {
- case 0:
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
- case 1:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEsi);
- gpRestrictMask &= ~var->regMask;
- break;
- case 2:
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEcx);
- gpRestrictMask &= ~var->regMask;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
- case kX86InstRepMovSB:
- case kX86InstRepMovSD:
- case kX86InstRepMovSQ:
- case kX86InstRepMovSW:
- case kX86InstRepECmpSB:
- case kX86InstRepECmpSD:
- case kX86InstRepECmpSQ:
- case kX86InstRepECmpSW:
- case kX86InstRepNECmpSB:
- case kX86InstRepNECmpSD:
- case kX86InstRepNECmpSQ:
- case kX86InstRepNECmpSW:
- switch (i)
- {
- case 0:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEdi);
- gpRestrictMask &= ~var->regMask;
- break;
- case 1:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEsi);
- gpRestrictMask &= ~var->regMask;
- break;
- case 2:
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEcx);
- gpRestrictMask &= ~var->regMask;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
- case kX86InstRepStoSB:
- case kX86InstRepStoSD:
- case kX86InstRepStoSQ:
- case kX86InstRepStoSW:
- switch (i)
- {
- case 0:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEdi);
- gpRestrictMask &= ~var->regMask;
- break;
- case 1:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
- case 2:
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEcx);
- gpRestrictMask &= ~var->regMask;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
- case kX86InstRepEScaSB:
- case kX86InstRepEScaSD:
- case kX86InstRepEScaSQ:
- case kX86InstRepEScaSW:
- case kX86InstRepNEScaSB:
- case kX86InstRepNEScaSD:
- case kX86InstRepNEScaSQ:
- case kX86InstRepNEScaSW:
- switch (i)
- {
- case 0:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEdi);
- gpRestrictMask &= ~var->regMask;
- break;
- case 1:
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEax);
- gpRestrictMask &= ~var->regMask;
- break;
- case 2:
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite | kVarAllocSpecial;
- var->regMask = IntUtil::maskFromIndex(kX86RegIndexEcx);
- gpRestrictMask &= ~var->regMask;
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- break;
-
- default:
- ASMJIT_ASSERT(0);
- }
- // ${SPECIAL_INSTRUCTION_HANDLING_END}
- }
- else
- {
- if (!i)
- {
- // CMP/TEST instruction.
- if (id->getCode() == kX86InstCmp || id->getCode() == kX86InstTest)
- {
- // Read-only case.
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead;
- }
- // CVTTSD2SI/CVTTSS2SI instructions.
- else if (id->getCode() == kX86InstCvttSD2SI || id->getCode() == kX86InstCvttSS2SI)
- {
- // In 32-bit mode the whole destination is replaced. In 64-bit mode
- // we need to check whether the destination operand size is 64-bits.
-#ifdef ASMJIT_X64
- if (this->_operands[0].isRegType(kX86RegTypeGpq))
- {
-#endif // ASMJIT_X64
- // Write-only case.
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite;
-#ifdef ASMJIT_X64
- }
- else
- {
- // Read/Write.
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite;
- }
-#endif // ASMJIT_X64
- }
- // MOV/MOVSS/MOVSD instructions.
- //
- // If instruction is MOV (source replaces the destination) or
- // MOVSS/MOVSD and source operand is memory location then register
- // allocator should know that previous destination value is lost
- // (write only operation).
- else if ((id->isMov()) || ((id->getCode() == kX86InstMovSS || id->getCode() == kX86InstMovSD) /* && _operands[1].isMem() */) ||
- (id->getCode() == kX86InstIMul && this->_operandsCount == 3 && !isSpecial()))
- {
- // Write-only case.
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite;
- }
- else if (id->getCode() == kX86InstLea)
- {
- // Write.
- ++vdata->regWriteCount;
- var->vflags |= kVarAllocWrite;
- }
- else
- {
- // Read/Write.
- ++vdata->regRwCount;
- var->vflags |= kVarAllocReadWrite;
- }
- }
- else
- {
- // Second, third, ... operands are read-only.
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRead;
- }
-
- if (!this->_memOp && i < 2 && (id->_opFlags[i] & kX86InstOpMem))
- var->vflags |= kVarAllocMem;
- }
-
- // If variable must be in specific register we could add some hint to allocator.
- if (var->vflags & kVarAllocSpecial)
- {
- vdata->prefRegisterMask |= var->regMask;
- x86Context._newRegisterHomeIndex(vdata, IntUtil::findFirstBit(var->regMask));
- }
- }
- else if (o.isMem())
- {
- if ((o.getId() & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *vdata = x86Compiler->_getVar(o.getId());
- ASMJIT_ASSERT(vdata);
-
- __GET_VARIABLE(vdata)
-
- if (!i)
- {
- // If variable is MOV instruction type (source replaces the destination)
- // or variable is MOVSS/MOVSD instruction then register allocator should
- // know that previous destination value is lost (write only operation).
- if (id->isMov() || (id->getCode() == kX86InstMovSS || id->getCode() == kX86InstMovSD))
- // Write only case.
- ++vdata->memWriteCount;
- else
- ++vdata->memRwCount;
- }
- else
- ++vdata->memReadCount;
- }
- else if ((o._mem.base & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *vdata = x86Compiler->_getVar(reinterpret_cast<Mem &>(o).getBase());
- ASMJIT_ASSERT(vdata);
-
- __GET_VARIABLE(vdata)
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRegister | kVarAllocRead;
- var->regMask &= gpRestrictMask;
- }
-
- if ((o._mem.index & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *vdata = x86Compiler->_getVar(reinterpret_cast<Mem &>(o).getIndex());
- ASMJIT_ASSERT(vdata);
-
- __GET_VARIABLE(vdata)
- ++vdata->regReadCount;
- var->vflags |= kVarAllocRegister | kVarAllocRead;
- var->regMask &= gpRestrictMask;
- }
- }
- }
-
- // Traverse all variables and update firstItem / lastItem. This
- // function is called from iterator that scans items using forward
- // direction so we can use this knowledge to optimize the process.
- //
- // Similar to X86CompilerFuncCall::prepare().
- for (i = 0; i < this->_variablesCount; ++i)
- {
- X86CompilerVar *v = this->_vars[i].vdata;
-
- // Update GP register allocator restrictions.
- if (X86Util::isVarTypeInt(v->getType()) && this->_vars[i].regMask == 0xFFFFFFFF)
- this->_vars[i].regMask &= gpRestrictMask;
-
- // Update first/last item (begin of variable scope).
- if (!v->firstItem)
- v->firstItem = this;
- v->lastItem = this;
- }
-
- // There are some instructions that can be used to clear or to set all bits
- // in a register:
- //
- // - andn reg, reg ; Set all bits in reg to 0.
- // - xor/pxor reg, reg ; Set all bits in reg to 0.
- // - sub/psub reg, reg ; Set all bits in reg to 0.
- // - pcmpgt reg, reg ; Set all bits in reg to 0.
- // - pcmpeq reg, reg ; Set all bits in reg to 1.
- //
- // There are also combinations which do nothing:
- //
- // - and reg, reg ; Nop.
- // - or reg, reg ; Nop.
- // - xchg reg, reg ; Nop.
-
- if (this->_variablesCount == 1 && this->_operandsCount > 1 && this->_operands[0].isVar() && this->_operands[1].isVar() && !this->_memOp)
- {
- switch (this->_code)
- {
- // ----------------------------------------------------------------------
- // [Zeros/Ones]
- // ----------------------------------------------------------------------
-
- // ANDN Instructions.
- case kX86InstPAndN:
- // XOR Instructions.
- case kX86InstXor:
- case kX86InstXorPD:
- case kX86InstXorPS:
- case kX86InstPXor:
- // SUB Instructions.
- case kX86InstSub:
- case kX86InstPSubB:
- case kX86InstPSubW:
- case kX86InstPSubD:
- case kX86InstPSubQ:
- case kX86InstPSubSB:
- case kX86InstPSubSW:
- case kX86InstPSubUSB:
- case kX86InstPSubUSW:
- // PCMPEQ Instructions.
- case kX86InstPCmpEqB:
- case kX86InstPCmpEqW:
- case kX86InstPCmpEqD:
- case kX86InstPCmpEqQ:
- // PCMPGT Instructions.
- case kX86InstPCmpGtB:
- case kX86InstPCmpGtW:
- case kX86InstPCmpGtD:
- case kX86InstPCmpGtQ:
- // Clear the read flag. This prevents variable alloc/spill.
- this->_vars[0].vflags = kVarAllocWrite;
- --this->_vars[0].vdata->regReadCount;
- break;
-
- // ----------------------------------------------------------------------
- // [Nop]
- // ----------------------------------------------------------------------
-
- // AND Instructions.
- case kX86InstAnd:
- case kX86InstAndPD:
- case kX86InstAndPS:
- case kX86InstPAnd:
- // OR Instructions.
- case kX86InstOr:
- case kX86InstOrPD:
- case kX86InstOrPS:
- case kX86InstPOr:
- // XCHG Instruction.
- case kX86InstXchg:
- // Clear the write flag.
- this->_vars[0].vflags = kVarAllocRead;
- --this->_vars[0].vdata->regWriteCount;
- break;
- }
- }
- ++x86Context._currentOffset;
-
-#undef __GET_VARIABLE
-}
-
-CompilerItem *X86CompilerInst::translate(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- X86Compiler *x86Compiler = this->getCompiler();
-
- uint32_t i;
- uint32_t variablesCount = this->_variablesCount;
-
- if (variablesCount > 0)
- {
- // These variables are used by the instruction and we set current offset
- // to their work offsets -> getSpillCandidate never return the variable
- // used this instruction.
- for (i = 0; i < variablesCount; ++i)
- this->_vars[i].vdata->workOffset = x86Context._currentOffset;
-
- // Alloc variables used by the instruction (special first).
- for (i = 0; i < variablesCount; ++i)
- {
- VarAllocRecord &r = this->_vars[i];
- // Alloc variables with specific register first.
- if (r.vflags & kVarAllocSpecial)
- x86Context.allocVar(r.vdata, r.regMask, r.vflags);
- }
-
- for (i = 0; i < variablesCount; ++i)
- {
- VarAllocRecord &r = this->_vars[i];
- // Alloc variables without specific register last.
- if (!(r.vflags & kVarAllocSpecial))
- x86Context.allocVar(r.vdata, r.regMask, r.vflags);
- }
-
- x86Context.translateOperands(this->_operands, this->_operandsCount);
- }
-
- if (this->_memOp && (this->_memOp->getId() & kOperandIdTypeMask) == kOperandIdTypeVar)
- {
- X86CompilerVar *cv = x86Compiler->_getVar(this->_memOp->getId());
- ASMJIT_ASSERT(cv);
-
- switch (cv->state)
- {
- case kVarStateUnused:
- cv->state = kVarStateMem;
- break;
- case kVarStateReg:
- cv->changed = false;
- x86Context.unuseVar(cv, kVarStateMem);
- }
- }
-
- for (i = 0; i < variablesCount; ++i)
- x86Context._unuseVarOnEndOfScope(this, &this->_vars[i]);
-
- return this->translated();
-}
-
-void X86CompilerInst::emit(Assembler &a)
-{
- X86Assembler &x86Asm = static_cast<X86Assembler &>(a);
-
- x86Asm._inlineComment = this->_comment;
- x86Asm._emitOptions = this->_emitOptions;
-
- if (this->isSpecial())
- {
- // ${SPECIAL_INSTRUCTION_HANDLING_BEGIN}
- switch (this->_code)
- {
- case kX86InstCpuId:
- x86Asm._emitInstruction(this->_code);
- return;
-
- case kX86InstCbw:
- case kX86InstCdq:
- case kX86InstCdqe:
- case kX86InstCwd:
- case kX86InstCwde:
- case kX86InstCqo:
- x86Asm._emitInstruction(this->_code);
- return;
-
- case kX86InstCmpXCHG:
- x86Asm._emitInstruction(this->_code, &this->_operands[1], &this->_operands[2]);
- return;
-
- case kX86InstCmpXCHG8B:
-#ifdef ASMJIT_X64
- case kX86InstCmpXCHG16B:
-#endif // ASMJIT_X64
- x86Asm._emitInstruction(this->_code, &this->_operands[4]);
- return;
-
-#ifdef ASMJIT_X86
- case kX86InstDaa:
- case kX86InstDas:
- x86Asm._emitInstruction(this->_code);
- return;
-#endif // ASMJIT_X86
-
- case kX86InstIMul:
- case kX86InstMul:
- case kX86InstIDiv:
- case kX86InstDiv:
- // INST dst_lo (implicit), dst_hi (implicit), src (explicit)
- ASMJIT_ASSERT(this->_operandsCount == 3);
- x86Asm._emitInstruction(this->_code, &this->_operands[2]);
- return;
-
- case kX86InstMovPtr:
- break;
-
- case kX86InstLahf:
- case kX86InstSahf:
- x86Asm._emitInstruction(this->_code);
- return;
-
- case kX86InstMaskMovQ:
- case kX86InstMaskMovDQU:
- x86Asm._emitInstruction(this->_code, &this->_operands[1], &this->_operands[2]);
- return;
-
- case kX86InstEnter:
- case kX86InstLeave:
- // TODO: SPECIAL INSTRUCTION.
- break;
-
- case kX86InstRet:
- // TODO: SPECIAL INSTRUCTION.
- break;
-
- case kX86InstMonitor:
- case kX86InstMWait:
- // TODO: MONITOR/MWAIT (COMPILER).
- break;
-
- case kX86InstPop:
- case kX86InstPopAD:
- case kX86InstPopFD:
- case kX86InstPopFQ:
- // TODO: SPECIAL INSTRUCTION.
- break;
-
- case kX86InstPush:
- case kX86InstPushAD:
- case kX86InstPushFD:
- case kX86InstPushFQ:
- // TODO: SPECIAL INSTRUCTION.
- break;
-
- case kX86InstRcl:
- case kX86InstRcr:
- case kX86InstRol:
- case kX86InstRor:
- case kX86InstSal:
- case kX86InstSar:
- case kX86InstShl:
- case kX86InstShr:
- x86Asm._emitInstruction(this->_code, &this->_operands[0], &cl);
- return;
-
- case kX86InstShld:
- case kX86InstShrd:
- x86Asm._emitInstruction(this->_code, &this->_operands[0], &this->_operands[1], &cl);
- return;
-
- case kX86InstRdtsc:
- case kX86InstRdtscP:
- x86Asm._emitInstruction(this->_code);
- return;
-
- case kX86InstRepLodSB:
- case kX86InstRepLodSD:
- case kX86InstRepLodSQ:
- case kX86InstRepLodSW:
- case kX86InstRepMovSB:
- case kX86InstRepMovSD:
- case kX86InstRepMovSQ:
- case kX86InstRepMovSW:
- case kX86InstRepStoSB:
- case kX86InstRepStoSD:
- case kX86InstRepStoSQ:
- case kX86InstRepStoSW:
- case kX86InstRepECmpSB:
- case kX86InstRepECmpSD:
- case kX86InstRepECmpSQ:
- case kX86InstRepECmpSW:
- case kX86InstRepEScaSB:
- case kX86InstRepEScaSD:
- case kX86InstRepEScaSQ:
- case kX86InstRepEScaSW:
- case kX86InstRepNECmpSB:
- case kX86InstRepNECmpSD:
- case kX86InstRepNECmpSQ:
- case kX86InstRepNECmpSW:
- case kX86InstRepNEScaSB:
- case kX86InstRepNEScaSD:
- case kX86InstRepNEScaSQ:
- case kX86InstRepNEScaSW:
- x86Asm._emitInstruction(this->_code);
- return;
-
- default:
- ASMJIT_ASSERT(0);
- }
- // ${SPECIAL_INSTRUCTION_HANDLING_END}
- }
-
- switch (this->_operandsCount)
- {
- case 0:
- x86Asm._emitInstruction(this->_code);
- break;
- case 1:
- x86Asm._emitInstruction(this->_code, &this->_operands[0]);
- break;
- case 2:
- x86Asm._emitInstruction(this->_code, &this->_operands[0], &this->_operands[1]);
- break;
- case 3:
- x86Asm._emitInstruction(this->_code, &this->_operands[0], &this->_operands[1], &this->_operands[2]);
- break;
- default:
- ASMJIT_ASSERT(0);
- }
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerInst - Misc]
-// ============================================================================
-
-int X86CompilerInst::getMaxSize() const
-{
- // TODO: Instruction max size.
- return 15;
-}
-
-bool X86CompilerInst::_tryUnuseVar(CompilerVar *_v)
-{
- X86CompilerVar *cv = static_cast<X86CompilerVar *>(_v);
-
- for (uint32_t i = 0; i < this->_variablesCount; ++i)
- if (this->_vars[i].vdata == cv)
- {
- this->_vars[i].vflags |= kVarAllocUnuseAfterUse;
- return true;
- }
-
- return false;
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerJmpInst - Construction / Destruction]
-// ============================================================================
-
-X86CompilerJmpInst::X86CompilerJmpInst(X86Compiler *x86Compiler, uint32_t code, Operand *opData, uint32_t opCount) : X86CompilerInst(x86Compiler, code, opData, opCount)
-{
- this->_jumpTarget = x86Compiler->_getTarget(this->_operands[0].getId());
- ++this->_jumpTarget->_jumpsCount;
-
- this->_jumpNext = static_cast<X86CompilerJmpInst *>(this->_jumpTarget->_from);
- this->_jumpTarget->_from = this;
-
- // The 'jmp' is always taken, conditional jump can contain hint, we detect it.
- if (this->getCode() == kX86InstJmp)
- this->setInstFlag(kX86CompilerInstFlagIsTaken);
- else if (opCount > 1 && opData[1].isImm() && reinterpret_cast<Imm *>(&opData[1])->getValue() == kCondHintLikely)
- this->setInstFlag(kX86CompilerInstFlagIsTaken);
-}
-
-X86CompilerJmpInst::~X86CompilerJmpInst()
-{
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerJmpInst - Interface]
-// ============================================================================
-
-void X86CompilerJmpInst::prepare(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- this->_offset = x86Context._currentOffset;
-
- // Update _isTaken to true if this is conditional backward jump. This behavior
- // can be overridden by using kCondHintUnlikely when using the instruction.
- if (this->getCode() != kX86InstJmp && this->_operandsCount == 1 && this->_jumpTarget->getOffset() < getOffset())
- this->setInstFlag(kX86CompilerInstFlagIsTaken);
-
- // Now patch all variables where jump location is in the active range.
- if (this->_jumpTarget->getOffset() != kInvalidValue && x86Context._active)
- {
- X86CompilerVar *first = static_cast<X86CompilerVar *>(x86Context._active);
- X86CompilerVar *var = first;
- uint32_t jumpOffset = this->_jumpTarget->getOffset();
-
- do
- {
- if (var->firstItem)
- {
- ASMJIT_ASSERT(var->lastItem);
- uint32_t start = var->firstItem->getOffset();
- uint32_t end = var->lastItem->getOffset();
-
- if (jumpOffset >= start && jumpOffset <= end)
- var->lastItem = this;
- }
- var = var->nextActive;
- } while (var != first);
- }
-
- ++x86Context._currentOffset;
-}
-
-CompilerItem* X86CompilerJmpInst::translate(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
-
- // Translate using X86CompilerInst.
- CompilerItem *ret = X86CompilerInst::translate(cc);
-
- // We jump with item if its kX86InstJUMP (not based on condiiton) and it
- // points into yet unknown location.
- if (this->_code == kX86InstJmp && !this->_jumpTarget->isTranslated())
- {
- x86Context.addBackwardCode(this);
- ret = this->_jumpTarget;
- }
- else
- {
- this->_state = x86Context._saveState();
- if (this->_jumpTarget->isTranslated())
- this->doJump(cc);
- else
- {
- // State is not known, so we need to call doJump() later. Compiler will
- // do it for us.
- x86Context.addForwardJump(this);
- this->_jumpTarget->_state = this->_state;
- }
-
- // Mark next code as unreachable, cleared by a next label (CompilerTarget).
- if (this->_code == kX86InstJmp)
- x86Context._isUnreachable = 1;
- }
-
- // Need to traverse over all active variables and unuse them if their scope ends
- // here.
- if (x86Context._active)
- {
- X86CompilerVar *first = static_cast<X86CompilerVar *>(x86Context._active);
- X86CompilerVar *var = first;
-
- do
- {
- x86Context._unuseVarOnEndOfScope(this, var);
- var = var->nextActive;
- } while (var != first);
- }
-
- return ret;
-}
-
-void X86CompilerJmpInst::emit(Assembler &a)
-{
- static const unsigned MAXIMUM_SHORT_JMP_SIZE = 127;
-
- // Try to minimize size of jump using SHORT jump (8-bit displacement) by
- // traversing into the target and calculating the maximum code size. We
- // end when code size reaches MAXIMUM_SHORT_JMP_SIZE.
- if (!(this->_emitOptions & kX86EmitOptionShortJump) && this->getJumpTarget()->getOffset() > this->getOffset())
- {
- // Calculate the code size.
- unsigned codeSize = 0;
- CompilerItem *cur = this->getNext();
- CompilerItem *target = this->getJumpTarget();
-
- while (cur)
- {
- if (cur == target)
- {
- // Target found, we can tell assembler to generate short form of jump.
- this->_emitOptions |= kX86EmitOptionShortJump;
- goto _End;
- }
-
- int s = cur->getMaxSize();
- if (s == -1)
- break;
-
- codeSize += s;
- if (codeSize > MAXIMUM_SHORT_JMP_SIZE)
- break;
-
- cur = cur->getNext();
- }
- }
-
-_End:
- X86CompilerInst::emit(a);
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerJmpInst - DoJump]
-// ============================================================================
-
-void X86CompilerJmpInst::doJump(CompilerContext &cc)
-{
- X86CompilerContext &x86Context = static_cast<X86CompilerContext &>(cc);
- X86Compiler *x86Compiler = this->getCompiler();
-
- // The state have to be already known. The doJump() method is called by
- // translate() or by Compiler in case that it's forward jump.
- ASMJIT_ASSERT(this->_jumpTarget->getState());
-
- if (this->getCode() == kX86InstJmp || (this->isTaken() && this->_jumpTarget->getOffset() < this->getOffset()))
- // Instruction type is JMP or conditional jump that should be taken (likely).
- // We can set state here instead of jumping out, setting state and jumping
- // to _jumpTarget.
- //
- // NOTE: We can't use this technique if instruction is forward conditional
- // jump. The reason is that when generating code we can't change state here,
- // because the next instruction depends on it.
- x86Context._restoreState(this->_jumpTarget->getState(), this->_jumpTarget->getOffset());
- else
- {
- // Instruction type is JMP or conditional jump that should be not normally
- // taken. If we need add code that will switch between different states we
- // add it after the end of function body (after epilog, using 'ExtraBlock').
- CompilerItem *ext = x86Context.getExtraBlock();
- CompilerItem *old = x86Compiler->setCurrentItem(ext);
-
- x86Context._restoreState(this->_jumpTarget->getState(), this->_jumpTarget->getOffset());
-
- if (x86Compiler->getCurrentItem() != ext)
- {
- // Add the jump to the target.
- x86Compiler->jmp(this->_jumpTarget->_label);
- ext = x86Compiler->getCurrentItem();
-
- // The x86Context._restoreState() method emitted some instructions so we need to
- // patch the jump.
- Label L = x86Compiler->newLabel();
- x86Compiler->setCurrentItem(x86Context.getExtraBlock());
- x86Compiler->bind(L);
-
- // Finally, patch the jump target.
- ASMJIT_ASSERT(this->_operandsCount > 0);
- this->_operands[0] = L; // Operand part (Label).
- this->_jumpTarget = x86Compiler->_getTarget(L.getId()); // Compiler part (CompilerTarget).
- }
-
- x86Context.setExtraBlock(ext);
- x86Compiler->setCurrentItem(old);
-
- // Assign state back.
- x86Context._assignState(static_cast<X86CompilerState *>(this->_state));
- }
-}
-
-// ============================================================================
-// [AsmJit::X86CompilerJmpInst - GetJumpTarget]
-// ============================================================================
-
-CompilerTarget *X86CompilerJmpInst::getJumpTarget() const
-{
- return this->_jumpTarget;
-}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86compileritem.h
+++ /dev/null
@@ -1,280 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../x86/x86assembler.h"
-#include "../x86/x86compiler.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit {
-
-//! @addtogroup AsmJit_X86
-//! @{
-
-// ============================================================================
-// [AsmJit::X86CompilerAlign]
-// ============================================================================
-
-//! @brief Compiler align item.
-struct X86CompilerAlign : public CompilerAlign
-{
- ASMJIT_NO_COPY(X86CompilerAlign)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref CompilerAlign instance.
- ASMJIT_API X86CompilerAlign(X86Compiler* x86Compiler, uint32_t size = 0);
- //! @brief Destroy the @ref CompilerAlign instance.
- ASMJIT_API virtual ~X86CompilerAlign();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get compiler as @ref X86Compiler.
- X86Compiler* getCompiler() const
- { return reinterpret_cast<X86Compiler*>(_compiler); }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void emit(Assembler& a);
-};
-
-// ============================================================================
-// [AsmJit::X86CompilerHint]
-// ============================================================================
-
-//! @brief @ref X86Compiler variable hint item.
-struct X86CompilerHint : public CompilerHint
-{
- ASMJIT_NO_COPY(X86CompilerHint)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref X86CompilerHint instance.
- ASMJIT_API X86CompilerHint(X86Compiler* compiler, X86CompilerVar* var, uint32_t hintId, uint32_t hintValue);
- //! @brief Destroy the @ref X86CompilerHint instance.
- ASMJIT_API virtual ~X86CompilerHint();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get variable as @ref X86CompilerVar.
- X86CompilerVar* getVar() const
- { return reinterpret_cast<X86CompilerVar*>(_var); }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void prepare(CompilerContext& cc);
- ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
-
- // --------------------------------------------------------------------------
- // [Misc]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual int getMaxSize() const;
-};
-
-// ============================================================================
-// [AsmJit::X86CompilerTarget]
-// ============================================================================
-
-//! @brief X86Compiler target item.
-struct X86CompilerTarget : public CompilerTarget
-{
- ASMJIT_NO_COPY(X86CompilerTarget)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref X86CompilerTarget instance.
- ASMJIT_API X86CompilerTarget(X86Compiler* x86Compiler, const Label& target);
- //! @brief Destroy the @ref X86CompilerTarget instance.
- ASMJIT_API virtual ~X86CompilerTarget();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get compiler as @ref X86Compiler.
- X86Compiler* getCompiler() const
- { return reinterpret_cast<X86Compiler*>(_compiler); }
-
- //! @brief Get state as @ref X86CompilerState.
- X86CompilerState* getState() const
- { return reinterpret_cast<X86CompilerState*>(_state); }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void prepare(CompilerContext& cc);
- ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
- ASMJIT_API virtual void emit(Assembler& a);
-};
-
-// ============================================================================
-// [AsmJit::X86CompilerInst]
-// ============================================================================
-
-//! @brief @ref X86Compiler instruction item.
-struct X86CompilerInst : public CompilerInst
-{
- ASMJIT_NO_COPY(X86CompilerInst)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref X86CompilerInst instance.
- ASMJIT_API X86CompilerInst(X86Compiler* x86Compiler, uint32_t code, Operand* opData, uint32_t opCount);
- //! @brief Destroy the @ref X86CompilerInst instance.
- ASMJIT_API virtual ~X86CompilerInst();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get compiler as @ref X86Compiler.
- X86Compiler* getCompiler() const
- { return reinterpret_cast<X86Compiler*>(_compiler); }
-
- //! @brief Get whether the instruction is special.
- bool isSpecial() const
- { return !!(_instFlags & kX86CompilerInstFlagIsSpecial); }
-
- //! @brief Get whether the instruction is FPU.
- bool isFpu() const
- { return !!(_instFlags & kX86CompilerInstFlagIsFpu); }
-
- //! @brief Get whether the instruction is used with GpbLo register.
- bool isGpbLoUsed() const
- { return !!(_instFlags & kX86CompilerInstFlagIsGpbLoUsed); }
-
- //! @brief Get whether the instruction is used with GpbHi register.
- bool isGpbHiUsed() const
- { return !!(_instFlags & kX86CompilerInstFlagIsGpbHiUsed); }
-
- //! @brief Get memory operand.
- Mem* getMemOp()
- { return _memOp; }
-
- //! @brief Set memory operand.
- void setMemOp(Mem* memOp)
- { _memOp = memOp; }
-
- //! @brief Get operands array (3 operands total).
- VarAllocRecord* getVars()
- { return _vars; }
-
- //! @brief Get operands array (3 operands total).
- const VarAllocRecord* getVars() const
- { return _vars; }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void prepare(CompilerContext& cc);
- ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
- ASMJIT_API virtual void emit(Assembler& a);
-
- // --------------------------------------------------------------------------
- // [Misc]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual int getMaxSize() const;
- ASMJIT_API virtual bool _tryUnuseVar(CompilerVar* v);
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Memory operand or NULL.
- Mem* _memOp;
- //! @brief Variables (extracted from operands).
- VarAllocRecord* _vars;
-};
-
-// ============================================================================
-// [AsmJit::X86CompilerJmpInst]
-// ============================================================================
-
-//! @brief @ref X86Compiler "jmp" instruction item.
-struct X86CompilerJmpInst : public X86CompilerInst
-{
- ASMJIT_NO_COPY(X86CompilerJmpInst)
-
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- ASMJIT_API X86CompilerJmpInst(X86Compiler* x86Compiler, uint32_t code, Operand* opData, uint32_t opCount);
- ASMJIT_API virtual ~X86CompilerJmpInst();
-
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- X86CompilerJmpInst* getJumpNext() const
- { return _jumpNext; }
-
- bool isTaken() const
- { return !!(_instFlags & kX86CompilerInstFlagIsTaken); }
-
- // --------------------------------------------------------------------------
- // [Interface]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual void prepare(CompilerContext& cc);
- ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
- ASMJIT_API virtual void emit(Assembler& a);
-
- // --------------------------------------------------------------------------
- // [DoJump]
- // --------------------------------------------------------------------------
-
- ASMJIT_API void doJump(CompilerContext& cc);
-
- // --------------------------------------------------------------------------
- // [Jump]
- // --------------------------------------------------------------------------
-
- ASMJIT_API virtual CompilerTarget* getJumpTarget() const;
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Jump target.
- X86CompilerTarget* _jumpTarget;
- //! @brief Next jump to the same target in a single linked list.
- X86CompilerJmpInst *_jumpNext;
- //! @brief State associated with the jump.
- X86CompilerState* _state;
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86context.cpp
@@ -1,1 +1,5696 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Guard]
+#include "../build.h"
+#if !defined(ASMJIT_DISABLE_COMPILER) && (defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64))
+
+// [Dependencies - AsmJit]
+#include "../base/intutil.h"
+#include "../base/string.h"
+#include "../x86/x86assembler.h"
+#include "../x86/x86compiler.h"
+#include "../x86/x86context_p.h"
+#include "../x86/x86cpuinfo.h"
+#include "../x86/x86scheduler_p.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [Forward Declarations]
+// ============================================================================
+
+static Error X86Context_translateOperands(X86Context* self, Operand* opList, uint32_t opCount);
+
+// ============================================================================
+// [asmjit::X86Context - Utils]
+// ============================================================================
+
+// Getting `VarClass` is the only safe operation when dealing with denormalized
+// `varType`. Any other property would require to map vType to the architecture
+// specific type.
+static ASMJIT_INLINE uint32_t x86VarTypeToClass(uint32_t vType) {
+ ASMJIT_ASSERT(vType < kX86VarTypeCount);
+ return _x86VarInfo[vType].getClass();
+}
+
+// ============================================================================
+// [asmjit::X86Context - Annotate]
+// ============================================================================
+
+// Annotation is also used by ASMJIT_TRACE.
+#ifndef ASMJIT_DISABLE_LOGGER
+static void X86Context_annotateVariable(X86Context*,
+ StringBuilder& sb, const VarData* vd) {
+
+ const char* name = vd->getName();
+ if (name && name[0] != '\0') {
+ sb.appendString(name);
+ }
+ else {
+ sb.appendChar('v');
+ sb.appendUInt(vd->getId() & kOperandIdNum);
+ }
+}
+
+static void X86Context_annotateOperand(X86Context* self,
+ StringBuilder& sb, const Operand* op) {
+
+ if (op->isVar()) {
+ X86Context_annotateVariable(self, sb, self->_compiler->getVdById(op->getId()));
+ }
+ else if (op->isMem()) {
+ const X86Mem* m = static_cast<const X86Mem*>(op);
+ bool isAbsolute = false;
+
+ sb.appendChar('[');
+ switch (m->getMemType()) {
+ case kMemTypeBaseIndex:
+ case kMemTypeStackIndex:
+ // [base + index << shift + displacement]
+ X86Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getBase()));
+ break;
+
+ case kMemTypeLabel:
+ // [label + index << shift + displacement]
+ sb.appendFormat("L%u", m->getBase());
+ break;
+
+ case kMemTypeAbsolute:
+ // [absolute]
+ isAbsolute = true;
+ sb.appendUInt(static_cast<uint32_t>(m->getDisplacement()), 16);
+ break;
+ }
+
+ if (m->hasIndex()) {
+ sb.appendChar('+');
+ X86Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getIndex()));
+
+ if (m->getShift()) {
+ sb.appendChar('*');
+ sb.appendChar("1248"[m->getShift() & 3]);
+ }
+ }
+
+ if (m->getDisplacement() && !isAbsolute) {
+ uint32_t base = 10;
+ int32_t dispOffset = m->getDisplacement();
+
+ char prefix = '+';
+ if (dispOffset < 0) {
+ dispOffset = -dispOffset;
+ prefix = '-';
+ }
+
+ sb.appendChar(prefix);
+ /*
+ if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) {
+ sb.appendString("0x", 2);
+ base = 16;
+ }
+ */
+ sb.appendUInt(static_cast<uint32_t>(dispOffset), base);
+ }
+
+ sb.appendChar(']');
+ }
+ else if (op->isImm()) {
+ const Imm* i = static_cast<const Imm*>(op);
+ int64_t val = i->getInt64();
+
+ /*
+ if ((loggerOptions & (1 << kLoggerOptionHexImmediate)) && static_cast<uint64_t>(val) > 9)
+ sb.appendUInt(static_cast<uint64_t>(val), 16);
+ else*/
+ sb.appendInt(val, 10);
+ }
+ else if (op->isLabel()) {
+ sb.appendFormat("L%u", op->getId());
+ }
+ else {
+ sb.appendString("None", 4);
+ }
+}
+
+static bool X86Context_annotateInstruction(X86Context* self,
+ StringBuilder& sb, uint32_t code, const Operand* opList, uint32_t opCount) {
+
+ sb.appendString(_x86InstInfo[code].getInstName());
+ for (uint32_t i = 0; i < opCount; i++) {
+ if (i == 0)
+ sb.appendChar(' ');
+ else
+ sb.appendString(", ", 2);
+ X86Context_annotateOperand(self, sb, &opList[i]);
+ }
+ return true;
+}
+#endif // !ASMJIT_DISABLE_LOGGER
+
+#ifdef ASMJIT_TRACE
+static void X86Context_traceNode(X86Context* self, Node* node_) {
+ StringBuilderT<256> sb;
+
+ switch (node_->getType()) {
+ case kNodeTypeAlign: {
+ AlignNode* node = static_cast<AlignNode*>(node_);
+ sb.appendFormat(".align %u (%s)",
+ node->getOffset(),
+ node->getMode() == kAlignCode ? "code" : "data");
+ break;
+ }
+
+ case kNodeTypeEmbed: {
+ EmbedNode* node = static_cast<EmbedNode*>(node_);
+ sb.appendFormat(".embed (%u bytes)", node->getSize());
+ break;
+ }
+
+ case kNodeTypeComment: {
+ CommentNode* node = static_cast<CommentNode*>(node_);
+ sb.appendFormat("; %s", node->getComment());
+ break;
+ }
+
+ case kNodeTypeHint: {
+ HintNode* node = static_cast<HintNode*>(node_);
+ static const char* hint[16] = {
+ "alloc",
+ "spill",
+ "save",
+ "save-unuse",
+ "unuse"
+ };
+ sb.appendFormat("[%s] %s",
+ hint[node->getHint()], node->getVd()->getName());
+ break;
+ }
+
+ case kNodeTypeTarget: {
+ TargetNode* node = static_cast<TargetNode*>(node_);
+ sb.appendFormat("L%u: (NumRefs=%u)",
+ node->getLabelId(),
+ node->getNumRefs());
+ break;
+ }
+
+ case kNodeTypeInst: {
+ InstNode* node = static_cast<InstNode*>(node_);
+ X86Context_annotateInstruction(self, sb,
+ node->getCode(), node->getOpList(), node->getOpCount());
+ break;
+ }
+
+ case kNodeTypeFunc: {
+ FuncNode* node = static_cast<FuncNode*>(node_);
+ sb.appendFormat("[func]");
+ break;
+ }
+
+ case kNodeTypeEnd: {
+ EndNode* node = static_cast<EndNode*>(node_);
+ sb.appendFormat("[end]");
+ break;
+ }
+
+ case kNodeTypeRet: {
+ RetNode* node = static_cast<RetNode*>(node_);
+ sb.appendFormat("[ret]");
+ break;
+ }
+
+ case kNodeTypeCall: {
+ CallNode* node = static_cast<CallNode*>(node_);
+ sb.appendFormat("[call]");
+ break;
+ }
+
+ case kNodeTypeSArg: {
+ SArgNode* node = static_cast<SArgNode*>(node_);
+ sb.appendFormat("[sarg]");
+ break;
+ }
+
+ default: {
+ sb.appendFormat("[unknown]");
+ break;
+ }
+ }
+
+ ASMJIT_TLOG("[%05u] %s\n", node_->getFlowId(), sb.getData());
+}
+#endif // ASMJIT_TRACE
+
+// ============================================================================
+// [asmjit::X86Context - Construction / Destruction]
+// ============================================================================
+
+X86Context::X86Context(X86Compiler* compiler) : Context(compiler) {
+ _varMapToVaListOffset = ASMJIT_OFFSET_OF(X86VarMap, _list);
+ _regCount = compiler->_regCount;
+
+ _zsp = compiler->zsp;
+ _zbp = compiler->zbp;
+
+ _memSlot._vmem.type = kMemTypeStackIndex;
+ _memSlot.setGpdBase(compiler->getArch() == kArchX86);
+
+#ifndef ASMJIT_DISABLE_LOGGER
+ _emitComments = compiler->hasLogger();
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ _state = &_x86State;
+ reset();
+}
+
+X86Context::~X86Context() {}
+
+// ============================================================================
+// [asmjit::X86Context - Reset]
+// ============================================================================
+
+void X86Context::reset(bool) {
+ Context::reset();
+
+ _x86State.reset(0);
+ _clobberedRegs.reset();
+
+ _stackFrameCell = nullptr;
+ _gaRegs[kX86RegClassGp ] = IntUtil::bits(_regCount.getGp()) & ~IntUtil::mask(kX86RegIndexSp);
+ _gaRegs[kX86RegClassFp ] = IntUtil::bits(_regCount.getFp());
+ _gaRegs[kX86RegClassMm ] = IntUtil::bits(_regCount.getMm());
+ _gaRegs[kX86RegClassXyz] = IntUtil::bits(_regCount.getXyz());
+
+ _argBaseReg = kInvalidReg; // Used by patcher.
+ _varBaseReg = kInvalidReg; // Used by patcher.
+
+ _argBaseOffset = 0; // Used by patcher.
+ _varBaseOffset = 0; // Used by patcher.
+
+ _argActualDisp = 0; // Used by translator.
+ _varActualDisp = 0; // Used by translator.
+}
+
+// ============================================================================
+// [asmjit::X86SpecialInst]
+// ============================================================================
+
+struct X86SpecialInst {
+ uint8_t inReg;
+ uint8_t outReg;
+ uint16_t flags;
+};
+
+static const X86SpecialInst x86SpecialInstCpuid[] = {
+ { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg },
+ { kInvalidReg , kX86RegIndexBx, kVarAttrOutReg },
+ { kInvalidReg , kX86RegIndexCx, kVarAttrOutReg },
+ { kInvalidReg , kX86RegIndexDx, kVarAttrOutReg }
+};
+
+static const X86SpecialInst x86SpecialInstCbwCdqeCwde[] = {
+ { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg }
+};
+
+static const X86SpecialInst x86SpecialInstCdqCwdCqo[] = {
+ { kInvalidReg , kX86RegIndexDx, kVarAttrOutReg },
+ { kX86RegIndexAx, kInvalidReg , kVarAttrInReg }
+};
+
+static const X86SpecialInst x86SpecialInstCmpxchg[] = {
+ { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg },
+ { kInvalidReg , kInvalidReg , kVarAttrInOutReg },
+ { kInvalidReg , kInvalidReg , kVarAttrInReg }
+};
+
+static const X86SpecialInst x86SpecialInstCmpxchg8b16b[] = {
+ { kX86RegIndexDx, kX86RegIndexDx, kVarAttrInOutReg },
+ { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg },
+ { kX86RegIndexCx, kInvalidReg , kVarAttrInReg },
+ { kX86RegIndexBx, kInvalidReg , kVarAttrInReg }
+};
+
+static const X86SpecialInst x86SpecialInstDaaDas[] = {
+ { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg }
+};
+
+static const X86SpecialInst x86SpecialInstDiv[] = {
+ { kInvalidReg , kX86RegIndexDx, kVarAttrInOutReg },
+ { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg },
+ { kInvalidReg , kInvalidReg , kVarAttrInReg }
+};
+
+static const X86SpecialInst x86SpecialInstJecxz[] = {
+ { kX86RegIndexCx, kInvalidReg , kVarAttrInReg }
+};
+
+static const X86SpecialInst x86SpecialInstLods[] = {
+ { kInvalidReg , kX86RegIndexAx, kVarAttrOutReg },
+ { kX86RegIndexSi, kX86RegIndexSi, kVarAttrInOutReg },
+ { kX86RegIndexCx, kX86RegIndexCx, kVarAttrInOutReg }
+};
+
+static const X86SpecialInst x86SpecialInstMul[] = {
+ { kInvalidReg , kX86RegIndexDx, kVarAttrOutReg },
+ { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg },
+ { kInvalidReg , kInvalidReg , kVarAttrInReg }
+};
+
+static const X86SpecialInst x86SpecialInstMovPtr[] = {
+ { kInvalidReg , kX86RegIndexAx, kVarAttrOutReg },
+ { kX86RegIndexAx, kInvalidReg , kVarAttrInReg }
+};
+
+static const X86SpecialInst x86SpecialInstMovsCmps[] = {
+ { kX86RegIndexDi, kX86RegIndexDi, kVarAttrInOutReg },
+ { kX86RegIndexSi, kX86RegIndexSi, kVarAttrInOutReg },
+ { kX86RegIndexCx, kX86RegIndexCx, kVarAttrInOutReg }
+};
+
+static const X86SpecialInst x86SpecialInstLahf[] = {
+ { kInvalidReg , kX86RegIndexAx, kVarAttrOutReg }
+};
+
+static const X86SpecialInst x86SpecialInstSahf[] = {
+ { kX86RegIndexAx, kInvalidReg , kVarAttrInReg }
+};
+
+static const X86SpecialInst x86SpecialInstMaskmovqMaskmovdqu[] = {
+ { kInvalidReg , kX86RegIndexDi, kVarAttrInReg },
+ { kInvalidReg , kInvalidReg , kVarAttrInReg },
+ { kInvalidReg , kInvalidReg , kVarAttrInReg }
+};
+
+static const X86SpecialInst x86SpecialInstRdtscRdtscp[] = {
+ { kInvalidReg , kX86RegIndexDx, kVarAttrOutReg },
+ { kInvalidReg , kX86RegIndexAx, kVarAttrOutReg },
+ { kInvalidReg , kX86RegIndexCx, kVarAttrOutReg }
+};
+
+static const X86SpecialInst x86SpecialInstRot[] = {
+ { kInvalidReg , kInvalidReg , kVarAttrInOutReg },
+ { kX86RegIndexCx, kInvalidReg , kVarAttrInReg }
+};
+
+static const X86SpecialInst x86SpecialInstScas[] = {
+ { kX86RegIndexDi, kX86RegIndexDi, kVarAttrInOutReg },
+ { kX86RegIndexAx, kInvalidReg , kVarAttrInReg },
+ { kX86RegIndexCx, kX86RegIndexCx, kVarAttrInOutReg }
+};
+
+static const X86SpecialInst x86SpecialInstShlrd[] = {
+ { kInvalidReg , kInvalidReg , kVarAttrInOutReg },
+ { kInvalidReg , kInvalidReg , kVarAttrInReg },
+ { kX86RegIndexCx, kInvalidReg , kVarAttrInReg }
+};
+
+static const X86SpecialInst x86SpecialInstStos[] = {
+ { kX86RegIndexDi, kInvalidReg , kVarAttrInReg },
+ { kX86RegIndexAx, kInvalidReg , kVarAttrInReg },
+ { kX86RegIndexCx, kX86RegIndexCx, kVarAttrInOutReg }
+};
+
+static const X86SpecialInst x86SpecialInstBlend[] = {
+ { kInvalidReg , kInvalidReg , kVarAttrOutReg },
+ { kInvalidReg , kInvalidReg , kVarAttrInReg },
+ { 0 , kInvalidReg , kVarAttrInReg }
+};
+
+static ASMJIT_INLINE const X86SpecialInst* X86SpecialInst_get(uint32_t code, const Operand* opList, uint32_t opCount) {
+ switch (code) {
+ case kX86InstIdCpuid:
+ return x86SpecialInstCpuid;
+
+ case kX86InstIdCbw:
+ case kX86InstIdCdqe:
+ case kX86InstIdCwde:
+ return x86SpecialInstCbwCdqeCwde;
+
+ case kX86InstIdCdq:
+ case kX86InstIdCwd:
+ case kX86InstIdCqo:
+ return x86SpecialInstCdqCwdCqo;
+
+ case kX86InstIdCmpsB:
+ case kX86InstIdCmpsD:
+ case kX86InstIdCmpsQ:
+ case kX86InstIdCmpsW:
+ case kX86InstIdRepeCmpsB:
+ case kX86InstIdRepeCmpsD:
+ case kX86InstIdRepeCmpsQ:
+ case kX86InstIdRepeCmpsW:
+ case kX86InstIdRepneCmpsB:
+ case kX86InstIdRepneCmpsD:
+ case kX86InstIdRepneCmpsQ:
+ case kX86InstIdRepneCmpsW:
+ return x86SpecialInstMovsCmps;
+
+ case kX86InstIdCmpxchg:
+ return x86SpecialInstCmpxchg;
+
+ case kX86InstIdCmpxchg8b:
+ case kX86InstIdCmpxchg16b:
+ return x86SpecialInstCmpxchg8b16b;
+
+ case kX86InstIdDaa:
+ case kX86InstIdDas:
+ return x86SpecialInstDaaDas;
+
+ case kX86InstIdJecxz:
+ return x86SpecialInstJecxz;
+
+ case kX86InstIdIdiv:
+ case kX86InstIdDiv:
+ return x86SpecialInstDiv;
+
+ case kX86InstIdImul:
+ if (opCount == 2)
+ return nullptr;
+ if (opCount == 3 && !(opList[0].isVar() && opList[1].isVar() && opList[2].isVarOrMem()))
+ return nullptr;
+ // ... Fall through ...
+ case kX86InstIdMul:
+ return x86SpecialInstMul;
+
+ case kX86InstIdMovPtr:
+ return x86SpecialInstMovPtr;
+
+ case kX86InstIdLodsB:
+ case kX86InstIdLodsD:
+ case kX86InstIdLodsQ:
+ case kX86InstIdLodsW:
+ case kX86InstIdRepLodsB:
+ case kX86InstIdRepLodsD:
+ case kX86InstIdRepLodsQ:
+ case kX86InstIdRepLodsW:
+ return x86SpecialInstLods;
+
+ case kX86InstIdMovsB:
+ case kX86InstIdMovsD:
+ case kX86InstIdMovsQ:
+ case kX86InstIdMovsW:
+ case kX86InstIdRepMovsB:
+ case kX86InstIdRepMovsD:
+ case kX86InstIdRepMovsQ:
+ case kX86InstIdRepMovsW:
+ return x86SpecialInstMovsCmps;
+
+ case kX86InstIdLahf:
+ return x86SpecialInstLahf;
+
+ case kX86InstIdSahf:
+ return x86SpecialInstSahf;
+
+ case kX86InstIdMaskmovq:
+ case kX86InstIdMaskmovdqu:
+ return x86SpecialInstMaskmovqMaskmovdqu;
+
+ // Not supported.
+ case kX86InstIdEnter:
+ case kX86InstIdLeave:
+ return nullptr;
+
+ // Not supported.
+ case kX86InstIdRet:
+ return nullptr;
+
+ case kX86InstIdMonitor:
+ case kX86InstIdMwait:
+ // TODO: [COMPILER] Monitor/MWait.
+ return nullptr;
+
+ case kX86InstIdPop:
+ // TODO: [COMPILER] Pop.
+ return nullptr;
+
+ // Not supported.
+ case kX86InstIdPopa:
+ case kX86InstIdPopf:
+ return nullptr;
+
+ case kX86InstIdPush:
+ // TODO: [COMPILER] Push.
+ return nullptr;
+
+ // Not supported.
+ case kX86InstIdPusha:
+ case kX86InstIdPushf:
+ return nullptr;
+
+ // Rot instruction is special only if the last operand is a variable.
+ case kX86InstIdRcl:
+ case kX86InstIdRcr:
+ case kX86InstIdRol:
+ case kX86InstIdRor:
+ case kX86InstIdSal:
+ case kX86InstIdSar:
+ case kX86InstIdShl:
+ case kX86InstIdShr:
+ if (!opList[1].isVar())
+ return nullptr;
+ return x86SpecialInstRot;
+
+ // Shld/Shrd instruction is special only if the last operand is a variable.
+ case kX86InstIdShld:
+ case kX86InstIdShrd:
+ if (!opList[2].isVar())
+ return nullptr;
+ return x86SpecialInstShlrd;
+
+ case kX86InstIdRdtsc:
+ case kX86InstIdRdtscp:
+ return x86SpecialInstRdtscRdtscp;
+
+ case kX86InstIdScasB:
+ case kX86InstIdScasD:
+ case kX86InstIdScasQ:
+ case kX86InstIdScasW:
+ case kX86InstIdRepeScasB:
+ case kX86InstIdRepeScasD:
+ case kX86InstIdRepeScasQ:
+ case kX86InstIdRepeScasW:
+ case kX86InstIdRepneScasB:
+ case kX86InstIdRepneScasD:
+ case kX86InstIdRepneScasQ:
+ case kX86InstIdRepneScasW:
+ return x86SpecialInstScas;
+
+ case kX86InstIdStosB:
+ case kX86InstIdStosD:
+ case kX86InstIdStosQ:
+ case kX86InstIdStosW:
+ case kX86InstIdRepStosB:
+ case kX86InstIdRepStosD:
+ case kX86InstIdRepStosQ:
+ case kX86InstIdRepStosW:
+ return x86SpecialInstStos;
+
+ case kX86InstIdBlendvpd:
+ case kX86InstIdBlendvps:
+ case kX86InstIdPblendvb:
+ return x86SpecialInstBlend;
+
+ default:
+ return nullptr;
+ }
+}
+
+// ============================================================================
+// [asmjit::X86Context - EmitLoad]
+// ============================================================================
+
+void X86Context::emitLoad(VarData* vd, uint32_t regIndex, const char* reason) {
+ ASMJIT_ASSERT(regIndex != kInvalidReg);
+
+ X86Compiler* compiler = getCompiler();
+ X86Mem m = getVarMem(vd);
+
+ Node* node = nullptr;
+ bool comment = _emitComments;
+
+ switch (vd->getType()) {
+ case kVarTypeInt8:
+ case kVarTypeUInt8:
+ node = compiler->emit(kX86InstIdMov, x86::gpb_lo(regIndex), m);
+ if (comment) goto _Comment;
+ break;
+
+ case kVarTypeInt16:
+ case kVarTypeUInt16:
+ node = compiler->emit(kX86InstIdMov, x86::gpw(regIndex), m);
+ if (comment) goto _Comment;
+ break;
+
+ case kVarTypeInt32:
+ case kVarTypeUInt32:
+ node = compiler->emit(kX86InstIdMov, x86::gpd(regIndex), m);
+ if (comment) goto _Comment;
+ break;
+
+#ifdef ASMJIT_BUILD_X64
+ case kVarTypeInt64:
+ case kVarTypeUInt64:
+ node = compiler->emit(kX86InstIdMov, x86::gpq(regIndex), m);
+ if (comment) goto _Comment;
+ break;
+#endif // ASMJIT_BUILD_X64
+
+ case kVarTypeFp32:
+ case kVarTypeFp64:
+ // TODO: [COMPILER] FPU.
+ break;
+
+ case kX86VarTypeMm:
+ node = compiler->emit(kX86InstIdMovq, x86::mm(regIndex), m);
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmm:
+ node = compiler->emit(kX86InstIdMovdqa, x86::xmm(regIndex), m);
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmmSs:
+ node = compiler->emit(kX86InstIdMovss, x86::xmm(regIndex), m);
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmmSd:
+ node = compiler->emit(kX86InstIdMovsd, x86::xmm(regIndex), m);
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmmPs:
+ node = compiler->emit(kX86InstIdMovaps, x86::xmm(regIndex), m);
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmmPd:
+ node = compiler->emit(kX86InstIdMovapd, x86::xmm(regIndex), m);
+ if (comment) goto _Comment;
+ break;
+ }
+ return;
+
+_Comment:
+ node->setComment(compiler->_stringZone.sformat("[%s] %s", reason, vd->getName()));
+}
+
+// ============================================================================
+// [asmjit::X86Context - EmitSave]
+// ============================================================================
+
+void X86Context::emitSave(VarData* vd, uint32_t regIndex, const char* reason) {
+ ASMJIT_ASSERT(regIndex != kInvalidReg);
+
+ X86Compiler* compiler = getCompiler();
+ X86Mem m = getVarMem(vd);
+
+ Node* node = nullptr;
+ bool comment = _emitComments;
+
+ switch (vd->getType()) {
+ case kVarTypeInt8:
+ case kVarTypeUInt8:
+ node = compiler->emit(kX86InstIdMov, m, x86::gpb_lo(regIndex));
+ if (comment) goto _Comment;
+ break;
+
+ case kVarTypeInt16:
+ case kVarTypeUInt16:
+ node = compiler->emit(kX86InstIdMov, m, x86::gpw(regIndex));
+ if (comment) goto _Comment;
+ break;
+
+ case kVarTypeInt32:
+ case kVarTypeUInt32:
+ node = compiler->emit(kX86InstIdMov, m, x86::gpd(regIndex));
+ if (comment) goto _Comment;
+ break;
+
+#ifdef ASMJIT_BUILD_X64
+ case kVarTypeInt64:
+ case kVarTypeUInt64:
+ node = compiler->emit(kX86InstIdMov, m, x86::gpq(regIndex));
+ if (comment) goto _Comment;
+ break;
+#endif // ASMJIT_BUILD_X64
+
+ case kVarTypeFp32:
+ case kVarTypeFp64:
+ // TODO: [COMPILER] FPU.
+ break;
+
+ case kX86VarTypeMm:
+ node = compiler->emit(kX86InstIdMovq, m, x86::mm(regIndex));
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmm:
+ node = compiler->emit(kX86InstIdMovdqa, m, x86::xmm(regIndex));
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmmSs:
+ node = compiler->emit(kX86InstIdMovss, m, x86::xmm(regIndex));
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmmSd:
+ node = compiler->emit(kX86InstIdMovsd, m, x86::xmm(regIndex));
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmmPs:
+ node = compiler->emit(kX86InstIdMovaps, m, x86::xmm(regIndex));
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmmPd:
+ node = compiler->emit(kX86InstIdMovapd, m, x86::xmm(regIndex));
+ if (comment) goto _Comment;
+ break;
+ }
+ return;
+
+_Comment:
+ node->setComment(compiler->_stringZone.sformat("[%s] %s", reason, vd->getName()));
+}
+
+// ============================================================================
+// [asmjit::X86Context - EmitMove]
+// ============================================================================
+
+void X86Context::emitMove(VarData* vd, uint32_t toRegIndex, uint32_t fromRegIndex, const char* reason) {
+ ASMJIT_ASSERT(toRegIndex != kInvalidReg);
+ ASMJIT_ASSERT(fromRegIndex != kInvalidReg);
+
+ X86Compiler* compiler = getCompiler();
+
+ Node* node = nullptr;
+ bool comment = _emitComments;
+
+ switch (vd->getType()) {
+ case kVarTypeInt8:
+ case kVarTypeUInt8:
+ case kVarTypeInt16:
+ case kVarTypeUInt16:
+ case kVarTypeInt32:
+ case kVarTypeUInt32:
+ node = compiler->emit(kX86InstIdMov, x86::gpd(toRegIndex), x86::gpd(fromRegIndex));
+ if (comment) goto _Comment;
+ break;
+
+#ifdef ASMJIT_BUILD_X64
+ case kVarTypeInt64:
+ case kVarTypeUInt64:
+ node = compiler->emit(kX86InstIdMov, x86::gpq(toRegIndex), x86::gpq(fromRegIndex));
+ if (comment) goto _Comment;
+ break;
+#endif // ASMJIT_BUILD_X64
+
+ case kVarTypeFp32:
+ case kVarTypeFp64:
+ // TODO: [COMPILER] FPU.
+ break;
+
+ case kX86VarTypeMm:
+ node = compiler->emit(kX86InstIdMovq, x86::mm(toRegIndex), x86::mm(fromRegIndex));
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmm:
+ node = compiler->emit(kX86InstIdMovaps, x86::xmm(toRegIndex), x86::xmm(fromRegIndex));
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmmSs:
+ node = compiler->emit(kX86InstIdMovss, x86::xmm(toRegIndex), x86::xmm(fromRegIndex));
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmmSd:
+ node = compiler->emit(kX86InstIdMovsd, x86::xmm(toRegIndex), x86::xmm(fromRegIndex));
+ if (comment) goto _Comment;
+ break;
+
+ case kX86VarTypeXmmPs:
+ case kX86VarTypeXmmPd:
+ node = compiler->emit(kX86InstIdMovaps, x86::xmm(toRegIndex), x86::xmm(fromRegIndex));
+ if (comment) goto _Comment;
+ break;
+ }
+ return;
+
+_Comment:
+ node->setComment(compiler->_stringZone.sformat("[%s] %s", reason, vd->getName()));
+}
+
+// ============================================================================
+// [asmjit::X86Context - EmitSwap]
+// ============================================================================
+
+void X86Context::emitSwapGp(VarData* aVd, VarData* bVd, uint32_t aIndex, uint32_t bIndex, const char* reason) {
+ ASMJIT_ASSERT(aIndex != kInvalidReg);
+ ASMJIT_ASSERT(bIndex != kInvalidReg);
+
+ X86Compiler* compiler = getCompiler();
+
+ Node* node = nullptr;
+ bool comment = _emitComments;
+
+#ifdef ASMJIT_BUILD_X64
+ uint32_t vType = IntUtil::iMax(aVd->getType(), bVd->getType());
+
+ if (vType == kVarTypeInt64 || vType == kVarTypeUInt64) {
+ node = compiler->emit(kX86InstIdXchg, x86::gpq(aIndex), x86::gpq(bIndex));
+ if (comment) goto _Comment;
+ return;
+ }
+#endif // ASMJIT_BUILD_X64
+
+ node = compiler->emit(kX86InstIdXchg, x86::gpd(aIndex), x86::gpd(bIndex));
+ if (comment) goto _Comment;
+ return;
+
+_Comment:
+ node->setComment(compiler->_stringZone.sformat("[%s] %s, %s", reason, aVd->getName(), bVd->getName()));
+}
+
+// ============================================================================
+// [asmjit::X86Context - EmitPushSequence / EmitPopSequence]
+// ============================================================================
+
+void X86Context::emitPushSequence(uint32_t regs) {
+ X86Compiler* compiler = getCompiler();
+ uint32_t i = 0;
+
+ X86GpReg gpReg(_zsp);
+ while (regs != 0) {
+ ASMJIT_ASSERT(i < _regCount.getGp());
+ if ((regs & 0x1) != 0)
+ compiler->emit(kX86InstIdPush, gpReg.setIndex(i));
+ i++;
+ regs >>= 1;
+ }
+}
+
+void X86Context::emitPopSequence(uint32_t regs) {
+ X86Compiler* compiler = getCompiler();
+
+ if (regs == 0)
+ return;
+
+ uint32_t i = static_cast<int32_t>(_regCount.getGp());
+ uint32_t mask = 0x1 << static_cast<uint32_t>(i - 1);
+
+ X86GpReg gpReg(_zsp);
+ while (i) {
+ i--;
+ if ((regs & mask) != 0)
+ compiler->emit(kX86InstIdPop, gpReg.setIndex(i));
+ mask >>= 1;
+ }
+}
+
+// ============================================================================
+// [asmjit::X86Context - EmitConvertVarToVar]
+// ============================================================================
+
+void X86Context::emitConvertVarToVar(uint32_t dstType, uint32_t dstIndex, uint32_t srcType, uint32_t srcIndex) {
+ X86Compiler* compiler = getCompiler();
+
+ switch (dstType) {
+ case kVarTypeInt8:
+ case kVarTypeUInt8:
+ case kVarTypeInt16:
+ case kVarTypeUInt16:
+ case kVarTypeInt32:
+ case kVarTypeUInt32:
+ case kVarTypeInt64:
+ case kVarTypeUInt64:
+ break;
+
+ case kX86VarTypeXmmPs:
+ if (srcType == kX86VarTypeXmmPd || srcType == kX86VarTypeYmmPd) {
+ compiler->emit(kX86InstIdCvtpd2ps, x86::xmm(dstIndex), x86::xmm(srcIndex));
+ return;
+ }
+ // ... Fall through ...
+
+ case kX86VarTypeXmmSs:
+ if (srcType == kX86VarTypeXmmSd || srcType == kX86VarTypeXmmPd || srcType == kX86VarTypeYmmPd) {
+ compiler->emit(kX86InstIdCvtsd2ss, x86::xmm(dstIndex), x86::xmm(srcIndex));
+ return;
+ }
+
+ if (IntUtil::inInterval<uint32_t>(srcType, _kVarTypeIntStart, _kVarTypeIntEnd)) {
+ // TODO:
+ ASMJIT_ASSERT(!"Reached");
+ }
+ break;
+
+ case kX86VarTypeXmmPd:
+ if (srcType == kX86VarTypeXmmPs || srcType == kX86VarTypeYmmPs) {
+ compiler->emit(kX86InstIdCvtps2pd, x86::xmm(dstIndex), x86::xmm(srcIndex));
+ return;
+ }
+ // ... Fall through ...
+
+ case kX86VarTypeXmmSd:
+ if (srcType == kX86VarTypeXmmSs || srcType == kX86VarTypeXmmPs || srcType == kX86VarTypeYmmPs) {
+ compiler->emit(kX86InstIdCvtss2sd, x86::xmm(dstIndex), x86::xmm(srcIndex));
+ return;
+ }
+
+ if (IntUtil::inInterval<uint32_t>(srcType, _kVarTypeIntStart, _kVarTypeIntEnd)) {
+ // TODO:
+ ASMJIT_ASSERT(!"Reached");
+ }
+ break;
+ }
+}
+
+// ============================================================================
+// [asmjit::X86Context - EmitMoveVarOnStack / EmitMoveImmOnStack]
+// ============================================================================
+
+void X86Context::emitMoveVarOnStack(
+ uint32_t dstType, const X86Mem* dst,
+ uint32_t srcType, uint32_t srcIndex) {
+
+ ASMJIT_ASSERT(srcIndex != kInvalidReg);
+ X86Compiler* compiler = getCompiler();
+
+ X86Mem m0(*dst);
+ X86Reg r0, r1;
+
+ uint32_t regSize = compiler->getRegSize();
+ uint32_t instCode;
+
+ switch (dstType) {
+ case kVarTypeInt8:
+ case kVarTypeUInt8:
+ // Move DWORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt8, kVarTypeUInt64))
+ goto _MovGpD;
+
+ // Move DWORD (Mm).
+ if (IntUtil::inInterval<uint32_t>(srcType, kX86VarTypeMm, kX86VarTypeMm))
+ goto _MovMmD;
+
+ // Move DWORD (Xmm).
+ if (IntUtil::inInterval<uint32_t>(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd))
+ goto _MovXmmD;
+
+ break;
+
+ case kVarTypeInt16:
+ case kVarTypeUInt16:
+ // Extend BYTE->WORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt8, kVarTypeUInt8)) {
+ r1.setSize(1);
+ r1.setCode(kX86RegTypeGpbLo, srcIndex);
+
+ instCode = (dstType == kVarTypeInt16 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx;
+ goto _ExtendMovGpD;
+ }
+
+ // Move DWORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt16, kVarTypeUInt64))
+ goto _MovGpD;
+
+ // Move DWORD (Mm).
+ if (IntUtil::inInterval<uint32_t>(srcType, kX86VarTypeMm, kX86VarTypeMm))
+ goto _MovMmD;
+
+ // Move DWORD (Xmm).
+ if (IntUtil::inInterval<uint32_t>(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd))
+ goto _MovXmmD;
+
+ break;
+
+ case kVarTypeInt32:
+ case kVarTypeUInt32:
+ // Extend BYTE->DWORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt8, kVarTypeUInt8)) {
+ r1.setSize(1);
+ r1.setCode(kX86RegTypeGpbLo, srcIndex);
+
+ instCode = (dstType == kVarTypeInt32 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx;
+ goto _ExtendMovGpD;
+ }
+
+ // Extend WORD->DWORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt16, kVarTypeUInt16)) {
+ r1.setSize(2);
+ r1.setCode(kX86RegTypeGpw, srcIndex);
+
+ instCode = (dstType == kVarTypeInt32 && srcType == kVarTypeInt16) ? kX86InstIdMovsx : kX86InstIdMovzx;
+ goto _ExtendMovGpD;
+ }
+
+ // Move DWORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt32, kVarTypeUInt64))
+ goto _MovGpD;
+
+ // Move DWORD (Mm).
+ if (IntUtil::inInterval<uint32_t>(srcType, kX86VarTypeMm, kX86VarTypeMm))
+ goto _MovMmD;
+
+ // Move DWORD (Xmm).
+ if (IntUtil::inInterval<uint32_t>(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd))
+ goto _MovXmmD;
+ break;
+
+ case kVarTypeInt64:
+ case kVarTypeUInt64:
+ // Extend BYTE->QWORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt8, kVarTypeUInt8)) {
+ r1.setSize(1);
+ r1.setCode(kX86RegTypeGpbLo, srcIndex);
+
+ instCode = (dstType == kVarTypeInt64 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx;
+ goto _ExtendMovGpXQ;
+ }
+
+ // Extend WORD->QWORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt16, kVarTypeUInt16)) {
+ r1.setSize(2);
+ r1.setCode(kX86RegTypeGpw, srcIndex);
+
+ instCode = (dstType == kVarTypeInt64 && srcType == kVarTypeInt16) ? kX86InstIdMovsx : kX86InstIdMovzx;
+ goto _ExtendMovGpXQ;
+ }
+
+ // Extend DWORD->QWORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt32, kVarTypeUInt32)) {
+ r1.setSize(4);
+ r1.setCode(kX86RegTypeGpd, srcIndex);
+
+ instCode = kX86InstIdMovsxd;
+ if (dstType == kVarTypeInt64 && srcType == kVarTypeInt32)
+ goto _ExtendMovGpXQ;
+ else
+ goto _ZeroExtendGpDQ;
+ }
+
+ // Move QWORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt64, kVarTypeUInt64))
+ goto _MovGpQ;
+
+ // Move QWORD (Mm).
+ if (IntUtil::inInterval<uint32_t>(srcType, kX86VarTypeMm, kX86VarTypeMm))
+ goto _MovMmQ;
+
+ // Move QWORD (Xmm).
+ if (IntUtil::inInterval<uint32_t>(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd))
+ goto _MovXmmQ;
+ break;
+
+ case kX86VarTypeMm:
+ // Extend BYTE->QWORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt8, kVarTypeUInt8)) {
+ r1.setSize(1);
+ r1.setCode(kX86RegTypeGpbLo, srcIndex);
+
+ instCode = kX86InstIdMovzx;
+ goto _ExtendMovGpXQ;
+ }
+
+ // Extend WORD->QWORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt16, kVarTypeUInt16)) {
+ r1.setSize(2);
+ r1.setCode(kX86RegTypeGpw, srcIndex);
+
+ instCode = kX86InstIdMovzx;
+ goto _ExtendMovGpXQ;
+ }
+
+ // Extend DWORD->QWORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt32, kVarTypeUInt32))
+ goto _ExtendMovGpDQ;
+
+ // Move QWORD (Gp).
+ if (IntUtil::inInterval<uint32_t>(srcType, kVarTypeInt64, kVarTypeUInt64))
+ goto _MovGpQ;
+
+ // Move QWORD (Mm).
+ if (IntUtil::inInterval<uint32_t>(srcType, kX86VarTypeMm, kX86VarTypeMm))
+ goto _MovMmQ;
+
+ // Move QWORD (Xmm).
+ if (IntUtil::inInterval<uint32_t>(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd))
+ goto _MovXmmQ;
+ break;
+
+ case kVarTypeFp32:
+ case kX86VarTypeXmmSs:
+ // Move FLOAT.
+ if (srcType == kX86VarTypeXmmSs || srcType == kX86VarTypeXmmPs || srcType == kX86VarTypeXmm)
+ goto _MovXmmD;
+
+ ASMJIT_ASSERT(!"Reached");
+ break;
+
+ case kVarTypeFp64:
+ case kX86VarTypeXmmSd:
+ // Move DOUBLE.
+ if (srcType == kX86VarTypeXmmSd || srcType == kX86VarTypeXmmPd || srcType == kX86VarTypeXmm)
+ goto _MovXmmQ;
+
+ ASMJIT_ASSERT(!"Reached");
+ break;
+
+ case kX86VarTypeXmm:
+ // TODO: [COMPILER].
+ ASMJIT_ASSERT(!"Reached");
+ break;
+
+ case kX86VarTypeXmmPs:
+ // TODO: [COMPILER].
+ ASMJIT_ASSERT(!"Reached");
+ break;
+
+ case kX86VarTypeXmmPd:
+ // TODO: [COMPILER].
+ ASMJIT_ASSERT(!"Reached");
+ break;
+ }
+ return;
+
+ // Extend+Move Gp.
+_ExtendMovGpD:
+ m0.setSize(4);
+ r0.setSize(4);
+ r0.setCode(kX86RegTypeGpd, srcIndex);
+
+ compiler->emit(instCode, r0, r1);
+ compiler->emit(kX86InstIdMov, m0, r0);
+ return;
+
+_ExtendMovGpXQ:
+ if (regSize == 8) {
+ m0.setSize(8);
+ r0.setSize(8);
+ r0.setCode(kX86RegTypeGpq, srcIndex);
+
+ compiler->emit(instCode, r0, r1);
+ compiler->emit(kX86InstIdMov, m0, r0);
+ }
+ else {
+ m0.setSize(4);
+ r0.setSize(4);
+ r0.setCode(kX86RegTypeGpd, srcIndex);
+
+ compiler->emit(instCode, r0, r1);
+
+_ExtendMovGpDQ:
+ compiler->emit(kX86InstIdMov, m0, r0);
+ m0.adjust(4);
+ compiler->emit(kX86InstIdAnd, m0, 0);
+ }
+ return;
+
+_ZeroExtendGpDQ:
+ m0.setSize(4);
+ r0.setSize(4);
+ r0.setCode(kX86RegTypeGpd, srcIndex);
+ goto _ExtendMovGpDQ;
+
+ // Move Gp.
+_MovGpD:
+ m0.setSize(4);
+ r0.setSize(4);
+ r0.setCode(kX86RegTypeGpd, srcIndex);
+ compiler->emit(kX86InstIdMov, m0, r0);
+ return;
+
+_MovGpQ:
+ m0.setSize(8);
+ r0.setSize(8);
+ r0.setCode(kX86RegTypeGpq, srcIndex);
+ compiler->emit(kX86InstIdMov, m0, r0);
+ return;
+
+ // Move Mm.
+_MovMmD:
+ m0.setSize(4);
+ r0.setSize(8);
+ r0.setCode(kX86RegTypeMm, srcIndex);
+ compiler->emit(kX86InstIdMovd, m0, r0);
+ return;
+
+_MovMmQ:
+ m0.setSize(8);
+ r0.setSize(8);
+ r0.setCode(kX86RegTypeMm, srcIndex);
+ compiler->emit(kX86InstIdMovq, m0, r0);
+ return;
+
+ // Move Xmm.
+_MovXmmD:
+ m0.setSize(4);
+ r0.setSize(16);
+ r0.setCode(kX86RegTypeXmm, srcIndex);
+ compiler->emit(kX86InstIdMovss, m0, r0);
+ return;
+
+_MovXmmQ:
+ m0.setSize(8);
+ r0.setSize(16);
+ r0.setCode(kX86RegTypeXmm, srcIndex);
+ compiler->emit(kX86InstIdMovlps, m0, r0);
+}
+
+void X86Context::emitMoveImmOnStack(uint32_t dstType, const X86Mem* dst, const Imm* src) {
+ X86Compiler* compiler = getCompiler();
+
+ X86Mem mem(*dst);
+ Imm imm(*src);
+
+ uint32_t regSize = compiler->getRegSize();
+
+ // One stack entry is equal to the native register size. That means that if
+ // we want to move 32-bit integer on the stack, we need to extend it to 64-bit
+ // integer.
+ mem.setSize(regSize);
+
+ switch (dstType) {
+ case kVarTypeInt8:
+ case kVarTypeUInt8:
+ imm.truncateTo8Bits();
+ goto _Move32;
+
+ case kVarTypeInt16:
+ case kVarTypeUInt16:
+ imm.truncateTo16Bits();
+ goto _Move32;
+
+ case kVarTypeInt32:
+ case kVarTypeUInt32:
+_Move32:
+ imm.truncateTo32Bits();
+ compiler->emit(kX86InstIdMov, mem, imm);
+ break;
+
+ case kVarTypeInt64:
+ case kVarTypeUInt64:
+_Move64:
+ if (regSize == 4) {
+ uint32_t hi = imm.getUInt32Hi();
+
+ // Lo-Part.
+ compiler->emit(kX86InstIdMov, mem, imm.truncateTo32Bits());
+ mem.adjust(regSize);
+
+ // Hi-Part.
+ compiler->emit(kX86InstIdMov, mem, imm.setUInt32(hi));
+ }
+ else {
+ compiler->emit(kX86InstIdMov, mem, imm);
+ }
+ break;
+
+ case kVarTypeFp32:
+ goto _Move32;
+
+ case kVarTypeFp64:
+ goto _Move64;
+
+ case kX86VarTypeMm:
+ goto _Move64;
+
+ case kX86VarTypeXmm:
+ case kX86VarTypeXmmSs:
+ case kX86VarTypeXmmPs:
+ case kX86VarTypeXmmSd:
+ case kX86VarTypeXmmPd:
+ if (regSize == 4) {
+ uint32_t hi = imm.getUInt32Hi();
+
+ // Lo part.
+ compiler->emit(kX86InstIdMov, mem, imm.truncateTo32Bits());
+ mem.adjust(regSize);
+
+ // Hi part.
+ compiler->emit(kX86InstIdMov, mem, imm.setUInt32(hi));
+ mem.adjust(regSize);
+
+ // Zero part.
+ compiler->emit(kX86InstIdMov, mem, imm.setUInt32(0));
+ mem.adjust(regSize);
+
+ compiler->emit(kX86InstIdMov, mem, imm);
+ }
+ else {
+ // Lo/Hi parts.
+ compiler->emit(kX86InstIdMov, mem, imm);
+ mem.adjust(regSize);
+
+ // Zero part.
+ compiler->emit(kX86InstIdMov, mem, imm.setUInt32(0));
+ }
+ break;
+
+ default:
+ ASMJIT_ASSERT(!"Reached");
+ break;
+ }
+}
+
+// ============================================================================
+// [asmjit::X86Context - EmitMoveImmToReg]
+// ============================================================================
+
+void X86Context::emitMoveImmToReg(uint32_t dstType, uint32_t dstIndex, const Imm* src) {
+ ASMJIT_ASSERT(dstIndex != kInvalidReg);
+ X86Compiler* compiler = getCompiler();
+
+ X86Reg r0;
+ Imm imm(*src);
+
+ switch (dstType) {
+ case kVarTypeInt8:
+ case kVarTypeUInt8:
+ imm.truncateTo8Bits();
+ goto _Move32;
+
+ case kVarTypeInt16:
+ case kVarTypeUInt16:
+ imm.truncateTo16Bits();
+ goto _Move32;
+
+ case kVarTypeInt32:
+ case kVarTypeUInt32:
+_Move32Truncate:
+ imm.truncateTo32Bits();
+_Move32:
+ r0.setSize(4);
+ r0.setCode(kX86RegTypeGpd, dstIndex);
+ compiler->emit(kX86InstIdMov, r0, imm);
+ break;
+
+ case kVarTypeInt64:
+ case kVarTypeUInt64:
+ // Move to Gpd register will also clear high DWORD of Gpq register in
+ // 64-bit mode.
+ if (imm.isUInt32())
+ goto _Move32Truncate;
+
+ r0.setSize(8);
+ r0.setCode(kX86RegTypeGpq, dstIndex);
+ compiler->emit(kX86InstIdMov, r0, imm);
+ break;
+
+ case kVarTypeFp32:
+ case kVarTypeFp64:
+ // TODO: [COMPILER] EmitMoveImmToReg.
+ break;
+
+ case kX86VarTypeMm:
+ // TODO: [COMPILER] EmitMoveImmToReg.
+ break;
+
+ case kX86VarTypeXmm:
+ case kX86VarTypeXmmSs:
+ case kX86VarTypeXmmSd:
+ case kX86VarTypeXmmPs:
+ case kX86VarTypeXmmPd:
+ // TODO: [COMPILER] EmitMoveImmToReg.
+ break;
+
+ default:
+ ASMJIT_ASSERT(!"Reached");
+ break;
+ }
+}
+
+// ============================================================================
+// [asmjit::X86Context - Register Management]
+// ============================================================================
+
+#ifdef ASMJIT_DEBUG
+template<int C>
+static ASMJIT_INLINE void X86Context_checkStateVars(X86Context* self) {
+ X86VarState* state = self->getState();
+ VarData** sVars = state->getListByClass(C);
+
+ uint32_t regIndex;
+ uint32_t regMask;
+ uint32_t regCount = self->_regCount.get(C);
+
+ uint32_t occupied = state->_occupied.get(C);
+ uint32_t modified = state->_modified.get(C);
+
+ for (regIndex = 0, regMask = 1; regIndex < regCount; regIndex++, regMask <<= 1) {
+ VarData* vd = sVars[regIndex];
+
+ if (!vd) {
+ ASMJIT_ASSERT((occupied & regMask) == 0);
+ ASMJIT_ASSERT((modified & regMask) == 0);
+ }
+ else {
+ ASMJIT_ASSERT((occupied & regMask) != 0);
+ ASMJIT_ASSERT((modified & regMask) == (static_cast<uint32_t>(vd->isModified()) << regIndex));
+
+ ASMJIT_ASSERT(vd->getClass() == C);
+ ASMJIT_ASSERT(vd->getState() == kVarStateReg);
+ ASMJIT_ASSERT(vd->getRegIndex() == regIndex);
+ }
+ }
+}
+
+void X86Context::_checkState() {
+ X86Context_checkStateVars<kX86RegClassGp >(this);
+ X86Context_checkStateVars<kX86RegClassMm >(this);
+ X86Context_checkStateVars<kX86RegClassXyz>(this);
+}
+#else
+void X86Context::_checkState() {}
+#endif // ASMJIT_DEBUG
+
+// ============================================================================
+// [asmjit::X86Context - State - Load]
+// ============================================================================
+
+template<int C>
+static ASMJIT_INLINE void X86Context_loadStateVars(X86Context* self, X86VarState* src) {
+ X86VarState* cur = self->getState();
+
+ VarData** cVars = cur->getListByClass(C);
+ VarData** sVars = src->getListByClass(C);
+
+ uint32_t regIndex;
+ uint32_t modified = src->_modified.get(C);
+ uint32_t regCount = self->_regCount.get(C);
+
+ for (regIndex = 0; regIndex < regCount; regIndex++, modified >>= 1) {
+ VarData* vd = sVars[regIndex];
+ cVars[regIndex] = vd;
+
+ if (!vd)
+ continue;
+
+ vd->setState(kVarStateReg);
+ vd->setRegIndex(regIndex);
+ vd->setModified(modified & 0x1);
+ }
+}
+
+void X86Context::loadState(VarState* src_) {
+ X86VarState* cur = getState();
+ X86VarState* src = static_cast<X86VarState*>(src_);
+
+ VarData** vdArray = _contextVd.getData();
+ uint32_t vdCount = static_cast<uint32_t>(_contextVd.getLength());
+
+ // Load allocated variables.
+ X86Context_loadStateVars<kX86RegClassGp >(this, src);
+ X86Context_loadStateVars<kX86RegClassMm >(this, src);
+ X86Context_loadStateVars<kX86RegClassXyz>(this, src);
+
+ // Load masks.
+ cur->_occupied = src->_occupied;
+ cur->_modified = src->_modified;
+
+ // Load states of other variables and clear their 'Modified' flags.
+ for (uint32_t i = 0; i < vdCount; i++) {
+ uint32_t vState = src->_cells[i].getState();
+
+ if (vState == kVarStateReg)
+ continue;
+
+ vdArray[i]->setState(vState);
+ vdArray[i]->setRegIndex(kInvalidReg);
+ vdArray[i]->setModified(false);
+ }
+
+ ASMJIT_X86_CHECK_STATE
+}
+
+// ============================================================================
+// [asmjit::X86Context - State - Save]
+// ============================================================================
+
+VarState* X86Context::saveState() {
+ VarData** vdArray = _contextVd.getData();
+ uint32_t vdCount = static_cast<uint32_t>(_contextVd.getLength());
+
+ size_t size = IntUtil::alignTo<size_t>(
+ sizeof(X86VarState) + vdCount * sizeof(X86StateCell), sizeof(void*));
+
+ X86VarState* cur = getState();
+ X86VarState* dst = _baseZone.allocT<X86VarState>(size);
+
+ if (!dst)
+ return nullptr;
+
+ // Store links.
+ ::memcpy(dst->_list, cur->_list, X86VarState::kAllCount * sizeof(VarData*));
+
+ // Store masks.
+ dst->_occupied = cur->_occupied;
+ dst->_modified = cur->_modified;
+
+ // Store cells.
+ for (uint32_t i = 0; i < vdCount; i++) {
+ VarData* vd = static_cast<VarData*>(vdArray[i]);
+ X86StateCell& cell = dst->_cells[i];
+
+ cell.reset();
+ cell.setState(vd->getState());
+ }
+
+ return dst;
+}
+
+// ============================================================================
+// [asmjit::X86Context - State - Switch]
+// ============================================================================
+
+template<int C>
+static ASMJIT_INLINE void X86Context_switchStateVars(X86Context* self, X86VarState* src) {
+ X86VarState* dst = self->getState();
+
+ VarData** dstVars = dst->getListByClass(C);
+ VarData** srcVars = src->getListByClass(C);
+
+ uint32_t regIndex;
+ uint32_t regMask;
+ uint32_t regCount = self->_regCount.get(C);
+
+ X86StateCell* cells = src->_cells;
+
+ bool didWork;
+ do {
+ didWork = false;
+
+ for (regIndex = 0, regMask = 0x1; regIndex < regCount; regIndex++, regMask <<= 1) {
+ VarData* dVd = dstVars[regIndex];
+ VarData* sVd = srcVars[regIndex];
+
+ if (dVd == sVd)
+ continue;
+
+ if (dVd) {
+ X86StateCell& cell = cells[dVd->getContextId()];
+
+ if (cell.getState() != kVarStateReg) {
+ if (cell.getState() == kVarStateMem)
+ self->spill<C>(dVd);
+ else
+ self->unuse<C>(dVd);
+
+ dVd = nullptr;
+ didWork = true;
+
+ if (!sVd)
+ continue;
+ }
+ }
+
+ if (!dVd && sVd) {
+_MoveOrLoad:
+ if (sVd->getRegIndex() != kInvalidReg)
+ self->move<C>(sVd, regIndex);
+ else
+ self->load<C>(sVd, regIndex);
+
+ didWork = true;
+ continue;
+ }
+
+ if (dVd && !sVd) {
+ X86StateCell& cell = cells[dVd->getContextId()];
+ if (cell.getState() == kVarStateReg)
+ continue;
+
+ if (cell.getState() == kVarStateMem)
+ self->spill<C>(dVd);
+ else
+ self->unuse<C>(dVd);
+
+ didWork = true;
+ continue;
+ }
+ else {
+ X86StateCell& cell = cells[dVd->getContextId()];
+
+ if (cell.getState() == kVarStateReg) {
+ if (dVd->getRegIndex() != kInvalidReg && sVd->getRegIndex() != kInvalidReg) {
+ if (C == kX86RegClassGp) {
+ self->swapGp(dVd, sVd);
+ }
+ else {
+ self->spill<C>(dVd);
+ self->move<C>(sVd, regIndex);
+ }
+
+ didWork = true;
+ continue;
+ }
+ else {
+ didWork = true;
+ continue;
+ }
+ }
+
+ if (cell.getState() == kVarStateMem)
+ self->spill<C>(dVd);
+ else
+ self->unuse<C>(dVd);
+ goto _MoveOrLoad;
+ }
+ }
+ } while (didWork);
+
+ uint32_t dstModified = dst->_modified.get(C);
+ uint32_t srcModified = src->_modified.get(C);
+
+ if (dstModified != srcModified) {
+ for (regIndex = 0, regMask = 0x1; regIndex < regCount; regIndex++, regMask <<= 1) {
+ VarData* vd = dstVars[regIndex];
+
+ if (!vd)
+ continue;
+
+ if ((dstModified & regMask) && !(srcModified & regMask)) {
+ self->save<C>(vd);
+ continue;
+ }
+
+ if (!(dstModified & regMask) && (srcModified & regMask)) {
+ self->modify<C>(vd);
+ continue;
+ }
+ }
+ }
+}
+
+void X86Context::switchState(VarState* src_) {
+ ASMJIT_ASSERT(src_);
+
+ X86VarState* cur = getState();
+ X86VarState* src = static_cast<X86VarState*>(src_);
+
+ // Ignore if both states are equal.
+ if (cur == src)
+ return;
+
+ // Switch variables.
+ X86Context_switchStateVars<kX86RegClassGp >(this, src);
+ X86Context_switchStateVars<kX86RegClassMm >(this, src);
+ X86Context_switchStateVars<kX86RegClassXyz>(this, src);
+
+ // Calculate changed state.
+ VarData** vdArray = _contextVd.getData();
+ uint32_t vdCount = static_cast<uint32_t>(_contextVd.getLength());
+
+ X86StateCell* cells = src->_cells;
+ for (uint32_t i = 0; i < vdCount; i++) {
+ VarData* vd = static_cast<VarData*>(vdArray[i]);
+ X86StateCell& cell = cells[i];
+
+ uint32_t vState = cell.getState();
+ if (vState != kVarStateReg) {
+ vd->setState(vState);
+ vd->setModified(false);
+ }
+ }
+
+ ASMJIT_X86_CHECK_STATE
+}
+
+// ============================================================================
+// [asmjit::X86Context - State - Intersect]
+// ============================================================================
+
+void X86Context::intersectStates(VarState* /*a_*/, VarState* /*b_*/) {
+ //X86VarState* aState = static_cast<X86VarState*>(a_);
+ //X86VarState* bState = static_cast<X86VarState*>(b_);
+
+ // TODO: [COMPILER] Intersect states.
+ ASMJIT_X86_CHECK_STATE
+}
+
+// ============================================================================
+// [asmjit::X86Context - GetJccFlow / GetOppositeJccFlow]
+// ============================================================================
+
+//! \internal
+static ASMJIT_INLINE Node* X86Context_getJccFlow(JumpNode* jNode) {
+ if (jNode->isTaken())
+ return jNode->getTarget();
+ else
+ return jNode->getNext();
+}
+
+//! \internal
+static ASMJIT_INLINE Node* X86Context_getOppositeJccFlow(JumpNode* jNode) {
+ if (jNode->isTaken())
+ return jNode->getNext();
+ else
+ return jNode->getTarget();
+}
+
+// ============================================================================
+// [asmjit::X86Context - SingleVarInst]
+// ============================================================================
+
+//! \internal
+static void X86Context_prepareSingleVarInst(uint32_t code, VarAttr* va) {
+ switch (code) {
+ // - andn reg, reg ; Set all bits in reg to 0.
+ // - xor/pxor reg, reg ; Set all bits in reg to 0.
+ // - sub/psub reg, reg ; Set all bits in reg to 0.
+ // - pcmpgt reg, reg ; Set all bits in reg to 0.
+ // - pcmpeq reg, reg ; Set all bits in reg to 1.
+ case kX86InstIdPandn :
+ case kX86InstIdXor : case kX86InstIdXorpd : case kX86InstIdXorps : case kX86InstIdPxor :
+ case kX86InstIdSub:
+ case kX86InstIdPsubb : case kX86InstIdPsubw : case kX86InstIdPsubd : case kX86InstIdPsubq :
+ case kX86InstIdPsubsb : case kX86InstIdPsubsw : case kX86InstIdPsubusb : case kX86InstIdPsubusw :
+ case kX86InstIdPcmpeqb : case kX86InstIdPcmpeqw : case kX86InstIdPcmpeqd : case kX86InstIdPcmpeqq :
+ case kX86InstIdPcmpgtb : case kX86InstIdPcmpgtw : case kX86InstIdPcmpgtd : case kX86InstIdPcmpgtq :
+ va->delFlags(kVarAttrInReg);
+ break;
+
+ // - and reg, reg ; Nop.
+ // - or reg, reg ; Nop.
+ // - xchg reg, reg ; Nop.
+ case kX86InstIdAnd : case kX86InstIdAndpd : case kX86InstIdAndps : case kX86InstIdPand :
+ case kX86InstIdOr : case kX86InstIdOrpd : case kX86InstIdOrps : case kX86InstIdPor :
+ case kX86InstIdXchg :
+ va->delFlags(kVarAttrOutReg);
+ break;
+ }
+}
+
+// ============================================================================
+// [asmjit::X86Context - Helpers]
+// ============================================================================
+
+//! \internal
+//!
+//! Add unreachable-flow data to the unreachable flow list.
+static ASMJIT_INLINE Error X86Context_addUnreachableNode(X86Context* self, Node* node) {
+ PodList<Node*>::Link* link = self->_baseZone.allocT<PodList<Node*>::Link>();
+ if (!link)
+ return self->setError(kErrorNoHeapMemory);
+
+ link->setValue(node);
+ self->_unreachableList.append(link);
+
+ return kErrorOk;
+}
+
+//! \internal
+//!
+//! Add jump-flow data to the jcc flow list.
+static ASMJIT_INLINE Error X86Context_addJccNode(X86Context* self, Node* node) {
+ PodList<Node*>::Link* link = self->_baseZone.allocT<PodList<Node*>::Link>();
+
+ if (!link)
+ ASMJIT_PROPAGATE_ERROR(self->setError(kErrorNoHeapMemory));
+
+ link->setValue(node);
+ self->_jccList.append(link);
+
+ return kErrorOk;
+}
+
+//! \internal
+//!
+//! Get mask of all registers actually used to pass function arguments.
+static ASMJIT_INLINE X86RegMask X86Context_getUsedArgs(X86Context*, X86CallNode*, X86FuncDecl* decl) {
+ X86RegMask regs;
+ regs.reset();
+
+ uint32_t i;
+ uint32_t argCount = decl->getArgCount();
+
+ for (i = 0; i < argCount; i++) {
+ const FuncInOut& arg = decl->getArg(i);
+ if (!arg.hasRegIndex())
+ continue;
+ regs.add(x86VarTypeToClass(arg.getVarType()), IntUtil::mask(arg.getRegIndex()));
+ }
+
+ return regs;
+}
+
+// ============================================================================
+// [asmjit::X86Context - SArg Insertion]
+// ============================================================================
+
+struct SArgData {
+ VarData* sVd;
+ VarData* cVd;
+ SArgNode* sArg;
+ uint32_t aType;
+};
+
+#define SARG(_Dst_, S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15, S16, S17, S18, S19, S20) \
+ (S0 << 0) | (S1 << 1) | (S2 << 2) | (S3 << 3) | \
+ (S4 << 4) | (S5 << 5) | (S6 << 6) | (S7 << 7) | \
+ (S8 << 8) | (S9 << 9) | (S10 << 10) | (S11 << 11) | \
+ (S12 << 12) | (S13 << 13) | (S14 << 14) | (S15 << 15) | \
+ (S16 << 16) | (S17 << 17) | (S18 << 18) | (S19 << 19) | \
+ (S20 << 20)
+#define A 0 /* Auto-convert (doesn't need conversion step). */
+static const uint32_t X86Context_sArgConvTable[kX86VarTypeCount] = {
+ // dst <- | i8| u8|i16|u16|i32|u32|i64|u64| iP| uP|f32|f64|mmx|xmm|xSs|xPs|xSd|xPd|ymm|yPs|yPd|
+ //--------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ SARG(i8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ),
+ SARG(u8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ),
+ SARG(i16 , A , A , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ),
+ SARG(u16 , A , A , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ),
+ SARG(i32 , A , A , A , A , 0 , 0 , 0 , 0 , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ),
+ SARG(u32 , A , A , A , A , 0 , 0 , 0 , 0 , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ),
+ SARG(i64 , A , A , A , A , A , A , 0 , 0 , A , A , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ),
+ SARG(u64 , A , A , A , A , A , A , 0 , 0 , A , A , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ),
+ SARG(iPtr , A , A , A , A , A , A , A , A , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ),
+ SARG(uPtr , A , A , A , A , A , A , A , A , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ),
+ SARG(f32 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , A , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 ),
+ SARG(f64 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , A , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 ),
+ SARG(mmx , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ),
+ SARG(xmm , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ),
+ SARG(xSs , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 ),
+ SARG(xPs , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 ),
+ SARG(xSd , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 ),
+ SARG(xPd , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 ),
+ SARG(ymm , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ),
+ SARG(yPs , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 ),
+ SARG(yPd , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 )
+};
+#undef A
+#undef SARG
+
+static ASMJIT_INLINE bool X86Context_mustConvertSArg(X86Context*, uint32_t aType, uint32_t sType) {
+ return (X86Context_sArgConvTable[aType] & (1 << sType)) != 0;
+}
+
+static ASMJIT_INLINE uint32_t X86Context_typeOfConvertedSArg(X86Context* self, uint32_t aType, uint32_t sType) {
+ ASMJIT_ASSERT(X86Context_mustConvertSArg(self, aType, sType));
+
+ if (IntUtil::inInterval<uint32_t>(aType, _kVarTypeIntStart, _kVarTypeIntEnd))
+ return aType;
+
+ if (aType == kVarTypeFp32)
+ return kX86VarTypeXmmSs;
+
+ if (aType == kVarTypeFp64)
+ return kX86VarTypeXmmSd;
+
+ if (IntUtil::inInterval<uint32_t>(aType, _kX86VarTypeXmmStart, _kX86VarTypeXmmEnd))
+ return aType;
+
+ if (IntUtil::inInterval<uint32_t>(aType, _kX86VarTypeYmmStart, _kX86VarTypeYmmEnd))
+ return aType;
+
+ ASMJIT_ASSERT(!"Reached");
+ return aType;
+}
+
+static ASMJIT_INLINE Error X86Context_insertSArgNode(
+ X86Context* self, X86CallNode* call,
+ VarData* sVd, const uint32_t* gaRegs,
+ const FuncInOut& arg, uint32_t argIndex,
+ SArgData* sArgList, uint32_t& sArgCount) {
+
+ X86Compiler* compiler = self->getCompiler();
+ uint32_t i;
+
+ uint32_t aType = arg.getVarType();
+ uint32_t sType = sVd->getType();
+
+ // First locate or create sArgBase.
+ for (i = 0; i < sArgCount; i++) {
+ if (sArgList[i].sVd == sVd && !sArgList[i].cVd)
+ break;
+ }
+
+ SArgData* sArgData = &sArgList[i];
+
+ if (i == sArgCount) {
+ sArgData->sVd = sVd;
+ sArgData->cVd = nullptr;
+ sArgData->sArg = nullptr;
+ sArgData->aType = 0xFF;
+ sArgCount++;
+ }
+
+ const X86VarInfo& sInfo = _x86VarInfo[sType];
+ uint32_t sClass = sInfo.getClass();
+
+ if (X86Context_mustConvertSArg(self, aType, sType)) {
+ uint32_t cType = X86Context_typeOfConvertedSArg(self, aType, sType);
+
+ const X86VarInfo& cInfo = _x86VarInfo[cType];
+ uint32_t cClass = cInfo.getClass();
+
+ while (++i < sArgCount) {
+ sArgData = &sArgList[i];
+ if (sArgData->sVd != sVd)
+ break;
+
+ if (sArgData->cVd->getType() != cType || sArgData->aType != aType)
+ continue;
+
+ sArgData->sArg->_args |= IntUtil::mask(argIndex);
+ return kErrorOk;
+ }
+
+ VarData* cVd = compiler->_newVd(cType, cInfo.getSize(), cInfo.getClass(), nullptr);
+ if (!cVd)
+ return kErrorNoHeapMemory;
+
+ SArgNode* sArg = compiler->newNode<SArgNode>(call, sVd, cVd);
+ if (!sArg)
+ return kErrorNoHeapMemory;
+
+ X86VarMap* map = self->newVarMap(2);
+ if (!map)
+ return kErrorNoHeapMemory;
+
+ ASMJIT_PROPAGATE_ERROR(self->_registerContextVar(cVd));
+ ASMJIT_PROPAGATE_ERROR(self->_registerContextVar(sVd));
+
+ map->_vaCount = 2;
+ map->_count.reset();
+ map->_count.add(sClass);
+ map->_count.add(cClass);
+
+ map->_start.reset();
+ map->_inRegs.reset();
+ map->_outRegs.reset();
+ map->_clobberedRegs.reset();
+
+ if (sClass <= cClass) {
+ map->_list[0].setup(sVd, kVarAttrInReg , 0, gaRegs[sClass]);
+ map->_list[1].setup(cVd, kVarAttrOutReg, 0, gaRegs[cClass]);
+ map->_start.set(cClass, sClass != cClass);
+ }
+ else {
+ map->_list[0].setup(cVd, kVarAttrOutReg, 0, gaRegs[cClass]);
+ map->_list[1].setup(sVd, kVarAttrInReg , 0, gaRegs[sClass]);
+ map->_start.set(sClass, 1);
+ }
+
+ sArg->setMap(map);
+ sArg->_args |= IntUtil::mask(argIndex);
+
+ compiler->addNodeBefore(sArg, call);
+ ::memmove(sArgData + 1, sArgData, (sArgCount - i) * sizeof(SArgData));
+
+ sArgData->sVd = sVd;
+ sArgData->cVd = cVd;
+ sArgData->sArg = sArg;
+ sArgData->aType = aType;
+
+ sArgCount++;
+ return kErrorOk;
+ }
+ else {
+ SArgNode* sArg = sArgData->sArg;
+ ASMJIT_PROPAGATE_ERROR(self->_registerContextVar(sVd));
+
+ if (!sArg) {
+ sArg = compiler->newNode<SArgNode>(call, sVd, nullptr);
+ if (!sArg)
+ return kErrorNoHeapMemory;
+
+ X86VarMap* map = self->newVarMap(1);
+ if (!map)
+ return kErrorNoHeapMemory;
+
+ map->_vaCount = 1;
+ map->_count.reset();
+ map->_count.add(sClass);
+ map->_start.reset();
+ map->_inRegs.reset();
+ map->_outRegs.reset();
+ map->_clobberedRegs.reset();
+ map->_list[0].setup(sVd, kVarAttrInReg, 0, gaRegs[sClass]);
+
+ sArg->setMap(map);
+ sArgData->sArg = sArg;
+
+ compiler->addNodeBefore(sArg, call);
+ }
+
+ sArg->_args |= IntUtil::mask(argIndex);
+ return kErrorOk;
+ }
+}
+
+// ============================================================================
+// [asmjit::X86Context - Fetch]
+// ============================================================================
+
+//! \internal
+//!
+//! Prepare the given function `func`.
+//!
+//! For each node:
+//! - Create and assign groupId and flowId.
+//! - Collect all variables and merge them to vaList.
+Error X86Context::fetch() {
+ ASMJIT_TLOG("[Fetch] === Begin ===\n");
+
+ X86Compiler* compiler = getCompiler();
+ X86FuncNode* func = getFunc();
+
+ uint32_t arch = compiler->getArch();
+
+ Node* node_ = func;
+ Node* next = nullptr;
+ Node* stop = getStop();
+
+ //uint32_t groupId = 1;
+ uint32_t flowId = 0;
+
+ VarAttr vaTmpList[80];
+ SArgData sArgList[80];
+
+ PodList<Node*>::Link* jLink = nullptr;
+
+ // Function flags.
+ func->clearFuncFlags(
+ kFuncFlagIsNaked |
+ kX86FuncFlagPushPop |
+ kX86FuncFlagEmms |
+ kX86FuncFlagSFence |
+ kX86FuncFlagLFence );
+
+ if (func->getHint(kFuncHintNaked ) != 0) func->addFuncFlags(kFuncFlagIsNaked );
+ if (func->getHint(kFuncHintCompact ) != 0) func->addFuncFlags(kX86FuncFlagPushPop | kX86FuncFlagEnter | kX86FuncFlagLeave);
+ if (func->getHint(kX86FuncHintPushPop) != 0) func->addFuncFlags(kX86FuncFlagPushPop);
+ if (func->getHint(kX86FuncHintEmms ) != 0) func->addFuncFlags(kX86FuncFlagEmms );
+ if (func->getHint(kX86FuncHintSFence ) != 0) func->addFuncFlags(kX86FuncFlagSFence );
+ if (func->getHint(kX86FuncHintLFence ) != 0) func->addFuncFlags(kX86FuncFlagLFence );
+
+ // Global allocable registers.
+ uint32_t* gaRegs = _gaRegs;
+
+ if (!func->hasFuncFlag(kFuncFlagIsNaked))
+ gaRegs[kX86RegClassGp] &= ~IntUtil::mask(kX86RegIndexBp);
+
+ // Allowed index registers (Gp/Xmm/Ymm).
+ const uint32_t indexMask = IntUtil::bits(_regCount.getGp()) & ~(IntUtil::mask(4, 12));
+
+ // --------------------------------------------------------------------------
+ // [VI Macros]
+ // --------------------------------------------------------------------------
+
+#define VI_BEGIN() \
+ do { \
+ uint32_t vaCount = 0; \
+ X86RegCount regCount; \
+ \
+ X86RegMask inRegs; \
+ X86RegMask outRegs; \
+ X86RegMask clobberedRegs; \
+ \
+ regCount.reset(); \
+ inRegs.reset(); \
+ outRegs.reset(); \
+ clobberedRegs.reset()
+
+#define VI_END(_Node_) \
+ if (vaCount == 0 && clobberedRegs.isEmpty()) \
+ break; \
+ \
+ X86VarMap* map = newVarMap(vaCount); \
+ if (!map) \
+ goto _NoMemory; \
+ \
+ X86RegCount vaIndex; \
+ vaIndex.makeIndex(regCount); \
+ \
+ map->_vaCount = vaCount; \
+ map->_count = regCount; \
+ map->_start = vaIndex; \
+ \
+ map->_inRegs = inRegs; \
+ map->_outRegs = outRegs; \
+ map->_clobberedRegs = clobberedRegs; \
+ \
+ va = vaTmpList; \
+ while (vaCount) { \
+ vd = va->getVd(); \
+ \
+ uint32_t class_ = vd->getClass(); \
+ uint32_t index = vaIndex.get(class_); \
+ \
+ vaIndex.add(class_); \
+ \
+ if (va->_inRegs) \
+ va->_allocableRegs = va->_inRegs; \
+ else if (va->_outRegIndex != kInvalidReg) \
+ va->_allocableRegs = IntUtil::mask(va->_outRegIndex); \
+ else \
+ va->_allocableRegs &= ~inRegs.get(class_); \
+ \
+ vd->_va = nullptr; \
+ map->getVa(index)[0] = va[0]; \
+ \
+ va++; \
+ vaCount--; \
+ } \
+ \
+ _Node_->setMap(map); \
+ } while (0)
+
+#define VI_ADD_VAR(_Vd_, _Va_, _Flags_, _NewAllocable_) \
+ do { \
+ ASMJIT_ASSERT(!_Vd_->_va); \
+ \
+ _Va_ = &vaTmpList[vaCount++]; \
+ _Va_->setup(_Vd_, _Flags_, 0, _NewAllocable_); \
+ _Va_->addVarCount(1); \
+ _Vd_->setVa(_Va_); \
+ \
+ if (_registerContextVar(_Vd_) != kErrorOk) \
+ goto _NoMemory; \
+ regCount.add(_Vd_->getClass()); \
+ } while (0)
+
+#define VI_MERGE_VAR(_Vd_, _Va_, _Flags_, _NewAllocable_) \
+ do { \
+ _Va_ = _Vd_->getVa(); \
+ \
+ if (!_Va_) { \
+ _Va_ = &vaTmpList[vaCount++]; \
+ _Va_->setup(_Vd_, 0, 0, _NewAllocable_); \
+ _Vd_->setVa(_Va_); \
+ \
+ if (_registerContextVar(_Vd_) != kErrorOk) \
+ goto _NoMemory; \
+ regCount.add(_Vd_->getClass()); \
+ } \
+ \
+ _Va_->addFlags(_Flags_); \
+ _Va_->addVarCount(1); \
+ } while (0)
+
+ // --------------------------------------------------------------------------
+ // [Loop]
+ // --------------------------------------------------------------------------
+
+ do {
+_Do:
+ while (node_->isFetched()) {
+_NextGroup:
+ if (!jLink)
+ jLink = _jccList.getFirst();
+ else
+ jLink = jLink->getNext();
+
+ if (!jLink)
+ goto _Done;
+ node_ = X86Context_getOppositeJccFlow(static_cast<JumpNode*>(jLink->getValue()));
+ }
+
+ flowId++;
+
+ next = node_->getNext();
+ node_->setFlowId(flowId);
+
+ ASMJIT_TSEC({
+ X86Context_traceNode(this, node_);
+ });
+
+ switch (node_->getType()) {
+ // ----------------------------------------------------------------------
+ // [Align/Embed]
+ // ----------------------------------------------------------------------
+
+ case kNodeTypeAlign:
+ case kNodeTypeEmbed:
+ break;
+
+ // ----------------------------------------------------------------------
+ // [Hint]
+ // ----------------------------------------------------------------------
+
+ case kNodeTypeHint: {
+ HintNode* node = static_cast<HintNode*>(node_);
+ VI_BEGIN();
+
+ VarData* vd;
+ VarAttr* va;
+
+ if (node->getHint() == kVarHintAlloc) {
+ uint32_t remain[kX86RegClassCount];
+ HintNode* cur = node;
+
+ remain[kX86RegClassGp ] = _regCount.getGp() - 1 - func->hasFuncFlag(kFuncFlagIsNaked);
+ remain[kX86RegClassFp ] = _regCount.getFp();
+ remain[kX86RegClassMm ] = _regCount.getMm();
+
+ // Correct. Instead of using `getXyz()` which may be 32 in 64-bit
+ // mode we use `getGp()`. The reason is that not all registers are
+ // accessible by all instructions when using AVX512, this makes the
+ // algorithm safe.
+ remain[kX86RegClassXyz] = _regCount.getGp();
+
+ // Merge as many alloc-hints as possible.
+ for (;;) {
+ vd = static_cast<VarData*>(cur->getVd());
+ va = vd->getVa();
+
+ uint32_t regClass = vd->getClass();
+ uint32_t regIndex = cur->getValue();
+ uint32_t regMask = 0;
+
+ // We handle both kInvalidReg and kInvalidValue.
+ if (regIndex < kInvalidReg)
+ regMask = IntUtil::mask(regIndex);
+
+ if (!va) {
+ if (inRegs.has(regClass, regMask))
+ break;
+ if (remain[regClass] == 0)
+ break;
+ VI_ADD_VAR(vd, va, kVarAttrInReg, gaRegs[regClass]);
+
+ if (regMask != 0) {
+ inRegs.xor_(regClass, regMask);
+ va->setInRegs(regMask);
+ va->setInRegIndex(regIndex);
+ }
+
+ remain[regClass]--;
+ }
+ else if (regMask != 0) {
+ if (inRegs.has(regClass, regMask) && va->getInRegs() != regMask)
+ break;
+
+ inRegs.xor_(regClass, va->getInRegs() | regMask);
+ va->setInRegs(regMask);
+ va->setInRegIndex(regIndex);
+ }
+
+ if (cur != node)
+ compiler->removeNode(cur);
+
+ cur = static_cast<HintNode*>(node->getNext());
+ if (!cur || cur->getType() != kNodeTypeHint || cur->getHint() != kVarHintAlloc)
+ break;
+ }
+
+ next = node->getNext();
+ }
+ else {
+ vd = static_cast<VarData*>(node->getVd());
+
+ uint32_t flags = 0;
+
+ switch (node->getHint()) {
+ case kVarHintSpill:
+ flags = kVarAttrInMem | kVarAttrSpill;
+ break;
+ case kVarHintSave:
+ flags = kVarAttrInMem;
+ break;
+ case kVarHintSaveAndUnuse:
+ flags = kVarAttrInMem | kVarAttrUnuse;
+ break;
+ case kVarHintUnuse:
+ flags = kVarAttrUnuse;
+ break;
+ }
+
+ VI_ADD_VAR(vd, va, flags, 0);
+ }
+
+ VI_END(node_);
+ break;
+ }
+
+ // ----------------------------------------------------------------------
+ // [Target]
+ // ----------------------------------------------------------------------
+
+ case kNodeTypeTarget: {
+ break;
+ }
+
+ // ----------------------------------------------------------------------
+ // [Inst]
+ // ----------------------------------------------------------------------
+
+ case kNodeTypeInst: {
+ InstNode* node = static_cast<InstNode*>(node_);
+
+ uint32_t code = node->getCode();
+ uint32_t flags = node->getFlags();
+
+ Operand* opList = node->getOpList();
+ uint32_t opCount = node->getOpCount();
+
+ if (opCount) {
+ const X86InstExtendedInfo& extendedInfo = _x86InstInfo[code].getExtendedInfo();
+ const X86SpecialInst* special = nullptr;
+ VI_BEGIN();
+
+ // Collect instruction flags and merge all 'VarAttr's.
+ if (extendedInfo.isFp())
+ flags |= kNodeFlagIsFp;
+
+ if (extendedInfo.isSpecial() && (special = X86SpecialInst_get(code, opList, opCount)))
+ flags |= kNodeFlagIsSpecial;
+
+ uint32_t gpAllowedMask = 0xFFFFFFFF;
+
+ VarData* vd;
+ VarAttr* va;
+ for (uint32_t i = 0; i < opCount; i++) {
+ Operand* op = &opList[i];
+
+ if (op->isVar()) {
+ vd = compiler->getVdById(op->getId());
+ VI_MERGE_VAR(vd, va, 0, gaRegs[vd->getClass()] & gpAllowedMask);
+
+ if (static_cast<X86Var*>(op)->isGpb()) {
+ va->addFlags(static_cast<X86GpVar*>(op)->isGpbLo() ? kX86VarAttrGpbLo : kX86VarAttrGpbHi);
+ if (arch == kArchX86) {
+ // If a byte register is accessed in 32-bit mode we have to limit
+ // all allocable registers for that variable to eax/ebx/ecx/edx.
+ // Other variables are not affected.
+ va->_allocableRegs &= 0x0F;
+ }
+ else {
+ // It's fine if lo-byte register is accessed in 64-bit mode;
+ // however, hi-byte has to be checked and if it's used all
+ // registers (Gp/Xmm) could be only allocated in the lower eight
+ // half. To do that, we patch 'allocableRegs' of all variables
+ // we collected until now and change the allocable restriction
+ // for variables that come after.
+ if (static_cast<X86GpVar*>(op)->isGpbHi()) {
+ va->_allocableRegs &= 0x0F;
+
+ if (gpAllowedMask != 0xFF) {
+ for (uint32_t j = 0; j < i; j++)
+ vaTmpList[j]._allocableRegs &= vaTmpList[j].hasFlag(kX86VarAttrGpbHi) ? 0x0F : 0xFF;
+ gpAllowedMask = 0xFF;
+ }
+ }
+ }
+ }
+
+ if (special) {
+ uint32_t inReg = special[i].inReg;
+ uint32_t outReg = special[i].outReg;
+ uint32_t c;
+
+ if (static_cast<const X86Reg*>(op)->isGp())
+ c = kX86RegClassGp;
+ else
+ c = kX86RegClassXyz;
+
+ if (inReg != kInvalidReg) {
+ uint32_t mask = IntUtil::mask(inReg);
+ inRegs.add(c, mask);
+ va->addInRegs(mask);
+ }
+
+ if (outReg != kInvalidReg) {
+ uint32_t mask = IntUtil::mask(outReg);
+ outRegs.add(c, mask);
+ va->setOutRegIndex(outReg);
+ }
+
+ va->addFlags(special[i].flags);
+ }
+ else {
+ uint32_t inFlags = kVarAttrInReg;
+ uint32_t outFlags = kVarAttrOutReg;
+ uint32_t combinedFlags;
+
+ if (i == 0) {
+ // Read/Write is usualy the combination of the first operand.
+ combinedFlags = inFlags | outFlags;
+
+ // Move instructions typically overwrite the first operand,
+ // but there are some exceptions based on the operands' size
+ // and type.
+ if (extendedInfo.isMove()) {
+ uint32_t movSize = extendedInfo.getMoveSize();
+ uint32_t varSize = vd->getSize();
+
+ // Exception - If the source operand is a memory location
+ // promote move size into 16 bytes.
+ if (extendedInfo.isZeroIfMem() && opList[1].isMem())
+ movSize = 16;
+
+ if (movSize >= varSize) {
+ // If move size is greater than or equal to the size of
+ // the variable there is nothing to do, because the move
+ // will overwrite the variable in all cases.
+ combinedFlags = outFlags;
+ }
+ else if (static_cast<const X86Var*>(op)->isGp()) {
+ uint32_t opSize = static_cast<const X86Var*>(op)->getSize();
+
+ // Move size is zero in case that it should be determined
+ // from the destination register.
+ if (movSize == 0)
+ movSize = opSize;
+
+ // Handle the case that a 32-bit operation in 64-bit mode
+ // always zeroes the rest of the destination register and
+ // the case that move size is actually greater than or
+ // equal to the size of the variable.
+ if (movSize >= 4 || movSize >= varSize)
+ combinedFlags = outFlags;
+ }
+ }
+ // Comparison/Test instructions don't modify any operand.
+ else if (extendedInfo.isTest()) {
+ combinedFlags = inFlags;
+ }
+ // Imul.
+ else if (code == kX86InstIdImul && opCount == 3) {
+ combinedFlags = outFlags;
+ }
+ }
+ else {
+ // Read-Only is usualy the combination of the second/third/fourth operands.
+ combinedFlags = inFlags;
+
+ // Idiv is a special instruction, never handled here.
+ ASMJIT_ASSERT(code != kX86InstIdIdiv);
+
+ // Xchg/Xadd/Imul.
+ if (extendedInfo.isXchg() || (code == kX86InstIdImul && opCount == 3 && i == 1))
+ combinedFlags = inFlags | outFlags;
+ }
+ va->addFlags(combinedFlags);
+ }
+ }
+ else if (op->isMem()) {
+ X86Mem* m = static_cast<X86Mem*>(op);
+ node->setMemOpIndex(i);
+
+ if (OperandUtil::isVarId(m->getBase()) && m->isBaseIndexType()) {
+ vd = compiler->getVdById(m->getBase());
+ if (!vd->isStack()) {
+ VI_MERGE_VAR(vd, va, 0, gaRegs[vd->getClass()] & gpAllowedMask);
+ if (m->getMemType() == kMemTypeBaseIndex) {
+ va->addFlags(kVarAttrInReg);
+ }
+ else {
+ uint32_t inFlags = kVarAttrInMem;
+ uint32_t outFlags = kVarAttrOutMem;
+ uint32_t combinedFlags;
+
+ if (i == 0) {
+ // Default for the first operand.
+ combinedFlags = inFlags | outFlags;
+
+ // Move to memory - setting the right flags is important
+ // as if it's just move to the register. It's just a bit
+ // simpler as there are no special cases.
+ if (extendedInfo.isMove()) {
+ uint32_t movSize = IntUtil::iMax<uint32_t>(extendedInfo.getMoveSize(), m->getSize());
+ uint32_t varSize = vd->getSize();
+
+ if (movSize >= varSize)
+ combinedFlags = outFlags;
+ }
+ // Comparison/Test instructions don't modify any operand.
+ else if (extendedInfo.isTest()) {
+ combinedFlags = inFlags;
+ }
+ }
+ else {
+ // Default for the second operand.
+ combinedFlags = inFlags;
+
+ // Handle Xchg instruction (modifies both operands).
+ if (extendedInfo.isXchg())
+ combinedFlags = inFlags | outFlags;
+ }
+
+ va->addFlags(combinedFlags);
+ }
+ }
+ }
+
+ if (OperandUtil::isVarId(m->getIndex())) {
+ // Restrict allocation to all registers except ESP/RSP/R12.
+ vd = compiler->getVdById(m->getIndex());
+ VI_MERGE_VAR(vd, va, 0, gaRegs[kX86RegClassGp] & gpAllowedMask);
+ va->andAllocableRegs(indexMask);
+ va->addFlags(kVarAttrInReg);
+ }
+ }
+ }
+
+ node->setFlags(flags);
+ if (vaCount) {
+ // Handle instructions which result in zeros/ones or nop if used with the
+ // same destination and source operand.
+ if (vaCount == 1 && opCount >= 2 && opList[0].isVar() && opList[1].isVar() && !node->hasMemOp())
+ X86Context_prepareSingleVarInst(code, &vaTmpList[0]);
+ }
+
+ VI_END(node_);
+ }
+
+ // Handle conditional/unconditional jump.
+ if (node->isJmpOrJcc()) {
+ JumpNode* jNode = static_cast<JumpNode*>(node);
+
+ Node* jNext = jNode->getNext();
+ TargetNode* jTarget = jNode->getTarget();
+
+ // If this jump is unconditional we put next node to unreachable node
+ // list so we can eliminate possible dead code. We have to do this in
+ // all cases since we are unable to translate without fetch() step.
+ //
+ // We also advance our node pointer to the target node to simulate
+ // natural flow of the function.
+ if (jNode->isJmp()) {
+ if (!jNext->isFetched())
+ ASMJIT_PROPAGATE_ERROR(X86Context_addUnreachableNode(this, jNext));
+
+ node_ = jTarget;
+ goto _Do;
+ }
+ else {
+ if (jTarget->isFetched()) {
+ uint32_t jTargetFlowId = jTarget->getFlowId();
+
+ // Update kNodeFlagIsTaken flag to true if this is a conditional
+ // backward jump. This behavior can be overridden by using
+ // `kInstOptionTaken` when the instruction is created.
+ if (!jNode->isTaken() && opCount == 1 && jTargetFlowId <= flowId) {
+ jNode->addFlags(kNodeFlagIsTaken);
+ }
+ }
+ else if (jNext->isFetched()) {
+ node_ = jTarget;
+ goto _Do;
+ }
+ else {
+ ASMJIT_PROPAGATE_ERROR(X86Context_addJccNode(this, jNode));
+
+ node_ = X86Context_getJccFlow(jNode);
+ goto _Do;
+ }
+ }
+ }
+ break;
+ }
+
+ // ----------------------------------------------------------------------
+ // [Func]
+ // ----------------------------------------------------------------------
+
+ case kNodeTypeFunc: {
+ ASMJIT_ASSERT(node_ == func);
+ X86FuncDecl* decl = func->getDecl();
+
+ VI_BEGIN();
+ VarData* vd;
+ VarAttr* va;
+ for (uint32_t i = 0, argCount = decl->getArgCount(); i < argCount; i++) {
+ const FuncInOut& arg = decl->getArg(i);
+
+ vd = func->getArg(i);
+
+ if (!vd)
+ continue;
+
+ // Overlapped function arguments.
+ if (vd->getVa())
+ return compiler->setError(kErrorOverlappedArgs);
+ VI_ADD_VAR(vd, va, 0, 0);
+
+ uint32_t aType = arg.getVarType();
+ uint32_t vType = vd->getType();
+
+ if (arg.hasRegIndex()) {
+ if (x86VarTypeToClass(aType) == vd->getClass()) {
+ va->addFlags(kVarAttrOutReg);
+ va->setOutRegIndex(arg.getRegIndex());
+ }
+ else {
+ va->addFlags(kVarAttrOutConv);
+ }
+ }
+ else {
+ if ((x86VarTypeToClass(aType) == vd->getClass()) ||
+ (vType == kX86VarTypeXmmSs && aType == kVarTypeFp32) ||
+ (vType == kX86VarTypeXmmSd && aType == kVarTypeFp64)) {
+ va->addFlags(kVarAttrOutMem);
+ }
+ else {
+ // TODO: [COMPILER] Not implemented.
+ ASMJIT_ASSERT(!"Implemented");
+ }
+ }
+ }
+ VI_END(node_);
+ break;
+ }
+
+ // ----------------------------------------------------------------------
+ // [End]
+ // ----------------------------------------------------------------------
+
+ case kNodeTypeEnd: {
+ goto _NextGroup;
+ }
+
+ // ----------------------------------------------------------------------
+ // [Ret]
+ // ----------------------------------------------------------------------
+
+ case kNodeTypeRet: {
+ RetNode* node = static_cast<RetNode*>(node_);
+ X86FuncDecl* decl = func->getDecl();
+
+ if (decl->hasRet()) {
+ const FuncInOut& ret = decl->getRet(0);
+ uint32_t retClass = x86VarTypeToClass(ret.getVarType());
+
+ VI_BEGIN();
+ VarData* vd;
+ VarAttr* va;
+ for (uint32_t i = 0; i < 2; i++) {
+ Operand* op = &node->_ret[i];
+
+ if (op->isVar()) {
+ vd = compiler->getVdById(op->getId());
+
+ if (vd->getClass() == retClass) {
+ // TODO: [COMPILER] Fix RetNode fetch.
+ VI_MERGE_VAR(vd, va, 0, 0);
+ va->setInRegs(i == 0 ? IntUtil::mask(kX86RegIndexAx) : IntUtil::mask(kX86RegIndexDx));
+ va->addFlags(kVarAttrInReg);
+ inRegs.add(retClass, va->getInRegs());
+ }
+ }
+ }
+ VI_END(node_);
+ }
+ break;
+ }
+
+ // ----------------------------------------------------------------------
+ // [Call]
+ // ----------------------------------------------------------------------
+
+ case kNodeTypeCall: {
+ X86CallNode* node = static_cast<X86CallNode*>(node_);
+ X86FuncDecl* decl = node->getDecl();
+
+ Operand* target = &node->_target;
+ Operand* argList = node->_args;
+ Operand* retList = node->_ret;
+
+ func->addFuncFlags(kFuncFlagIsCaller);
+ func->mergeCallStackSize(node->_x86Decl.getArgStackSize());
+ node->_usedArgs = X86Context_getUsedArgs(this, node, decl);
+
+ uint32_t i;
+ uint32_t argCount = decl->getArgCount();
+ uint32_t sArgCount = 0;
+ uint32_t gpAllocableMask = gaRegs[kX86RegClassGp] & ~node->_usedArgs.get(kX86RegClassGp);
+
+ VarData* vd;
+ VarAttr* va;
+
+ VI_BEGIN();
+
+ // Function-call operand.
+ if (target->isVar()) {
+ vd = compiler->getVdById(target->getId());
+ VI_MERGE_VAR(vd, va, 0, 0);
+
+ va->addFlags(kVarAttrInReg | kVarAttrInCall);
+ if (va->getInRegs() == 0)
+ va->addAllocableRegs(gpAllocableMask);
+ }
+ else if (target->isMem()) {
+ X86Mem* m = static_cast<X86Mem*>(target);
+
+ if (OperandUtil::isVarId(m->getBase()) && m->isBaseIndexType()) {
+ vd = compiler->getVdById(m->getBase());
+ if (!vd->isStack()) {
+ VI_MERGE_VAR(vd, va, 0, 0);
+ if (m->getMemType() == kMemTypeBaseIndex) {
+ va->addFlags(kVarAttrInReg | kVarAttrInCall);
+ if (va->getInRegs() == 0)
+ va->addAllocableRegs(gpAllocableMask);
+ }
+ else {
+ va->addFlags(kVarAttrInMem | kVarAttrInCall);
+ }
+ }
+ }
+
+ if (OperandUtil::isVarId(m->getIndex())) {
+ // Restrict allocation to all registers except ESP/RSP/R12.
+ vd = compiler->getVdById(m->getIndex());
+ VI_MERGE_VAR(vd, va, 0, 0);
+
+ va->addFlags(kVarAttrInReg | kVarAttrInCall);
+ if ((va->getInRegs() & ~indexMask) == 0)
+ va->andAllocableRegs(gpAllocableMask & indexMask);
+ }
+ }
+
+ // Function-call arguments.
+ for (i = 0; i < argCount; i++) {
+ Operand* op = &argList[i];
+ if (!op->isVar())
+ continue;
+
+ vd = compiler->getVdById(op->getId());
+ const FuncInOut& arg = decl->getArg(i);
+
+ if (arg.hasRegIndex()) {
+ VI_MERGE_VAR(vd, va, 0, 0);
+
+ uint32_t argType = arg.getVarType();
+ uint32_t argClass = x86VarTypeToClass(argType);
+
+ if (vd->getClass() == argClass) {
+ va->addInRegs(IntUtil::mask(arg.getRegIndex()));
+ va->addFlags(kVarAttrInReg | kVarAttrInArg);
+ }
+ else {
+ va->addFlags(kVarAttrInConv | kVarAttrInArg);
+ }
+ }
+ // If this is a stack-based argument we insert SArgNode instead of
+ // using VarAttr. It improves the code, because the argument can be
+ // moved onto stack as soon as it is ready and the register used by
+ // the variable can be reused for something else. It is also much
+ // easier to handle argument conversions, because there will be at
+ // most only one node per conversion.
+ else {
+ if (X86Context_insertSArgNode(this, node, vd, gaRegs, arg, i, sArgList, sArgCount) != kErrorOk)
+ goto _NoMemory;
+ }
+ }
+
+ // Function-call return(s).
+ for (i = 0; i < 2; i++) {
+ Operand* op = &retList[i];
+ if (!op->isVar())
+ continue;
+
+ const FuncInOut& ret = decl->getRet(i);
+ if (ret.hasRegIndex()) {
+ uint32_t retType = ret.getVarType();
+ uint32_t retClass = x86VarTypeToClass(retType);
+
+ vd = compiler->getVdById(op->getId());
+ VI_MERGE_VAR(vd, va, 0, 0);
+
+ if (vd->getClass() == retClass) {
+ va->setOutRegIndex(ret.getRegIndex());
+ va->addFlags(kVarAttrOutReg | kVarAttrOutRet);
+ }
+ else {
+ va->addFlags(kVarAttrOutConv | kVarAttrOutRet);
+ }
+ }
+ }
+
+ // Init clobbered.
+ clobberedRegs.set(kX86RegClassGp , IntUtil::bits(_regCount.getGp()) & (~decl->getPreserved(kX86RegClassGp)));
+ clobberedRegs.set(kX86RegClassFp , IntUtil::bits(_regCount.getFp()));
+ clobberedRegs.set(kX86RegClassMm , IntUtil::bits(_regCount.getMm()) & (~decl->getPreserved(kX86RegClassMm)));
+ clobberedRegs.set(kX86RegClassXyz, IntUtil::bits(_regCount.getXyz()) & (~decl->getPreserved(kX86RegClassXyz)));
+
+ VI_END(node_);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ node_ = next;
+ } while (node_ != stop);
+
+_Done:
+ ASMJIT_TLOG("[Fetch] === Done ===\n\n");
+ return kErrorOk;
+
+ // --------------------------------------------------------------------------
+ // [Failure]
+ // --------------------------------------------------------------------------
+
+_NoMemory:
+ ASMJIT_TLOG("[Fetch] === Out of Memory ===\n");
+ return compiler->setError(kErrorNoHeapMemory);
+}
+
+// ============================================================================
+// [asmjit::X86Context - Annotate]
+// ============================================================================
+
+Error X86Context::annotate() {
+#ifndef ASMJIT_DISABLE_LOGGER
+ FuncNode* func = getFunc();
+
+ Node* node_ = func;
+ Node* end = func->getEnd();
+
+ Zone& sa = _compiler->_stringZone;
+ StringBuilderT<128> sb;
+
+ uint32_t maxLen = 0;
+ while (node_ != end) {
+ if (!node_->getComment()) {
+ if (node_->getType() == kNodeTypeInst) {
+ InstNode* node = static_cast<InstNode*>(node_);
+ X86Context_annotateInstruction(this, sb, node->getCode(), node->getOpList(), node->getOpCount());
+
+ node_->setComment(static_cast<char*>(sa.dup(sb.getData(), sb.getLength() + 1)));
+ maxLen = IntUtil::iMax<uint32_t>(maxLen, static_cast<uint32_t>(sb.getLength()));
+
+ sb.clear();
+ }
+ }
+
+ node_ = node_->getNext();
+ }
+ _annotationLength = maxLen + 1;
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86BaseAlloc]
+// ============================================================================
+
+struct X86BaseAlloc {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE X86BaseAlloc(X86Context* context) {
+ _context = context;
+ _compiler = context->getCompiler();
+ }
+ ASMJIT_INLINE ~X86BaseAlloc() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get the context.
+ ASMJIT_INLINE X86Context* getContext() const { return _context; }
+ //! Get the current state (always the same instance as X86Context::_x86State).
+ ASMJIT_INLINE X86VarState* getState() const { return _context->getState(); }
+
+ //! Get the node.
+ ASMJIT_INLINE Node* getNode() const { return _node; }
+
+ //! Get VarAttr list (all).
+ ASMJIT_INLINE VarAttr* getVaList() const { return _vaList[0]; }
+ //! Get VarAttr list (per class).
+ ASMJIT_INLINE VarAttr* getVaListByClass(uint32_t c) const { return _vaList[c]; }
+
+ //! Get VarAttr count (all).
+ ASMJIT_INLINE uint32_t getVaCount() const { return _vaCount; }
+ //! Get VarAttr count (per class).
+ ASMJIT_INLINE uint32_t getVaCountByClass(uint32_t c) const { return _count.get(c); }
+
+ //! Get whether all variables of class `c` are done.
+ ASMJIT_INLINE bool isVaDone(uint32_t c) const { return _done.get(c) == _count.get(c); }
+
+ //! Get how many variables have been allocated.
+ ASMJIT_INLINE uint32_t getVaDone(uint32_t c) const { return _done.get(c); }
+
+ ASMJIT_INLINE void addVaDone(uint32_t c, uint32_t n = 1) { _done.add(c, n); }
+
+ //! Get number of allocable registers per class.
+ ASMJIT_INLINE uint32_t getGaRegs(uint32_t c) const {
+ return _context->_gaRegs[c];
+ }
+
+ // --------------------------------------------------------------------------
+ // [Init / Cleanup]
+ // --------------------------------------------------------------------------
+
+protected:
+ // Just to prevent calling these methods by X86Context::translate().
+
+ ASMJIT_INLINE void init(Node* node, X86VarMap* map);
+ ASMJIT_INLINE void cleanup();
+
+ // --------------------------------------------------------------------------
+ // [Unuse]
+ // --------------------------------------------------------------------------
+
+ template<int C>
+ ASMJIT_INLINE void unuseBefore();
+
+ template<int C>
+ ASMJIT_INLINE void unuseAfter();
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Context.
+ X86Context* _context;
+ //! Compiler.
+ X86Compiler* _compiler;
+
+ //! Node.
+ Node* _node;
+
+ //! Variable map.
+ X86VarMap* _map;
+ //! VarAttr list (per register class).
+ VarAttr* _vaList[4];
+
+ //! Count of all VarAttr's.
+ uint32_t _vaCount;
+
+ //! VarAttr's total counter.
+ X86RegCount _count;
+ //! VarAttr's done counter.
+ X86RegCount _done;
+};
+
+// ============================================================================
+// [asmjit::X86BaseAlloc - Init / Cleanup]
+// ============================================================================
+
+ASMJIT_INLINE void X86BaseAlloc::init(Node* node, X86VarMap* map) {
+ _node = node;
+ _map = map;
+
+ // We have to set the correct cursor in case any instruction is emitted
+ // during the allocation phase; it has to be emitted before the current
+ // instruction.
+ _compiler->_setCursor(node->getPrev());
+
+ // Setup the lists of variables.
+ {
+ VarAttr* va = map->getVaList();
+ _vaList[kX86RegClassGp ] = va;
+ _vaList[kX86RegClassFp ] = va + map->getVaStart(kX86RegClassFp );
+ _vaList[kX86RegClassMm ] = va + map->getVaStart(kX86RegClassMm );
+ _vaList[kX86RegClassXyz] = va + map->getVaStart(kX86RegClassXyz);
+ }
+
+ // Setup counters.
+ _vaCount = map->getVaCount();
+
+ _count = map->_count;
+ _done.reset();
+
+ // Connect Vd->Va.
+ for (uint32_t i = 0; i < _vaCount; i++) {
+ VarAttr* va = &_vaList[0][i];
+ VarData* vd = va->getVd();
+
+ vd->setVa(va);
+ }
+}
+
+ASMJIT_INLINE void X86BaseAlloc::cleanup() {
+ // Disconnect Vd->Va.
+ for (uint32_t i = 0; i < _vaCount; i++) {
+ VarAttr* va = &_vaList[0][i];
+ VarData* vd = va->getVd();
+
+ vd->setVa(nullptr);
+ }
+}
+
+// ============================================================================
+// [asmjit::X86BaseAlloc - Unuse]
+// ============================================================================
+
+template<int C>
+ASMJIT_INLINE void X86BaseAlloc::unuseBefore() {
+ VarAttr* list = getVaListByClass(C);
+ uint32_t count = getVaCountByClass(C);
+
+ const uint32_t checkFlags =
+ kVarAttrInOutReg |
+ kVarAttrInMem |
+ kVarAttrInArg |
+ kVarAttrInCall |
+ kVarAttrInConv ;
+
+ for (uint32_t i = 0; i < count; i++) {
+ VarAttr* va = &list[i];
+
+ if ((va->getFlags() & checkFlags) == kVarAttrOutReg) {
+ _context->unuse<C>(va->getVd());
+ }
+ }
+}
+
+template<int C>
+ASMJIT_INLINE void X86BaseAlloc::unuseAfter() {
+ VarAttr* list = getVaListByClass(C);
+ uint32_t count = getVaCountByClass(C);
+
+ for (uint32_t i = 0; i < count; i++) {
+ VarAttr* va = &list[i];
+
+ if (va->getFlags() & kVarAttrUnuse)
+ _context->unuse<C>(va->getVd());
+ }
+}
+
+// ============================================================================
+// [asmjit::X86VarAlloc]
+// ============================================================================
+
+//! \internal
+//!
+//! Register allocator context (asm instructions).
+struct X86VarAlloc : public X86BaseAlloc {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE X86VarAlloc(X86Context* context) : X86BaseAlloc(context) {}
+ ASMJIT_INLINE ~X86VarAlloc() {}
+
+ // --------------------------------------------------------------------------
+ // [Run]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Error run(Node* node);
+
+ // --------------------------------------------------------------------------
+ // [Init / Cleanup]
+ // --------------------------------------------------------------------------
+
+protected:
+ // Just to prevent calling these methods by X86Context::translate().
+
+ ASMJIT_INLINE void init(Node* node, X86VarMap* map);
+ ASMJIT_INLINE void cleanup();
+
+ // --------------------------------------------------------------------------
+ // [Plan / Spill / Alloc]
+ // --------------------------------------------------------------------------
+
+ template<int C>
+ ASMJIT_INLINE void plan();
+
+ template<int C>
+ ASMJIT_INLINE void spill();
+
+ template<int C>
+ ASMJIT_INLINE void alloc();
+
+ // --------------------------------------------------------------------------
+ // [GuessAlloc / GuessSpill]
+ // --------------------------------------------------------------------------
+
+ //! Guess which register is the best candidate for 'vd' from
+ //! 'allocableRegs'.
+ //!
+ //! The guess is based on looking ahead and inspecting register allocator
+ //! instructions. The main reason is to prevent allocation to a register
+ //! which is needed by next instruction(s). The guess look tries to go as far
+ //! as possible, after the remaining registers are zero, the mask of previous
+ //! registers (called 'safeRegs') is returned.
+ template<int C>
+ ASMJIT_INLINE uint32_t guessAlloc(VarData* vd, uint32_t allocableRegs);
+
+ //! Guess whether to move the given 'vd' instead of spill.
+ template<int C>
+ ASMJIT_INLINE uint32_t guessSpill(VarData* vd, uint32_t allocableRegs);
+
+ // --------------------------------------------------------------------------
+ // [Modified]
+ // --------------------------------------------------------------------------
+
+ template<int C>
+ ASMJIT_INLINE void modified();
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Will alloc to these registers.
+ X86RegMask _willAlloc;
+ //! Will spill these registers.
+ X86RegMask _willSpill;
+};
+
+// ============================================================================
+// [asmjit::X86VarAlloc - Run]
+// ============================================================================
+
+ASMJIT_INLINE Error X86VarAlloc::run(Node* node_) {
+ // Initialize.
+ X86VarMap* map = node_->getMap<X86VarMap>();
+ if (!map)
+ return kErrorOk;
+
+ // Initialize the allocator; connect Vd->Va.
+ init(node_, map);
+
+ // Unuse overwritten variables.
+ unuseBefore<kX86RegClassGp >();
+ unuseBefore<kX86RegClassMm >();
+ unuseBefore<kX86RegClassXyz>();
+
+ // Plan the allocation. Planner assigns input/output registers for each
+ // variable and decides whether to allocate it in register or stack.
+ plan<kX86RegClassGp >();
+ plan<kX86RegClassMm >();
+ plan<kX86RegClassXyz>();
+
+ // Spill all variables marked by plan().
+ spill<kX86RegClassGp >();
+ spill<kX86RegClassMm >();
+ spill<kX86RegClassXyz>();
+
+ // Alloc all variables marked by plan().
+ alloc<kX86RegClassGp >();
+ alloc<kX86RegClassMm >();
+ alloc<kX86RegClassXyz>();
+
+ // Translate node operands.
+ if (node_->getType() == kNodeTypeInst) {
+ InstNode* node = static_cast<InstNode*>(node_);
+ ASMJIT_PROPAGATE_ERROR(X86Context_translateOperands(_context, node->getOpList(), node->getOpCount()));
+ }
+ else if (node_->getType() == kNodeTypeSArg) {
+ SArgNode* node = static_cast<SArgNode*>(node_);
+
+ X86CallNode* call = static_cast<X86CallNode*>(node->getCall());
+ X86FuncDecl* decl = call->getDecl();
+
+ uint32_t argIndex = 0;
+ uint32_t argMask = node->_args;
+
+ VarData* sVd = node->getSVd();
+ VarData* cVd = node->getCVd();
+
+ // Convert first.
+ ASMJIT_ASSERT(sVd->getRegIndex() != kInvalidReg);
+
+ if (cVd) {
+ ASMJIT_ASSERT(cVd->getRegIndex() != kInvalidReg);
+ _context->emitConvertVarToVar(
+ cVd->getType(), cVd->getRegIndex(),
+ sVd->getType(), sVd->getRegIndex());
+ sVd = cVd;
+ }
+
+ while (argMask != 0) {
+ if (argMask & 0x1) {
+ FuncInOut& arg = decl->getArg(argIndex);
+ ASMJIT_ASSERT(arg.hasStackOffset());
+
+ X86Mem dst = x86::ptr(_context->_zsp, -static_cast<int>(_context->getRegSize()) + arg.getStackOffset());
+ _context->emitMoveVarOnStack(arg.getVarType(), &dst, sVd->getType(), sVd->getRegIndex());
+ }
+
+ argIndex++;
+ argMask >>= 1;
+ }
+ }
+
+ // Mark variables as modified.
+ modified<kX86RegClassGp >();
+ modified<kX86RegClassMm >();
+ modified<kX86RegClassXyz>();
+
+ // Cleanup; disconnect Vd->Va.
+ cleanup();
+
+ // Update clobbered mask.
+ _context->_clobberedRegs.add(_willAlloc);
+ _context->_clobberedRegs.add(map->_clobberedRegs);
+
+ // Unuse.
+ unuseAfter<kX86RegClassGp >();
+ unuseAfter<kX86RegClassMm >();
+ unuseAfter<kX86RegClassXyz>();
+
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86VarAlloc - Init / Cleanup]
+// ============================================================================
+
+ASMJIT_INLINE void X86VarAlloc::init(Node* node, X86VarMap* map) {
+ X86BaseAlloc::init(node, map);
+
+ // These will block planner from assigning them during planning. Planner will
+ // add more registers when assigning registers to variables that don't need
+ // any specific register.
+ _willAlloc = map->_inRegs;
+ _willAlloc.add(map->_outRegs);
+ _willSpill.reset();
+}
+
+ASMJIT_INLINE void X86VarAlloc::cleanup() {
+ X86BaseAlloc::cleanup();
+}
+
+// ============================================================================
+// [asmjit::X86VarAlloc - Plan / Spill / Alloc]
+// ============================================================================
+
+template<int C>
+ASMJIT_INLINE void X86VarAlloc::plan() {
+ if (isVaDone(C))
+ return;
+
+ uint32_t i;
+
+ uint32_t willAlloc = _willAlloc.get(C);
+ uint32_t willFree = 0;
+
+ VarAttr* list = getVaListByClass(C);
+ uint32_t count = getVaCountByClass(C);
+
+ X86VarState* state = getState();
+ //VarData** sVars = state->getListByClass(C);
+
+ // Calculate 'willAlloc' and 'willFree' masks based on mandatory masks.
+ for (i = 0; i < count; i++) {
+ VarAttr* va = &list[i];
+ VarData* vd = va->getVd();
+
+ uint32_t vaFlags = va->getFlags();
+ uint32_t regIndex = vd->getRegIndex();
+ uint32_t regMask = (regIndex != kInvalidReg) ? IntUtil::mask(regIndex) : 0;
+
+ if ((vaFlags & kVarAttrInOutReg) != 0) {
+ // Planning register allocation. First check whether the variable is
+ // already allocated in register and if it can stay allocated there.
+ //
+ // The following conditions may happen:
+ //
+ // a) Allocated register is one of the mandatoryRegs.
+ // b) Allocated register is one of the allocableRegs.
+ uint32_t mandatoryRegs = va->getInRegs();
+ uint32_t allocableRegs = va->getAllocableRegs();
+
+ ASMJIT_TLOG("[RA-PLAN ] %s (%s)\n",
+ vd->getName(),
+ (vaFlags & kVarAttrInOutReg) == kVarAttrOutReg ? "Out Reg" : "In/Out Reg");
+
+ ASMJIT_TLOG("[RA-PLAN ] RegMask=%08X Mandatory=%08X Allocable=%08X\n",
+ regMask, mandatoryRegs, allocableRegs);
+
+ if (regMask != 0) {
+ // Special path for planning output-only registers.
+ if ((vaFlags & kVarAttrInOutReg) == kVarAttrOutReg) {
+ uint32_t outRegIndex = va->getOutRegIndex();
+ mandatoryRegs = (outRegIndex != kInvalidReg) ? IntUtil::mask(outRegIndex) : 0;
+
+ if ((mandatoryRegs | allocableRegs) & regMask) {
+ va->setOutRegIndex(regIndex);
+ va->addFlags(kVarAttrAllocOutDone);
+
+ if (mandatoryRegs & regMask) {
+ // Case 'a' - 'willAlloc' contains initially all inRegs from all VarAttr's.
+ ASMJIT_ASSERT((willAlloc & regMask) != 0);
+ }
+ else {
+ // Case 'b'.
+ va->setOutRegIndex(regIndex);
+ willAlloc |= regMask;
+ }
+
+ ASMJIT_TLOG("[RA-PLAN ] WillAlloc\n");
+ addVaDone(C);
+
+ continue;
+ }
+ }
+ else {
+ if ((mandatoryRegs | allocableRegs) & regMask) {
+ va->setInRegIndex(regIndex);
+ va->addFlags(kVarAttrAllocInDone);
+
+ if (mandatoryRegs & regMask) {
+ // Case 'a' - 'willAlloc' contains initially all inRegs from all VarAttr's.
+ ASMJIT_ASSERT((willAlloc & regMask) != 0);
+ }
+ else {
+ // Case 'b'.
+ va->addInRegs(regMask);
+ willAlloc |= regMask;
+ }
+
+ ASMJIT_TLOG("[RA-PLAN ] WillAlloc\n");
+ addVaDone(C);
+
+ continue;
+ }
+ }
+
+ // Trace it here so we don't pollute log by `WillFree` of zero regMask.
+ ASMJIT_TLOG("[RA-PLAN ] WillFree\n");
+ }
+
+ // Variable is not allocated or allocated in register that doesn't
+ // match inRegs or allocableRegs. The next step is to pick the best
+ // register for this variable. If `inRegs` contains any register the
+ // decision is simple - we have to follow, in other case will use
+ // the advantage of `guessAlloc()` to find a register (or registers)
+ // by looking ahead. But the best way to find a good register is not
+ // here since now we have no information about the registers that
+ // will be freed. So instead of finding register here, we just mark
+ // the current register (if variable is allocated) as `willFree` so
+ // the planner can use this information in second step to plan other
+ // allocation of other variables.
+ willFree |= regMask;
+ continue;
+ }
+ else {
+ // Memory access - if variable is allocated it has to be freed.
+ ASMJIT_TLOG("[RA-PLAN ] %s (Memory)\n", vd->getName());
+
+ if (regMask != 0) {
+ ASMJIT_TLOG("[RA-PLAN ] WillFree\n");
+ willFree |= regMask;
+ continue;
+ }
+ else {
+ ASMJIT_TLOG("[RA-PLAN ] Done\n");
+ va->addFlags(kVarAttrAllocInDone);
+ addVaDone(C);
+ continue;
+ }
+ }
+ }
+
+ // Occupied registers without 'willFree' registers; contains basically
+ // all the registers we can use to allocate variables without inRegs
+ // speficied.
+ uint32_t occupied = state->_occupied.get(C) & ~willFree;
+ uint32_t willSpill = 0;
+
+ // Find the best registers for variables that are not allocated yet.
+ for (i = 0; i < count; i++) {
+ VarAttr* va = &list[i];
+ VarData* vd = va->getVd();
+
+ uint32_t vaFlags = va->getFlags();
+
+ if ((vaFlags & kVarAttrInOutReg) != 0) {
+ if ((vaFlags & kVarAttrInOutReg) == kVarAttrOutReg) {
+ if (vaFlags & kVarAttrAllocOutDone)
+ continue;
+
+ // Skip all registers that have assigned outRegIndex. Spill if occupied.
+ if (va->hasOutRegIndex()) {
+ uint32_t outRegs = IntUtil::mask(va->getOutRegIndex());
+ willSpill |= occupied & outRegs;
+ continue;
+ }
+ }
+ else {
+ if (vaFlags & kVarAttrAllocInDone)
+ continue;
+
+ // We skip all registers that have assigned inRegIndex, indicates that
+ // the register to allocate in is known.
+ if (va->hasInRegIndex()) {
+ uint32_t inRegs = va->getInRegs();
+ willSpill |= occupied & inRegs;
+ continue;
+ }
+ }
+
+ uint32_t m = va->getInRegs();
+ if (va->hasOutRegIndex())
+ m |= IntUtil::mask(va->getOutRegIndex());
+
+ m = va->getAllocableRegs() & ~(willAlloc ^ m);
+ m = guessAlloc<C>(vd, m);
+ ASMJIT_ASSERT(m != 0);
+
+ uint32_t candidateRegs = m & ~occupied;
+ uint32_t homeMask = vd->getHomeMask();
+
+ uint32_t regIndex;
+ uint32_t regMask;
+
+ if (candidateRegs == 0) {
+ candidateRegs = m & occupied & ~state->_modified.get(C);
+ if (candidateRegs == 0)
+ candidateRegs = m;
+ }
+
+ if (candidateRegs & homeMask)
+ candidateRegs &= homeMask;
+
+ regIndex = IntUtil::findFirstBit(candidateRegs);
+ regMask = IntUtil::mask(regIndex);
+
+ if ((vaFlags & kVarAttrInOutReg) == kVarAttrOutReg) {
+ va->setOutRegIndex(regIndex);
+ }
+ else {
+ va->setInRegIndex(regIndex);
+ va->setInRegs(regMask);
+ }
+
+ willAlloc |= regMask;
+ willSpill |= regMask & occupied;
+ willFree &=~regMask;
+ occupied |= regMask;
+
+ continue;
+ }
+ else if ((vaFlags & kVarAttrInOutMem) != 0) {
+ uint32_t regIndex = vd->getRegIndex();
+ if (regIndex != kInvalidReg && (vaFlags & kVarAttrInOutMem) != kVarAttrOutMem) {
+ willSpill |= IntUtil::mask(regIndex);
+ }
+ }
+ }
+
+ // Set calculated masks back to the allocator; needed by spill() and alloc().
+ _willSpill.set(C, willSpill);
+ _willAlloc.set(C, willAlloc);
+}
+
+template<int C>
+ASMJIT_INLINE void X86VarAlloc::spill() {
+ uint32_t m = _willSpill.get(C);
+ uint32_t i = static_cast<uint32_t>(0) - 1;
+
+ if (m == 0)
+ return;
+
+ X86VarState* state = getState();
+ VarData** sVars = state->getListByClass(C);
+
+ // Available registers for decision if move has any benefit over spill.
+ uint32_t availableRegs = getGaRegs(C) & ~(state->_occupied.get(C) | m | _willAlloc.get(C));
+
+ do {
+ // We always advance one more to destroy the bit that we have found.
+ uint32_t bitIndex = IntUtil::findFirstBit(m) + 1;
+
+ i += bitIndex;
+ m >>= bitIndex;
+
+ VarData* vd = sVars[i];
+ ASMJIT_ASSERT(vd);
+
+ VarAttr* va = vd->getVa();
+ ASMJIT_ASSERT(!va || !va->hasFlag(kVarAttrInOutReg));
+
+ if (vd->isModified() && availableRegs) {
+ // Don't check for alternatives if the variable has to be spilled.
+ if (!va || !va->hasFlag(kVarAttrSpill)) {
+ uint32_t altRegs = guessSpill<C>(vd, availableRegs);
+
+ if (altRegs != 0) {
+ uint32_t regIndex = IntUtil::findFirstBit(altRegs);
+ uint32_t regMask = IntUtil::mask(regIndex);
+
+ _context->move<C>(vd, regIndex);
+ availableRegs ^= regMask;
+ continue;
+ }
+ }
+ }
+
+ _context->spill<C>(vd);
+ } while (m != 0);
+}
+
+template<int C>
+ASMJIT_INLINE void X86VarAlloc::alloc() {
+ if (isVaDone(C))
+ return;
+
+ VarAttr* list = getVaListByClass(C);
+ uint32_t count = getVaCountByClass(C);
+
+ X86VarState* state = getState();
+ VarData** sVars = state->getListByClass(C);
+
+ uint32_t i;
+ bool didWork;
+
+ // Alloc 'in' regs.
+ do {
+ didWork = false;
+ for (i = 0; i < count; i++) {
+ VarAttr* aVa = &list[i];
+ VarData* aVd = aVa->getVd();
+
+ if ((aVa->getFlags() & (kVarAttrInReg | kVarAttrAllocInDone)) != kVarAttrInReg)
+ continue;
+
+ uint32_t aIndex = aVd->getRegIndex();
+ uint32_t bIndex = aVa->getInRegIndex();
+
+ // Shouldn't be the same.
+ ASMJIT_ASSERT(aIndex != bIndex);
+
+ VarData* bVd = getState()->getListByClass(C)[bIndex];
+ if (bVd) {
+ // Gp registers only - Swap two registers if we can solve two
+ // allocation tasks by a single 'xchg' instruction, swapping
+ // two registers required by the instruction/node or one register
+ // required with another non-required.
+ if (C == kX86RegClassGp && aIndex != kInvalidReg) {
+ VarAttr* bVa = bVd->getVa();
+ _context->swapGp(aVd, bVd);
+
+ aVa->addFlags(kVarAttrAllocInDone);
+ addVaDone(C);
+
+ // Doublehit, two registers allocated by a single swap.
+ if (bVa && bVa->getInRegIndex() == aIndex) {
+ bVa->addFlags(kVarAttrAllocInDone);
+ addVaDone(C);
+ }
+
+ didWork = true;
+ continue;
+ }
+ }
+ else if (aIndex != kInvalidReg) {
+ _context->move<C>(aVd, bIndex);
+
+ aVa->addFlags(kVarAttrAllocInDone);
+ addVaDone(C);
+
+ didWork = true;
+ continue;
+ }
+ else {
+ _context->alloc<C>(aVd, bIndex);
+
+ aVa->addFlags(kVarAttrAllocInDone);
+ addVaDone(C);
+
+ didWork = true;
+ continue;
+ }
+ }
+ } while (didWork);
+
+ // Alloc 'out' regs.
+ for (i = 0; i < count; i++) {
+ VarAttr* va = &list[i];
+ VarData* vd = va->getVd();
+
+ if ((va->getFlags() & (kVarAttrInOutReg | kVarAttrAllocOutDone)) != kVarAttrOutReg)
+ continue;
+
+ uint32_t regIndex = va->getOutRegIndex();
+ ASMJIT_ASSERT(regIndex != kInvalidReg);
+
+ if (vd->getRegIndex() != regIndex) {
+ ASMJIT_ASSERT(!sVars[regIndex]);
+ _context->attach<C>(vd, regIndex, false);
+ }
+
+ va->addFlags(kVarAttrAllocOutDone);
+ addVaDone(C);
+ }
+}
+
+// ============================================================================
+// [asmjit::X86VarAlloc - GuessAlloc / GuessSpill]
+// ============================================================================
+
+template<int C>
+ASMJIT_INLINE uint32_t X86VarAlloc::guessAlloc(VarData* vd, uint32_t allocableRegs) {
+ ASMJIT_ASSERT(allocableRegs != 0);
+
+ // Stop now if there is only one bit (register) set in `allocableRegs` mask.
+ if (IntUtil::isPowerOf2(allocableRegs))
+ return allocableRegs;
+
+ uint32_t cId = vd->getContextId();
+ uint32_t safeRegs = allocableRegs;
+
+ uint32_t i;
+ uint32_t maxLookAhead = _compiler->getMaxLookAhead();
+
+ // Look ahead and calculate mask of special registers on both - input/output.
+ Node* node = _node;
+ for (i = 0; i < maxLookAhead; i++) {
+ VarBits* liveness = node->getLiveness();
+
+ // If the variable becomes dead it doesn't make sense to continue.
+ if (liveness && !liveness->getBit(cId))
+ break;
+
+ // Stop on 'RetNode' and 'EndNode.
+ if (node->hasFlag(kNodeFlagIsRet))
+ break;
+
+ // Stop on conditional jump, we don't follow them.
+ if (node->hasFlag(kNodeFlagIsJcc))
+ break;
+
+ // Advance on non-conditional jump.
+ if (node->hasFlag(kNodeFlagIsJmp))
+ node = static_cast<JumpNode*>(node)->getTarget();
+
+ node = node->getNext();
+ ASMJIT_ASSERT(node);
+
+ X86VarMap* map = node->getMap<X86VarMap>();
+ if (map) {
+ VarAttr* va = map->findVaByClass(C, vd);
+ uint32_t mask;
+
+ if (va) {
+ // If the variable is overwritten it doesn't mase sense to continue.
+ if (!(va->getFlags() & kVarAttrInAll))
+ break;
+
+ mask = va->getAllocableRegs();
+ if (mask != 0) {
+ allocableRegs &= mask;
+ if (allocableRegs == 0)
+ break;
+ safeRegs = allocableRegs;
+ }
+
+ mask = va->getInRegs();
+ if (mask != 0) {
+ allocableRegs &= mask;
+ if (allocableRegs == 0)
+ break;
+ safeRegs = allocableRegs;
+ break;
+ }
+
+ allocableRegs &= ~(map->_outRegs.get(C) | map->_clobberedRegs.get(C));
+ if (allocableRegs == 0)
+ break;
+ }
+ else {
+ allocableRegs &= ~(map->_inRegs.get(C) | map->_outRegs.get(C) | map->_clobberedRegs.get(C));
+ if (allocableRegs == 0)
+ break;
+ }
+
+ safeRegs = allocableRegs;
+ }
+ }
+
+ return safeRegs;
+}
+
+template<int C>
+ASMJIT_INLINE uint32_t X86VarAlloc::guessSpill(VarData*, uint32_t allocableRegs) {
+ ASMJIT_ASSERT(allocableRegs != 0);
+
+ return 0;
+}
+
+// ============================================================================
+// [asmjit::X86VarAlloc - Modified]
+// ============================================================================
+
+template<int C>
+ASMJIT_INLINE void X86VarAlloc::modified() {
+ VarAttr* list = getVaListByClass(C);
+ uint32_t count = getVaCountByClass(C);
+
+ for (uint32_t i = 0; i < count; i++) {
+ VarAttr* va = &list[i];
+
+ if (va->hasFlag(kVarAttrOutReg)) {
+ VarData* vd = va->getVd();
+
+ uint32_t regIndex = vd->getRegIndex();
+ uint32_t regMask = IntUtil::mask(regIndex);
+
+ vd->setModified(true);
+ _context->_x86State._modified.add(C, regMask);
+ }
+ }
+}
+
+// ============================================================================
+// [asmjit::X86CallAlloc]
+// ============================================================================
+
+//! \internal
+//!
+//! Register allocator context (function call).
+struct X86CallAlloc : public X86BaseAlloc {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE X86CallAlloc(X86Context* context) : X86BaseAlloc(context) {}
+ ASMJIT_INLINE ~X86CallAlloc() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get the node.
+ ASMJIT_INLINE X86CallNode* getNode() const { return static_cast<X86CallNode*>(_node); }
+
+ // --------------------------------------------------------------------------
+ // [Run]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Error run(X86CallNode* node);
+
+ // --------------------------------------------------------------------------
+ // [Init / Cleanup]
+ // --------------------------------------------------------------------------
+
+protected:
+ // Just to prevent calling these methods from X86Context::translate().
+
+ ASMJIT_INLINE void init(X86CallNode* node, X86VarMap* map);
+ ASMJIT_INLINE void cleanup();
+
+ // --------------------------------------------------------------------------
+ // [Plan / Alloc / Spill / Move]
+ // --------------------------------------------------------------------------
+
+ template<int C>
+ ASMJIT_INLINE void plan();
+
+ template<int C>
+ ASMJIT_INLINE void spill();
+
+ template<int C>
+ ASMJIT_INLINE void alloc();
+
+ // --------------------------------------------------------------------------
+ // [AllocImmsOnStack]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void allocImmsOnStack();
+
+ // --------------------------------------------------------------------------
+ // [Duplicate]
+ // --------------------------------------------------------------------------
+
+ template<int C>
+ ASMJIT_INLINE void duplicate();
+
+ // --------------------------------------------------------------------------
+ // [GuessAlloc / GuessSpill]
+ // --------------------------------------------------------------------------
+
+ template<int C>
+ ASMJIT_INLINE uint32_t guessAlloc(VarData* vd, uint32_t allocableRegs);
+
+ template<int C>
+ ASMJIT_INLINE uint32_t guessSpill(VarData* vd, uint32_t allocableRegs);
+
+ // --------------------------------------------------------------------------
+ // [Save]
+ // --------------------------------------------------------------------------
+
+ template<int C>
+ ASMJIT_INLINE void save();
+
+ // --------------------------------------------------------------------------
+ // [Clobber]
+ // --------------------------------------------------------------------------
+
+ template<int C>
+ ASMJIT_INLINE void clobber();
+
+ // --------------------------------------------------------------------------
+ // [Ret]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void ret();
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Will alloc to these registers.
+ X86RegMask _willAlloc;
+ //! Will spill these registers.
+ X86RegMask _willSpill;
+};
+
+// ============================================================================
+// [asmjit::X86CallAlloc - Run]
+// ============================================================================
+
+ASMJIT_INLINE Error X86CallAlloc::run(X86CallNode* node) {
+ // Initialize.
+ X86VarMap* map = node->getMap<X86VarMap>();
+ if (!map)
+ return kErrorOk;
+
+ // Initialize the allocator; prepare basics and connect Vd->Va.
+ init(node, map);
+
+ // Plan register allocation. Planner is only able to assign one register per
+ // variable. If any variable is used multiple times it will be handled later.
+ plan<kX86RegClassGp >();
+ plan<kX86RegClassMm >();
+ plan<kX86RegClassXyz>();
+
+ // Spill.
+ spill<kX86RegClassGp >();
+ spill<kX86RegClassMm >();
+ spill<kX86RegClassXyz>();
+
+ // Alloc.
+ alloc<kX86RegClassGp >();
+ alloc<kX86RegClassMm >();
+ alloc<kX86RegClassXyz>();
+
+ // Unuse clobbered registers that are not used to pass function arguments and
+ // save variables used to pass function arguments that will be reused later on.
+ save<kX86RegClassGp >();
+ save<kX86RegClassMm >();
+ save<kX86RegClassXyz>();
+
+ // Allocate immediates in registers and on the stack.
+ allocImmsOnStack();
+
+ // Duplicate.
+ duplicate<kX86RegClassGp >();
+ duplicate<kX86RegClassMm >();
+ duplicate<kX86RegClassXyz>();
+
+ // Translate call operand.
+ ASMJIT_PROPAGATE_ERROR(X86Context_translateOperands(_context, &node->_target, 1));
+
+ // To emit instructions after call.
+ _compiler->_setCursor(node);
+
+ // If the callee pops stack it has to be manually adjusted back.
+ X86FuncDecl* decl = node->getDecl();
+ if (decl->getCalleePopsStack() && decl->getArgStackSize() != 0) {
+ _compiler->emit(kX86InstIdSub, _context->_zsp, static_cast<int>(decl->getArgStackSize()));
+ }
+
+ // Clobber.
+ clobber<kX86RegClassGp >();
+ clobber<kX86RegClassMm >();
+ clobber<kX86RegClassXyz>();
+
+ // Return.
+ ret();
+
+ // Unuse.
+ unuseAfter<kX86RegClassGp >();
+ unuseAfter<kX86RegClassMm >();
+ unuseAfter<kX86RegClassXyz>();
+
+ // Cleanup; disconnect Vd->Va.
+ cleanup();
+
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86CallAlloc - Init / Cleanup]
+// ============================================================================
+
+ASMJIT_INLINE void X86CallAlloc::init(X86CallNode* node, X86VarMap* map) {
+ X86BaseAlloc::init(node, map);
+
+ // Create mask of all registers that will be used to pass function arguments.
+ _willAlloc = node->_usedArgs;
+ _willSpill.reset();
+}
+
+ASMJIT_INLINE void X86CallAlloc::cleanup() {
+ X86BaseAlloc::cleanup();
+}
+
+// ============================================================================
+// [asmjit::X86CallAlloc - Plan / Spill / Alloc]
+// ============================================================================
+
+template<int C>
+ASMJIT_INLINE void X86CallAlloc::plan() {
+ uint32_t i;
+ uint32_t clobbered = _map->_clobberedRegs.get(C);
+
+ uint32_t willAlloc = _willAlloc.get(C);
+ uint32_t willFree = clobbered & ~willAlloc;
+
+ VarAttr* list = getVaListByClass(C);
+ uint32_t count = getVaCountByClass(C);
+
+ X86VarState* state = getState();
+ //VarData** sVars = state->getListByClass(C);
+
+ // Calculate 'willAlloc' and 'willFree' masks based on mandatory masks.
+ for (i = 0; i < count; i++) {
+ VarAttr* va = &list[i];
+ VarData* vd = va->getVd();
+
+ uint32_t vaFlags = va->getFlags();
+ uint32_t regIndex = vd->getRegIndex();
+ uint32_t regMask = (regIndex != kInvalidReg) ? IntUtil::mask(regIndex) : 0;
+
+ if ((vaFlags & kVarAttrInReg) != 0) {
+ // Planning register allocation. First check whether the variable is
+ // already allocated in register and if it can stay there. Function
+ // arguments are passed either in a specific register or in stack so
+ // we care mostly of mandatory registers.
+ uint32_t inRegs = va->getInRegs();
+
+ if (inRegs == 0) {
+ inRegs = va->getAllocableRegs();
+ }
+
+ // Optimize situation where the variable has to be allocated in a
+ // mandatory register, but it's already allocated in register that
+ // is not clobbered (i.e. it will survive function call).
+ if ((regMask & inRegs) != 0 || ((regMask & ~clobbered) != 0 && (vaFlags & kVarAttrUnuse) == 0)) {
+ va->setInRegIndex(regIndex);
+ va->addFlags(kVarAttrAllocInDone);
+ addVaDone(C);
+ }
+ else {
+ willFree |= regMask;
+ }
+ }
+ else {
+ // Memory access - if variable is allocated it has to be freed.
+ if (regMask != 0) {
+ willFree |= regMask;
+ }
+ else {
+ va->addFlags(kVarAttrAllocInDone);
+ addVaDone(C);
+ }
+ }
+ }
+
+ // Occupied registers without 'willFree' registers; contains basically
+ // all the registers we can use to allocate variables without inRegs
+ // speficied.
+ uint32_t occupied = state->_occupied.get(C) & ~willFree;
+ uint32_t willSpill = 0;
+
+ // Find the best registers for variables that are not allocated yet. Only
+ // useful for Gp registers used as call operand.
+ for (i = 0; i < count; i++) {
+ VarAttr* va = &list[i];
+ VarData* vd = va->getVd();
+
+ uint32_t vaFlags = va->getFlags();
+ if ((vaFlags & kVarAttrAllocInDone) != 0 || (vaFlags & kVarAttrInReg) == 0)
+ continue;
+
+ // All registers except Gp used by call itself must have inRegIndex.
+ uint32_t m = va->getInRegs();
+ if (C != kX86RegClassGp || m) {
+ ASMJIT_ASSERT(m != 0);
+ va->setInRegIndex(IntUtil::findFirstBit(m));
+ willSpill |= occupied & m;
+ continue;
+ }
+
+ m = va->getAllocableRegs() & ~(willAlloc ^ m);
+ m = guessAlloc<C>(vd, m);
+ ASMJIT_ASSERT(m != 0);
+
+ uint32_t candidateRegs = m & ~occupied;
+ if (candidateRegs == 0) {
+ candidateRegs = m & occupied & ~state->_modified.get(C);
+ if (candidateRegs == 0)
+ candidateRegs = m;
+ }
+
+ if (!(vaFlags & (kVarAttrOutReg | kVarAttrUnuse)) && (candidateRegs & ~clobbered))
+ candidateRegs &= ~clobbered;
+
+ uint32_t regIndex = IntUtil::findFirstBit(candidateRegs);
+ uint32_t regMask = IntUtil::mask(regIndex);
+
+ va->setInRegIndex(regIndex);
+ va->setInRegs(regMask);
+
+ willAlloc |= regMask;
+ willSpill |= regMask & occupied;
+ willFree &= ~regMask;
+
+ occupied |= regMask;
+ continue;
+ }
+
+ // Set calculated masks back to the allocator; needed by spill() and alloc().
+ _willSpill.set(C, willSpill);
+ _willAlloc.set(C, willAlloc);
+}
+
+template<int C>
+ASMJIT_INLINE void X86CallAlloc::spill() {
+ uint32_t m = _willSpill.get(C);
+ uint32_t i = static_cast<uint32_t>(0) - 1;
+
+ if (m == 0)
+ return;
+
+ X86VarState* state = getState();
+ VarData** sVars = state->getListByClass(C);
+
+ // Available registers for decision if move has any benefit over spill.
+ uint32_t availableRegs = getGaRegs(C) & ~(state->_occupied.get(C) | m | _willAlloc.get(C));
+
+ do {
+ // We always advance one more to destroy the bit that we have found.
+ uint32_t bitIndex = IntUtil::findFirstBit(m) + 1;
+
+ i += bitIndex;
+ m >>= bitIndex;
+
+ VarData* vd = sVars[i];
+ ASMJIT_ASSERT(vd);
+ ASMJIT_ASSERT(!vd->getVa());
+
+ if (vd->isModified() && availableRegs) {
+ uint32_t n = guessSpill<C>(vd, availableRegs);
+
+ if (n != 0) {
+ uint32_t regIndex = IntUtil::findFirstBit(n);
+ uint32_t regMask = IntUtil::mask(regIndex);
+
+ _context->move<C>(vd, regIndex);
+ availableRegs ^= regMask;
+ continue;
+ }
+ }
+
+ _context->spill<C>(vd);
+ } while (m != 0);
+}
+
+template<int C>
+ASMJIT_INLINE void X86CallAlloc::alloc() {
+ if (isVaDone(C))
+ return;
+
+ VarAttr* list = getVaListByClass(C);
+ uint32_t count = getVaCountByClass(C);
+
+ //X86VarState* state = getState();
+ //VarData** sVars = state->getListByClass(C);
+
+ uint32_t i;
+ bool didWork;
+
+ do {
+ didWork = false;
+ for (i = 0; i < count; i++) {
+ VarAttr* aVa = &list[i];
+ VarData* aVd = aVa->getVd();
+
+ if ((aVa->getFlags() & (kVarAttrInReg | kVarAttrAllocInDone)) != kVarAttrInReg)
+ continue;
+
+ uint32_t aIndex = aVd->getRegIndex();
+ uint32_t bIndex = aVa->getInRegIndex();
+
+ // Shouldn't be the same.
+ ASMJIT_ASSERT(aIndex != bIndex);
+
+ VarData* bVd = getState()->getListByClass(C)[bIndex];
+ if (bVd) {
+ VarAttr* bVa = bVd->getVa();
+
+ // Gp registers only - Swap two registers if we can solve two
+ // allocation tasks by a single 'xchg' instruction, swapping
+ // two registers required by the instruction/node or one register
+ // required with another non-required.
+ if (C == kX86RegClassGp) {
+ _context->swapGp(aVd, bVd);
+
+ aVa->addFlags(kVarAttrAllocInDone);
+ addVaDone(C);
+
+ // Doublehit, two registers allocated by a single swap.
+ if (bVa && bVa->getInRegIndex() == aIndex) {
+ bVa->addFlags(kVarAttrAllocInDone);
+ addVaDone(C);
+ }
+
+ didWork = true;
+ continue;
+ }
+ }
+ else if (aIndex != kInvalidReg) {
+ _context->move<C>(aVd, bIndex);
+
+ aVa->addFlags(kVarAttrAllocInDone);
+ addVaDone(C);
+
+ didWork = true;
+ continue;
+ }
+ else {
+ _context->alloc<C>(aVd, bIndex);
+
+ aVa->addFlags(kVarAttrAllocInDone);
+ addVaDone(C);
+
+ didWork = true;
+ continue;
+ }
+ }
+ } while (didWork);
+}
+
+// ============================================================================
+// [asmjit::X86CallAlloc - AllocImmsOnStack]
+// ============================================================================
+
+ASMJIT_INLINE void X86CallAlloc::allocImmsOnStack() {
+ X86CallNode* node = getNode();
+ X86FuncDecl* decl = node->getDecl();
+
+ uint32_t argCount = decl->getArgCount();
+ Operand* argList = node->_args;
+
+ for (uint32_t i = 0; i < argCount; i++) {
+ Operand& op = argList[i];
+
+ if (!op.isImm())
+ continue;
+
+ const Imm& imm = static_cast<const Imm&>(op);
+ const FuncInOut& arg = decl->getArg(i);
+ uint32_t varType = arg.getVarType();
+
+ if (arg.hasStackOffset()) {
+ X86Mem dst = x86::ptr(_context->_zsp, -static_cast<int>(_context->getRegSize()) + arg.getStackOffset());
+ _context->emitMoveImmOnStack(varType, &dst, &imm);
+ }
+ else {
+ _context->emitMoveImmToReg(varType, arg.getRegIndex(), &imm);
+ }
+ }
+}
+
+// ============================================================================
+// [asmjit::X86CallAlloc - Duplicate]
+// ============================================================================
+
+template<int C>
+ASMJIT_INLINE void X86CallAlloc::duplicate() {
+ VarAttr* list = getVaListByClass(C);
+ uint32_t count = getVaCountByClass(C);
+
+ for (uint32_t i = 0; i < count; i++) {
+ VarAttr* va = &list[i];
+ if (!va->hasFlag(kVarAttrInReg))
+ continue;
+
+ uint32_t inRegs = va->getInRegs();
+ if (!inRegs)
+ continue;
+
+ VarData* vd = va->getVd();
+ uint32_t regIndex = vd->getRegIndex();
+
+ ASMJIT_ASSERT(regIndex != kInvalidReg);
+
+ inRegs &= ~IntUtil::mask(regIndex);
+ if (!inRegs)
+ continue;
+
+ for (uint32_t dupIndex = 0; inRegs != 0; dupIndex++, inRegs >>= 1) {
+ if (inRegs & 0x1) {
+ _context->emitMove(vd, dupIndex, regIndex, "Duplicate");
+ _context->_clobberedRegs.add(C, IntUtil::mask(dupIndex));
+ }
+ }
+ }
+}
+
+// ============================================================================
+// [asmjit::X86CallAlloc - GuessAlloc / GuessSpill]
+// ============================================================================
+
+template<int C>
+ASMJIT_INLINE uint32_t X86CallAlloc::guessAlloc(VarData* vd, uint32_t allocableRegs) {
+ ASMJIT_ASSERT(allocableRegs != 0);
+
+ // Stop now if there is only one bit (register) set in 'allocableRegs' mask.
+ if (IntUtil::isPowerOf2(allocableRegs))
+ return allocableRegs;
+
+ uint32_t i;
+ uint32_t safeRegs = allocableRegs;
+ uint32_t maxLookAhead = _compiler->getMaxLookAhead();
+
+ // Look ahead and calculate mask of special registers on both - input/output.
+ Node* node = _node;
+ for (i = 0; i < maxLookAhead; i++) {
+ // Stop on 'RetNode' and 'EndNode.
+ if (node->hasFlag(kNodeFlagIsRet))
+ break;
+
+ // Stop on conditional jump, we don't follow them.
+ if (node->hasFlag(kNodeFlagIsJcc))
+ break;
+
+ // Advance on non-conditional jump.
+ if (node->hasFlag(kNodeFlagIsJmp))
+ node = static_cast<JumpNode*>(node)->getTarget();
+
+ node = node->getNext();
+ ASMJIT_ASSERT(node);
+
+ X86VarMap* map = node->getMap<X86VarMap>();
+ if (map) {
+ VarAttr* va = map->findVaByClass(C, vd);
+ if (va) {
+ uint32_t inRegs = va->getInRegs();
+ if (inRegs != 0) {
+ safeRegs = allocableRegs;
+ allocableRegs &= inRegs;
+
+ if (allocableRegs == 0)
+ goto _UseSafeRegs;
+ else
+ return allocableRegs;
+ }
+ }
+
+ safeRegs = allocableRegs;
+ allocableRegs &= ~(map->_inRegs.get(C) | map->_outRegs.get(C) | map->_clobberedRegs.get(C));
+
+ if (allocableRegs == 0)
+ break;
+ }
+ }
+
+_UseSafeRegs:
+ return safeRegs;
+}
+
+template<int C>
+ASMJIT_INLINE uint32_t X86CallAlloc::guessSpill(VarData*, uint32_t allocableRegs) {
+ ASMJIT_ASSERT(allocableRegs != 0);
+
+ return 0;
+}
+
+// ============================================================================
+// [asmjit::X86CallAlloc - Save]
+// ============================================================================
+
+template<int C>
+ASMJIT_INLINE void X86CallAlloc::save() {
+ X86VarState* state = getState();
+ VarData** sVars = state->getListByClass(C);
+
+ uint32_t i;
+ uint32_t affected = _map->_clobberedRegs.get(C) & state->_occupied.get(C) & state->_modified.get(C);
+
+ for (i = 0; affected != 0; i++, affected >>= 1) {
+ if (affected & 0x1) {
+ VarData* vd = sVars[i];
+ ASMJIT_ASSERT(vd);
+ ASMJIT_ASSERT(vd->isModified());
+
+ VarAttr* va = vd->getVa();
+ if (!va || (va->getFlags() & (kVarAttrOutReg | kVarAttrUnuse)) == 0) {
+ _context->save<C>(vd);
+ }
+ }
+ }
+}
+
+// ============================================================================
+// [asmjit::X86CallAlloc - Clobber]
+// ============================================================================
+
+template<int C>
+ASMJIT_INLINE void X86CallAlloc::clobber() {
+ X86VarState* state = getState();
+ VarData** sVars = state->getListByClass(C);
+
+ uint32_t i;
+ uint32_t affected = _map->_clobberedRegs.get(C) & state->_occupied.get(C);
+
+ for (i = 0; affected != 0; i++, affected >>= 1) {
+ if (affected & 0x1) {
+ VarData* vd = sVars[i];
+ ASMJIT_ASSERT(vd);
+
+ VarAttr* va = vd->getVa();
+ uint32_t vdState = kVarStateUnused;
+
+ if (!vd->isModified() || (va && (va->getFlags() & (kVarAttrOutAll | kVarAttrUnuse)) != 0)) {
+ vdState = kVarStateMem;
+ }
+
+ _context->unuse<C>(vd, vdState);
+ }
+ }
+}
+
+// ============================================================================
+// [asmjit::X86CallAlloc - Ret]
+// ============================================================================
+
+ASMJIT_INLINE void X86CallAlloc::ret() {
+ X86CallNode* node = getNode();
+ X86FuncDecl* decl = node->getDecl();
+
+ uint32_t i;
+ Operand* retList = node->_ret;
+
+ for (i = 0; i < 2; i++) {
+ const FuncInOut& retFunc = decl->getRet(i);
+ Operand* op = &retList[i];
+
+ if (!retFunc.hasRegIndex() || !op->isVar())
+ continue;
+
+ VarData* vd = _compiler->getVdById(op->getId());
+ uint32_t regIndex = retFunc.getRegIndex();
+
+ switch (vd->getClass()) {
+ case kX86RegClassGp:
+ if (vd->getRegIndex() != kInvalidReg)
+ _context->unuse<kX86RegClassGp>(vd);
+ _context->attach<kX86RegClassGp>(vd, regIndex, true);
+ break;
+ case kX86RegClassMm:
+ if (vd->getRegIndex() != kInvalidReg)
+ _context->unuse<kX86RegClassMm>(vd);
+ _context->attach<kX86RegClassMm>(vd, regIndex, true);
+ break;
+ case kX86RegClassXyz:
+ if (vd->getRegIndex() != kInvalidReg)
+ _context->unuse<kX86RegClassXyz>(vd);
+ _context->attach<kX86RegClassXyz>(vd, regIndex, true);
+ break;
+ }
+ }
+}
+
+// ============================================================================
+// [asmjit::X86Context - TranslateOperands]
+// ============================================================================
+
+//! \internal
+static Error X86Context_translateOperands(X86Context* self, Operand* opList, uint32_t opCount) {
+ X86Compiler* compiler = self->getCompiler();
+ //const X86VarInfo* varInfo = _x86VarInfo;
+
+ uint32_t hasGpdBase = compiler->getRegSize() == 4;
+
+ // Translate variables into registers.
+ for (uint32_t i = 0; i < opCount; i++) {
+ Operand* op = &opList[i];
+
+ if (op->isVar()) {
+ VarData* vd = compiler->getVdById(op->getId());
+ ASMJIT_ASSERT(vd);
+ ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg);
+
+ op->_vreg.op = kOperandTypeReg;
+ op->_vreg.index = vd->getRegIndex();
+ }
+ else if (op->isMem()) {
+ X86Mem* m = static_cast<X86Mem*>(op);
+
+ if (m->isBaseIndexType() && OperandUtil::isVarId(m->getBase())) {
+ VarData* vd = compiler->getVdById(m->getBase());
+
+ if (m->getMemType() == kMemTypeBaseIndex) {
+ ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg);
+ op->_vmem.base = vd->getRegIndex();
+ }
+ else {
+ if (!vd->isMemArg())
+ self->getVarCell(vd);
+
+ // Offset will be patched later by X86Context_patchFuncMem().
+ m->setGpdBase(hasGpdBase);
+ m->adjust(vd->isMemArg() ? self->_argActualDisp : self->_varActualDisp);
+ }
+ }
+
+ if (OperandUtil::isVarId(m->getIndex())) {
+ VarData* vd = compiler->getVdById(m->getIndex());
+ ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg);
+ ASMJIT_ASSERT(vd->getRegIndex() != kX86RegIndexR12);
+ op->_vmem.index = vd->getRegIndex();
+ }
+ }
+ }
+
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86Context - TranslatePrologEpilog]
+// ============================================================================
+
+//! \internal
+static Error X86Context_initFunc(X86Context* self, X86FuncNode* func) {
+ X86Compiler* compiler = self->getCompiler();
+ X86FuncDecl* decl = func->getDecl();
+
+ X86RegMask& clobberedRegs = self->_clobberedRegs;
+ uint32_t regSize = compiler->getRegSize();
+
+ // Setup "Save-Restore" registers.
+ func->_saveRestoreRegs.set(kX86RegClassGp , clobberedRegs.get(kX86RegClassGp ) & decl->getPreserved(kX86RegClassGp ));
+ func->_saveRestoreRegs.set(kX86RegClassFp , 0);
+ func->_saveRestoreRegs.set(kX86RegClassMm , clobberedRegs.get(kX86RegClassMm ) & decl->getPreserved(kX86RegClassMm ));
+ func->_saveRestoreRegs.set(kX86RegClassXyz, clobberedRegs.get(kX86RegClassXyz) & decl->getPreserved(kX86RegClassXyz));
+
+ ASMJIT_ASSERT(!func->_saveRestoreRegs.has(kX86RegClassGp, IntUtil::mask(kX86RegIndexSp)));
+
+ // Setup required stack alignment and kFuncFlagIsStackMisaligned.
+ {
+ uint32_t requiredStackAlignment = IntUtil::iMax(self->_memMaxAlign, self->getRegSize());
+
+ if (requiredStackAlignment < 16) {
+ // Require 16-byte alignment if 8-byte vars are used.
+ if (self->_mem8ByteVarsUsed)
+ requiredStackAlignment = 16;
+ else if (func->_saveRestoreRegs.get(kX86RegClassMm) || func->_saveRestoreRegs.get(kX86RegClassXyz))
+ requiredStackAlignment = 16;
+ else if (IntUtil::inInterval<uint32_t>(func->getRequiredStackAlignment(), 8, 16))
+ requiredStackAlignment = 16;
+ }
+
+ if (func->getRequiredStackAlignment() < requiredStackAlignment)
+ func->setRequiredStackAlignment(requiredStackAlignment);
+
+ func->updateRequiredStackAlignment();
+ }
+
+ // Adjust stack pointer if function is caller.
+ if (func->isCaller()) {
+ func->addFuncFlags(kFuncFlagIsStackAdjusted);
+ }
+
+ // Adjust stack pointer if manual stack alignment is needed.
+ if (func->isStackMisaligned() && func->isNaked()) {
+ // Get a memory cell where the original stack frame will be stored.
+ MemCell* cell = self->_newStackCell(regSize, regSize);
+ if (!cell)
+ return self->getError();
+
+ func->addFuncFlags(kFuncFlagIsStackAdjusted);
+ self->_stackFrameCell = cell;
+
+ if (decl->getArgStackSize() > 0) {
+ func->addFuncFlags(kX86FuncFlagMoveArgs);
+ func->setExtraStackSize(decl->getArgStackSize());
+ }
+
+ // Get temporary register which will be used to align the stack frame.
+ uint32_t fRegMask = IntUtil::bits(self->_regCount.getGp());
+ uint32_t stackFrameCopyRegs;
+
+ fRegMask &= ~(decl->getUsed(kX86RegClassGp) | IntUtil::mask(kX86RegIndexSp));
+ stackFrameCopyRegs = fRegMask;
+
+ // Try to remove modified registers from the mask.
+ uint32_t tRegMask = fRegMask & ~self->getClobberedRegs(kX86RegClassGp);
+ if (tRegMask != 0)
+ fRegMask = tRegMask;
+
+ // Try to remove preserved registers from the mask.
+ tRegMask = fRegMask & ~decl->getPreserved(kX86RegClassGp);
+ if (tRegMask != 0)
+ fRegMask = tRegMask;
+
+ ASMJIT_ASSERT(fRegMask != 0);
+
+ uint32_t fRegIndex = IntUtil::findFirstBit(fRegMask);
+ func->_stackFrameRegIndex = static_cast<uint8_t>(fRegIndex);
+
+ // We have to save the register on the stack (it will be the part of prolog
+ // and epilog), however we shouldn't save it twice, so we will remove it
+ // from '_saveRestoreRegs' in case that it is preserved.
+ fRegMask = IntUtil::mask(fRegIndex);
+ if ((fRegMask & decl->getPreserved(kX86RegClassGp)) != 0) {
+ func->_saveRestoreRegs.del(kX86RegClassGp, fRegMask);
+ func->_isStackFrameRegPreserved = true;
+ }
+
+ if (func->hasFuncFlag(kX86FuncFlagMoveArgs)) {
+ uint32_t maxRegs = (func->getArgStackSize() + regSize - 1) / regSize;
+ stackFrameCopyRegs &= ~fRegMask;
+
+ tRegMask = stackFrameCopyRegs & self->getClobberedRegs(kX86RegClassGp);
+ uint32_t tRegCnt = IntUtil::bitCount(tRegMask);
+
+ if (tRegCnt > 1 || (tRegCnt > 0 && tRegCnt <= maxRegs))
+ stackFrameCopyRegs = tRegMask;
+ else
+ stackFrameCopyRegs = IntUtil::keepNOnesFromRight(stackFrameCopyRegs, IntUtil::iMin<uint32_t>(maxRegs, 2));
+
+ func->_saveRestoreRegs.add(kX86RegClassGp, stackFrameCopyRegs & decl->getPreserved(kX86RegClassGp));
+ IntUtil::indexNOnesFromRight(func->_stackFrameCopyGpIndex, stackFrameCopyRegs, maxRegs);
+ }
+ }
+ // If function is not naked we generate standard "EBP/RBP" stack frame.
+ else if (!func->isNaked()) {
+ uint32_t fRegIndex = kX86RegIndexBp;
+
+ func->_stackFrameRegIndex = static_cast<uint8_t>(fRegIndex);
+ func->_isStackFrameRegPreserved = true;
+ }
+
+ ASMJIT_PROPAGATE_ERROR(self->resolveCellOffsets());
+
+ // Adjust stack pointer if requested memory can't fit into "Red Zone" or "Spill Zone".
+ if (self->_memAllTotal > IntUtil::iMax<uint32_t>(func->getRedZoneSize(), func->getSpillZoneSize())) {
+ func->addFuncFlags(kFuncFlagIsStackAdjusted);
+ }
+
+ // Setup stack size used to save preserved registers.
+ {
+ uint32_t memGpSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kX86RegClassGp )) * regSize;
+ uint32_t memMmSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kX86RegClassMm )) * 8;
+ uint32_t memXmmSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kX86RegClassXyz)) * 16;
+
+ if (func->hasFuncFlag(kX86FuncFlagPushPop)) {
+ func->_pushPopStackSize = memGpSize;
+ func->_moveStackSize = memXmmSize + IntUtil::alignTo<uint32_t>(memMmSize, 16);
+ }
+ else {
+ func->_pushPopStackSize = 0;
+ func->_moveStackSize = memXmmSize + IntUtil::alignTo<uint32_t>(memMmSize + memGpSize, 16);
+ }
+ }
+
+ // Setup adjusted stack size.
+ if (func->isStackMisaligned()) {
+ func->_alignStackSize = 0;
+ }
+ else {
+ // If function is aligned, the RETURN address is stored in the aligned
+ // [ZSP - PtrSize] which makes current ZSP unaligned.
+ int32_t v = static_cast<int32_t>(regSize);
+
+ // If we have to store function frame pointer we have to count it as well,
+ // because it is the first thing pushed on the stack.
+ if (func->hasStackFrameReg() && func->isStackFrameRegPreserved())
+ v += regSize;
+
+ // Count push/pop sequence.
+ v += func->getPushPopStackSize();
+
+ // Calculate the final offset to keep stack alignment.
+ func->_alignStackSize = IntUtil::deltaTo<uint32_t>(v, func->getRequiredStackAlignment());
+ }
+
+ // Memory stack size.
+ func->_memStackSize = self->_memAllTotal;
+ func->_alignedMemStackSize = IntUtil::alignTo<uint32_t>(func->_memStackSize, func->_requiredStackAlignment);
+
+ if (func->isNaked()) {
+ self->_argBaseReg = kX86RegIndexSp;
+
+ if (func->isStackAdjusted()) {
+ if (func->isStackMisaligned()) {
+ self->_argBaseOffset = static_cast<int32_t>(
+ func->getCallStackSize() +
+ func->getAlignedMemStackSize() +
+ func->getMoveStackSize() +
+ func->getAlignStackSize());
+ self->_argBaseOffset -= regSize;
+ }
+ else {
+ self->_argBaseOffset = static_cast<int32_t>(
+ func->getCallStackSize() +
+ func->getAlignedMemStackSize() +
+ func->getMoveStackSize() +
+ func->getPushPopStackSize() +
+ func->getExtraStackSize() +
+ func->getAlignStackSize());
+ }
+ }
+ else {
+ self->_argBaseOffset = func->getPushPopStackSize();
+ }
+ }
+ else {
+ self->_argBaseReg = kX86RegIndexBp;
+ // Caused by "push zbp".
+ self->_argBaseOffset = regSize;
+ }
+
+ self->_varBaseReg = kX86RegIndexSp;
+ self->_varBaseOffset = func->getCallStackSize();
+
+ if (!func->isStackAdjusted()) {
+ self->_varBaseOffset = -static_cast<int32_t>(
+ func->_alignStackSize +
+ func->_alignedMemStackSize +
+ func->_moveStackSize);
+ }
+
+ return kErrorOk;
+}
+
+//! \internal
+static Error X86Context_patchFuncMem(X86Context* self, X86FuncNode* func, Node* stop) {
+ X86Compiler* compiler = self->getCompiler();
+ Node* node = func;
+
+ do {
+ if (node->getType() == kNodeTypeInst) {
+ InstNode* iNode = static_cast<InstNode*>(node);
+
+ if (iNode->hasMemOp()) {
+ X86Mem* m = iNode->getMemOp<X86Mem>();
+
+ if (m->getMemType() == kMemTypeStackIndex && OperandUtil::isVarId(m->getBase())) {
+ VarData* vd = compiler->getVdById(m->getBase());
+ ASMJIT_ASSERT(vd);
+
+ if (vd->isMemArg()) {
+ m->_vmem.base = self->_argBaseReg;
+ m->_vmem.displacement += vd->getMemOffset();
+ m->_vmem.displacement += self->_argBaseOffset;
+ }
+ else {
+ MemCell* cell = vd->getMemCell();
+ ASMJIT_ASSERT(cell);
+
+ m->_vmem.base = self->_varBaseReg;
+ m->_vmem.displacement += cell->getOffset();
+ m->_vmem.displacement += self->_varBaseOffset;
+ }
+ }
+ }
+ }
+
+ node = node->getNext();
+ } while (node != stop);
+
+ return kErrorOk;
+}
+
+//! \internal
+static Error X86Context_translatePrologEpilog(X86Context* self, X86FuncNode* func) {
+ X86Compiler* compiler = self->getCompiler();
+ X86FuncDecl* decl = func->getDecl();
+
+ uint32_t regSize = compiler->getRegSize();
+
+ int32_t stackSize = static_cast<int32_t>(
+ func->getAlignStackSize() +
+ func->getCallStackSize() +
+ func->getAlignedMemStackSize() +
+ func->getMoveStackSize() +
+ func->getExtraStackSize());
+ int32_t stackAlignment = func->getRequiredStackAlignment();
+
+ int32_t stackBase;
+ int32_t stackPtr;
+
+ if (func->isStackAdjusted()) {
+ stackBase = static_cast<int32_t>(
+ func->getCallStackSize() +
+ func->getAlignedMemStackSize());
+ }
+ else {
+ stackBase = -static_cast<int32_t>(
+ func->getAlignedMemStackSize() +
+ func->getAlignStackSize() +
+ func->getExtraStackSize());
+ }
+
+ uint32_t i, mask;
+ uint32_t regsGp = func->getSaveRestoreRegs(kX86RegClassGp );
+ uint32_t regsMm = func->getSaveRestoreRegs(kX86RegClassMm );
+ uint32_t regsXmm = func->getSaveRestoreRegs(kX86RegClassXyz);
+
+ bool earlyPushPop = false;
+ bool useLeaEpilog = false;
+
+ X86GpReg gpReg(self->_zsp);
+ X86GpReg fpReg(self->_zbp);
+
+ X86Mem fpOffset;
+
+ // --------------------------------------------------------------------------
+ // [Prolog]
+ // --------------------------------------------------------------------------
+
+ compiler->_setCursor(func->getEntryNode());
+
+ // Entry.
+ if (func->isNaked()) {
+ if (func->isStackMisaligned()) {
+ fpReg.setIndex(func->getStackFrameRegIndex());
+ fpOffset = x86::ptr(self->_zsp, static_cast<int32_t>(self->_stackFrameCell->getOffset()));
+
+ earlyPushPop = func->hasFuncFlag(kX86FuncFlagPushPop);
+ if (earlyPushPop)
+ self->emitPushSequence(regsGp);
+
+ if (func->isStackFrameRegPreserved())
+ compiler->emit(kX86InstIdPush, fpReg);
+
+ compiler->emit(kX86InstIdMov, fpReg, self->_zsp);
+ }
+ }
+ else {
+ compiler->emit(kX86InstIdPush, fpReg);
+ compiler->emit(kX86InstIdMov, fpReg, self->_zsp);
+ }
+
+ if (func->hasFuncFlag(kX86FuncFlagPushPop) && !earlyPushPop) {
+ self->emitPushSequence(regsGp);
+ if (func->isStackMisaligned() && regsGp != 0)
+ useLeaEpilog = true;
+ }
+
+ // Adjust stack pointer.
+ if (func->isStackAdjusted()) {
+ stackBase = static_cast<int32_t>(func->getAlignedMemStackSize() + func->getCallStackSize());
+
+ if (stackSize)
+ compiler->emit(kX86InstIdSub, self->_zsp, stackSize);
+
+ if (func->isStackMisaligned())
+ compiler->emit(kX86InstIdAnd, self->_zsp, -stackAlignment);
+
+ if (func->isStackMisaligned() && func->isNaked())
+ compiler->emit(kX86InstIdMov, fpOffset, fpReg);
+ }
+ else {
+ stackBase = -static_cast<int32_t>(func->getAlignStackSize() + func->getMoveStackSize());
+ }
+
+ // Save Xmm/Mm/Gp (Mov).
+ stackPtr = stackBase;
+ for (i = 0, mask = regsXmm; mask != 0; i++, mask >>= 1) {
+ if (mask & 0x1) {
+ compiler->emit(kX86InstIdMovaps, x86::oword_ptr(self->_zsp, stackPtr), x86::xmm(i));
+ stackPtr += 16;
+ }
+ }
+
+ for (i = 0, mask = regsMm; mask != 0; i++, mask >>= 1) {
+ if (mask & 0x1) {
+ compiler->emit(kX86InstIdMovq, x86::qword_ptr(self->_zsp, stackPtr), x86::mm(i));
+ stackPtr += 8;
+ }
+ }
+
+ if (!func->hasFuncFlag(kX86FuncFlagPushPop)) {
+ for (i = 0, mask = regsGp; mask != 0; i++, mask >>= 1) {
+ if (mask & 0x1) {
+ compiler->emit(kX86InstIdMov, x86::ptr(self->_zsp, stackPtr), gpReg.setIndex(i));
+ stackPtr += regSize;
+ }
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // [Move-Args]
+ // --------------------------------------------------------------------------
+
+ if (func->hasFuncFlag(kX86FuncFlagMoveArgs)) {
+ uint32_t argStackPos = 0;
+ uint32_t argStackSize = decl->getArgStackSize();
+
+ uint32_t moveIndex = 0;
+ uint32_t moveCount = (argStackSize + regSize - 1) / regSize;
+
+ X86GpReg r[8];
+ uint32_t numRegs = 0;
+
+ for (i = 0; i < 6; i++)
+ if (func->_stackFrameCopyGpIndex[i] != kInvalidReg)
+ r[numRegs++] = gpReg.setIndex(func->_stackFrameCopyGpIndex[i]);
+
+ int32_t dSrc = func->getPushPopStackSize() + regSize;
+ int32_t dDst = func->getAlignStackSize() +
+ func->getCallStackSize() +
+ func->getAlignedMemStackSize() +
+ func->getMoveStackSize();
+
+ if (func->isStackFrameRegPreserved())
+ dSrc += regSize;
+
+ X86Mem mSrc = x86::ptr(fpReg, dSrc);
+ X86Mem mDst = x86::ptr(self->_zsp, dDst);
+
+ while (moveIndex < moveCount) {
+ uint32_t numMovs = IntUtil::iMin<uint32_t>(moveCount - moveIndex, numRegs);
+
+ for (i = 0; i < numMovs; i++)
+ compiler->emit(kX86InstIdMov, r[i], mSrc.adjusted((moveIndex + i) * regSize));
+ for (i = 0; i < numMovs; i++)
+ compiler->emit(kX86InstIdMov, mDst.adjusted((moveIndex + i) * regSize), r[i]);
+
+ argStackPos += numMovs * regSize;
+ moveIndex += numMovs;
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // [Epilog]
+ // --------------------------------------------------------------------------
+
+ compiler->_setCursor(func->getExitNode());
+
+ // Restore Xmm/Mm/Gp (Mov).
+ stackPtr = stackBase;
+ for (i = 0, mask = regsXmm; mask != 0; i++, mask >>= 1) {
+ if (mask & 0x1) {
+ compiler->emit(kX86InstIdMovaps, x86::xmm(i), x86::oword_ptr(self->_zsp, stackPtr));
+ stackPtr += 16;
+ }
+ }
+
+ for (i = 0, mask = regsMm; mask != 0; i++, mask >>= 1) {
+ if (mask & 0x1) {
+ compiler->emit(kX86InstIdMovq, x86::mm(i), x86::qword_ptr(self->_zsp, stackPtr));
+ stackPtr += 8;
+ }
+ }
+
+ if (!func->hasFuncFlag(kX86FuncFlagPushPop)) {
+ for (i = 0, mask = regsGp; mask != 0; i++, mask >>= 1) {
+ if (mask & 0x1) {
+ compiler->emit(kX86InstIdMov, gpReg.setIndex(i), x86::ptr(self->_zsp, stackPtr));
+ stackPtr += regSize;
+ }
+ }
+ }
+
+ // Adjust stack.
+ if (useLeaEpilog) {
+ compiler->emit(kX86InstIdLea, self->_zsp, x86::ptr(fpReg, -static_cast<int32_t>(func->getPushPopStackSize())));
+ }
+ else if (!func->isStackMisaligned()) {
+ if (func->isStackAdjusted() && stackSize != 0)
+ compiler->emit(kX86InstIdAdd, self->_zsp, stackSize);
+ }
+
+ // Restore Gp (Push/Pop).
+ if (func->hasFuncFlag(kX86FuncFlagPushPop) && !earlyPushPop)
+ self->emitPopSequence(regsGp);
+
+ // Emms.
+ if (func->hasFuncFlag(kX86FuncFlagEmms))
+ compiler->emit(kX86InstIdEmms);
+
+ // MFence/SFence/LFence.
+ if (func->hasFuncFlag(kX86FuncFlagSFence) & func->hasFuncFlag(kX86FuncFlagLFence))
+ compiler->emit(kX86InstIdMfence);
+ else if (func->hasFuncFlag(kX86FuncFlagSFence))
+ compiler->emit(kX86InstIdSfence);
+ else if (func->hasFuncFlag(kX86FuncFlagLFence))
+ compiler->emit(kX86InstIdLfence);
+
+ // Leave.
+ if (func->isNaked()) {
+ if (func->isStackMisaligned()) {
+ compiler->emit(kX86InstIdMov, self->_zsp, fpOffset);
+
+ if (func->isStackFrameRegPreserved())
+ compiler->emit(kX86InstIdPop, fpReg);
+
+ if (earlyPushPop)
+ self->emitPopSequence(regsGp);
+ }
+ }
+ else {
+ if (useLeaEpilog) {
+ compiler->emit(kX86InstIdPop, fpReg);
+ }
+ else if (func->hasFuncFlag(kX86FuncFlagLeave)) {
+ compiler->emit(kX86InstIdLeave);
+ }
+ else {
+ compiler->emit(kX86InstIdMov, self->_zsp, fpReg);
+ compiler->emit(kX86InstIdPop, fpReg);
+ }
+ }
+
+ // Emit return.
+ if (decl->getCalleePopsStack())
+ compiler->emit(kX86InstIdRet, static_cast<int32_t>(decl->getArgStackSize()));
+ else
+ compiler->emit(kX86InstIdRet);
+
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86Context - Translate - Jump]
+// ============================================================================
+
+//! \internal
+static void X86Context_translateJump(X86Context* self, JumpNode* jNode, TargetNode* jTarget) {
+ X86Compiler* compiler = self->getCompiler();
+ Node* extNode = self->getExtraBlock();
+
+ // TODO: [COMPILER] State Change.
+ compiler->_setCursor(extNode);
+ self->switchState(jTarget->getState());
+
+ // If one or more instruction has been added during switchState() it will be
+ // moved at the end of the function body.
+ if (compiler->getCursor() != extNode) {
+ TargetNode* jTrampolineTarget = compiler->newTarget();
+
+ // Add the jump to the target.
+ compiler->jmp(jTarget->getLabel());
+
+ // Add the trampoline-label we jump to change the state.
+ extNode = compiler->setCursor(extNode);
+ compiler->addNode(jTrampolineTarget);
+
+ // Finally, patch the jump target.
+ ASMJIT_ASSERT(jNode->getOpCount() > 0);
+ jNode->_opList[0] = jTrampolineTarget->getLabel();
+ jNode->_target = jTrampolineTarget;
+ }
+
+ // Store the extNode and load the state back.
+ self->setExtraBlock(extNode);
+ self->loadState(jNode->_state);
+}
+
+// ============================================================================
+// [asmjit::X86Context - Translate - Ret]
+// ============================================================================
+
+static Error X86Context_translateRet(X86Context* self, RetNode* rNode, TargetNode* exitTarget) {
+ Node* node = rNode->getNext();
+
+ while (node) {
+ switch (node->getType()) {
+ // If we have found an exit label we just return, there is no need to
+ // emit jump to that.
+ case kNodeTypeTarget:
+ if (static_cast<TargetNode*>(node) == exitTarget)
+ return kErrorOk;
+ goto _EmitRet;
+
+ case kNodeTypeEmbed:
+ case kNodeTypeInst:
+ case kNodeTypeCall:
+ case kNodeTypeRet:
+ goto _EmitRet;
+
+ // Continue iterating.
+ case kNodeTypeComment:
+ case kNodeTypeAlign:
+ case kNodeTypeHint:
+ break;
+
+ // Invalid node to be here.
+ case kNodeTypeFunc:
+ return self->getCompiler()->setError(kErrorInvalidState);
+
+ // We can't go forward from here.
+ case kNodeTypeEnd:
+ return kErrorOk;
+ }
+
+ node = node->getNext();
+ }
+
+_EmitRet:
+ {
+ X86Compiler* compiler = self->getCompiler();
+
+ compiler->_setCursor(rNode);
+ compiler->jmp(exitTarget->getLabel());
+ }
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86Context - Translate - Func]
+// ============================================================================
+
+Error X86Context::translate() {
+ ASMJIT_TLOG("[Translate] === Begin ===\n");
+
+ X86Compiler* compiler = getCompiler();
+ X86FuncNode* func = getFunc();
+
+ // Register allocator contexts.
+ X86VarAlloc vAlloc(this);
+ X86CallAlloc cAlloc(this);
+
+ // Flow.
+ Node* node_ = func;
+ Node* next = nullptr;
+ Node* stop = getStop();
+
+ PodList<Node*>::Link* jLink = _jccList.getFirst();
+
+ for (;;) {
+ while (node_->isTranslated()) {
+ // Switch state if we went to the already translated node.
+ if (node_->getType() == kNodeTypeTarget) {
+ TargetNode* node = static_cast<TargetNode*>(node_);
+ compiler->_setCursor(node->getPrev());
+ switchState(node->getState());
+ }
+
+_NextGroup:
+ if (!jLink) {
+ goto _Done;
+ }
+ else {
+ node_ = jLink->getValue();
+ jLink = jLink->getNext();
+
+ Node* jFlow = X86Context_getOppositeJccFlow(static_cast<JumpNode*>(node_));
+ loadState(node_->getState());
+
+ if (jFlow->getState()) {
+ X86Context_translateJump(this,
+ static_cast<JumpNode*>(node_),
+ static_cast<TargetNode*>(jFlow));
+
+ node_ = jFlow;
+ if (node_->isTranslated())
+ goto _NextGroup;
+ }
+ else {
+ node_ = jFlow;
+ }
+
+ break;
+ }
+ }
+
+ next = node_->getNext();
+ node_->addFlags(kNodeFlagIsTranslated);
+
+ ASMJIT_TSEC({
+ X86Context_traceNode(this, node_);
+ });
+
+ switch (node_->getType()) {
+ // ----------------------------------------------------------------------
+ // [Align / Embed]
+ // ----------------------------------------------------------------------
+
+ case kNodeTypeAlign:
+ case kNodeTypeEmbed:
+ break;
+
+ // ----------------------------------------------------------------------
+ // [Target]
+ // ----------------------------------------------------------------------
+
+ case kNodeTypeTarget: {
+ TargetNode* node = static_cast<TargetNode*>(node_);
+ ASMJIT_ASSERT(!node->hasState());
+ node->setState(saveState());
+ break;
+ }
+
+ // ----------------------------------------------------------------------
+ // [Inst/Call/SArg/Ret]
+ // ----------------------------------------------------------------------
+
+ case kNodeTypeInst:
+ case kNodeTypeCall:
+ case kNodeTypeSArg:
+ // Update VarAttr's unuse flags based on liveness of the next node.
+ if (!node_->isJcc()) {
+ X86VarMap* map = static_cast<X86VarMap*>(node_->getMap());
+ VarBits* liveness = next->getLiveness();
+
+ if (map && liveness) {
+ VarAttr* vaList = map->getVaList();
+ uint32_t vaCount = map->getVaCount();
+
+ for (uint32_t i = 0; i < vaCount; i++) {
+ VarAttr* va = &vaList[i];
+ VarData* vd = va->getVd();
+
+ if (!liveness->getBit(vd->getContextId()))
+ va->addFlags(kVarAttrUnuse);
+ }
+ }
+ }
+
+ if (node_->getType() == kNodeTypeCall) {
+ ASMJIT_PROPAGATE_ERROR(cAlloc.run(static_cast<X86CallNode*>(node_)));
+ break;
+ }
+ // ... Fall through ...
+
+ case kNodeTypeHint:
+ case kNodeTypeRet: {
+ ASMJIT_PROPAGATE_ERROR(vAlloc.run(node_));
+
+ // Handle conditional/unconditional jump.
+ if (node_->isJmpOrJcc()) {
+ JumpNode* node = static_cast<JumpNode*>(node_);
+ TargetNode* jTarget = node->getTarget();
+
+ if (node->isJmp()) {
+ if (jTarget->hasState()) {
+ compiler->_setCursor(node->getPrev());
+ switchState(jTarget->getState());
+
+ goto _NextGroup;
+ }
+ else {
+ next = jTarget;
+ }
+ }
+ else {
+ Node* jNext = node->getNext();
+
+ if (jTarget->isTranslated()) {
+ if (jNext->isTranslated()) {
+ ASMJIT_ASSERT(jNext->getType() == kNodeTypeTarget);
+ // TODO: [COMPILER] State - Do intersection of two states if possible.
+ }
+
+ VarState* savedState = saveState();
+ node->setState(savedState);
+
+ X86Context_translateJump(this, node, jTarget);
+ next = jNext;
+ }
+ else if (jNext->isTranslated()) {
+ ASMJIT_ASSERT(jNext->getType() == kNodeTypeTarget);
+
+ VarState* savedState = saveState();
+ node->setState(savedState);
+
+ compiler->_setCursor(node);
+ switchState(static_cast<TargetNode*>(jNext)->getState());
+
+ next = jTarget;
+ }
+ else {
+ node->setState(saveState());
+ next = X86Context_getJccFlow(node);
+ }
+ }
+ }
+ else if (node_->isRet()) {
+ ASMJIT_PROPAGATE_ERROR(
+ X86Context_translateRet(this, static_cast<RetNode*>(node_), func->getExitNode()));
+ }
+ break;
+ }
+
+ // ----------------------------------------------------------------------
+ // [Func]
+ // ----------------------------------------------------------------------
+
+ case kNodeTypeFunc: {
+ ASMJIT_ASSERT(node_ == func);
+
+ X86FuncDecl* decl = func->getDecl();
+ X86VarMap* map = func->getMap<X86VarMap>();
+
+ if (map) {
+ uint32_t i;
+ uint32_t argCount = func->_x86Decl.getArgCount();
+
+ for (i = 0; i < argCount; i++) {
+ const FuncInOut& arg = decl->getArg(i);
+
+ VarData* vd = func->getArg(i);
+ VarAttr* va = map->findVa(vd);
+ ASMJIT_ASSERT(va);
+
+ if (va->getFlags() & kVarAttrUnuse)
+ continue;
+
+ uint32_t regIndex = va->getOutRegIndex();
+ if (regIndex != kInvalidReg && (va->getFlags() & kVarAttrOutConv) == 0) {
+ switch (vd->getClass()) {
+ case kX86RegClassGp : attach<kX86RegClassGp >(vd, regIndex, true); break;
+ case kX86RegClassMm : attach<kX86RegClassMm >(vd, regIndex, true); break;
+ case kX86RegClassXyz: attach<kX86RegClassXyz>(vd, regIndex, true); break;
+ }
+ }
+ else if (va->hasFlag(kVarAttrOutConv)) {
+ // TODO: [COMPILER] Function Argument Conversion.
+ ASMJIT_ASSERT(!"Reached");
+ }
+ else {
+ vd->_isMemArg = true;
+ vd->setMemOffset(arg.getStackOffset());
+ vd->setState(kVarStateMem);
+ }
+ }
+ }
+ break;
+ }
+
+ // ----------------------------------------------------------------------
+ // [End]
+ // ----------------------------------------------------------------------
+
+ case kNodeTypeEnd: {
+ goto _NextGroup;
+ }
+
+ default:
+ break;
+ }
+
+ if (next == stop)
+ goto _NextGroup;
+ node_ = next;
+ }
+
+_Done:
+ ASMJIT_PROPAGATE_ERROR(X86Context_initFunc(this, func));
+ ASMJIT_PROPAGATE_ERROR(X86Context_patchFuncMem(this, func, stop));
+ ASMJIT_PROPAGATE_ERROR(X86Context_translatePrologEpilog(this, func));
+
+ ASMJIT_TLOG("[Translate] === Done ===\n\n");
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86Context - Schedule]
+// ============================================================================
+
+Error X86Context::schedule() {
+ X86Compiler* compiler = getCompiler();
+ X86Scheduler scheduler(compiler,
+ static_cast<const X86CpuInfo*>(compiler->getRuntime()->getCpuInfo()));
+
+ Node* node_ = getFunc();
+ Node* stop = getStop();
+
+ PodList<Node*>::Link* jLink = _jccList.getFirst();
+
+ // --------------------------------------------------------------------------
+ // [Loop]
+ // --------------------------------------------------------------------------
+
+_Advance:
+ while (node_->isScheduled()) {
+_NextGroup:
+ if (!jLink)
+ goto _Done;
+
+ // We always go to the next instruction in the main loop so we have to
+ // jump to the `jcc` target here.
+ node_ = static_cast<JumpNode*>(jLink->getValue())->getTarget();
+ jLink = jLink->getNext();
+ }
+
+ // Find interval that can be passed to scheduler.
+ for (;;) {
+ Node* schedStart = node_;
+
+ for (;;) {
+ Node* next = node_->getNext();
+ node_->addFlags(kNodeFlagIsScheduled);
+
+ // Shouldn't happen here, investigate if hit.
+ ASMJIT_ASSERT(node_ != stop);
+
+ uint32_t nodeType = node_->getType();
+ if (nodeType != kNodeTypeInst) {
+ // If we didn't reach any instruction node we simply advance. In this
+ // case no informative nodes will be removed and everything else just
+ // skipped.
+ if (schedStart == node_) {
+ node_ = next;
+ if (nodeType == kNodeTypeEnd || nodeType == kNodeTypeRet)
+ goto _NextGroup;
+ else
+ goto _Advance;
+ }
+
+ // Remove informative nodes if we are in a middle of instruction stream.
+ //
+ // TODO: Shouldn't be there an option for this? Maybe it can be useful
+ // to stop if there is a comment or something. I'm not sure if it's
+ // good to always remove.
+ if (node_->isInformative()) {
+ compiler->removeNode(node_);
+ node_ = next;
+ continue;
+ }
+
+ break;
+ }
+
+ // Stop if `node_` is `jmp` or `jcc`.
+ if (node_->isJmpOrJcc())
+ break;
+
+ node_ = next;
+ }
+
+ // If the stream is less than 3 instructions it will not be passed to
+ // scheduler.
+ if (schedStart != node_ &&
+ schedStart->getNext() != node_ &&
+ schedStart->getNext() != node_->getPrev()) {
+
+ scheduler.run(schedStart, node_);
+ }
+
+ // If node is `jmp` we follow it as well.
+ if (node_->isJmp()) {
+ node_ = static_cast<JumpNode*>(node_)->getTarget();
+ goto _Advance;
+ }
+
+ // Handle stop nodes.
+ {
+ uint32_t nodeType = node_->getType();
+ if (nodeType == kNodeTypeEnd || nodeType == kNodeTypeRet)
+ goto _NextGroup;
+ }
+
+ node_ = node_->getNext();
+ goto _Advance;
+ }
+
+_Done:
+ return kErrorOk;
+}
+
+// ============================================================================
+// [asmjit::X86Context - Serialize]
+// ============================================================================
+
+template<int LoggingEnabled>
+static ASMJIT_INLINE Error X86Context_serialize(X86Context* self, X86Assembler* assembler, Node* start, Node* stop) {
+ Node* node_ = start;
+ StringBuilder& sb = self->_stringBuilder;
+
+#ifndef ASMJIT_DISABLE_LOGGER
+ uint32_t vdCount;
+ uint32_t annotationLength;
+
+ Logger* logger;
+
+ if (LoggingEnabled) {
+ logger = assembler->getLogger();
+
+ vdCount = static_cast<uint32_t>(self->_contextVd.getLength());
+ annotationLength = self->_annotationLength;
+ }
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ // Create labels on Assembler side.
+ ASMJIT_PROPAGATE_ERROR(
+ assembler->_registerIndexedLabels(self->getCompiler()->_targetList.getLength()));
+
+ do {
+#ifndef ASMJIT_DISABLE_LOGGER
+ if (LoggingEnabled) {
+ sb.clear();
+
+ if (node_->getComment()) {
+ sb.appendString(node_->getComment());
+ }
+
+ if (sb.getLength() < annotationLength)
+ sb.appendChars(' ', annotationLength - sb.getLength());
+
+ size_t offset = sb.getLength();
+ sb.appendChars(' ', vdCount);
+
+ if (node_->hasLiveness()) {
+ VarBits* liveness = node_->getLiveness();
+ X86VarMap* map = static_cast<X86VarMap*>(node_->getMap());
+
+ uint32_t i;
+ for (i = 0; i < vdCount; i++) {
+ if (liveness->getBit(i))
+ sb.getData()[offset + i] = '.';
+ }
+
+ if (map) {
+ uint32_t vaCount = map->getVaCount();
+
+ for (i = 0; i < vaCount; i++) {
+ VarAttr* va = map->getVa(i);
+ VarData* vd = va->getVd();
+
+ uint32_t flags = va->getFlags();
+ char c = 'u';
+
+ if ( (flags & kVarAttrInAll) && !(flags & kVarAttrOutAll)) c = 'r';
+ if (!(flags & kVarAttrInAll) && (flags & kVarAttrOutAll)) c = 'w';
+ if ( (flags & kVarAttrInAll) && (flags & kVarAttrOutAll)) c = 'x';
+
+ if ((flags & kVarAttrUnuse))
+ c -= 'a' - 'A';
+
+ sb.getData()[offset + vd->getContextId()] = c;
+ }
+ }
+ }
+
+ assembler->_comment = sb.getData();
+ }
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ switch (node_->getType()) {
+ case kNodeTypeAlign: {
+ AlignNode* node = static_cast<AlignNode*>(node_);
+ assembler->align(node->getMode(), node->getOffset());
+ break;
+ }
+
+ case kNodeTypeEmbed: {
+ EmbedNode* node = static_cast<EmbedNode*>(node_);
+ assembler->embed(node->getData(), node->getSize());
+ break;
+ }
+
+ case kNodeTypeComment: {
+ CommentNode* node = static_cast<CommentNode*>(node_);
+
+#ifndef ASMJIT_DISABLE_LOGGER
+ if (LoggingEnabled)
+ logger->logFormat(kLoggerStyleComment,
+ "%s; %s\n", logger->getIndentation(), node->getComment());
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ break;
+ }
+
+ case kNodeTypeHint: {
+ break;
+ }
+
+ case kNodeTypeTarget: {
+ TargetNode* node = static_cast<TargetNode*>(node_);
+
+ node->setOffset(assembler->getOffset());
+ assembler->bind(node->getLabel());
+ break;
+ }
+
+ case kNodeTypeInst: {
+ InstNode* node = static_cast<InstNode*>(node_);
+
+ uint32_t code = node->getCode();
+ uint32_t opCount = node->getOpCount();
+
+ const Operand* opList = node->getOpList();
+ assembler->_instOptions = node->getOptions();
+
+ const Operand* o0 = &noOperand;
+ const Operand* o1 = &noOperand;
+ const Operand* o2 = &noOperand;
+
+ if (node->isSpecial()) {
+ switch (code) {
+ case kX86InstIdCpuid:
+ break;
+
+ case kX86InstIdCbw:
+ case kX86InstIdCdq:
+ case kX86InstIdCdqe:
+ case kX86InstIdCwd:
+ case kX86InstIdCwde:
+ case kX86InstIdCqo:
+ break;
+
+ case kX86InstIdCmpxchg:
+ o0 = &opList[1];
+ o1 = &opList[2];
+ break;
+
+ case kX86InstIdCmpxchg8b :
+ case kX86InstIdCmpxchg16b:
+ o0 = &opList[4];
+ break;
+
+ case kX86InstIdDaa:
+ case kX86InstIdDas:
+ break;
+
+ case kX86InstIdImul:
+ case kX86InstIdMul:
+ case kX86InstIdIdiv:
+ case kX86InstIdDiv:
+ // Assume "Mul/Div dst_hi (implicit), dst_lo (implicit), src (explicit)".
+ ASMJIT_ASSERT(opCount == 3);
+ o0 = &opList[2];
+ break;
+
+ case kX86InstIdMovPtr:
+ break;
+
+ case kX86InstIdLahf:
+ case kX86InstIdSahf:
+ break;
+
+ case kX86InstIdMaskmovq:
+ case kX86InstIdMaskmovdqu:
+ o0 = &opList[1];
+ o1 = &opList[2];
+ break;
+
+ case kX86InstIdEnter:
+ o0 = &opList[0];
+ o1 = &opList[1];
+ break;
+
+ case kX86InstIdLeave:
+ break;
+
+ case kX86InstIdRet:
+ if (opCount > 0)
+ o0 = &opList[0];
+ break;
+
+ case kX86InstIdMonitor:
+ case kX86InstIdMwait:
+ break;
+
+ case kX86InstIdPop:
+ o0 = &opList[0];
+ break;
+
+ case kX86InstIdPopa:
+ case kX86InstIdPopf:
+ break;
+
+ case kX86InstIdPush:
+ o0 = &opList[0];
+ break;
+
+ case kX86InstIdPusha:
+ case kX86InstIdPushf:
+ break;
+
+ case kX86InstIdRcl:
+ case kX86InstIdRcr:
+ case kX86InstIdRol:
+ case kX86InstIdRor:
+ case kX86InstIdSal:
+ case kX86InstIdSar:
+ case kX86InstIdShl:
+ case kX86InstIdShr:
+ o0 = &opList[0];
+ o1 = &x86::cl;
+ break;
+
+ case kX86InstIdShld:
+ case kX86InstIdShrd:
+ o0 = &opList[0];
+ o1 = &opList[1];
+ o2 = &x86::cl;
+ break;
+
+ case kX86InstIdRdtsc:
+ case kX86InstIdRdtscp:
+ break;
+
+ case kX86InstIdRepLodsB : case kX86InstIdRepLodsD : case kX86InstIdRepLodsQ : case kX86InstIdRepLodsW :
+ case kX86InstIdRepMovsB : case kX86InstIdRepMovsD : case kX86InstIdRepMovsQ : case kX86InstIdRepMovsW :
+ case kX86InstIdRepStosB : case kX86InstIdRepStosD : case kX86InstIdRepStosQ : case kX86InstIdRepStosW :
+ case kX86InstIdRepeCmpsB : case kX86InstIdRepeCmpsD : case kX86InstIdRepeCmpsQ : case kX86InstIdRepeCmpsW :
+ case kX86InstIdRepeScasB : case kX86InstIdRepeScasD : case kX86InstIdRepeScasQ : case kX86InstIdRepeScasW :
+ case kX86InstIdRepneCmpsB: case kX86InstIdRepneCmpsD: case kX86InstIdRepneCmpsQ: case kX86InstIdRepneCmpsW:
+ case kX86InstIdRepneScasB: case kX86InstIdRepneScasD: case kX86InstIdRepneScasQ: case kX86InstIdRepneScasW:
+ break;
+
+ default:
+ ASMJIT_ASSERT(!"Reached");
+ }
+ }
+ else {
+ if (opCount > 0) o0 = &opList[0];
+ if (opCount > 1) o1 = &opList[1];
+ if (opCount > 2) o2 = &opList[2];
+ }
+
+ // We use this form, because it is the main one.
+ assembler->emit(code, *o0, *o1, *o2);
+ break;
+ }
+
+ // Function scope and return is translated to another nodes, no special
+ // handling is required at this point.
+ case kNodeTypeFunc:
+ case kNodeTypeEnd:
+ case kNodeTypeRet: {
+ break;
+ }
+
+ // Function call adds nodes before and after, but it's required to emit
+ // the call instruction by itself.
+ case kNodeTypeCall: {
+ X86CallNode* node = static_cast<X86CallNode*>(node_);
+ assembler->emit(kX86InstIdCall, node->_target, noOperand, noOperand);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ node_ = node_->getNext();
+ } while (node_ != stop);
+
+ return kErrorOk;
+}
+
+Error X86Context::serialize(Assembler* assembler, Node* start, Node* stop) {
+#ifndef ASMJIT_DISABLE_LOGGER
+ if (assembler->hasLogger())
+ return X86Context_serialize<1>(this, static_cast<X86Assembler*>(assembler), start, stop);
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ return X86Context_serialize<0>(this, static_cast<X86Assembler*>(assembler), start, stop);
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // !ASMJIT_DISABLE_COMPILER && (ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64)
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86context_p.h
@@ -1,1 +1,520 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+#include "../build.h"
+#ifndef ASMJIT_DISABLE_COMPILER
+
+// [Dependencies - AsmJit]
+#include "../base/compiler.h"
+#include "../base/context_p.h"
+#include "../base/intutil.h"
+#include "../x86/x86assembler.h"
+#include "../x86/x86compiler.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_x86_compiler
+//! \{
+
+// ============================================================================
+// [asmjit::X86Context]
+// ============================================================================
+
+#ifdef ASMJIT_DEBUG
+# define ASMJIT_X86_CHECK_STATE _checkState();
+#else
+# define ASMJIT_X86_CHECK_STATE
+#endif // ASMJIT_DEBUG
+
+//! \internal
+//!
+//! Compiler context is used by `X86Compiler`.
+//!
+//! Compiler context is used during compilation and normally developer doesn't
+//! need access to it. The context is user per function (it's reset after each
+//! function is generated).
+struct X86Context : public Context {
+ ASMJIT_NO_COPY(X86Context)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `X86Context` instance.
+ X86Context(X86Compiler* compiler);
+ //! Destroy the `X86Context` instance.
+ virtual ~X86Context();
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ virtual void reset(bool = false);
+
+ // --------------------------------------------------------------------------
+ // [Arch]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE bool isX64() const {
+ return _zsp.getSize() == 16;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get compiler as `X86Compiler`.
+ ASMJIT_INLINE X86Compiler* getCompiler() const {
+ return static_cast<X86Compiler*>(_compiler);
+ }
+
+ //! Get function as `X86FuncNode`.
+ ASMJIT_INLINE X86FuncNode* getFunc() const {
+ return reinterpret_cast<X86FuncNode*>(_func);
+ }
+
+ //! Get clobbered registers (global).
+ ASMJIT_INLINE uint32_t getClobberedRegs(uint32_t c) {
+ return _clobberedRegs.get(c);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Helpers]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE X86VarMap* newVarMap(uint32_t vaCount) {
+ return static_cast<X86VarMap*>(
+ _baseZone.alloc(sizeof(X86VarMap) + vaCount * sizeof(VarAttr)));
+ }
+
+ // --------------------------------------------------------------------------
+ // [Emit]
+ // --------------------------------------------------------------------------
+
+ void emitLoad(VarData* vd, uint32_t regIndex, const char* reason);
+ void emitSave(VarData* vd, uint32_t regIndex, const char* reason);
+ void emitMove(VarData* vd, uint32_t toRegIndex, uint32_t fromRegIndex, const char* reason);
+ void emitSwapGp(VarData* aVd, VarData* bVd, uint32_t aIndex, uint32_t bIndex, const char* reason);
+
+ void emitPushSequence(uint32_t regs);
+ void emitPopSequence(uint32_t regs);
+
+ void emitConvertVarToVar(uint32_t dstType, uint32_t dstIndex, uint32_t srcType, uint32_t srcIndex);
+ void emitMoveVarOnStack(uint32_t dstType, const X86Mem* dst, uint32_t srcType, uint32_t srcIndex);
+ void emitMoveImmOnStack(uint32_t dstType, const X86Mem* dst, const Imm* src);
+
+ void emitMoveImmToReg(uint32_t dstType, uint32_t dstIndex, const Imm* src);
+
+ // --------------------------------------------------------------------------
+ // [Register Management]
+ // --------------------------------------------------------------------------
+
+ void _checkState();
+
+ ASMJIT_INLINE uint32_t getRegSize() const {
+ return _zsp.getSize();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Attach / Detach]
+ // --------------------------------------------------------------------------
+
+ //! Attach.
+ //!
+ //! Attach a register to the 'VarData', changing 'VarData' members to show
+ //! that the variable is currently alive and linking variable with the
+ //! current 'X86VarState'.
+ template<int C>
+ ASMJIT_INLINE void attach(VarData* vd, uint32_t regIndex, bool modified) {
+ ASMJIT_ASSERT(vd->getClass() == C);
+ ASMJIT_ASSERT(regIndex != kInvalidReg);
+
+ // Prevent Esp allocation if C==Gp.
+ ASMJIT_ASSERT(C != kX86RegClassGp || regIndex != kX86RegIndexSp);
+
+ uint32_t regMask = IntUtil::mask(regIndex);
+
+ vd->setState(kVarStateReg);
+ vd->setRegIndex(regIndex);
+ vd->addHomeIndex(regIndex);
+ vd->setModified(modified);
+
+ _x86State.getListByClass(C)[regIndex] = vd;
+ _x86State._occupied.add(C, regMask);
+ _x86State._modified.add(C, static_cast<uint32_t>(modified) << regIndex);
+
+ ASMJIT_X86_CHECK_STATE
+ }
+
+ //! Detach.
+ //!
+ //! The opposite of 'Attach'. Detach resets the members in 'VarData'
+ //! (regIndex, state and changed flags) and unlinks the variable with the
+ //! current 'X86VarState'.
+ template<int C>
+ ASMJIT_INLINE void detach(VarData* vd, uint32_t regIndex, uint32_t vState) {
+ ASMJIT_ASSERT(vd->getClass() == C);
+ ASMJIT_ASSERT(vd->getRegIndex() == regIndex);
+ ASMJIT_ASSERT(vState != kVarStateReg);
+
+ uint32_t regMask = IntUtil::mask(regIndex);
+
+ vd->setState(vState);
+ vd->resetRegIndex();
+ vd->setModified(false);
+
+ _x86State.getListByClass(C)[regIndex] = nullptr;
+ _x86State._occupied.del(C, regMask);
+ _x86State._modified.del(C, regMask);
+
+ ASMJIT_X86_CHECK_STATE
+ }
+
+ // --------------------------------------------------------------------------
+ // [Rebase]
+ // --------------------------------------------------------------------------
+
+ //! Rebase.
+ //!
+ //! Change the register of the 'VarData' changing also the current 'X86VarState'.
+ //! Rebase is nearly identical to 'Detach' and 'Attach' sequence, but doesn't
+ // change the 'VarData' modified flag.
+ template<int C>
+ ASMJIT_INLINE void rebase(VarData* vd, uint32_t newRegIndex, uint32_t oldRegIndex) {
+ ASMJIT_ASSERT(vd->getClass() == C);
+
+ uint32_t newRegMask = IntUtil::mask(newRegIndex);
+ uint32_t oldRegMask = IntUtil::mask(oldRegIndex);
+ uint32_t bothRegMask = newRegMask ^ oldRegMask;
+
+ vd->setRegIndex(newRegIndex);
+
+ _x86State.getListByClass(C)[oldRegIndex] = nullptr;
+ _x86State.getListByClass(C)[newRegIndex] = vd;
+
+ _x86State._occupied.xor_(C, bothRegMask);
+ _x86State._modified.xor_(C, bothRegMask & -static_cast<int32_t>(vd->isModified()));
+
+ ASMJIT_X86_CHECK_STATE
+ }
+
+ // --------------------------------------------------------------------------
+ // [Load / Save]
+ // --------------------------------------------------------------------------
+
+ //! Load.
+ //!
+ //! Load variable from its memory slot to a register, emitting 'Load'
+ //! instruction and changing the variable state to allocated.
+ template<int C>
+ ASMJIT_INLINE void load(VarData* vd, uint32_t regIndex) {
+ // Can be only called if variable is not allocated.
+ ASMJIT_ASSERT(vd->getClass() == C);
+ ASMJIT_ASSERT(vd->getState() != kVarStateReg);
+ ASMJIT_ASSERT(vd->getRegIndex() == kInvalidReg);
+
+ emitLoad(vd, regIndex, "Load");
+ attach<C>(vd, regIndex, false);
+
+ ASMJIT_X86_CHECK_STATE
+ }
+
+ //! Save.
+ //!
+ //! Save the variable into its home location, but keep it as allocated.
+ template<int C>
+ ASMJIT_INLINE void save(VarData* vd) {
+ ASMJIT_ASSERT(vd->getClass() == C);
+ ASMJIT_ASSERT(vd->getState() == kVarStateReg);
+ ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg);
+
+ uint32_t regIndex = vd->getRegIndex();
+ uint32_t regMask = IntUtil::mask(regIndex);
+
+ emitSave(vd, regIndex, "Save");
+
+ vd->setModified(false);
+ _x86State._modified.del(C, regMask);
+
+ ASMJIT_X86_CHECK_STATE
+ }
+
+ // --------------------------------------------------------------------------
+ // [Move / Swap]
+ // --------------------------------------------------------------------------
+
+ //! Move a register.
+ //!
+ //! Move register from one index to another, emitting 'Move' if needed. This
+ //! function does nothing if register is already at the given index.
+ template<int C>
+ ASMJIT_INLINE void move(VarData* vd, uint32_t regIndex) {
+ ASMJIT_ASSERT(vd->getClass() == C);
+ ASMJIT_ASSERT(vd->getState() == kVarStateReg);
+ ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg);
+
+ uint32_t oldIndex = vd->getRegIndex();
+ if (regIndex != oldIndex) {
+ emitMove(vd, regIndex, oldIndex, "Move");
+ rebase<C>(vd, regIndex, oldIndex);
+ }
+
+ ASMJIT_X86_CHECK_STATE
+ }
+
+ //! Swap two registers
+ //!
+ //! It's only possible to swap Gp registers.
+ ASMJIT_INLINE void swapGp(VarData* aVd, VarData* bVd) {
+ ASMJIT_ASSERT(aVd != bVd);
+
+ ASMJIT_ASSERT(aVd->getClass() == kX86RegClassGp);
+ ASMJIT_ASSERT(aVd->getState() == kVarStateReg);
+ ASMJIT_ASSERT(aVd->getRegIndex() != kInvalidReg);
+
+ ASMJIT_ASSERT(bVd->getClass() == kX86RegClassGp);
+ ASMJIT_ASSERT(bVd->getState() == kVarStateReg);
+ ASMJIT_ASSERT(bVd->getRegIndex() != kInvalidReg);
+
+ uint32_t aIndex = aVd->getRegIndex();
+ uint32_t bIndex = bVd->getRegIndex();
+
+ emitSwapGp(aVd, bVd, aIndex, bIndex, "Swap");
+
+ aVd->setRegIndex(bIndex);
+ bVd->setRegIndex(aIndex);
+
+ _x86State.getListByClass(kX86RegClassGp)[aIndex] = bVd;
+ _x86State.getListByClass(kX86RegClassGp)[bIndex] = aVd;
+
+ uint32_t m = aVd->isModified() ^ bVd->isModified();
+ _x86State._modified.xor_(kX86RegClassGp, (m << aIndex) | (m << bIndex));
+
+ ASMJIT_X86_CHECK_STATE
+ }
+
+ // --------------------------------------------------------------------------
+ // [Alloc / Spill]
+ // --------------------------------------------------------------------------
+
+ //! Alloc.
+ template<int C>
+ ASMJIT_INLINE void alloc(VarData* vd, uint32_t regIndex) {
+ ASMJIT_ASSERT(vd->getClass() == C);
+ ASMJIT_ASSERT(regIndex != kInvalidReg);
+
+ uint32_t oldRegIndex = vd->getRegIndex();
+ uint32_t oldState = vd->getState();
+ uint32_t regMask = IntUtil::mask(regIndex);
+
+ ASMJIT_ASSERT(!_x86State.getListByClass(C)[regIndex] || regIndex == oldRegIndex);
+
+ if (oldState != kVarStateReg) {
+ if (oldState == kVarStateMem)
+ emitLoad(vd, regIndex, "Alloc");
+ vd->setModified(false);
+ }
+ else if (oldRegIndex != regIndex) {
+ emitMove(vd, regIndex, oldRegIndex, "Alloc");
+
+ _x86State.getListByClass(C)[oldRegIndex] = nullptr;
+ regMask ^= IntUtil::mask(oldRegIndex);
+ }
+ else {
+ ASMJIT_X86_CHECK_STATE
+ return;
+ }
+
+ vd->setState(kVarStateReg);
+ vd->setRegIndex(regIndex);
+
+ _x86State.getListByClass(C)[regIndex] = vd;
+ _x86State._occupied.xor_(C, regMask);
+ _x86State._modified.xor_(C, regMask & -static_cast<int32_t>(vd->isModified()));
+
+ ASMJIT_X86_CHECK_STATE
+ }
+
+ //! Spill.
+ //!
+ //! Spill variable/register, saves the content to the memory-home if modified.
+ template<int C>
+ ASMJIT_INLINE void spill(VarData* vd) {
+ ASMJIT_ASSERT(vd->getClass() == C);
+
+ if (vd->getState() != kVarStateReg) {
+ ASMJIT_X86_CHECK_STATE
+ return;
+ }
+
+ uint32_t regIndex = vd->getRegIndex();
+
+ ASMJIT_ASSERT(regIndex != kInvalidReg);
+ ASMJIT_ASSERT(_x86State.getListByClass(C)[regIndex] == vd);
+
+ if (vd->isModified())
+ emitSave(vd, regIndex, "Spill");
+ detach<C>(vd, regIndex, kVarStateMem);
+
+ ASMJIT_X86_CHECK_STATE
+ }
+
+ // --------------------------------------------------------------------------
+ // [Modify]
+ // --------------------------------------------------------------------------
+
+ template<int C>
+ ASMJIT_INLINE void modify(VarData* vd) {
+ ASMJIT_ASSERT(vd->getClass() == C);
+
+ uint32_t regIndex = vd->getRegIndex();
+ uint32_t regMask = IntUtil::mask(regIndex);
+
+ vd->setModified(true);
+ _x86State._modified.add(C, regMask);
+
+ ASMJIT_X86_CHECK_STATE
+ }
+
+ // --------------------------------------------------------------------------
+ // [Unuse]
+ // --------------------------------------------------------------------------
+
+ //! Unuse.
+ //!
+ //! Unuse variable, it will be detached it if it's allocated then its state
+ //! will be changed to kVarStateUnused.
+ template<int C>
+ ASMJIT_INLINE void unuse(VarData* vd, uint32_t vState = kVarStateUnused) {
+ ASMJIT_ASSERT(vd->getClass() == C);
+ ASMJIT_ASSERT(vState != kVarStateReg);
+
+ uint32_t regIndex = vd->getRegIndex();
+ if (regIndex != kInvalidReg)
+ detach<C>(vd, regIndex, vState);
+ else
+ vd->setState(vState);
+
+ ASMJIT_X86_CHECK_STATE
+ }
+
+ // --------------------------------------------------------------------------
+ // [State]
+ // --------------------------------------------------------------------------
+
+ //! Get state as `X86VarState`.
+ ASMJIT_INLINE X86VarState* getState() const {
+ return const_cast<X86VarState*>(&_x86State);
+ }
+
+ virtual void loadState(VarState* src);
+ virtual VarState* saveState();
+
+ virtual void switchState(VarState* src);
+ virtual void intersectStates(VarState* a, VarState* b);
+
+ // --------------------------------------------------------------------------
+ // [Memory]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE X86Mem getVarMem(VarData* vd) {
+ (void)getVarCell(vd);
+
+ X86Mem mem(_memSlot);
+ mem.setBase(vd->getId());
+ return mem;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Fetch]
+ // --------------------------------------------------------------------------
+
+ virtual Error fetch();
+
+ // --------------------------------------------------------------------------
+ // [Annotate]
+ // --------------------------------------------------------------------------
+
+ virtual Error annotate();
+
+ // --------------------------------------------------------------------------
+ // [Translate]
+ // --------------------------------------------------------------------------
+
+ virtual Error translate();
+
+ // --------------------------------------------------------------------------
+ // [Schedule]
+ // --------------------------------------------------------------------------
+
+ virtual Error schedule();
+
+ // --------------------------------------------------------------------------
+ // [Serialize]
+ // --------------------------------------------------------------------------
+
+ virtual Error serialize(Assembler* assembler, Node* start, Node* stop);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Count of X86/X64 registers.
+ X86RegCount _regCount;
+ //! X86/X64 stack-pointer (esp or rsp).
+ X86GpReg _zsp;
+ //! X86/X64 frame-pointer (ebp or rbp).
+ X86GpReg _zbp;
+ //! Temporary memory operand.
+ X86Mem _memSlot;
+
+ //! X86/X64 specific compiler state, linked to `_state`.
+ X86VarState _x86State;
+ //! Clobbered registers (for the whole function).
+ X86RegMask _clobberedRegs;
+
+ //! Memory cell where is stored address used to restore manually
+ //! aligned stack.
+ MemCell* _stackFrameCell;
+
+ //! Global allocable registers mask.
+ uint32_t _gaRegs[kX86RegClassCount];
+
+ //! Function arguments base pointer (register).
+ uint8_t _argBaseReg;
+ //! Function variables base pointer (register).
+ uint8_t _varBaseReg;
+ //! Whether to emit comments.
+ uint8_t _emitComments;
+
+ //! Function arguments base offset.
+ int32_t _argBaseOffset;
+ //! Function variables base offset.
+ int32_t _varBaseOffset;
+
+ //! Function arguments displacement.
+ int32_t _argActualDisp;
+ //! Function variables displacement.
+ int32_t _varActualDisp;
+
+ //! Temporary string builder used for logging.
+ StringBuilderT<256> _stringBuilder;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+#endif // !ASMJIT_DISABLE_COMPILER
+
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86cpuinfo.cpp
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86cpuinfo.cpp
@@ -1,328 +1,304 @@
// [AsmJit]
-// Complete JIT Assembler for C++ Language.
+// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
-// Zlib - See COPYING file in this package.
-
+// Zlib - See LICENSE.md file in the package.
+
+// [Export]
#define ASMJIT_EXPORTS
+// [Guard]
+#include "../build.h"
+#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
+
// [Dependencies - AsmJit]
+#include "../base/intutil.h"
#include "../x86/x86cpuinfo.h"
-#include "../x86/x86defs.h"
// 2009-02-05: Thanks to Mike Tajmajer for VC7.1 compiler support. It shouldn't
// affect x64 compilation, because x64 compiler starts with VS2005 (VC8.0).
#if defined(_MSC_VER) && _MSC_VER >= 1400
# include <intrin.h>
-#endif // _MSC_VER && _MSC_VER >= 1400 (>= VS2005)
+#endif // _MSC_VER >= 1400
// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
+#include "../apibegin.h"
+
+namespace asmjit {
// ============================================================================
-// [AsmJit::X86CpuVendor]
+// [asmjit::X86CpuVendor]
// ============================================================================
-struct X86CpuVendor
-{
- uint32_t id;
- char text[12];
+struct X86CpuVendor {
+ uint32_t id;
+ char text[12];
};
-static const X86CpuVendor x86CpuVendor[] =
-{
- { kCpuIntel , { 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'I', 'n', 't', 'e', 'l' } },
-
- { kCpuAmd , { 'A', 'u', 't', 'h', 'e', 'n', 't', 'i', 'c', 'A', 'M', 'D' } },
- { kCpuAmd , { 'A', 'M', 'D', 'i', 's', 'b', 'e', 't', 't', 'e', 'r', '!' } },
-
- { kCpuNSM , { 'G', 'e', 'o', 'd', 'e', ' ', 'b', 'y', ' ', 'N', 'S', 'C' } },
- { kCpuNSM , { 'C', 'y', 'r', 'i', 'x', 'I', 'n', 's', 't', 'e', 'a', 'd' } },
-
- { kCpuTransmeta, { 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'T', 'M', 'x', '8', '6' } },
- { kCpuTransmeta, { 'T', 'r', 'a', 'n', 's', 'm', 'e', 't', 'a', 'C', 'P', 'U' } },
-
- { kCpuVia , { 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 } },
- { kCpuVia , { 'C', 'e', 'n', 't', 'a', 'u', 'r', 'H', 'a', 'u', 'l', 's' } }
+static const X86CpuVendor x86CpuVendorList[] = {
+ { kCpuVendorIntel , { 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'I', 'n', 't', 'e', 'l' } },
+ { kCpuVendorAmd , { 'A', 'u', 't', 'h', 'e', 'n', 't', 'i', 'c', 'A', 'M', 'D' } },
+ { kCpuVendorVia , { 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 } },
+ { kCpuVendorVia , { 'C', 'e', 'n', 't', 'a', 'u', 'r', 'H', 'a', 'u', 'l', 's' } }
};
-static inline bool x86CpuVendorEq(const X86CpuVendor &info, const char *vendorString)
-{
- const uint32_t *a = reinterpret_cast<const uint32_t *>(info.text);
- const uint32_t *b = reinterpret_cast<const uint32_t *>(vendorString);
-
- return a[0] == b[0] && a[1] == b[1] && a[2] == b[2];
+static ASMJIT_INLINE bool x86CpuVendorEq(const X86CpuVendor& info, const char* vendorString) {
+ const uint32_t* a = reinterpret_cast<const uint32_t*>(info.text);
+ const uint32_t* b = reinterpret_cast<const uint32_t*>(vendorString);
+
+ return (a[0] == b[0]) & (a[1] == b[1]) & (a[2] == b[2]);
}
+static ASMJIT_INLINE void x86SimplifyBrandString(char* s) {
+ // Always clear the current character in the buffer. It ensures that there
+ // is no garbage after the string NULL terminator.
+ char* d = s;
+
+ char prev = 0;
+ char curr = s[0];
+ s[0] = '\0';
+
+ for (;;) {
+ if (curr == 0)
+ break;
+
+ if (curr == ' ') {
+ if (prev == '@' || s[1] == ' ' || s[1] == '@')
+ goto _Skip;
+ }
+
+ d[0] = curr;
+ d++;
+ prev = curr;
+
+_Skip:
+ curr = *++s;
+ s[0] = '\0';
+ }
+
+ d[0] = '\0';
+}
+
// ============================================================================
-// [AsmJit::x86CpuSimplifyBrandString]
+// [asmjit::X86CpuUtil]
// ============================================================================
-static inline void x86CpuSimplifyBrandString(char *s)
-{
- // Always clear the current character in the buffer. This ensures that there
- // is no garbage after the string NULL terminator.
- char *d = s;
-
- char prev = 0;
- char curr = s[0];
- s[0] = 0;
-
- for (;;)
- {
- if (!curr)
- break;
-
- if (curr == ' ')
- {
- if (prev == '@')
- goto _Skip;
- if (s[1] == ' ' || s[1] == '@')
- goto _Skip;
- }
-
- d[0] = curr;
- ++d;
- prev = curr;
-
- _Skip:
- curr = *++s;
- s[0] = 0;
- }
-
- d[0] = 0;
-}
-
-// ============================================================================
-// [AsmJit::x86CpuId]
-// ============================================================================
-
-// This is messy, I know. cpuid is implemented as intrinsic in VS2005, but
+// This is messy, I know. Cpuid is implemented as intrinsic in VS2005, but
// we should support other compilers as well. Main problem is that MS compilers
// in 64-bit mode not allows to use inline assembler, so we need intrinsic and
// we need also asm version.
-// x86CpuId() and detectCpuInfo() for x86 and x64 platforms begins here.
-#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
-void x86CpuId(uint32_t in, X86CpuId *out)
-{
+// callCpuId() and detectCpuInfo() for x86 and x64 platforms begins here.
+#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
+void X86CpuUtil::callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* outResult) {
+
#ifdef _MSC_VER
- // 2009-02-05: Thanks to Mike Tajmajer for supporting VC7.1 compiler.
- // ASMJIT_X64 is here only for readibility, only VS2005 can compile 64-bit code.
-# if _MSC_VER >= 1400 || defined(ASMJIT_X64)
- // Done by intrinsics.
- __cpuid(reinterpret_cast<int *>(out->i), in);
+// 2009-02-05: Thanks to Mike Tajmajer for supporting VC7.1 compiler.
+// ASMJIT_HOST_X64 is here only for readibility, only VS2005 can compile 64-bit code.
+# if _MSC_VER >= 1400 || defined(ASMJIT_HOST_X64)
+ // Done by intrinsics.
+ __cpuidex(reinterpret_cast<int*>(outResult->i), inEax, inEcx);
# else // _MSC_VER < 1400
- uint32_t cpuid_in = in;
- uint32_t *cpuid_out = out->i;
-
- __asm
- {
- mov eax, cpuid_in
- mov edi, cpuid_out
- cpuid
- mov dword ptr[edi + 0], eax
- mov dword ptr[edi + 4], ebx
- mov dword ptr[edi + 8], ecx
- mov dword ptr[edi + 12], edx
- }
+ uint32_t cpuid_eax = inEax;
+ uint32_t cpuid_ecx = inCax;
+ uint32_t* cpuid_out = outResult->i;
+
+ __asm {
+ mov eax, cpuid_eax
+ mov ecx, cpuid_ecx
+ mov edi, cpuid_out
+ cpuid
+ mov dword ptr[edi + 0], eax
+ mov dword ptr[edi + 4], ebx
+ mov dword ptr[edi + 8], ecx
+ mov dword ptr[edi + 12], edx
+ }
# endif // _MSC_VER < 1400
+
#elif defined(__GNUC__)
-// Note, need to preserve ebx/rbx register!
-# ifdef ASMJIT_X86
-# define __myCpuId(a, b, c, d, inp) \
- asm ("mov %%ebx, %%edi\n" \
- "cpuid\n" \
- "xchg %%edi, %%ebx\n" \
- : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
+// Note, patched to preserve ebx/rbx register which is used by GCC.
+# if defined(ASMJIT_HOST_X86)
+# define __myCpuId(inEax, inEcx, outEax, outEbx, outEcx, outEdx) \
+ asm ("mov %%ebx, %%edi\n" \
+ "cpuid\n" \
+ "xchg %%edi, %%ebx\n" \
+ : "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) : "a" (inEax), "c" (inEcx))
# else
-# define __myCpuId(a, b, c, d, inp) \
- asm ("mov %%rbx, %%rdi\n" \
- "cpuid\n" \
- "xchg %%rdi, %%rbx\n" \
- : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
+# define __myCpuId(inEax, inEcx, outEax, outEbx, outEcx, outEdx) \
+ asm ("mov %%rbx, %%rdi\n" \
+ "cpuid\n" \
+ "xchg %%rdi, %%rbx\n" \
+ : "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) : "a" (inEax), "c" (inEcx))
# endif
- __myCpuId(out->eax, out->ebx, out->ecx, out->edx, in);
-#endif // Compiler #ifdef.
+ __myCpuId(inEax, inEcx, outResult->eax, outResult->ebx, outResult->ecx, outResult->edx);
+#endif // COMPILER
}
-// ============================================================================
-// [AsmJit::x86CpuDetect]
-// ============================================================================
-
-void x86CpuDetect(X86CpuInfo *out)
-{
- uint32_t i;
- X86CpuId regs;
-
- // Clear everything except the '_size' member.
- memset(reinterpret_cast<uint8_t *>(out) + sizeof(uint32_t), 0, sizeof(CpuInfo) - sizeof(uint32_t));
-
- // Fill safe defaults.
- memcpy(out->_vendorString, "Unknown", 8);
- out->_numberOfProcessors = CpuInfo::detectNumberOfProcessors();
-
- // Get vendor string/id.
- x86CpuId(0, ®s);
-
- memcpy(out->_vendorString, ®s.ebx, 4);
- memcpy(out->_vendorString + 4, ®s.edx, 4);
- memcpy(out->_vendorString + 8, ®s.ecx, 4);
-
- for (i = 0; i < 3; ++i)
- if (x86CpuVendorEq(x86CpuVendor[i], out->_vendorString))
- {
- out->_vendorId = x86CpuVendor[i].id;
- break;
- }
-
- // Get feature flags in ecx/edx, and family/model in eax.
- x86CpuId(1, ®s);
-
- // Fill family and model fields.
- out->_family = (regs.eax >> 8) & 0x0F;
- out->_model = (regs.eax >> 4) & 0x0F;
- out->_stepping = regs.eax & 0x0F;
-
- // Use extended family and model fields.
- if (out->_family == 0x0F)
- {
- out->_family += (regs.eax >> 20) & 0xFF;
- out->_model += ((regs.eax >> 16) & 0x0F) << 4;
- }
-
- out->_processorType = (regs.eax >> 12) & 0x03;
- out->_brandIndex = regs.ebx & 0xFF;
- out->_flushCacheLineSize = ((regs.ebx >> 8) & 0xFF) * 8;
- out->_maxLogicalProcessors = (regs.ebx >> 16) & 0xFF;
- out->_apicPhysicalId = (regs.ebx >> 24) & 0xFF;
-
- if (regs.ecx & 0x00000001U)
- out->_features |= kX86FeatureSse3;
- if (regs.ecx & 0x00000002U)
- out->_features |= kX86FeaturePclMulDQ;
- if (regs.ecx & 0x00000008U)
- out->_features |= kX86FeatureMonitorMWait;
- if (regs.ecx & 0x00000200U)
- out->_features |= kX86FeatureSsse3;
- if (regs.ecx & 0x00002000U)
- out->_features |= kX86FeatureCmpXchg16B;
- if (regs.ecx & 0x00080000U)
- out->_features |= kX86FeatureSse41;
- if (regs.ecx & 0x00100000U)
- out->_features |= kX86FeatureSse42;
- if (regs.ecx & 0x00400000U)
- out->_features |= kX86FeatureMovBE;
- if (regs.ecx & 0x00800000U)
- out->_features |= kX86FeaturePopCnt;
- if (regs.ecx & 0x10000000U)
- out->_features |= kX86FeatureAvx;
-
- if (regs.edx & 0x00000010U)
- out->_features |= kX86FeatureRdtsc;
- if (regs.edx & 0x00000100U)
- out->_features |= kX86FeatureCmpXchg8B;
- if (regs.edx & 0x00008000U)
- out->_features |= kX86FeatureCMov;
- if (regs.edx & 0x00800000U)
- out->_features |= kX86FeatureMmx;
- if (regs.edx & 0x01000000U)
- out->_features |= kX86FeatureFXSR;
- if (regs.edx & 0x02000000U)
- out->_features |= kX86FeatureSse | kX86FeatureMmxExt;
- if (regs.edx & 0x04000000U)
- out->_features |= kX86FeatureSse | kX86FeatureSse2;
- if (regs.edx & 0x10000000U)
- out->_features |= kX86FeatureMultiThreading;
-
- if (out->_vendorId == kCpuAmd && (regs.edx & 0x10000000U))
- {
- // AMD sets Multithreading to ON if it has more cores.
- if (out->_numberOfProcessors == 1)
- out->_numberOfProcessors = 2;
- }
-
- // This comment comes from V8 and I think that its important:
- //
- // Opteron Rev E has i bug in which on very rare occasions i locked
- // instruction doesn't act as i read-acquire barrier if followed by i
- // non-locked read-modify-write instruction. Rev F has this bug in
- // pre-release versions, but not in versions released to customers,
- // so we test only for Rev E, which is family 15, model 32..63 inclusive.
-
- if (out->_vendorId == kCpuAmd && out->_family == 15 && out->_model >= 32 && out->_model <= 63)
- out->_bugs |= kX86BugAmdLockMB;
-
- // Calling cpuid with 0x80000000 as the in argument
- // gets the number of valid extended IDs.
-
- x86CpuId(0x80000000, ®s);
-
- uint32_t exIds = regs.eax;
- if (exIds > 0x80000004)
- exIds = 0x80000004;
-
- uint32_t *brand = reinterpret_cast<uint32_t *>(out->_brandString);
-
- for (i = 0x80000001; i <= exIds; ++i)
- {
- x86CpuId(i, ®s);
-
- switch (i)
- {
- case 0x80000001:
- if (regs.ecx & 0x00000001U)
- out->_features |= kX86FeatureLahfSahf;
- if (regs.ecx & 0x00000020U)
- out->_features |= kX86FeatureLzCnt;
- if (regs.ecx & 0x00000040U)
- out->_features |= kX86FeatureSse4A;
- if (regs.ecx & 0x00000080U)
- out->_features |= kX86FeatureMSse;
- if (regs.ecx & 0x00000100U)
- out->_features |= kX86FeaturePrefetch;
-
- if (regs.edx & 0x00100000U)
- out->_features |= kX86FeatureExecuteDisableBit;
- if (regs.edx & 0x00200000U)
- out->_features |= kX86FeatureFFXSR;
- if (regs.edx & 0x00400000U)
- out->_features |= kX86FeatureMmxExt;
- if (regs.edx & 0x08000000U)
- out->_features |= kX86FeatureRdtscP;
- if (regs.edx & 0x20000000U)
- out->_features |= kX86Feature64Bit;
- if (regs.edx & 0x40000000U)
- out->_features |= kX86Feature3dNowExt | kX86FeatureMmxExt;
- if (regs.edx & 0x80000000U)
- out->_features |= kX86Feature3dNow;
- break;
-
- case 0x80000002:
- case 0x80000003:
- case 0x80000004:
- *brand++ = regs.eax;
- *brand++ = regs.ebx;
- *brand++ = regs.ecx;
- *brand++ = regs.edx;
- break;
-
- default:
- // Additional features can be detected in the future.
- break;
- }
- }
-
- // Simplify the brand string (remove unnecessary spaces to make it printable).
- x86CpuSimplifyBrandString(out->_brandString);
+void X86CpuUtil::detect(X86CpuInfo* cpuInfo) {
+ X86CpuId regs;
+
+ uint32_t i;
+ uint32_t maxId;
+
+ // Clear everything except the '_size' member.
+ ::memset(reinterpret_cast<uint8_t*>(cpuInfo) + sizeof(uint32_t),
+ 0, sizeof(CpuInfo) - sizeof(uint32_t));
+
+ // Fill safe defaults.
+ cpuInfo->_hwThreadsCount = CpuInfo::detectHwThreadsCount();
+
+ // --------------------------------------------------------------------------
+ // [CPUID EAX=0x00000000]
+ // --------------------------------------------------------------------------
+
+ // Get vendor string/id.
+ callCpuId(0, 0, ®s);
+
+ maxId = regs.eax;
+
+ ::memcpy(cpuInfo->_vendorString, ®s.ebx, 4);
+ ::memcpy(cpuInfo->_vendorString + 4, ®s.edx, 4);
+ ::memcpy(cpuInfo->_vendorString + 8, ®s.ecx, 4);
+
+ for (i = 0; i < ASMJIT_ARRAY_SIZE(x86CpuVendorList); i++) {
+ if (x86CpuVendorEq(x86CpuVendorList[i], cpuInfo->_vendorString)) {
+ cpuInfo->_vendorId = x86CpuVendorList[i].id;
+ break;
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // [CPUID EAX=0x00000001]
+ // --------------------------------------------------------------------------
+
+ // Get feature flags in ecx/edx and family/model in eax.
+ callCpuId(1, 0, ®s);
+
+ // Fill family and model fields.
+ cpuInfo->_family = (regs.eax >> 8) & 0x0F;
+ cpuInfo->_model = (regs.eax >> 4) & 0x0F;
+ cpuInfo->_stepping = (regs.eax ) & 0x0F;
+
+ // Use extended family and model fields.
+ if (cpuInfo->_family == 0x0F) {
+ cpuInfo->_family += ((regs.eax >> 20) & 0xFF);
+ cpuInfo->_model += ((regs.eax >> 16) & 0x0F) << 4;
+ }
+
+ cpuInfo->_processorType = ((regs.eax >> 12) & 0x03);
+ cpuInfo->_brandIndex = ((regs.ebx ) & 0xFF);
+ cpuInfo->_flushCacheLineSize = ((regs.ebx >> 8) & 0xFF) * 8;
+ cpuInfo->_maxLogicalProcessors = ((regs.ebx >> 16) & 0xFF);
+
+ if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureSse3);
+ if (regs.ecx & 0x00000002U) cpuInfo->addFeature(kX86CpuFeaturePclmulqdq);
+ if (regs.ecx & 0x00000008U) cpuInfo->addFeature(kX86CpuFeatureMonitorMWait);
+ if (regs.ecx & 0x00000200U) cpuInfo->addFeature(kX86CpuFeatureSsse3);
+ if (regs.ecx & 0x00002000U) cpuInfo->addFeature(kX86CpuFeatureCmpXchg16B);
+ if (regs.ecx & 0x00080000U) cpuInfo->addFeature(kX86CpuFeatureSse41);
+ if (regs.ecx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureSse42);
+ if (regs.ecx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMovbe);
+ if (regs.ecx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeaturePopcnt);
+ if (regs.ecx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureAesni);
+ if (regs.ecx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeatureRdrand);
+
+ if (regs.edx & 0x00000010U) cpuInfo->addFeature(kX86CpuFeatureRdtsc);
+ if (regs.edx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeatureCmpXchg8B);
+ if (regs.edx & 0x00008000U) cpuInfo->addFeature(kX86CpuFeatureCmov);
+ if (regs.edx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeatureMmx);
+ if (regs.edx & 0x01000000U) cpuInfo->addFeature(kX86CpuFeatureFxsr);
+ if (regs.edx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureSse).addFeature(kX86CpuFeatureMmxExt);
+ if (regs.edx & 0x04000000U) cpuInfo->addFeature(kX86CpuFeatureSse).addFeature(kX86CpuFeatureSse2);
+ if (regs.edx & 0x10000000U) cpuInfo->addFeature(kX86CpuFeatureMultithreading);
+
+ if (cpuInfo->_vendorId == kCpuVendorAmd && (regs.edx & 0x10000000U)) {
+ // AMD sets Multithreading to ON if it has more cores.
+ if (cpuInfo->_hwThreadsCount == 1)
+ cpuInfo->_hwThreadsCount = 2;
+ }
+
+ // Detect AVX.
+ if (regs.ecx & 0x10000000U) {
+ cpuInfo->addFeature(kX86CpuFeatureAvx);
+
+ if (regs.ecx & 0x00000800U) cpuInfo->addFeature(kX86CpuFeatureXop);
+ if (regs.ecx & 0x00004000U) cpuInfo->addFeature(kX86CpuFeatureFma3);
+ if (regs.ecx & 0x00010000U) cpuInfo->addFeature(kX86CpuFeatureFma4);
+ if (regs.ecx & 0x20000000U) cpuInfo->addFeature(kX86CpuFeatureF16C);
+ }
+
+ // Detect new features if the processor supports CPUID-07.
+ if (maxId >= 7) {
+ callCpuId(7, 0, ®s);
+
+ if (regs.ebx & 0x00000001) cpuInfo->addFeature(kX86CpuFeatureFsGsBase);
+ if (regs.ebx & 0x00000008) cpuInfo->addFeature(kX86CpuFeatureBmi);
+ if (regs.ebx & 0x00000010) cpuInfo->addFeature(kX86CpuFeatureHle);
+ if (regs.ebx & 0x00000100) cpuInfo->addFeature(kX86CpuFeatureBmi2);
+ if (regs.ebx & 0x00000200) cpuInfo->addFeature(kX86CpuFeatureRepMovsbStosbExt);
+ if (regs.ebx & 0x00000800) cpuInfo->addFeature(kX86CpuFeatureRtm);
+
+ // AVX2 depends on AVX.
+ if (cpuInfo->hasFeature(kX86CpuFeatureAvx)) {
+ if (regs.ebx & 0x00000020) cpuInfo->addFeature(kX86CpuFeatureAvx2);
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // [CPUID EAX=0x80000000]
+ // --------------------------------------------------------------------------
+
+ // Calling cpuid with 0x80000000 as the in argument gets the number of valid
+ // extended IDs.
+ callCpuId(0x80000000, 0, ®s);
+
+ uint32_t maxExtId = IntUtil::iMin<uint32_t>(regs.eax, 0x80000004);
+ uint32_t* brand = reinterpret_cast<uint32_t*>(cpuInfo->_brandString);
+
+ for (i = 0x80000001; i <= maxExtId; i++) {
+ callCpuId(i, 0, ®s);
+
+ switch (i) {
+ case 0x80000001:
+ if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureLahfSahf);
+ if (regs.ecx & 0x00000020U) cpuInfo->addFeature(kX86CpuFeatureLzcnt);
+ if (regs.ecx & 0x00000040U) cpuInfo->addFeature(kX86CpuFeatureSse4A);
+ if (regs.ecx & 0x00000080U) cpuInfo->addFeature(kX86CpuFeatureMsse);
+ if (regs.ecx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeaturePrefetch);
+
+ if (regs.edx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureExecuteDisableBit);
+ if (regs.edx & 0x00200000U) cpuInfo->addFeature(kX86CpuFeatureFfxsr);
+ if (regs.edx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMmxExt);
+ if (regs.edx & 0x08000000U) cpuInfo->addFeature(kX86CpuFeatureRdtscp);
+ if (regs.edx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeature3dNowExt).addFeature(kX86CpuFeatureMmxExt);
+ if (regs.edx & 0x80000000U) cpuInfo->addFeature(kX86CpuFeature3dNow);
+ break;
+
+ case 0x80000002:
+ case 0x80000003:
+ case 0x80000004:
+ *brand++ = regs.eax;
+ *brand++ = regs.ebx;
+ *brand++ = regs.ecx;
+ *brand++ = regs.edx;
+ break;
+
+ default:
+ // Additional features can be detected in the future.
+ break;
+ }
+ }
+
+ // Simplify the brand string (remove unnecessary spaces to make printing nicer).
+ x86SimplifyBrandString(cpuInfo->_brandString);
}
#endif
-} // AsmJit
+} // asmjit namespace
// [Api-End]
-#include "../core/apiend.h"
-
+#include "../apiend.h"
+
+// [Guard]
+#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64
+
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86cpuinfo.h
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86cpuinfo.h
@@ -1,126 +1,228 @@
// [AsmJit]
-// Complete JIT Assembler for C++ Language.
+// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
-// Zlib - See COPYING file in this package.
+// Zlib - See LICENSE.md file in the package.
#pragma once
// [Dependencies - AsmJit]
-#include "../core/cpuinfo.h"
-#include "../core/defs.h"
+#include "../base/cpuinfo.h"
// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit {
-
-//! @addtogroup AsmJit_X86
-//! @{
-
-// ============================================================================
-// [AsmJit::X86CpuId]
-// ============================================================================
-
-//! @brief X86 CpuId output.
-union X86CpuId
-{
- //! @brief EAX/EBX/ECX/EDX output.
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [Forward Declarations]
+// ============================================================================
+
+struct X86CpuInfo;
+
+//! \addtogroup asmjit_x86_general
+//! \{
+
+// ============================================================================
+// [asmjit::kX86CpuFeature]
+// ============================================================================
+
+//! X86 CPU features.
+ASMJIT_ENUM(kX86CpuFeature) {
+ //! Cpu has multithreading.
+ kX86CpuFeatureMultithreading = 1,
+ //! Cpu has execute disable bit.
+ kX86CpuFeatureExecuteDisableBit,
+ //! Cpu has RDTSC.
+ kX86CpuFeatureRdtsc,
+ //! Cpu has RDTSCP.
+ kX86CpuFeatureRdtscp,
+ //! Cpu has CMOV.
+ kX86CpuFeatureCmov,
+ //! Cpu has CMPXCHG8B.
+ kX86CpuFeatureCmpXchg8B,
+ //! Cpu has CMPXCHG16B (x64).
+ kX86CpuFeatureCmpXchg16B,
+ //! Cpu has CLFUSH.
+ kX86CpuFeatureClflush,
+ //! Cpu has PREFETCH.
+ kX86CpuFeaturePrefetch,
+ //! Cpu has LAHF/SAHF.
+ kX86CpuFeatureLahfSahf,
+ //! Cpu has FXSAVE/FXRSTOR.
+ kX86CpuFeatureFxsr,
+ //! Cpu has FXSAVE/FXRSTOR optimizations.
+ kX86CpuFeatureFfxsr,
+ //! Cpu has MMX.
+ kX86CpuFeatureMmx,
+ //! Cpu has extended MMX.
+ kX86CpuFeatureMmxExt,
+ //! Cpu has 3dNow!
+ kX86CpuFeature3dNow,
+ //! Cpu has enchanced 3dNow!
+ kX86CpuFeature3dNowExt,
+ //! Cpu has SSE.
+ kX86CpuFeatureSse,
+ //! Cpu has SSE2.
+ kX86CpuFeatureSse2,
+ //! Cpu has SSE3.
+ kX86CpuFeatureSse3,
+ //! Cpu has Supplemental SSE3 (SSSE3).
+ kX86CpuFeatureSsse3,
+ //! Cpu has SSE4.A.
+ kX86CpuFeatureSse4A,
+ //! Cpu has SSE4.1.
+ kX86CpuFeatureSse41,
+ //! Cpu has SSE4.2.
+ kX86CpuFeatureSse42,
+ //! Cpu has Misaligned SSE (MSSE).
+ kX86CpuFeatureMsse,
+ //! Cpu has MONITOR and MWAIT.
+ kX86CpuFeatureMonitorMWait,
+ //! Cpu has MOVBE.
+ kX86CpuFeatureMovbe,
+ //! Cpu has POPCNT.
+ kX86CpuFeaturePopcnt,
+ //! Cpu has LZCNT.
+ kX86CpuFeatureLzcnt,
+ //! Cpu has AESNI.
+ kX86CpuFeatureAesni,
+ //! Cpu has PCLMULQDQ.
+ kX86CpuFeaturePclmulqdq,
+ //! Cpu has RDRAND.
+ kX86CpuFeatureRdrand,
+ //! Cpu has AVX.
+ kX86CpuFeatureAvx,
+ //! Cpu has AVX2.
+ kX86CpuFeatureAvx2,
+ //! Cpu has F16C.
+ kX86CpuFeatureF16C,
+ //! Cpu has FMA3.
+ kX86CpuFeatureFma3,
+ //! Cpu has FMA4.
+ kX86CpuFeatureFma4,
+ //! Cpu has XOP.
+ kX86CpuFeatureXop,
+ //! Cpu has BMI.
+ kX86CpuFeatureBmi,
+ //! Cpu has BMI2.
+ kX86CpuFeatureBmi2,
+ //! Cpu has HLE.
+ kX86CpuFeatureHle,
+ //! Cpu has RTM.
+ kX86CpuFeatureRtm,
+ //! Cpu has FSGSBASE.
+ kX86CpuFeatureFsGsBase,
+ //! Cpu has enhanced REP MOVSB/STOSB.
+ kX86CpuFeatureRepMovsbStosbExt,
+
+ //! Count of X86/X64 Cpu features.
+ kX86CpuFeatureCount
+};
+
+// ============================================================================
+// [asmjit::X86CpuId]
+// ============================================================================
+
+//! X86/X64 CPUID output.
+union X86CpuId {
+ //! EAX/EBX/ECX/EDX output.
uint32_t i[4];
- struct
- {
- //! @brief EAX output.
+ struct {
+ //! EAX output.
uint32_t eax;
- //! @brief EBX output.
+ //! EBX output.
uint32_t ebx;
- //! @brief ECX output.
+ //! ECX output.
uint32_t ecx;
- //! @brief EDX output.
+ //! EDX output.
uint32_t edx;
};
};
// ============================================================================
-// [AsmJit::X86CpuInfo]
-// ============================================================================
-
-struct X86CpuInfo : public CpuInfo
-{
+// [asmjit::X86CpuUtil]
+// ============================================================================
+
+#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
+//! CPU utilities available only if the host processor is X86/X64.
+struct X86CpuUtil {
+ //! Get the result of calling CPUID instruction to `out`.
+ ASMJIT_API static void callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* out);
+
+ //! Detect the Host CPU.
+ ASMJIT_API static void detect(X86CpuInfo* cpuInfo);
+};
+#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64
+
+// ============================================================================
+// [asmjit::X86CpuInfo]
+// ============================================================================
+
+struct X86CpuInfo : public CpuInfo {
+ ASMJIT_NO_COPY(X86CpuInfo)
+
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
- X86CpuInfo(uint32_t size = sizeof(X86CpuInfo)) :
- CpuInfo(size)
- {
- }
+ ASMJIT_INLINE X86CpuInfo(uint32_t size = sizeof(X86CpuInfo)) :
+ CpuInfo(size) {}
// --------------------------------------------------------------------------
// [Accessors]
// --------------------------------------------------------------------------
- //! @brief Get processor type.
- uint32_t getProcessorType() const { return _processorType; }
- //! @brief Get brand index.
- uint32_t getBrandIndex() const { return _brandIndex; }
- //! @brief Get flush cache line size.
- uint32_t getFlushCacheLineSize() const { return _flushCacheLineSize; }
- //! @brief Get maximum logical processors count.
- uint32_t getMaxLogicalProcessors() const { return _maxLogicalProcessors; }
- //! @brief Get APIC physical ID.
- uint32_t getApicPhysicalId() const { return _apicPhysicalId; }
+ //! Get processor type.
+ ASMJIT_INLINE uint32_t getProcessorType() const {
+ return _processorType;
+ }
+
+ //! Get brand index.
+ ASMJIT_INLINE uint32_t getBrandIndex() const {
+ return _brandIndex;
+ }
+
+ //! Get flush cache line size.
+ ASMJIT_INLINE uint32_t getFlushCacheLineSize() const {
+ return _flushCacheLineSize;
+ }
+
+ //! Get maximum logical processors count.
+ ASMJIT_INLINE uint32_t getMaxLogicalProcessors() const {
+ return _maxLogicalProcessors;
+ }
// --------------------------------------------------------------------------
// [Statics]
// --------------------------------------------------------------------------
- //! @brief Get global instance of @ref X86CpuInfo.
- static const X86CpuInfo* getGlobal()
- { return static_cast<const X86CpuInfo*>(CpuInfo::getGlobal()); }
+#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
+ //! Get global instance of `X86CpuInfo`.
+ static ASMJIT_INLINE const X86CpuInfo* getHost() {
+ return static_cast<const X86CpuInfo*>(CpuInfo::getHost());
+ }
+#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
- //! @brief Processor type.
+ //! Processor type.
uint32_t _processorType;
- //! @brief Brand index.
+ //! Brand index.
uint32_t _brandIndex;
- //! @brief Flush cache line size in bytes.
+ //! Flush cache line size in bytes.
uint32_t _flushCacheLineSize;
- //! @brief Maximum number of addressable IDs for logical processors.
+ //! Maximum number of addressable IDs for logical processors.
uint32_t _maxLogicalProcessors;
- //! @brief Initial APIC ID.
- uint32_t _apicPhysicalId;
-};
-
-// ============================================================================
-// [AsmJit::x86CpuId]
-// ============================================================================
-
-#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
-//! @brief Calls CPUID instruction with eax == @a in and stores output 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 x86CpuId(uint32_t in, X86CpuId* out);
-
-// ============================================================================
-// [AsmJit::x86CpuDetect]
-// ============================================================================
-
-//! @brief Detect CPU features to CpuInfo structure @a out.
-//!
-//! @sa @c CpuInfo.
-ASMJIT_API void x86CpuDetect(X86CpuInfo* out);
-#endif // ASMJIT_X86 || ASMJIT_X64
-
-//! @}
-
-} // AsmJit namespace
+};
+
+//! \}
+
+} // asmjit namespace
// [Api-End]
-#include "../core/apiend.h"
-
+#include "../apiend.h"
+
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86defs.cpp
+++ /dev/null
@@ -1,1817 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../x86/x86defs.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::x86InstName]
-// ============================================================================
-
-// Following {DATA SECTION} is auto-generated by generate-defs.py tool using
-// X86InstInfo data.
-//
-// ${X86_INST_DATA:BEGIN}
-const char x86InstName[] =
- "\0"
- "adc\0"
- "add\0"
- "addpd\0"
- "addps\0"
- "addsd\0"
- "addss\0"
- "addsubpd\0"
- "addsubps\0"
- "amd_prefetch\0"
- "amd_prefetchw\0"
- "and\0"
- "andnpd\0"
- "andnps\0"
- "andpd\0"
- "andps\0"
- "blendpd\0"
- "blendps\0"
- "blendvpd\0"
- "blendvps\0"
- "bsf\0"
- "bsr\0"
- "bswap\0"
- "bt\0"
- "btc\0"
- "btr\0"
- "bts\0"
- "call\0"
- "cbw\0"
- "cdq\0"
- "cdqe\0"
- "clc\0"
- "cld\0"
- "clflush\0"
- "cmc\0"
- "cmova\0"
- "cmovae\0"
- "cmovb\0"
- "cmovbe\0"
- "cmovc\0"
- "cmove\0"
- "cmovg\0"
- "cmovge\0"
- "cmovl\0"
- "cmovle\0"
- "cmovna\0"
- "cmovnae\0"
- "cmovnb\0"
- "cmovnbe\0"
- "cmovnc\0"
- "cmovne\0"
- "cmovng\0"
- "cmovnge\0"
- "cmovnl\0"
- "cmovnle\0"
- "cmovno\0"
- "cmovnp\0"
- "cmovns\0"
- "cmovnz\0"
- "cmovo\0"
- "cmovp\0"
- "cmovpe\0"
- "cmovpo\0"
- "cmovs\0"
- "cmovz\0"
- "cmp\0"
- "cmppd\0"
- "cmpps\0"
- "cmpsd\0"
- "cmpss\0"
- "cmpxchg\0"
- "cmpxchg16b\0"
- "cmpxchg8b\0"
- "comisd\0"
- "comiss\0"
- "cpuid\0"
- "cqo\0"
- "crc32\0"
- "cvtdq2pd\0"
- "cvtdq2ps\0"
- "cvtpd2dq\0"
- "cvtpd2pi\0"
- "cvtpd2ps\0"
- "cvtpi2pd\0"
- "cvtpi2ps\0"
- "cvtps2dq\0"
- "cvtps2pd\0"
- "cvtps2pi\0"
- "cvtsd2si\0"
- "cvtsd2ss\0"
- "cvtsi2sd\0"
- "cvtsi2ss\0"
- "cvtss2sd\0"
- "cvtss2si\0"
- "cvttpd2dq\0"
- "cvttpd2pi\0"
- "cvttps2dq\0"
- "cvttps2pi\0"
- "cvttsd2si\0"
- "cvttss2si\0"
- "cwd\0"
- "cwde\0"
- "daa\0"
- "das\0"
- "dec\0"
- "div\0"
- "divpd\0"
- "divps\0"
- "divsd\0"
- "divss\0"
- "dppd\0"
- "dpps\0"
- "emms\0"
- "enter\0"
- "extractps\0"
- "f2xm1\0"
- "fabs\0"
- "fadd\0"
- "faddp\0"
- "fbld\0"
- "fbstp\0"
- "fchs\0"
- "fclex\0"
- "fcmovb\0"
- "fcmovbe\0"
- "fcmove\0"
- "fcmovnb\0"
- "fcmovnbe\0"
- "fcmovne\0"
- "fcmovnu\0"
- "fcmovu\0"
- "fcom\0"
- "fcomi\0"
- "fcomip\0"
- "fcomp\0"
- "fcompp\0"
- "fcos\0"
- "fdecstp\0"
- "fdiv\0"
- "fdivp\0"
- "fdivr\0"
- "fdivrp\0"
- "femms\0"
- "ffree\0"
- "fiadd\0"
- "ficom\0"
- "ficomp\0"
- "fidiv\0"
- "fidivr\0"
- "fild\0"
- "fimul\0"
- "fincstp\0"
- "finit\0"
- "fist\0"
- "fistp\0"
- "fisttp\0"
- "fisub\0"
- "fisubr\0"
- "fld\0"
- "fld1\0"
- "fldcw\0"
- "fldenv\0"
- "fldl2e\0"
- "fldl2t\0"
- "fldlg2\0"
- "fldln2\0"
- "fldpi\0"
- "fldz\0"
- "fmul\0"
- "fmulp\0"
- "fnclex\0"
- "fninit\0"
- "fnop\0"
- "fnsave\0"
- "fnstcw\0"
- "fnstenv\0"
- "fnstsw\0"
- "fpatan\0"
- "fprem\0"
- "fprem1\0"
- "fptan\0"
- "frndint\0"
- "frstor\0"
- "fsave\0"
- "fscale\0"
- "fsin\0"
- "fsincos\0"
- "fsqrt\0"
- "fst\0"
- "fstcw\0"
- "fstenv\0"
- "fstp\0"
- "fstsw\0"
- "fsub\0"
- "fsubp\0"
- "fsubr\0"
- "fsubrp\0"
- "ftst\0"
- "fucom\0"
- "fucomi\0"
- "fucomip\0"
- "fucomp\0"
- "fucompp\0"
- "fwait\0"
- "fxam\0"
- "fxch\0"
- "fxrstor\0"
- "fxsave\0"
- "fxtract\0"
- "fyl2x\0"
- "fyl2xp1\0"
- "haddpd\0"
- "haddps\0"
- "hsubpd\0"
- "hsubps\0"
- "idiv\0"
- "imul\0"
- "inc\0"
- "int3\0"
- "ja\0"
- "jae\0"
- "jb\0"
- "jbe\0"
- "jc\0"
- "je\0"
- "jg\0"
- "jge\0"
- "jl\0"
- "jle\0"
- "jna\0"
- "jnae\0"
- "jnb\0"
- "jnbe\0"
- "jnc\0"
- "jne\0"
- "jng\0"
- "jnge\0"
- "jnl\0"
- "jnle\0"
- "jno\0"
- "jnp\0"
- "jns\0"
- "jnz\0"
- "jo\0"
- "jp\0"
- "jpe\0"
- "jpo\0"
- "js\0"
- "jz\0"
- "jmp\0"
- "lddqu\0"
- "ldmxcsr\0"
- "lahf\0"
- "lea\0"
- "leave\0"
- "lfence\0"
- "maskmovdqu\0"
- "maskmovq\0"
- "maxpd\0"
- "maxps\0"
- "maxsd\0"
- "maxss\0"
- "mfence\0"
- "minpd\0"
- "minps\0"
- "minsd\0"
- "minss\0"
- "monitor\0"
- "mov\0"
- "movapd\0"
- "movaps\0"
- "movbe\0"
- "movd\0"
- "movddup\0"
- "movdq2q\0"
- "movdqa\0"
- "movdqu\0"
- "movhlps\0"
- "movhpd\0"
- "movhps\0"
- "movlhps\0"
- "movlpd\0"
- "movlps\0"
- "movmskpd\0"
- "movmskps\0"
- "movntdq\0"
- "movntdqa\0"
- "movnti\0"
- "movntpd\0"
- "movntps\0"
- "movntq\0"
- "movq\0"
- "movq2dq\0"
- "movsd\0"
- "movshdup\0"
- "movsldup\0"
- "movss\0"
- "movsx\0"
- "movsxd\0"
- "movupd\0"
- "movups\0"
- "movzx\0"
- "mov_ptr\0"
- "mpsadbw\0"
- "mul\0"
- "mulpd\0"
- "mulps\0"
- "mulsd\0"
- "mulss\0"
- "mwait\0"
- "neg\0"
- "nop\0"
- "not\0"
- "or\0"
- "orpd\0"
- "orps\0"
- "pabsb\0"
- "pabsd\0"
- "pabsw\0"
- "packssdw\0"
- "packsswb\0"
- "packusdw\0"
- "packuswb\0"
- "paddb\0"
- "paddd\0"
- "paddq\0"
- "paddsb\0"
- "paddsw\0"
- "paddusb\0"
- "paddusw\0"
- "paddw\0"
- "palignr\0"
- "pand\0"
- "pandn\0"
- "pause\0"
- "pavgb\0"
- "pavgw\0"
- "pblendvb\0"
- "pblendw\0"
- "pcmpeqb\0"
- "pcmpeqd\0"
- "pcmpeqq\0"
- "pcmpeqw\0"
- "pcmpestri\0"
- "pcmpestrm\0"
- "pcmpgtb\0"
- "pcmpgtd\0"
- "pcmpgtq\0"
- "pcmpgtw\0"
- "pcmpistri\0"
- "pcmpistrm\0"
- "pextrb\0"
- "pextrd\0"
- "pextrq\0"
- "pextrw\0"
- "pf2id\0"
- "pf2iw\0"
- "pfacc\0"
- "pfadd\0"
- "pfcmpeq\0"
- "pfcmpge\0"
- "pfcmpgt\0"
- "pfmax\0"
- "pfmin\0"
- "pfmul\0"
- "pfnacc\0"
- "pfpnacc\0"
- "pfrcp\0"
- "pfrcpit1\0"
- "pfrcpit2\0"
- "pfrsqit1\0"
- "pfrsqrt\0"
- "pfsub\0"
- "pfsubr\0"
- "phaddd\0"
- "phaddsw\0"
- "phaddw\0"
- "phminposuw\0"
- "phsubd\0"
- "phsubsw\0"
- "phsubw\0"
- "pi2fd\0"
- "pi2fw\0"
- "pinsrb\0"
- "pinsrd\0"
- "pinsrq\0"
- "pinsrw\0"
- "pmaddubsw\0"
- "pmaddwd\0"
- "pmaxsb\0"
- "pmaxsd\0"
- "pmaxsw\0"
- "pmaxub\0"
- "pmaxud\0"
- "pmaxuw\0"
- "pminsb\0"
- "pminsd\0"
- "pminsw\0"
- "pminub\0"
- "pminud\0"
- "pminuw\0"
- "pmovmskb\0"
- "pmovsxbd\0"
- "pmovsxbq\0"
- "pmovsxbw\0"
- "pmovsxdq\0"
- "pmovsxwd\0"
- "pmovsxwq\0"
- "pmovzxbd\0"
- "pmovzxbq\0"
- "pmovzxbw\0"
- "pmovzxdq\0"
- "pmovzxwd\0"
- "pmovzxwq\0"
- "pmuldq\0"
- "pmulhrsw\0"
- "pmulhuw\0"
- "pmulhw\0"
- "pmulld\0"
- "pmullw\0"
- "pmuludq\0"
- "pop\0"
- "popad\0"
- "popcnt\0"
- "popfd\0"
- "popfq\0"
- "por\0"
- "prefetch\0"
- "psadbw\0"
- "pshufb\0"
- "pshufd\0"
- "pshufw\0"
- "pshufhw\0"
- "pshuflw\0"
- "psignb\0"
- "psignd\0"
- "psignw\0"
- "pslld\0"
- "pslldq\0"
- "psllq\0"
- "psllw\0"
- "psrad\0"
- "psraw\0"
- "psrld\0"
- "psrldq\0"
- "psrlq\0"
- "psrlw\0"
- "psubb\0"
- "psubd\0"
- "psubq\0"
- "psubsb\0"
- "psubsw\0"
- "psubusb\0"
- "psubusw\0"
- "psubw\0"
- "pswapd\0"
- "ptest\0"
- "punpckhbw\0"
- "punpckhdq\0"
- "punpckhqdq\0"
- "punpckhwd\0"
- "punpcklbw\0"
- "punpckldq\0"
- "punpcklqdq\0"
- "punpcklwd\0"
- "push\0"
- "pushad\0"
- "pushfd\0"
- "pushfq\0"
- "pxor\0"
- "rcl\0"
- "rcpps\0"
- "rcpss\0"
- "rcr\0"
- "rdtsc\0"
- "rdtscp\0"
- "rep lodsb\0"
- "rep lodsd\0"
- "rep lodsq\0"
- "rep lodsw\0"
- "rep movsb\0"
- "rep movsd\0"
- "rep movsq\0"
- "rep movsw\0"
- "rep stosb\0"
- "rep stosd\0"
- "rep stosq\0"
- "rep stosw\0"
- "repe cmpsb\0"
- "repe cmpsd\0"
- "repe cmpsq\0"
- "repe cmpsw\0"
- "repe scasb\0"
- "repe scasd\0"
- "repe scasq\0"
- "repe scasw\0"
- "repne cmpsb\0"
- "repne cmpsd\0"
- "repne cmpsq\0"
- "repne cmpsw\0"
- "repne scasb\0"
- "repne scasd\0"
- "repne scasq\0"
- "repne scasw\0"
- "ret\0"
- "rol\0"
- "ror\0"
- "roundpd\0"
- "roundps\0"
- "roundsd\0"
- "roundss\0"
- "rsqrtps\0"
- "rsqrtss\0"
- "sahf\0"
- "sal\0"
- "sar\0"
- "sbb\0"
- "seta\0"
- "setae\0"
- "setb\0"
- "setbe\0"
- "setc\0"
- "sete\0"
- "setg\0"
- "setge\0"
- "setl\0"
- "setle\0"
- "setna\0"
- "setnae\0"
- "setnb\0"
- "setnbe\0"
- "setnc\0"
- "setne\0"
- "setng\0"
- "setnge\0"
- "setnl\0"
- "setnle\0"
- "setno\0"
- "setnp\0"
- "setns\0"
- "setnz\0"
- "seto\0"
- "setp\0"
- "setpe\0"
- "setpo\0"
- "sets\0"
- "setz\0"
- "sfence\0"
- "shl\0"
- "shld\0"
- "shr\0"
- "shrd\0"
- "shufpd\0"
- "shufps\0"
- "sqrtpd\0"
- "sqrtps\0"
- "sqrtsd\0"
- "sqrtss\0"
- "stc\0"
- "std\0"
- "stmxcsr\0"
- "sub\0"
- "subpd\0"
- "subps\0"
- "subsd\0"
- "subss\0"
- "test\0"
- "ucomisd\0"
- "ucomiss\0"
- "ud2\0"
- "unpckhpd\0"
- "unpckhps\0"
- "unpcklpd\0"
- "unpcklps\0"
- "xadd\0"
- "xchg\0"
- "xor\0"
- "xorpd\0"
- "xorps\0";
-
-#define INDEX_kInstNone 0
-#define INDEX_kX86InstAdc 1
-#define INDEX_kX86InstAdd 5
-#define INDEX_kX86InstAddPD 9
-#define INDEX_kX86InstAddPS 15
-#define INDEX_kX86InstAddSD 21
-#define INDEX_kX86InstAddSS 27
-#define INDEX_kX86InstAddSubPD 33
-#define INDEX_kX86InstAddSubPS 42
-#define INDEX_kX86InstAmdPrefetch 51
-#define INDEX_kX86InstAmdPrefetchW 64
-#define INDEX_kX86InstAnd 78
-#define INDEX_kX86InstAndnPD 82
-#define INDEX_kX86InstAndnPS 89
-#define INDEX_kX86InstAndPD 96
-#define INDEX_kX86InstAndPS 102
-#define INDEX_kX86InstBlendPD 108
-#define INDEX_kX86InstBlendPS 116
-#define INDEX_kX86InstBlendVPD 124
-#define INDEX_kX86InstBlendVPS 133
-#define INDEX_kX86InstBsf 142
-#define INDEX_kX86InstBsr 146
-#define INDEX_kX86InstBSwap 150
-#define INDEX_kX86InstBt 156
-#define INDEX_kX86InstBtc 159
-#define INDEX_kX86InstBtr 163
-#define INDEX_kX86InstBts 167
-#define INDEX_kX86InstCall 171
-#define INDEX_kX86InstCbw 176
-#define INDEX_kX86InstCdq 180
-#define INDEX_kX86InstCdqe 184
-#define INDEX_kX86InstClc 189
-#define INDEX_kX86InstCld 193
-#define INDEX_kX86InstClFlush 197
-#define INDEX_kX86InstCmc 205
-#define INDEX_kX86InstCMovA 209
-#define INDEX_kX86InstCMovAE 215
-#define INDEX_kX86InstCMovB 222
-#define INDEX_kX86InstCMovBE 228
-#define INDEX_kX86InstCMovC 235
-#define INDEX_kX86InstCMovE 241
-#define INDEX_kX86InstCMovG 247
-#define INDEX_kX86InstCMovGE 253
-#define INDEX_kX86InstCMovL 260
-#define INDEX_kX86InstCMovLE 266
-#define INDEX_kX86InstCMovNA 273
-#define INDEX_kX86InstCMovNAE 280
-#define INDEX_kX86InstCMovNB 288
-#define INDEX_kX86InstCMovNBE 295
-#define INDEX_kX86InstCMovNC 303
-#define INDEX_kX86InstCMovNE 310
-#define INDEX_kX86InstCMovNG 317
-#define INDEX_kX86InstCMovNGE 324
-#define INDEX_kX86InstCMovNL 332
-#define INDEX_kX86InstCMovNLE 339
-#define INDEX_kX86InstCMovNO 347
-#define INDEX_kX86InstCMovNP 354
-#define INDEX_kX86InstCMovNS 361
-#define INDEX_kX86InstCMovNZ 368
-#define INDEX_kX86InstCMovO 375
-#define INDEX_kX86InstCMovP 381
-#define INDEX_kX86InstCMovPE 387
-#define INDEX_kX86InstCMovPO 394
-#define INDEX_kX86InstCMovS 401
-#define INDEX_kX86InstCMovZ 407
-#define INDEX_kX86InstCmp 413
-#define INDEX_kX86InstCmpPD 417
-#define INDEX_kX86InstCmpPS 423
-#define INDEX_kX86InstCmpSD 429
-#define INDEX_kX86InstCmpSS 435
-#define INDEX_kX86InstCmpXCHG 441
-#define INDEX_kX86InstCmpXCHG16B 449
-#define INDEX_kX86InstCmpXCHG8B 460
-#define INDEX_kX86InstComISD 470
-#define INDEX_kX86InstComISS 477
-#define INDEX_kX86InstCpuId 484
-#define INDEX_kX86InstCqo 490
-#define INDEX_kX86InstCrc32 494
-#define INDEX_kX86InstCvtDQ2PD 500
-#define INDEX_kX86InstCvtDQ2PS 509
-#define INDEX_kX86InstCvtPD2DQ 518
-#define INDEX_kX86InstCvtPD2PI 527
-#define INDEX_kX86InstCvtPD2PS 536
-#define INDEX_kX86InstCvtPI2PD 545
-#define INDEX_kX86InstCvtPI2PS 554
-#define INDEX_kX86InstCvtPS2DQ 563
-#define INDEX_kX86InstCvtPS2PD 572
-#define INDEX_kX86InstCvtPS2PI 581
-#define INDEX_kX86InstCvtSD2SI 590
-#define INDEX_kX86InstCvtSD2SS 599
-#define INDEX_kX86InstCvtSI2SD 608
-#define INDEX_kX86InstCvtSI2SS 617
-#define INDEX_kX86InstCvtSS2SD 626
-#define INDEX_kX86InstCvtSS2SI 635
-#define INDEX_kX86InstCvttPD2DQ 644
-#define INDEX_kX86InstCvttPD2PI 654
-#define INDEX_kX86InstCvttPS2DQ 664
-#define INDEX_kX86InstCvttPS2PI 674
-#define INDEX_kX86InstCvttSD2SI 684
-#define INDEX_kX86InstCvttSS2SI 694
-#define INDEX_kX86InstCwd 704
-#define INDEX_kX86InstCwde 708
-#define INDEX_kX86InstDaa 713
-#define INDEX_kX86InstDas 717
-#define INDEX_kX86InstDec 721
-#define INDEX_kX86InstDiv 725
-#define INDEX_kX86InstDivPD 729
-#define INDEX_kX86InstDivPS 735
-#define INDEX_kX86InstDivSD 741
-#define INDEX_kX86InstDivSS 747
-#define INDEX_kX86InstDpPD 753
-#define INDEX_kX86InstDpPS 758
-#define INDEX_kX86InstEmms 763
-#define INDEX_kX86InstEnter 768
-#define INDEX_kX86InstExtractPS 774
-#define INDEX_kX86InstF2XM1 784
-#define INDEX_kX86InstFAbs 790
-#define INDEX_kX86InstFAdd 795
-#define INDEX_kX86InstFAddP 800
-#define INDEX_kX86InstFBLd 806
-#define INDEX_kX86InstFBStP 811
-#define INDEX_kX86InstFCHS 817
-#define INDEX_kX86InstFClex 822
-#define INDEX_kX86InstFCMovB 828
-#define INDEX_kX86InstFCMovBE 835
-#define INDEX_kX86InstFCMovE 843
-#define INDEX_kX86InstFCMovNB 850
-#define INDEX_kX86InstFCMovNBE 858
-#define INDEX_kX86InstFCMovNE 867
-#define INDEX_kX86InstFCMovNU 875
-#define INDEX_kX86InstFCMovU 883
-#define INDEX_kX86InstFCom 890
-#define INDEX_kX86InstFComI 895
-#define INDEX_kX86InstFComIP 901
-#define INDEX_kX86InstFComP 908
-#define INDEX_kX86InstFComPP 914
-#define INDEX_kX86InstFCos 921
-#define INDEX_kX86InstFDecStP 926
-#define INDEX_kX86InstFDiv 934
-#define INDEX_kX86InstFDivP 939
-#define INDEX_kX86InstFDivR 945
-#define INDEX_kX86InstFDivRP 951
-#define INDEX_kX86InstFEmms 958
-#define INDEX_kX86InstFFree 964
-#define INDEX_kX86InstFIAdd 970
-#define INDEX_kX86InstFICom 976
-#define INDEX_kX86InstFIComP 982
-#define INDEX_kX86InstFIDiv 989
-#define INDEX_kX86InstFIDivR 995
-#define INDEX_kX86InstFILd 1002
-#define INDEX_kX86InstFIMul 1007
-#define INDEX_kX86InstFIncStP 1013
-#define INDEX_kX86InstFInit 1021
-#define INDEX_kX86InstFISt 1027
-#define INDEX_kX86InstFIStP 1032
-#define INDEX_kX86InstFISttP 1038
-#define INDEX_kX86InstFISub 1045
-#define INDEX_kX86InstFISubR 1051
-#define INDEX_kX86InstFLd 1058
-#define INDEX_kX86InstFLd1 1062
-#define INDEX_kX86InstFLdCw 1067
-#define INDEX_kX86InstFLdEnv 1073
-#define INDEX_kX86InstFLdL2E 1080
-#define INDEX_kX86InstFLdL2T 1087
-#define INDEX_kX86InstFLdLg2 1094
-#define INDEX_kX86InstFLdLn2 1101
-#define INDEX_kX86InstFLdPi 1108
-#define INDEX_kX86InstFLdZ 1114
-#define INDEX_kX86InstFMul 1119
-#define INDEX_kX86InstFMulP 1124
-#define INDEX_kX86InstFNClex 1130
-#define INDEX_kX86InstFNInit 1137
-#define INDEX_kX86InstFNop 1144
-#define INDEX_kX86InstFNSave 1149
-#define INDEX_kX86InstFNStCw 1156
-#define INDEX_kX86InstFNStEnv 1163
-#define INDEX_kX86InstFNStSw 1171
-#define INDEX_kX86InstFPAtan 1178
-#define INDEX_kX86InstFPRem 1185
-#define INDEX_kX86InstFPRem1 1191
-#define INDEX_kX86InstFPTan 1198
-#define INDEX_kX86InstFRndInt 1204
-#define INDEX_kX86InstFRstor 1212
-#define INDEX_kX86InstFSave 1219
-#define INDEX_kX86InstFScale 1225
-#define INDEX_kX86InstFSin 1232
-#define INDEX_kX86InstFSinCos 1237
-#define INDEX_kX86InstFSqrt 1245
-#define INDEX_kX86InstFSt 1251
-#define INDEX_kX86InstFStCw 1255
-#define INDEX_kX86InstFStEnv 1261
-#define INDEX_kX86InstFStP 1268
-#define INDEX_kX86InstFStSw 1273
-#define INDEX_kX86InstFSub 1279
-#define INDEX_kX86InstFSubP 1284
-#define INDEX_kX86InstFSubR 1290
-#define INDEX_kX86InstFSubRP 1296
-#define INDEX_kX86InstFTst 1303
-#define INDEX_kX86InstFUCom 1308
-#define INDEX_kX86InstFUComI 1314
-#define INDEX_kX86InstFUComIP 1321
-#define INDEX_kX86InstFUComP 1329
-#define INDEX_kX86InstFUComPP 1336
-#define INDEX_kX86InstFWait 1344
-#define INDEX_kX86InstFXam 1350
-#define INDEX_kX86InstFXch 1355
-#define INDEX_kX86InstFXRstor 1360
-#define INDEX_kX86InstFXSave 1368
-#define INDEX_kX86InstFXtract 1375
-#define INDEX_kX86InstFYL2X 1383
-#define INDEX_kX86InstFYL2XP1 1389
-#define INDEX_kX86InstHAddPD 1397
-#define INDEX_kX86InstHAddPS 1404
-#define INDEX_kX86InstHSubPD 1411
-#define INDEX_kX86InstHSubPS 1418
-#define INDEX_kX86InstIDiv 1425
-#define INDEX_kX86InstIMul 1430
-#define INDEX_kX86InstInc 1435
-#define INDEX_kX86InstInt3 1439
-#define INDEX_kX86InstJA 1444
-#define INDEX_kX86InstJAE 1447
-#define INDEX_kX86InstJB 1451
-#define INDEX_kX86InstJBE 1454
-#define INDEX_kX86InstJC 1458
-#define INDEX_kX86InstJE 1461
-#define INDEX_kX86InstJG 1464
-#define INDEX_kX86InstJGE 1467
-#define INDEX_kX86InstJL 1471
-#define INDEX_kX86InstJLE 1474
-#define INDEX_kX86InstJNA 1478
-#define INDEX_kX86InstJNAE 1482
-#define INDEX_kX86InstJNB 1487
-#define INDEX_kX86InstJNBE 1491
-#define INDEX_kX86InstJNC 1496
-#define INDEX_kX86InstJNE 1500
-#define INDEX_kX86InstJNG 1504
-#define INDEX_kX86InstJNGE 1508
-#define INDEX_kX86InstJNL 1513
-#define INDEX_kX86InstJNLE 1517
-#define INDEX_kX86InstJNO 1522
-#define INDEX_kX86InstJNP 1526
-#define INDEX_kX86InstJNS 1530
-#define INDEX_kX86InstJNZ 1534
-#define INDEX_kX86InstJO 1538
-#define INDEX_kX86InstJP 1541
-#define INDEX_kX86InstJPE 1544
-#define INDEX_kX86InstJPO 1548
-#define INDEX_kX86InstJS 1552
-#define INDEX_kX86InstJZ 1555
-#define INDEX_kX86InstJmp 1558
-#define INDEX_kX86InstLdDQU 1562
-#define INDEX_kX86InstLdMXCSR 1568
-#define INDEX_kX86InstLahf 1576
-#define INDEX_kX86InstLea 1581
-#define INDEX_kX86InstLeave 1585
-#define INDEX_kX86InstLFence 1591
-#define INDEX_kX86InstMaskMovDQU 1598
-#define INDEX_kX86InstMaskMovQ 1609
-#define INDEX_kX86InstMaxPD 1618
-#define INDEX_kX86InstMaxPS 1624
-#define INDEX_kX86InstMaxSD 1630
-#define INDEX_kX86InstMaxSS 1636
-#define INDEX_kX86InstMFence 1642
-#define INDEX_kX86InstMinPD 1649
-#define INDEX_kX86InstMinPS 1655
-#define INDEX_kX86InstMinSD 1661
-#define INDEX_kX86InstMinSS 1667
-#define INDEX_kX86InstMonitor 1673
-#define INDEX_kX86InstMov 1681
-#define INDEX_kX86InstMovAPD 1685
-#define INDEX_kX86InstMovAPS 1692
-#define INDEX_kX86InstMovBE 1699
-#define INDEX_kX86InstMovD 1705
-#define INDEX_kX86InstMovDDup 1710
-#define INDEX_kX86InstMovDQ2Q 1718
-#define INDEX_kX86InstMovDQA 1726
-#define INDEX_kX86InstMovDQU 1733
-#define INDEX_kX86InstMovHLPS 1740
-#define INDEX_kX86InstMovHPD 1748
-#define INDEX_kX86InstMovHPS 1755
-#define INDEX_kX86InstMovLHPS 1762
-#define INDEX_kX86InstMovLPD 1770
-#define INDEX_kX86InstMovLPS 1777
-#define INDEX_kX86InstMovMskPD 1784
-#define INDEX_kX86InstMovMskPS 1793
-#define INDEX_kX86InstMovNTDQ 1802
-#define INDEX_kX86InstMovNTDQA 1810
-#define INDEX_kX86InstMovNTI 1819
-#define INDEX_kX86InstMovNTPD 1826
-#define INDEX_kX86InstMovNTPS 1834
-#define INDEX_kX86InstMovNTQ 1842
-#define INDEX_kX86InstMovQ 1849
-#define INDEX_kX86InstMovQ2DQ 1854
-#define INDEX_kX86InstMovSD 1862
-#define INDEX_kX86InstMovSHDup 1868
-#define INDEX_kX86InstMovSLDup 1877
-#define INDEX_kX86InstMovSS 1886
-#define INDEX_kX86InstMovSX 1892
-#define INDEX_kX86InstMovSXD 1898
-#define INDEX_kX86InstMovUPD 1905
-#define INDEX_kX86InstMovUPS 1912
-#define INDEX_kX86InstMovZX 1919
-#define INDEX_kX86InstMovPtr 1925
-#define INDEX_kX86InstMPSADBW 1933
-#define INDEX_kX86InstMul 1941
-#define INDEX_kX86InstMulPD 1945
-#define INDEX_kX86InstMulPS 1951
-#define INDEX_kX86InstMulSD 1957
-#define INDEX_kX86InstMulSS 1963
-#define INDEX_kX86InstMWait 1969
-#define INDEX_kX86InstNeg 1975
-#define INDEX_kX86InstNop 1979
-#define INDEX_kX86InstNot 1983
-#define INDEX_kX86InstOr 1987
-#define INDEX_kX86InstOrPD 1990
-#define INDEX_kX86InstOrPS 1995
-#define INDEX_kX86InstPAbsB 2000
-#define INDEX_kX86InstPAbsD 2006
-#define INDEX_kX86InstPAbsW 2012
-#define INDEX_kX86InstPackSSDW 2018
-#define INDEX_kX86InstPackSSWB 2027
-#define INDEX_kX86InstPackUSDW 2036
-#define INDEX_kX86InstPackUSWB 2045
-#define INDEX_kX86InstPAddB 2054
-#define INDEX_kX86InstPAddD 2060
-#define INDEX_kX86InstPAddQ 2066
-#define INDEX_kX86InstPAddSB 2072
-#define INDEX_kX86InstPAddSW 2079
-#define INDEX_kX86InstPAddUSB 2086
-#define INDEX_kX86InstPAddUSW 2094
-#define INDEX_kX86InstPAddW 2102
-#define INDEX_kX86InstPAlignR 2108
-#define INDEX_kX86InstPAnd 2116
-#define INDEX_kX86InstPAndN 2121
-#define INDEX_kX86InstPause 2127
-#define INDEX_kX86InstPAvgB 2133
-#define INDEX_kX86InstPAvgW 2139
-#define INDEX_kX86InstPBlendVB 2145
-#define INDEX_kX86InstPBlendW 2154
-#define INDEX_kX86InstPCmpEqB 2162
-#define INDEX_kX86InstPCmpEqD 2170
-#define INDEX_kX86InstPCmpEqQ 2178
-#define INDEX_kX86InstPCmpEqW 2186
-#define INDEX_kX86InstPCmpEStrI 2194
-#define INDEX_kX86InstPCmpEStrM 2204
-#define INDEX_kX86InstPCmpGtB 2214
-#define INDEX_kX86InstPCmpGtD 2222
-#define INDEX_kX86InstPCmpGtQ 2230
-#define INDEX_kX86InstPCmpGtW 2238
-#define INDEX_kX86InstPCmpIStrI 2246
-#define INDEX_kX86InstPCmpIStrM 2256
-#define INDEX_kX86InstPExtrB 2266
-#define INDEX_kX86InstPExtrD 2273
-#define INDEX_kX86InstPExtrQ 2280
-#define INDEX_kX86InstPExtrW 2287
-#define INDEX_kX86InstPF2ID 2294
-#define INDEX_kX86InstPF2IW 2300
-#define INDEX_kX86InstPFAcc 2306
-#define INDEX_kX86InstPFAdd 2312
-#define INDEX_kX86InstPFCmpEQ 2318
-#define INDEX_kX86InstPFCmpGE 2326
-#define INDEX_kX86InstPFCmpGT 2334
-#define INDEX_kX86InstPFMax 2342
-#define INDEX_kX86InstPFMin 2348
-#define INDEX_kX86InstPFMul 2354
-#define INDEX_kX86InstPFNAcc 2360
-#define INDEX_kX86InstPFPNAcc 2367
-#define INDEX_kX86InstPFRcp 2375
-#define INDEX_kX86InstPFRcpIt1 2381
-#define INDEX_kX86InstPFRcpIt2 2390
-#define INDEX_kX86InstPFRSqIt1 2399
-#define INDEX_kX86InstPFRSqrt 2408
-#define INDEX_kX86InstPFSub 2416
-#define INDEX_kX86InstPFSubR 2422
-#define INDEX_kX86InstPHAddD 2429
-#define INDEX_kX86InstPHAddSW 2436
-#define INDEX_kX86InstPHAddW 2444
-#define INDEX_kX86InstPHMinPOSUW 2451
-#define INDEX_kX86InstPHSubD 2462
-#define INDEX_kX86InstPHSubSW 2469
-#define INDEX_kX86InstPHSubW 2477
-#define INDEX_kX86InstPI2FD 2484
-#define INDEX_kX86InstPI2FW 2490
-#define INDEX_kX86InstPInsRB 2496
-#define INDEX_kX86InstPInsRD 2503
-#define INDEX_kX86InstPInsRQ 2510
-#define INDEX_kX86InstPInsRW 2517
-#define INDEX_kX86InstPMAddUBSW 2524
-#define INDEX_kX86InstPMAddWD 2534
-#define INDEX_kX86InstPMaxSB 2542
-#define INDEX_kX86InstPMaxSD 2549
-#define INDEX_kX86InstPMaxSW 2556
-#define INDEX_kX86InstPMaxUB 2563
-#define INDEX_kX86InstPMaxUD 2570
-#define INDEX_kX86InstPMaxUW 2577
-#define INDEX_kX86InstPMinSB 2584
-#define INDEX_kX86InstPMinSD 2591
-#define INDEX_kX86InstPMinSW 2598
-#define INDEX_kX86InstPMinUB 2605
-#define INDEX_kX86InstPMinUD 2612
-#define INDEX_kX86InstPMinUW 2619
-#define INDEX_kX86InstPMovMskB 2626
-#define INDEX_kX86InstPMovSXBD 2635
-#define INDEX_kX86InstPMovSXBQ 2644
-#define INDEX_kX86InstPMovSXBW 2653
-#define INDEX_kX86InstPMovSXDQ 2662
-#define INDEX_kX86InstPMovSXWD 2671
-#define INDEX_kX86InstPMovSXWQ 2680
-#define INDEX_kX86InstPMovZXBD 2689
-#define INDEX_kX86InstPMovZXBQ 2698
-#define INDEX_kX86InstPMovZXBW 2707
-#define INDEX_kX86InstPMovZXDQ 2716
-#define INDEX_kX86InstPMovZXWD 2725
-#define INDEX_kX86InstPMovZXWQ 2734
-#define INDEX_kX86InstPMulDQ 2743
-#define INDEX_kX86InstPMulHRSW 2750
-#define INDEX_kX86InstPMulHUW 2759
-#define INDEX_kX86InstPMulHW 2767
-#define INDEX_kX86InstPMulLD 2774
-#define INDEX_kX86InstPMulLW 2781
-#define INDEX_kX86InstPMulUDQ 2788
-#define INDEX_kX86InstPop 2796
-#define INDEX_kX86InstPopAD 2800
-#define INDEX_kX86InstPopCnt 2806
-#define INDEX_kX86InstPopFD 2813
-#define INDEX_kX86InstPopFQ 2819
-#define INDEX_kX86InstPOr 2825
-#define INDEX_kX86InstPrefetch 2829
-#define INDEX_kX86InstPSADBW 2838
-#define INDEX_kX86InstPShufB 2845
-#define INDEX_kX86InstPShufD 2852
-#define INDEX_kX86InstPShufW 2859
-#define INDEX_kX86InstPShufHW 2866
-#define INDEX_kX86InstPShufLW 2874
-#define INDEX_kX86InstPSignB 2882
-#define INDEX_kX86InstPSignD 2889
-#define INDEX_kX86InstPSignW 2896
-#define INDEX_kX86InstPSllD 2903
-#define INDEX_kX86InstPSllDQ 2909
-#define INDEX_kX86InstPSllQ 2916
-#define INDEX_kX86InstPSllW 2922
-#define INDEX_kX86InstPSraD 2928
-#define INDEX_kX86InstPSraW 2934
-#define INDEX_kX86InstPSrlD 2940
-#define INDEX_kX86InstPSrlDQ 2946
-#define INDEX_kX86InstPSrlQ 2953
-#define INDEX_kX86InstPSrlW 2959
-#define INDEX_kX86InstPSubB 2965
-#define INDEX_kX86InstPSubD 2971
-#define INDEX_kX86InstPSubQ 2977
-#define INDEX_kX86InstPSubSB 2983
-#define INDEX_kX86InstPSubSW 2990
-#define INDEX_kX86InstPSubUSB 2997
-#define INDEX_kX86InstPSubUSW 3005
-#define INDEX_kX86InstPSubW 3013
-#define INDEX_kX86InstPSwapD 3019
-#define INDEX_kX86InstPTest 3026
-#define INDEX_kX86InstPunpckHBW 3032
-#define INDEX_kX86InstPunpckHDQ 3042
-#define INDEX_kX86InstPunpckHQDQ 3052
-#define INDEX_kX86InstPunpckHWD 3063
-#define INDEX_kX86InstPunpckLBW 3073
-#define INDEX_kX86InstPunpckLDQ 3083
-#define INDEX_kX86InstPunpckLQDQ 3093
-#define INDEX_kX86InstPunpckLWD 3104
-#define INDEX_kX86InstPush 3114
-#define INDEX_kX86InstPushAD 3119
-#define INDEX_kX86InstPushFD 3126
-#define INDEX_kX86InstPushFQ 3133
-#define INDEX_kX86InstPXor 3140
-#define INDEX_kX86InstRcl 3145
-#define INDEX_kX86InstRcpPS 3149
-#define INDEX_kX86InstRcpSS 3155
-#define INDEX_kX86InstRcr 3161
-#define INDEX_kX86InstRdtsc 3165
-#define INDEX_kX86InstRdtscP 3171
-#define INDEX_kX86InstRepLodSB 3178
-#define INDEX_kX86InstRepLodSD 3188
-#define INDEX_kX86InstRepLodSQ 3198
-#define INDEX_kX86InstRepLodSW 3208
-#define INDEX_kX86InstRepMovSB 3218
-#define INDEX_kX86InstRepMovSD 3228
-#define INDEX_kX86InstRepMovSQ 3238
-#define INDEX_kX86InstRepMovSW 3248
-#define INDEX_kX86InstRepStoSB 3258
-#define INDEX_kX86InstRepStoSD 3268
-#define INDEX_kX86InstRepStoSQ 3278
-#define INDEX_kX86InstRepStoSW 3288
-#define INDEX_kX86InstRepECmpSB 3298
-#define INDEX_kX86InstRepECmpSD 3309
-#define INDEX_kX86InstRepECmpSQ 3320
-#define INDEX_kX86InstRepECmpSW 3331
-#define INDEX_kX86InstRepEScaSB 3342
-#define INDEX_kX86InstRepEScaSD 3353
-#define INDEX_kX86InstRepEScaSQ 3364
-#define INDEX_kX86InstRepEScaSW 3375
-#define INDEX_kX86InstRepNECmpSB 3386
-#define INDEX_kX86InstRepNECmpSD 3398
-#define INDEX_kX86InstRepNECmpSQ 3410
-#define INDEX_kX86InstRepNECmpSW 3422
-#define INDEX_kX86InstRepNEScaSB 3434
-#define INDEX_kX86InstRepNEScaSD 3446
-#define INDEX_kX86InstRepNEScaSQ 3458
-#define INDEX_kX86InstRepNEScaSW 3470
-#define INDEX_kX86InstRet 3482
-#define INDEX_kX86InstRol 3486
-#define INDEX_kX86InstRor 3490
-#define INDEX_kX86InstRoundPD 3494
-#define INDEX_kX86InstRoundPS 3502
-#define INDEX_kX86InstRoundSD 3510
-#define INDEX_kX86InstRoundSS 3518
-#define INDEX_kX86InstRSqrtPS 3526
-#define INDEX_kX86InstRSqrtSS 3534
-#define INDEX_kX86InstSahf 3542
-#define INDEX_kX86InstSal 3547
-#define INDEX_kX86InstSar 3551
-#define INDEX_kX86InstSbb 3555
-#define INDEX_kX86InstSetA 3559
-#define INDEX_kX86InstSetAE 3564
-#define INDEX_kX86InstSetB 3570
-#define INDEX_kX86InstSetBE 3575
-#define INDEX_kX86InstSetC 3581
-#define INDEX_kX86InstSetE 3586
-#define INDEX_kX86InstSetG 3591
-#define INDEX_kX86InstSetGE 3596
-#define INDEX_kX86InstSetL 3602
-#define INDEX_kX86InstSetLE 3607
-#define INDEX_kX86InstSetNA 3613
-#define INDEX_kX86InstSetNAE 3619
-#define INDEX_kX86InstSetNB 3626
-#define INDEX_kX86InstSetNBE 3632
-#define INDEX_kX86InstSetNC 3639
-#define INDEX_kX86InstSetNE 3645
-#define INDEX_kX86InstSetNG 3651
-#define INDEX_kX86InstSetNGE 3657
-#define INDEX_kX86InstSetNL 3664
-#define INDEX_kX86InstSetNLE 3670
-#define INDEX_kX86InstSetNO 3677
-#define INDEX_kX86InstSetNP 3683
-#define INDEX_kX86InstSetNS 3689
-#define INDEX_kX86InstSetNZ 3695
-#define INDEX_kX86InstSetO 3701
-#define INDEX_kX86InstSetP 3706
-#define INDEX_kX86InstSetPE 3711
-#define INDEX_kX86InstSetPO 3717
-#define INDEX_kX86InstSetS 3723
-#define INDEX_kX86InstSetZ 3728
-#define INDEX_kX86InstSFence 3733
-#define INDEX_kX86InstShl 3740
-#define INDEX_kX86InstShld 3744
-#define INDEX_kX86InstShr 3749
-#define INDEX_kX86InstShrd 3753
-#define INDEX_kX86InstShufPD 3758
-#define INDEX_kX86InstShufPS 3765
-#define INDEX_kX86InstSqrtPD 3772
-#define INDEX_kX86InstSqrtPS 3779
-#define INDEX_kX86InstSqrtSD 3786
-#define INDEX_kX86InstSqrtSS 3793
-#define INDEX_kX86InstStc 3800
-#define INDEX_kX86InstStd 3804
-#define INDEX_kX86InstStMXCSR 3808
-#define INDEX_kX86InstSub 3816
-#define INDEX_kX86InstSubPD 3820
-#define INDEX_kX86InstSubPS 3826
-#define INDEX_kX86InstSubSD 3832
-#define INDEX_kX86InstSubSS 3838
-#define INDEX_kX86InstTest 3844
-#define INDEX_kX86InstUComISD 3849
-#define INDEX_kX86InstUComISS 3857
-#define INDEX_kX86InstUd2 3865
-#define INDEX_kX86InstUnpckHPD 3869
-#define INDEX_kX86InstUnpckHPS 3878
-#define INDEX_kX86InstUnpckLPD 3887
-#define INDEX_kX86InstUnpckLPS 3896
-#define INDEX_kX86InstXadd 3905
-#define INDEX_kX86InstXchg 3910
-#define INDEX_kX86InstXor 3915
-#define INDEX_kX86InstXorPD 3919
-#define INDEX_kX86InstXorPS 3925
-// ${X86_INST_DATA:END}
-
-// ============================================================================
-// [AsmJit::x86InstInfo]
-// ============================================================================
-
-#define INST(_Code_, _Name_, _Group_, _Flags_, _OpFlags0_, _OpFlags1_, _OpReg_, _OpCode0_, _OpCode1_) \
- { _Code_, INDEX_##_Code_, _Group_, _Flags_, { _OpFlags0_, _OpFlags1_ }, _OpReg_, { _OpCode0_, _OpCode1_ } }
-
-#define G(_Group_) kX86InstGroup##_Group_
-#define F(_Flags_) kX86InstFlag##_Flags_
-#define O(_Op_) kX86InstOp##_Op_
-
-const X86InstInfo x86InstInfo[] =
-{
- // Instruction code | Instruction name | Instruction group| Instruction flags| Operand flags[0] | Operand flags[1] | r| opCode[0] | opcode[1]
- INST(kInstNone , "" , G(None) , F(None) , 0 , 0 , 0, 0 , 0),
- INST(kX86InstAdc , "adc" , G(Arith) , F(Lockable) , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , 2, 0x00000010, 0x00000080),
- INST(kX86InstAdd , "add" , G(Arith) , F(Lockable) , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , 0, 0x00000000, 0x00000080),
- INST(kX86InstAddPD , "addpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F58, 0),
- INST(kX86InstAddPS , "addps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F58, 0),
- INST(kX86InstAddSD , "addsd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF2000F58, 0),
- INST(kX86InstAddSS , "addss" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF3000F58, 0),
- INST(kX86InstAddSubPD , "addsubpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000FD0, 0),
- INST(kX86InstAddSubPS , "addsubps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF2000FD0, 0),
- INST(kX86InstAmdPrefetch , "amd_prefetch" , G(Mem) , F(None) , O(Mem) , 0 , 0, 0x00000F0D, 0),
- INST(kX86InstAmdPrefetchW , "amd_prefetchw" , G(Mem) , F(None) , O(Mem) , 0 , 1, 0x00000F0D, 0),
- INST(kX86InstAnd , "and" , G(Arith) , F(Lockable) , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , 4, 0x00000020, 0x00000080),
- INST(kX86InstAndnPD , "andnpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F55, 0),
- INST(kX86InstAndnPS , "andnps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F55, 0),
- INST(kX86InstAndPD , "andpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F54, 0),
- INST(kX86InstAndPS , "andps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F54, 0),
- INST(kX86InstBlendPD , "blendpd" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3A0D, 0),
- INST(kX86InstBlendPS , "blendps" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3A0C, 0),
- INST(kX86InstBlendVPD , "blendvpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3815, 0),
- INST(kX86InstBlendVPS , "blendvps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3814, 0),
- INST(kX86InstBsf , "bsf" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000FBC, 0),
- INST(kX86InstBsr , "bsr" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000FBD, 0),
- INST(kX86InstBSwap , "bswap" , G(BSwap) , F(None) , O(Gqd) , 0 , 0, 0 , 0),
- INST(kX86InstBt , "bt" , G(BTest) , F(None) , O(Gqdw)|O(Mem) , O(Gqdw)|O(Imm) , 4, 0x00000FA3, 0x00000FBA),
- INST(kX86InstBtc , "btc" , G(BTest) , F(Lockable) , O(Gqdw)|O(Mem) , O(Gqdw)|O(Imm) , 7, 0x00000FBB, 0x00000FBA),
- INST(kX86InstBtr , "btr" , G(BTest) , F(Lockable) , O(Gqdw)|O(Mem) , O(Gqdw)|O(Imm) , 6, 0x00000FB3, 0x00000FBA),
- INST(kX86InstBts , "bts" , G(BTest) , F(Lockable) , O(Gqdw)|O(Mem) , O(Gqdw)|O(Imm) , 5, 0x00000FAB, 0x00000FBA),
- INST(kX86InstCall , "call" , G(Call) , F(Jump) , O(Gqd) |O(Mem) , 0 , 0, 0 , 0),
- INST(kX86InstCbw , "cbw" , G(Emit) , F(Special) , 0 , 0 , 0, 0x66000098, 0),
- INST(kX86InstCdq , "cdq" , G(Emit) , F(Special) , 0 , 0 , 0, 0x00000099, 0),
- INST(kX86InstCdqe , "cdqe" , G(Emit) , F(Special) , 0 , 0 , 0, 0x48000098, 0),
- INST(kX86InstClc , "clc" , G(Emit) , F(None) , 0 , 0 , 0, 0x000000F8, 0),
- INST(kX86InstCld , "cld" , G(Emit) , F(None) , 0 , 0 , 0, 0x000000FC, 0),
- INST(kX86InstClFlush , "clflush" , G(Mem) , F(None) , O(Mem) , 0 , 7, 0x00000FAE, 0),
- INST(kX86InstCmc , "cmc" , G(Emit) , F(None) , 0 , 0 , 0, 0x000000F5, 0),
- INST(kX86InstCMovA , "cmova" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F47, 0),
- INST(kX86InstCMovAE , "cmovae" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F43, 0),
- INST(kX86InstCMovB , "cmovb" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F42, 0),
- INST(kX86InstCMovBE , "cmovbe" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F46, 0),
- INST(kX86InstCMovC , "cmovc" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F42, 0),
- INST(kX86InstCMovE , "cmove" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F44, 0),
- INST(kX86InstCMovG , "cmovg" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F4F, 0),
- INST(kX86InstCMovGE , "cmovge" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F4D, 0),
- INST(kX86InstCMovL , "cmovl" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F4C, 0),
- INST(kX86InstCMovLE , "cmovle" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F4E, 0),
- INST(kX86InstCMovNA , "cmovna" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F46, 0),
- INST(kX86InstCMovNAE , "cmovnae" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F42, 0),
- INST(kX86InstCMovNB , "cmovnb" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F43, 0),
- INST(kX86InstCMovNBE , "cmovnbe" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F47, 0),
- INST(kX86InstCMovNC , "cmovnc" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F43, 0),
- INST(kX86InstCMovNE , "cmovne" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F45, 0),
- INST(kX86InstCMovNG , "cmovng" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F4E, 0),
- INST(kX86InstCMovNGE , "cmovnge" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F4C, 0),
- INST(kX86InstCMovNL , "cmovnl" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F4D, 0),
- INST(kX86InstCMovNLE , "cmovnle" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F4F, 0),
- INST(kX86InstCMovNO , "cmovno" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F41, 0),
- INST(kX86InstCMovNP , "cmovnp" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F4B, 0),
- INST(kX86InstCMovNS , "cmovns" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F49, 0),
- INST(kX86InstCMovNZ , "cmovnz" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F45, 0),
- INST(kX86InstCMovO , "cmovo" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F40, 0),
- INST(kX86InstCMovP , "cmovp" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F4A, 0),
- INST(kX86InstCMovPE , "cmovpe" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F4A, 0),
- INST(kX86InstCMovPO , "cmovpo" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F4B, 0),
- INST(kX86InstCMovS , "cmovs" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F48, 0),
- INST(kX86InstCMovZ , "cmovz" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0x00000F44, 0),
- INST(kX86InstCmp , "cmp" , G(Arith) , F(None) , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , 7, 0x00000038, 0x00000080),
- INST(kX86InstCmpPD , "cmppd" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000FC2, 0),
- INST(kX86InstCmpPS , "cmpps" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000FC2, 0),
- INST(kX86InstCmpSD , "cmpsd" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF2000FC2, 0),
- INST(kX86InstCmpSS , "cmpss" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF3000FC2, 0),
- INST(kX86InstCmpXCHG , "cmpxchg" , G(RmReg) , F(Special)|F(Lockable), 0 , 0 , 0, 0x00000FB0, 0),
- INST(kX86InstCmpXCHG16B , "cmpxchg16b" , G(Mem) , F(Special) , O(Mem) , 0 , 1, 0x00000FC7, 1 /* RexW */),
- INST(kX86InstCmpXCHG8B , "cmpxchg8b" , G(Mem) , F(Special) , O(Mem) , 0 , 1, 0x00000FC7, 0),
- INST(kX86InstComISD , "comisd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F2F, 0),
- INST(kX86InstComISS , "comiss" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F2F, 0),
- INST(kX86InstCpuId , "cpuid" , G(Emit) , F(Special) , 0 , 0 , 0, 0x00000FA2, 0),
- INST(kX86InstCqo , "cqo" , G(Emit) , F(Special) , 0 , 0 , 0, 0x48000099, 0), // TODO, set RexW bit instead?
- INST(kX86InstCrc32 , "crc32" , G(Crc32) , F(None) , O(Gqd) , O(GqdwbMem) , 0, 0xF20F38F0, 0),
- INST(kX86InstCvtDQ2PD , "cvtdq2pd" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0xF3000FE6, 0),
- INST(kX86InstCvtDQ2PS , "cvtdq2ps" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x00000F5B, 0),
- INST(kX86InstCvtPD2DQ , "cvtpd2dq" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0xF2000FE6, 0),
- INST(kX86InstCvtPD2PI , "cvtpd2pi" , G(MmuRmI) , F(Mov) , O(Mm) , O(XmmMem) , 0, 0x66000F2D, 0),
- INST(kX86InstCvtPD2PS , "cvtpd2ps" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x66000F5A, 0),
- INST(kX86InstCvtPI2PD , "cvtpi2pd" , G(MmuRmI) , F(Mov) , O(Xmm) , O(MmMem) , 0, 0x66000F2A, 0),
- INST(kX86InstCvtPI2PS , "cvtpi2ps" , G(MmuRmI) , F(None) , O(Xmm) , O(MmMem) , 0, 0x00000F2A, 0),
- INST(kX86InstCvtPS2DQ , "cvtps2dq" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x66000F5B, 0),
- INST(kX86InstCvtPS2PD , "cvtps2pd" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x00000F5A, 0),
- INST(kX86InstCvtPS2PI , "cvtps2pi" , G(MmuRmI) , F(Mov) , O(Mm) , O(XmmMem) , 0, 0x00000F2D, 0),
- INST(kX86InstCvtSD2SI , "cvtsd2si" , G(MmuRmI) , F(Mov) , O(Gqd) , O(XmmMem) , 0, 0xF2000F2D, 0),
- INST(kX86InstCvtSD2SS , "cvtsd2ss" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF2000F5A, 0),
- INST(kX86InstCvtSI2SD , "cvtsi2sd" , G(MmuRmI) , F(None) , O(Xmm) , O(Gqd)|O(Mem) , 0, 0xF2000F2A, 0),
- INST(kX86InstCvtSI2SS , "cvtsi2ss" , G(MmuRmI) , F(None) , O(Xmm) , O(Gqd)|O(Mem) , 0, 0xF3000F2A, 0),
- INST(kX86InstCvtSS2SD , "cvtss2sd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF3000F5A, 0),
- INST(kX86InstCvtSS2SI , "cvtss2si" , G(MmuRmI) , F(None) , O(Gqd) , O(XmmMem) , 0, 0xF3000F2D, 0),
- INST(kX86InstCvttPD2DQ , "cvttpd2dq" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x66000FE6, 0),
- INST(kX86InstCvttPD2PI , "cvttpd2pi" , G(MmuRmI) , F(Mov) , O(Mm) , O(XmmMem) , 0, 0x66000F2C, 0),
- INST(kX86InstCvttPS2DQ , "cvttps2dq" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0xF3000F5B, 0),
- INST(kX86InstCvttPS2PI , "cvttps2pi" , G(MmuRmI) , F(Mov) , O(Mm) , O(XmmMem) , 0, 0x00000F2C, 0),
- INST(kX86InstCvttSD2SI , "cvttsd2si" , G(MmuRmI) , F(None) , O(Gqd) , O(XmmMem) , 0, 0xF2000F2C, 0),
- INST(kX86InstCvttSS2SI , "cvttss2si" , G(MmuRmI) , F(None) , O(Gqd) , O(XmmMem) , 0, 0xF3000F2C, 0),
- INST(kX86InstCwd , "cwd" , G(Emit) , F(Special) , 0 , 0 , 0, 0x66000099, 0),
- INST(kX86InstCwde , "cwde" , G(Emit) , F(Special) , 0 , 0 , 0, 0x00000098, 0),
- INST(kX86InstDaa , "daa" , G(Emit) , F(Special) , 0 , 0 , 0, 0x00000027, 0),
- INST(kX86InstDas , "das" , G(Emit) , F(Special) , 0 , 0 , 0, 0x0000002F, 0),
- INST(kX86InstDec , "dec" , G(IncDec) , F(Lockable) , O(GqdwbMem) , 0 , 1, 0x00000048, 0x000000FE),
- INST(kX86InstDiv , "div" , G(Rm) , F(Special) , 0 , 0 , 6, 0x000000F6, 0),
- INST(kX86InstDivPD , "divpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F5E, 0),
- INST(kX86InstDivPS , "divps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F5E, 0),
- INST(kX86InstDivSD , "divsd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF2000F5E, 0),
- INST(kX86InstDivSS , "divss" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF3000F5E, 0),
- INST(kX86InstDpPD , "dppd" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3A41, 0),
- INST(kX86InstDpPS , "dpps" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3A40, 0),
- INST(kX86InstEmms , "emms" , G(Emit) , F(None) , 0 , 0 , 0, 0x00000F77, 0),
- INST(kX86InstEnter , "enter" , G(Enter) , F(Special) , 0 , 0 , 0, 0x000000C8, 0),
- INST(kX86InstExtractPS , "extractps" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3A17, 0),
- INST(kX86InstF2XM1 , "f2xm1" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9F0, 0),
- INST(kX86InstFAbs , "fabs" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9E1, 0),
- INST(kX86InstFAdd , "fadd" , G(X87StM) , F(Fpu) , 0 , 0 , 0, 0xD8DCC0C0, 0),
- INST(kX86InstFAddP , "faddp" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DEC0, 0),
- INST(kX86InstFBLd , "fbld" , G(Mem) , F(Fpu) , O(Mem) , 0 , 4, 0x000000DF, 0),
- INST(kX86InstFBStP , "fbstp" , G(Mem) , F(Fpu) , O(Mem) , 0 , 6, 0x000000DF, 0),
- INST(kX86InstFCHS , "fchs" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9E0, 0),
- INST(kX86InstFClex , "fclex" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x9B00DBE2, 0),
- INST(kX86InstFCMovB , "fcmovb" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DAC0, 0),
- INST(kX86InstFCMovBE , "fcmovbe" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DAD0, 0),
- INST(kX86InstFCMovE , "fcmove" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DAC8, 0),
- INST(kX86InstFCMovNB , "fcmovnb" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DBC0, 0),
- INST(kX86InstFCMovNBE , "fcmovnbe" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DBD0, 0),
- INST(kX86InstFCMovNE , "fcmovne" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DBC8, 0),
- INST(kX86InstFCMovNU , "fcmovnu" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DBD8, 0),
- INST(kX86InstFCMovU , "fcmovu" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DAD8, 0),
- INST(kX86InstFCom , "fcom" , G(X87StM) , F(Fpu) , 0 , 0 , 2, 0xD8DCD0D0, 0),
- INST(kX86InstFComI , "fcomi" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DBF0, 0),
- INST(kX86InstFComIP , "fcomip" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DFF0, 0),
- INST(kX86InstFComP , "fcomp" , G(X87StM) , F(Fpu) , 0 , 0 , 3, 0xD8DCD8D8, 0),
- INST(kX86InstFComPP , "fcompp" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000DED9, 0),
- INST(kX86InstFCos , "fcos" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9FF, 0),
- INST(kX86InstFDecStP , "fdecstp" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9F6, 0),
- INST(kX86InstFDiv , "fdiv" , G(X87StM) , F(Fpu) , 0 , 0 , 6, 0xD8DCF0F8, 0),
- INST(kX86InstFDivP , "fdivp" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DEF8, 0),
- INST(kX86InstFDivR , "fdivr" , G(X87StM) , F(Fpu) , 0 , 0 , 7, 0xD8DCF8F0, 0),
- INST(kX86InstFDivRP , "fdivrp" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DEF0, 0),
- INST(kX86InstFEmms , "femms" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x00000F0E, 0),
- INST(kX86InstFFree , "ffree" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DDC0, 0),
- INST(kX86InstFIAdd , "fiadd" , G(X87Mem) , F(Fpu) , O(StM2_4) , 0 , 0, 0xDEDA0000, 0),
- INST(kX86InstFICom , "ficom" , G(X87Mem) , F(Fpu) , O(StM2_4) , 0 , 2, 0xDEDA0000, 0),
- INST(kX86InstFIComP , "ficomp" , G(X87Mem) , F(Fpu) , O(StM2_4) , 0 , 3, 0xDEDA0000, 0),
- INST(kX86InstFIDiv , "fidiv" , G(X87Mem) , F(Fpu) , O(StM2_4) , 0 , 6, 0xDEDA0000, 0),
- INST(kX86InstFIDivR , "fidivr" , G(X87Mem) , F(Fpu) , O(StM2_4) , 0 , 7, 0xDEDA0000, 0),
- INST(kX86InstFILd , "fild" , G(X87Mem) , F(Fpu) , O(StM2_4_8) , 0 , 0, 0xDFDBDF05, 0),
- INST(kX86InstFIMul , "fimul" , G(X87Mem) , F(Fpu) , O(StM2_4) , 0 , 1, 0xDEDA0000, 0),
- INST(kX86InstFIncStP , "fincstp" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9F7, 0),
- INST(kX86InstFInit , "finit" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x9B00DBE3, 0),
- INST(kX86InstFISt , "fist" , G(X87Mem) , F(Fpu) , O(StM2_4) , 0 , 2, 0xDFDB0000, 0),
- INST(kX86InstFIStP , "fistp" , G(X87Mem) , F(Fpu) , O(StM2_4_8) , 0 , 3, 0xDFDBDF07, 0),
- INST(kX86InstFISttP , "fisttp" , G(X87Mem) , F(Fpu) , O(StM2_4_8) , 0 , 1, 0xDFDBDD01, 0),
- INST(kX86InstFISub , "fisub" , G(X87Mem) , F(Fpu) , O(StM2_4) , 0 , 4, 0xDEDA0000, 0),
- INST(kX86InstFISubR , "fisubr" , G(X87Mem) , F(Fpu) , O(StM2_4) , 0 , 5, 0xDEDA0000, 0),
- INST(kX86InstFLd , "fld" , G(X87FldFst) , F(Fpu) , O(StM4_8_10) , 0 , 0, 0x00D9DD00, 0xD9C0DB05),
- INST(kX86InstFLd1 , "fld1" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9E8, 0),
- INST(kX86InstFLdCw , "fldcw" , G(Mem) , F(Fpu) , O(Mem) , 0 , 5, 0x000000D9, 0),
- INST(kX86InstFLdEnv , "fldenv" , G(Mem) , F(Fpu) , O(Mem) , 0 , 4, 0x000000D9, 0),
- INST(kX86InstFLdL2E , "fldl2e" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9EA, 0),
- INST(kX86InstFLdL2T , "fldl2t" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9E9, 0),
- INST(kX86InstFLdLg2 , "fldlg2" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9EC, 0),
- INST(kX86InstFLdLn2 , "fldln2" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9ED, 0),
- INST(kX86InstFLdPi , "fldpi" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9EB, 0),
- INST(kX86InstFLdZ , "fldz" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9EE, 0),
- INST(kX86InstFMul , "fmul" , G(X87StM) , F(Fpu) , 0 , 0 , 1, 0xD8DCC8C8, 0),
- INST(kX86InstFMulP , "fmulp" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DEC8, 0),
- INST(kX86InstFNClex , "fnclex" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000DBE2, 0),
- INST(kX86InstFNInit , "fninit" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000DBE3, 0),
- INST(kX86InstFNop , "fnop" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9D0, 0),
- INST(kX86InstFNSave , "fnsave" , G(Mem) , F(Fpu) , O(Mem) , 0 , 6, 0x000000DD, 0),
- INST(kX86InstFNStCw , "fnstcw" , G(Mem) , F(Fpu) , O(Mem) , 0 , 7, 0x000000D9, 0),
- INST(kX86InstFNStEnv , "fnstenv" , G(Mem) , F(Fpu) , O(Mem) , 0 , 6, 0x000000D9, 0),
- INST(kX86InstFNStSw , "fnstsw" , G(X87Status) , F(Fpu) , O(Mem) , 0 , 7, 0x000000DD, 0x0000DFE0),
- INST(kX86InstFPAtan , "fpatan" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9F3, 0),
- INST(kX86InstFPRem , "fprem" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9F8, 0),
- INST(kX86InstFPRem1 , "fprem1" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9F5, 0),
- INST(kX86InstFPTan , "fptan" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9F2, 0),
- INST(kX86InstFRndInt , "frndint" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9FC, 0),
- INST(kX86InstFRstor , "frstor" , G(Mem) , F(Fpu) , O(Mem) , 0 , 4, 0x000000DD, 0),
- INST(kX86InstFSave , "fsave" , G(Mem) , F(Fpu) , O(Mem) , 0 , 6, 0x9B0000DD, 0),
- INST(kX86InstFScale , "fscale" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9FD, 0),
- INST(kX86InstFSin , "fsin" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9FE, 0),
- INST(kX86InstFSinCos , "fsincos" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9FB, 0),
- INST(kX86InstFSqrt , "fsqrt" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9FA, 0),
- INST(kX86InstFSt , "fst" , G(X87FldFst) , F(Fpu) , O(StM4_8) , 0 , 2, 0x00D9DD02, 0xDDD00000),
- INST(kX86InstFStCw , "fstcw" , G(Mem) , F(Fpu) , O(Mem) , 0 , 7, 0x9B0000D9, 0),
- INST(kX86InstFStEnv , "fstenv" , G(Mem) , F(Fpu) , O(Mem) , 0 , 6, 0x9B0000D9, 0),
- INST(kX86InstFStP , "fstp" , G(X87FldFst) , F(Fpu) , O(StM4_8_10) , 0 , 3, 0x00D9DD03, 0xDDD8DB07),
- INST(kX86InstFStSw , "fstsw" , G(X87Status) , F(Fpu) , O(Mem) , 0 , 7, 0x9B0000DD, 0x9B00DFE0),
- INST(kX86InstFSub , "fsub" , G(X87StM) , F(Fpu) , 0 , 0 , 4, 0xD8DCE0E8, 0),
- INST(kX86InstFSubP , "fsubp" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DEE8, 0),
- INST(kX86InstFSubR , "fsubr" , G(X87StM) , F(Fpu) , 0 , 0 , 5, 0xD8DCE8E0, 0),
- INST(kX86InstFSubRP , "fsubrp" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DEE0, 0),
- INST(kX86InstFTst , "ftst" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9E4, 0),
- INST(kX86InstFUCom , "fucom" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DDE0, 0),
- INST(kX86InstFUComI , "fucomi" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DBE8, 0),
- INST(kX86InstFUComIP , "fucomip" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DFE8, 0),
- INST(kX86InstFUComP , "fucomp" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000DDE8, 0),
- INST(kX86InstFUComPP , "fucompp" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000DAE9, 0),
- INST(kX86InstFWait , "fwait" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x000000DB, 0),
- INST(kX86InstFXam , "fxam" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9E5, 0),
- INST(kX86InstFXch , "fxch" , G(X87StI) , F(Fpu) , 0 , 0 , 0, 0x0000D9C8, 0),
- INST(kX86InstFXRstor , "fxrstor" , G(Mem) , F(Fpu) , 0 , 0 , 1, 0x00000FAE, 0),
- INST(kX86InstFXSave , "fxsave" , G(Mem) , F(Fpu) , 0 , 0 , 0, 0x00000FAE, 0),
- INST(kX86InstFXtract , "fxtract" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9F4, 0),
- INST(kX86InstFYL2X , "fyl2x" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9F1, 0),
- INST(kX86InstFYL2XP1 , "fyl2xp1" , G(Emit) , F(Fpu) , 0 , 0 , 0, 0x0000D9F9, 0),
- INST(kX86InstHAddPD , "haddpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F7C, 0),
- INST(kX86InstHAddPS , "haddps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF2000F7C, 0),
- INST(kX86InstHSubPD , "hsubpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F7D, 0),
- INST(kX86InstHSubPS , "hsubps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF2000F7D, 0),
- INST(kX86InstIDiv , "idiv" , G(Rm) , F(Special) , 0 , 0 , 7, 0x000000F6, 0),
- INST(kX86InstIMul , "imul" , G(IMul) , F(Special) , 0 , 0 , 0, 0 , 0),
- INST(kX86InstInc , "inc" , G(IncDec) , F(Lockable) , O(GqdwbMem) , 0 , 0, 0x00000040, 0x000000FE),
- INST(kX86InstInt3 , "int3" , G(Emit) , F(None) , 0 , 0 , 0, 0x000000CC, 0),
- INST(kX86InstJA , "ja" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x7 , 0),
- INST(kX86InstJAE , "jae" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x3 , 0),
- INST(kX86InstJB , "jb" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x2 , 0),
- INST(kX86InstJBE , "jbe" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x6 , 0),
- INST(kX86InstJC , "jc" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x2 , 0),
- INST(kX86InstJE , "je" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x4 , 0),
- INST(kX86InstJG , "jg" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0xF , 0),
- INST(kX86InstJGE , "jge" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0xD , 0),
- INST(kX86InstJL , "jl" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0xC , 0),
- INST(kX86InstJLE , "jle" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0xE , 0),
- INST(kX86InstJNA , "jna" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x6 , 0),
- INST(kX86InstJNAE , "jnae" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x2 , 0),
- INST(kX86InstJNB , "jnb" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x3 , 0),
- INST(kX86InstJNBE , "jnbe" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x7 , 0),
- INST(kX86InstJNC , "jnc" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x3 , 0),
- INST(kX86InstJNE , "jne" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x5 , 0),
- INST(kX86InstJNG , "jng" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0xE , 0),
- INST(kX86InstJNGE , "jnge" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0xC , 0),
- INST(kX86InstJNL , "jnl" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0xD , 0),
- INST(kX86InstJNLE , "jnle" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0xF , 0),
- INST(kX86InstJNO , "jno" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x1 , 0),
- INST(kX86InstJNP , "jnp" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0xB , 0),
- INST(kX86InstJNS , "jns" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x9 , 0),
- INST(kX86InstJNZ , "jnz" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x5 , 0),
- INST(kX86InstJO , "jo" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x0 , 0),
- INST(kX86InstJP , "jp" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0xA , 0),
- INST(kX86InstJPE , "jpe" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0xA , 0),
- INST(kX86InstJPO , "jpo" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0xB , 0),
- INST(kX86InstJS , "js" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x8 , 0),
- INST(kX86InstJZ , "jz" , G(Jcc) , F(Jump) , 0 , 0 , 0, 0x4 , 0),
- INST(kX86InstJmp , "jmp" , G(Jmp) , F(Jump) , 0 , 0 , 0, 0 , 0),
- INST(kX86InstLdDQU , "lddqu" , G(MmuRmI) , F(None) , O(Xmm) , O(Mem) , 0, 0xF2000FF0, 0),
- INST(kX86InstLdMXCSR , "ldmxcsr" , G(Mem) , F(None) , O(Mem) , 0 , 2, 0x00000FAE, 0),
- INST(kX86InstLahf , "lahf" , G(Emit) , F(Special) , 0 , 0 , 0, 0x0000009F, 0),
- INST(kX86InstLea , "lea" , G(Lea) , F(None) , O(Gqd) , O(Mem) , 0, 0 , 0),
- INST(kX86InstLeave , "leave" , G(Emit) , F(Special) , 0 , 0 , 0, 0x000000C9, 0),
- INST(kX86InstLFence , "lfence" , G(Emit) , F(None) , 0 , 0 , 0, 0x000FAEE8, 0),
- INST(kX86InstMaskMovDQU , "maskmovdqu" , G(MmuRmI) , F(Special) , O(Xmm) , O(Xmm) , 0, 0x66000F57, 0),
- INST(kX86InstMaskMovQ , "maskmovq" , G(MmuRmI) , F(Special) , O(Mm) , O(Mm) , 0, 0x00000FF7, 0),
- INST(kX86InstMaxPD , "maxpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F5F, 0),
- INST(kX86InstMaxPS , "maxps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F5F, 0),
- INST(kX86InstMaxSD , "maxsd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF2000F5F, 0),
- INST(kX86InstMaxSS , "maxss" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF3000F5F, 0),
- INST(kX86InstMFence , "mfence" , G(Emit) , F(None) , 0 , 0 , 0, 0x000FAEF0, 0),
- INST(kX86InstMinPD , "minpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F5D, 0),
- INST(kX86InstMinPS , "minps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F5D, 0),
- INST(kX86InstMinSD , "minsd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF2000F5D, 0),
- INST(kX86InstMinSS , "minss" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF3000F5D, 0),
- INST(kX86InstMonitor , "monitor" , G(Emit) , F(Special) , 0 , 0 , 0, 0x000F01C8, 0),
- INST(kX86InstMov , "mov" , G(Mov) , F(Mov) , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , 0, 0 , 0),
- INST(kX86InstMovAPD , "movapd" , G(MmuMov) , F(Mov) , O(XmmMem) , O(XmmMem) , 0, 0x66000F28, 0x66000F29),
- INST(kX86InstMovAPS , "movaps" , G(MmuMov) , F(Mov) , O(XmmMem) , O(XmmMem) , 0, 0x00000F28, 0x00000F29),
- INST(kX86InstMovBE , "movbe" , G(MovBE) , F(Mov) , O(Gqdw)|O(Mem) , O(Gqdw)|O(Mem) , 0, 0x000F38F0, 0x000F38F1),
- INST(kX86InstMovD , "movd" , G(MmuMovD) , F(Mov) , O(Gd)|O(MmXmmMem) , O(Gd)|O(MmXmmMem) , 0, 0 , 0),
- INST(kX86InstMovDDup , "movddup" , G(MmuMov) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0xF2000F12, 0),
- INST(kX86InstMovDQ2Q , "movdq2q" , G(MmuMov) , F(Mov) , O(Mm) , O(Xmm) , 0, 0xF2000FD6, 0),
- INST(kX86InstMovDQA , "movdqa" , G(MmuMov) , F(Mov) , O(XmmMem) , O(XmmMem) , 0, 0x66000F6F, 0x66000F7F),
- INST(kX86InstMovDQU , "movdqu" , G(MmuMov) , F(Mov) , O(XmmMem) , O(XmmMem) , 0, 0xF3000F6F, 0xF3000F7F),
- INST(kX86InstMovHLPS , "movhlps" , G(MmuMov) , F(None) , O(Xmm) , O(Xmm) , 0, 0x00000F12, 0),
- INST(kX86InstMovHPD , "movhpd" , G(MmuMov) , F(None) , O(XmmMem) , O(XmmMem) , 0, 0x66000F16, 0x66000F17),
- INST(kX86InstMovHPS , "movhps" , G(MmuMov) , F(None) , O(XmmMem) , O(XmmMem) , 0, 0x00000F16, 0x00000F17),
- INST(kX86InstMovLHPS , "movlhps" , G(MmuMov) , F(None) , O(Xmm) , O(Xmm) , 0, 0x00000F16, 0),
- INST(kX86InstMovLPD , "movlpd" , G(MmuMov) , F(None) , O(XmmMem) , O(XmmMem) , 0, 0x66000F12, 0x66000F13),
- INST(kX86InstMovLPS , "movlps" , G(MmuMov) , F(None) , O(XmmMem) , O(XmmMem) , 0, 0x00000F12, 0x00000F13),
- INST(kX86InstMovMskPD , "movmskpd" , G(MmuMov) , F(Mov) , O(Gqd)|O(NoRex) , O(Xmm) , 0, 0x66000F50, 0),
- INST(kX86InstMovMskPS , "movmskps" , G(MmuMov) , F(Mov) , O(Gqd)|O(NoRex) , O(Xmm) , 0, 0x00000F50, 0),
- INST(kX86InstMovNTDQ , "movntdq" , G(MmuMov) , F(None) , O(Mem) , O(Xmm) , 0, 0 , 0x66000FE7),
- INST(kX86InstMovNTDQA , "movntdqa" , G(MmuMov) , F(Mov) , O(Xmm) , O(Mem) , 0, 0x660F382A, 0),
- INST(kX86InstMovNTI , "movnti" , G(MmuMov) , F(Mov) , O(Mem) , O(Gqd) , 0, 0 , 0x00000FC3),
- INST(kX86InstMovNTPD , "movntpd" , G(MmuMov) , F(None) , O(Mem) , O(Xmm) , 0, 0 , 0x66000F2B),
- INST(kX86InstMovNTPS , "movntps" , G(MmuMov) , F(None) , O(Mem) , O(Xmm) , 0, 0 , 0x00000F2B),
- INST(kX86InstMovNTQ , "movntq" , G(MmuMov) , F(None) , O(Mem) , O(Mm) , 0, 0 , 0x00000FE7),
- INST(kX86InstMovQ , "movq" , G(MmuMovQ) , F(Mov) , O(Gq)|O(MmXmmMem) , O(Gq)|O(MmXmmMem) , 0, 0 , 0),
- INST(kX86InstMovQ2DQ , "movq2dq" , G(MmuRmI) , F(Mov) , O(Xmm) , O(Mm) , 0, 0xF3000FD6, 0),
- INST(kX86InstMovSD , "movsd" , G(MmuMov) , F(None) , O(XmmMem) , O(XmmMem) , 0, 0xF2000F10, 0xF2000F11),
- INST(kX86InstMovSHDup , "movshdup" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0xF3000F16, 0),
- INST(kX86InstMovSLDup , "movsldup" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0xF3000F12, 0),
- INST(kX86InstMovSS , "movss" , G(MmuMov) , F(None) , O(XmmMem) , O(XmmMem) , 0, 0xF3000F10, 0xF3000F11),
- INST(kX86InstMovSX , "movsx" , G(MovSxMovZx) , F(None) , O(Gqdw) , O(GwbMem) , 0, 0x00000FBE, 0),
- INST(kX86InstMovSXD , "movsxd" , G(MovSxD) , F(None) , O(Gq) , O(GdMem) , 0, 0 , 0),
- INST(kX86InstMovUPD , "movupd" , G(MmuMov) , F(Mov) , O(XmmMem) , O(XmmMem) , 0, 0x66000F10, 0x66000F11),
- INST(kX86InstMovUPS , "movups" , G(MmuMov) , F(Mov) , O(XmmMem) , O(XmmMem) , 0, 0x00000F10, 0x00000F11),
- INST(kX86InstMovZX , "movzx" , G(MovSxMovZx) , F(Mov) , O(Gqdw) , O(GwbMem) , 0, 0x00000FB6, 0),
- INST(kX86InstMovPtr , "mov_ptr" , G(MovPtr) , F(Mov)|F(Special), O(Gqdwb) , O(Imm) , 0, 0 , 0),
- INST(kX86InstMPSADBW , "mpsadbw" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3A42, 0),
- INST(kX86InstMul , "mul" , G(Rm) , F(Special) , 0 , 0 , 4, 0x000000F6, 0),
- INST(kX86InstMulPD , "mulpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F59, 0),
- INST(kX86InstMulPS , "mulps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F59, 0),
- INST(kX86InstMulSD , "mulsd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF2000F59, 0),
- INST(kX86InstMulSS , "mulss" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF3000F59, 0),
- INST(kX86InstMWait , "mwait" , G(Emit) , F(Special) , 0 , 0 , 0, 0x000F01C9, 0),
- INST(kX86InstNeg , "neg" , G(Rm) , F(Lockable) , O(GqdwbMem) , 0 , 3, 0x000000F6, 0),
- INST(kX86InstNop , "nop" , G(Emit) , F(None) , 0 , 0 , 0, 0x00000090, 0),
- INST(kX86InstNot , "not" , G(Rm) , F(Lockable) , O(GqdwbMem) , 0 , 2, 0x000000F6, 0),
- INST(kX86InstOr , "or" , G(Arith) , F(Lockable) , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , 1, 0x00000008, 0x00000080),
- INST(kX86InstOrPD , "orpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F56, 0),
- INST(kX86InstOrPS , "orps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F56, 0),
- INST(kX86InstPAbsB , "pabsb" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F381C, 0),
- INST(kX86InstPAbsD , "pabsd" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F381E, 0),
- INST(kX86InstPAbsW , "pabsw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F381D, 0),
- INST(kX86InstPackSSDW , "packssdw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F6B, 0),
- INST(kX86InstPackSSWB , "packsswb" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F63, 0),
- INST(kX86InstPackUSDW , "packusdw" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F382B, 0),
- INST(kX86InstPackUSWB , "packuswb" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F67, 0),
- INST(kX86InstPAddB , "paddb" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FFC, 0),
- INST(kX86InstPAddD , "paddd" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FFE, 0),
- INST(kX86InstPAddQ , "paddq" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FD4, 0),
- INST(kX86InstPAddSB , "paddsb" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FEC, 0),
- INST(kX86InstPAddSW , "paddsw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FED, 0),
- INST(kX86InstPAddUSB , "paddusb" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FDC, 0),
- INST(kX86InstPAddUSW , "paddusw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FDD, 0),
- INST(kX86InstPAddW , "paddw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FFD, 0),
- INST(kX86InstPAlignR , "palignr" , G(MmuRmImm8) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F3A0F, 0),
- INST(kX86InstPAnd , "pand" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FDB, 0),
- INST(kX86InstPAndN , "pandn" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FDF, 0),
- INST(kX86InstPause , "pause" , G(Emit) , F(None) , 0 , 0 , 0, 0xF3000090, 0),
- INST(kX86InstPAvgB , "pavgb" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FE0, 0),
- INST(kX86InstPAvgW , "pavgw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FE3, 0),
- INST(kX86InstPBlendVB , "pblendvb" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3810, 0),
- INST(kX86InstPBlendW , "pblendw" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3A0E, 0),
- INST(kX86InstPCmpEqB , "pcmpeqb" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F74, 0),
- INST(kX86InstPCmpEqD , "pcmpeqd" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F76, 0),
- INST(kX86InstPCmpEqQ , "pcmpeqq" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3829, 0),
- INST(kX86InstPCmpEqW , "pcmpeqw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F75, 0),
- INST(kX86InstPCmpEStrI , "pcmpestri" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3A61, 0),
- INST(kX86InstPCmpEStrM , "pcmpestrm" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3A60, 0),
- INST(kX86InstPCmpGtB , "pcmpgtb" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F64, 0),
- INST(kX86InstPCmpGtD , "pcmpgtd" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F66, 0),
- INST(kX86InstPCmpGtQ , "pcmpgtq" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3837, 0),
- INST(kX86InstPCmpGtW , "pcmpgtw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F65, 0),
- INST(kX86InstPCmpIStrI , "pcmpistri" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3A63, 0),
- INST(kX86InstPCmpIStrM , "pcmpistrm" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3A62, 0),
- INST(kX86InstPExtrB , "pextrb" , G(MmuExtract) , F(None) , O(Gd)|O(Gb)|O(Mem) , O(Xmm) , 0, 0x000F3A14, 0),
- INST(kX86InstPExtrD , "pextrd" , G(MmuExtract) , F(None) , O(Gd) |O(Mem) , O(Xmm) , 0, 0x000F3A16, 0),
- INST(kX86InstPExtrQ , "pextrq" , G(MmuExtract) , F(None) , O(Gqd) |O(Mem) , O(Xmm) , 1, 0x000F3A16, 0),
- INST(kX86InstPExtrW , "pextrw" , G(MmuExtract) , F(None) , O(Gd) |O(Mem) , O(MmXmm) , 0, 0x000F3A15, 0),
- INST(kX86InstPF2ID , "pf2id" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0x1D),
- INST(kX86InstPF2IW , "pf2iw" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0x1C),
- INST(kX86InstPFAcc , "pfacc" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0xAE),
- INST(kX86InstPFAdd , "pfadd" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0x9E),
- INST(kX86InstPFCmpEQ , "pfcmpeq" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0xB0),
- INST(kX86InstPFCmpGE , "pfcmpge" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0x90),
- INST(kX86InstPFCmpGT , "pfcmpgt" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0xA0),
- INST(kX86InstPFMax , "pfmax" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0xA4),
- INST(kX86InstPFMin , "pfmin" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0x94),
- INST(kX86InstPFMul , "pfmul" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0xB4),
- INST(kX86InstPFNAcc , "pfnacc" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0x8A),
- INST(kX86InstPFPNAcc , "pfpnacc" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0x8E),
- INST(kX86InstPFRcp , "pfrcp" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0x96),
- INST(kX86InstPFRcpIt1 , "pfrcpit1" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0xA6),
- INST(kX86InstPFRcpIt2 , "pfrcpit2" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0xB6),
- INST(kX86InstPFRSqIt1 , "pfrsqit1" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0xA7),
- INST(kX86InstPFRSqrt , "pfrsqrt" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0x97),
- INST(kX86InstPFSub , "pfsub" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0x9A),
- INST(kX86InstPFSubR , "pfsubr" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0xAA),
- INST(kX86InstPHAddD , "phaddd" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F3802, 0),
- INST(kX86InstPHAddSW , "phaddsw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F3803, 0),
- INST(kX86InstPHAddW , "phaddw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F3801, 0),
- INST(kX86InstPHMinPOSUW , "phminposuw" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3841, 0),
- INST(kX86InstPHSubD , "phsubd" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F3806, 0),
- INST(kX86InstPHSubSW , "phsubsw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F3807, 0),
- INST(kX86InstPHSubW , "phsubw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F3805, 0),
- INST(kX86InstPI2FD , "pi2fd" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0x0D),
- INST(kX86InstPI2FW , "pi2fw" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0x0C),
- INST(kX86InstPInsRB , "pinsrb" , G(MmuRmImm8) , F(None) , O(Xmm) , O(Gd) | O(Mem) , 0, 0x660F3A20, 0),
- INST(kX86InstPInsRD , "pinsrd" , G(MmuRmImm8) , F(None) , O(Xmm) , O(Gd) | O(Mem) , 0, 0x660F3A22, 0),
- INST(kX86InstPInsRQ , "pinsrq" , G(MmuRmImm8) , F(None) , O(Xmm) , O(Gq) | O(Mem) , 0, 0x660F3A22, 0),
- INST(kX86InstPInsRW , "pinsrw" , G(MmuRmImm8) , F(None) , O(MmXmm) , O(Gd) | O(Mem) , 0, 0x00000FC4, 0),
- INST(kX86InstPMAddUBSW , "pmaddubsw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F3804, 0),
- INST(kX86InstPMAddWD , "pmaddwd" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FF5, 0),
- INST(kX86InstPMaxSB , "pmaxsb" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F383C, 0),
- INST(kX86InstPMaxSD , "pmaxsd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F383D, 0),
- INST(kX86InstPMaxSW , "pmaxsw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FEE, 0),
- INST(kX86InstPMaxUB , "pmaxub" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FDE, 0),
- INST(kX86InstPMaxUD , "pmaxud" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F383F, 0),
- INST(kX86InstPMaxUW , "pmaxuw" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F383E, 0),
- INST(kX86InstPMinSB , "pminsb" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3838, 0),
- INST(kX86InstPMinSD , "pminsd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3839, 0),
- INST(kX86InstPMinSW , "pminsw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FEA, 0),
- INST(kX86InstPMinUB , "pminub" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FDA, 0),
- INST(kX86InstPMinUD , "pminud" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F383B, 0),
- INST(kX86InstPMinUW , "pminuw" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F383A, 0),
- INST(kX86InstPMovMskB , "pmovmskb" , G(MmuRmI) , F(Mov) , O(Gqd) , O(MmXmm) , 0, 0x00000FD7, 0),
- INST(kX86InstPMovSXBD , "pmovsxbd" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3821, 0),
- INST(kX86InstPMovSXBQ , "pmovsxbq" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3822, 0),
- INST(kX86InstPMovSXBW , "pmovsxbw" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3820, 0),
- INST(kX86InstPMovSXDQ , "pmovsxdq" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3825, 0),
- INST(kX86InstPMovSXWD , "pmovsxwd" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3823, 0),
- INST(kX86InstPMovSXWQ , "pmovsxwq" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3824, 0),
- INST(kX86InstPMovZXBD , "pmovzxbd" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3831, 0),
- INST(kX86InstPMovZXBQ , "pmovzxbq" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3832, 0),
- INST(kX86InstPMovZXBW , "pmovzxbw" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3830, 0),
- INST(kX86InstPMovZXDQ , "pmovzxdq" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3835, 0),
- INST(kX86InstPMovZXWD , "pmovzxwd" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3833, 0),
- INST(kX86InstPMovZXWQ , "pmovzxwq" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3834, 0),
- INST(kX86InstPMulDQ , "pmuldq" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3828, 0),
- INST(kX86InstPMulHRSW , "pmulhrsw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F380B, 0),
- INST(kX86InstPMulHUW , "pmulhuw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FE4, 0),
- INST(kX86InstPMulHW , "pmulhw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FE5, 0),
- INST(kX86InstPMulLD , "pmulld" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3840, 0),
- INST(kX86InstPMulLW , "pmullw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FD5, 0),
- INST(kX86InstPMulUDQ , "pmuludq" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FF4, 0),
- INST(kX86InstPop , "pop" , G(Pop) , F(Special) , 0 , 0 , 0, 0x00000058, 0x0000008F),
- INST(kX86InstPopAD , "popad" , G(Emit) , F(Special) , 0 , 0 , 0, 0x00000061, 0),
- INST(kX86InstPopCnt , "popcnt" , G(RegRm) , F(None) , O(Gqdw) , O(GqdwMem) , 0, 0xF3000FB8, 0),
- INST(kX86InstPopFD , "popfd" , G(Emit) , F(Special) , 0 , 0 , 0, 0x0000009D, 0),
- INST(kX86InstPopFQ , "popfq" , G(Emit) , F(Special) , 0 , 0 , 0, 0x0000009D, 0),
- INST(kX86InstPOr , "por" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FEB, 0),
- INST(kX86InstPrefetch , "prefetch" , G(MmuPrefetch) , F(None) , O(Mem) , O(Imm) , 0, 0 , 0),
- INST(kX86InstPSADBW , "psadbw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FF6, 0),
- INST(kX86InstPShufB , "pshufb" , G(MmuRmI) , F(Mov) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F3800, 0),
- INST(kX86InstPShufD , "pshufd" , G(MmuRmImm8) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x66000F70, 0),
- INST(kX86InstPShufW , "pshufw" , G(MmuRmImm8) , F(Mov) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F70, 0),
- INST(kX86InstPShufHW , "pshufhw" , G(MmuRmImm8) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0xF3000F70, 0),
- INST(kX86InstPShufLW , "pshuflw" , G(MmuRmImm8) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0xF2000F70, 0),
- INST(kX86InstPSignB , "psignb" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F3808, 0),
- INST(kX86InstPSignD , "psignd" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F380A, 0),
- INST(kX86InstPSignW , "psignw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x000F3809, 0),
- INST(kX86InstPSllD , "pslld" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem)|O(Imm) , 6, 0x00000FF2, 0x00000F72),
- INST(kX86InstPSllDQ , "pslldq" , G(MmuRmI) , F(None) , O(Xmm) , O(Imm) , 7, 0 , 0x66000F73),
- INST(kX86InstPSllQ , "psllq" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem)|O(Imm) , 6, 0x00000FF3, 0x00000F73),
- INST(kX86InstPSllW , "psllw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem)|O(Imm) , 6, 0x00000FF1, 0x00000F71),
- INST(kX86InstPSraD , "psrad" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem)|O(Imm) , 4, 0x00000FE2, 0x00000F72),
- INST(kX86InstPSraW , "psraw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem)|O(Imm) , 4, 0x00000FE1, 0x00000F71),
- INST(kX86InstPSrlD , "psrld" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem)|O(Imm) , 2, 0x00000FD2, 0x00000F72),
- INST(kX86InstPSrlDQ , "psrldq" , G(MmuRmI) , F(None) , O(Xmm) , O(Imm) , 3, 0 , 0x66000F73),
- INST(kX86InstPSrlQ , "psrlq" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem)|O(Imm) , 2, 0x00000FD3, 0x00000F73),
- INST(kX86InstPSrlW , "psrlw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem)|O(Imm) , 2, 0x00000FD1, 0x00000F71),
- INST(kX86InstPSubB , "psubb" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FF8, 0),
- INST(kX86InstPSubD , "psubd" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FFA, 0),
- INST(kX86InstPSubQ , "psubq" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FFB, 0),
- INST(kX86InstPSubSB , "psubsb" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FE8, 0),
- INST(kX86InstPSubSW , "psubsw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FE9, 0),
- INST(kX86InstPSubUSB , "psubusb" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FD8, 0),
- INST(kX86InstPSubUSW , "psubusw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FD9, 0),
- INST(kX86InstPSubW , "psubw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FF9, 0),
- INST(kX86InstPSwapD , "pswapd" , G(MmuRm3dNow) , F(None) , O(Mm) , O(MmMem) , 0, 0x00000F0F, 0xBB),
- INST(kX86InstPTest , "ptest" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3817, 0),
- INST(kX86InstPunpckHBW , "punpckhbw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F68, 0),
- INST(kX86InstPunpckHDQ , "punpckhdq" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F6A, 0),
- INST(kX86InstPunpckHQDQ , "punpckhqdq" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F6D, 0),
- INST(kX86InstPunpckHWD , "punpckhwd" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F69, 0),
- INST(kX86InstPunpckLBW , "punpcklbw" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F60, 0),
- INST(kX86InstPunpckLDQ , "punpckldq" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F62, 0),
- INST(kX86InstPunpckLQDQ , "punpcklqdq" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F6C, 0),
- INST(kX86InstPunpckLWD , "punpcklwd" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000F61, 0),
- INST(kX86InstPush , "push" , G(Push) , F(Special) , 0 , 0 , 6, 0x00000050, 0x000000FF),
- INST(kX86InstPushAD , "pushad" , G(Emit) , F(Special) , 0 , 0 , 0, 0x00000060, 0),
- INST(kX86InstPushFD , "pushfd" , G(Emit) , F(Special) , 0 , 0 , 0, 0x0000009C, 0),
- INST(kX86InstPushFQ , "pushfq" , G(Emit) , F(Special) , 0 , 0 , 0, 0x0000009C, 0),
- INST(kX86InstPXor , "pxor" , G(MmuRmI) , F(None) , O(MmXmm) , O(MmXmmMem) , 0, 0x00000FEF, 0),
- INST(kX86InstRcl , "rcl" , G(Rot) , F(Special) , O(GqdwbMem) , O(Gb)|O(Imm) , 2, 0 , 0),
- INST(kX86InstRcpPS , "rcpps" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x00000F53, 0),
- INST(kX86InstRcpSS , "rcpss" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0xF3000F53, 0),
- INST(kX86InstRcr , "rcr" , G(Rot) , F(Special) , O(GqdwbMem) , O(Gb)|O(Imm) , 3, 0 , 0),
- INST(kX86InstRdtsc , "rdtsc" , G(Emit) , F(Special) , 0 , 0 , 0, 0x00000F31, 0),
- INST(kX86InstRdtscP , "rdtscp" , G(Emit) , F(Special) , 0 , 0 , 0, 0x000F01F9, 0),
- INST(kX86InstRepLodSB , "rep lodsb" , G(Rep) , F(Special) , O(Mem) , 0 , 0, 0xF30000AC, 1 /* Size of mem */),
- INST(kX86InstRepLodSD , "rep lodsd" , G(Rep) , F(Special) , O(Mem) , 0 , 0, 0xF30000AC, 4 /* Size of mem */),
- INST(kX86InstRepLodSQ , "rep lodsq" , G(Rep) , F(Special) , O(Mem) , 0 , 0, 0xF30000AC, 8 /* Size of mem */),
- INST(kX86InstRepLodSW , "rep lodsw" , G(Rep) , F(Special) , O(Mem) , 0 , 0, 0xF30000AC, 2 /* Size of mem */),
- INST(kX86InstRepMovSB , "rep movsb" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF30000A4, 1 /* Size of mem */),
- INST(kX86InstRepMovSD , "rep movsd" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF30000A4, 4 /* Size of mem */),
- INST(kX86InstRepMovSQ , "rep movsq" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF30000A4, 8 /* Size of mem */),
- INST(kX86InstRepMovSW , "rep movsw" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF30000A4, 2 /* Size of mem */),
- INST(kX86InstRepStoSB , "rep stosb" , G(Rep) , F(Special) , O(Mem) , 0 , 0, 0xF30000AA, 1 /* Size of mem */),
- INST(kX86InstRepStoSD , "rep stosd" , G(Rep) , F(Special) , O(Mem) , 0 , 0, 0xF30000AA, 4 /* Size of mem */),
- INST(kX86InstRepStoSQ , "rep stosq" , G(Rep) , F(Special) , O(Mem) , 0 , 0, 0xF30000AA, 8 /* Size of mem */),
- INST(kX86InstRepStoSW , "rep stosw" , G(Rep) , F(Special) , O(Mem) , 0 , 0, 0xF30000AA, 2 /* Size of mem */),
- INST(kX86InstRepECmpSB , "repe cmpsb" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF30000A6, 1 /* Size of mem */),
- INST(kX86InstRepECmpSD , "repe cmpsd" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF30000A6, 4 /* Size of mem */),
- INST(kX86InstRepECmpSQ , "repe cmpsq" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF30000A6, 8 /* Size of mem */),
- INST(kX86InstRepECmpSW , "repe cmpsw" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF30000A6, 2 /* Size of mem */),
- INST(kX86InstRepEScaSB , "repe scasb" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF30000AE, 1 /* Size of mem */),
- INST(kX86InstRepEScaSD , "repe scasd" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF30000AE, 4 /* Size of mem */),
- INST(kX86InstRepEScaSQ , "repe scasq" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF30000AE, 8 /* Size of mem */),
- INST(kX86InstRepEScaSW , "repe scasw" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF30000AE, 2 /* Size of mem */),
- INST(kX86InstRepNECmpSB , "repne cmpsb" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF20000A6, 1 /* Size of mem */),
- INST(kX86InstRepNECmpSD , "repne cmpsd" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF20000A6, 4 /* Size of mem */),
- INST(kX86InstRepNECmpSQ , "repne cmpsq" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF20000A6, 8 /* Size of mem */),
- INST(kX86InstRepNECmpSW , "repne cmpsw" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF20000A6, 2 /* Size of mem */),
- INST(kX86InstRepNEScaSB , "repne scasb" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF20000AE, 1 /* Size of mem */),
- INST(kX86InstRepNEScaSD , "repne scasd" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF20000AE, 4 /* Size of mem */),
- INST(kX86InstRepNEScaSQ , "repne scasq" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF20000AE, 8 /* Size of mem */),
- INST(kX86InstRepNEScaSW , "repne scasw" , G(Rep) , F(Special) , O(Mem) , O(Mem) , 0, 0xF20000AE, 2 /* Size of mem */),
- INST(kX86InstRet , "ret" , G(Ret) , F(Special) , 0 , 0 , 0, 0 , 0),
- INST(kX86InstRol , "rol" , G(Rot) , F(Special) , O(GqdwbMem) , O(Gb)|O(Imm) , 0, 0 , 0),
- INST(kX86InstRor , "ror" , G(Rot) , F(Special) , O(GqdwbMem) , O(Gb)|O(Imm) , 1, 0 , 0),
- INST(kX86InstRoundPD , "roundpd" , G(MmuRmImm8) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3A09, 0),
- INST(kX86InstRoundPS , "roundps" , G(MmuRmImm8) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x660F3A08, 0),
- INST(kX86InstRoundSD , "roundsd" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3A0B, 0),
- INST(kX86InstRoundSS , "roundss" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x660F3A0A, 0),
- INST(kX86InstRSqrtPS , "rsqrtps" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x00000F52, 0),
- INST(kX86InstRSqrtSS , "rsqrtss" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF3000F52, 0),
- INST(kX86InstSahf , "sahf" , G(Emit) , F(Special) , 0 , 0 , 0, 0x0000009E, 0),
- INST(kX86InstSal , "sal" , G(Rot) , F(Special) , O(GqdwbMem) , O(Gb)|O(Imm) , 4, 0 , 0),
- INST(kX86InstSar , "sar" , G(Rot) , F(Special) , O(GqdwbMem) , O(Gb)|O(Imm) , 7, 0 , 0),
- INST(kX86InstSbb , "sbb" , G(Arith) , F(Lockable) , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , 3, 0x00000018, 0x00000080),
- INST(kX86InstSetA , "seta" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F97, 0),
- INST(kX86InstSetAE , "setae" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F93, 0),
- INST(kX86InstSetB , "setb" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F92, 0),
- INST(kX86InstSetBE , "setbe" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F96, 0),
- INST(kX86InstSetC , "setc" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F92, 0),
- INST(kX86InstSetE , "sete" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F94, 0),
- INST(kX86InstSetG , "setg" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F9F, 0),
- INST(kX86InstSetGE , "setge" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F9D, 0),
- INST(kX86InstSetL , "setl" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F9C, 0),
- INST(kX86InstSetLE , "setle" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F9E, 0),
- INST(kX86InstSetNA , "setna" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F96, 0),
- INST(kX86InstSetNAE , "setnae" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F92, 0),
- INST(kX86InstSetNB , "setnb" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F93, 0),
- INST(kX86InstSetNBE , "setnbe" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F97, 0),
- INST(kX86InstSetNC , "setnc" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F93, 0),
- INST(kX86InstSetNE , "setne" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F95, 0),
- INST(kX86InstSetNG , "setng" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F9E, 0),
- INST(kX86InstSetNGE , "setnge" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F9C, 0),
- INST(kX86InstSetNL , "setnl" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F9D, 0),
- INST(kX86InstSetNLE , "setnle" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F9F, 0),
- INST(kX86InstSetNO , "setno" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F91, 0),
- INST(kX86InstSetNP , "setnp" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F9B, 0),
- INST(kX86InstSetNS , "setns" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F99, 0),
- INST(kX86InstSetNZ , "setnz" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F95, 0),
- INST(kX86InstSetO , "seto" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F90, 0),
- INST(kX86InstSetP , "setp" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F9A, 0),
- INST(kX86InstSetPE , "setpe" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F9A, 0),
- INST(kX86InstSetPO , "setpo" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F9B, 0),
- INST(kX86InstSetS , "sets" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F98, 0),
- INST(kX86InstSetZ , "setz" , G(RmByte) , F(None) , O(GbMem) , 0 , 0, 0x00000F94, 0),
- INST(kX86InstSFence , "sfence" , G(Emit) , F(None) , 0 , 0 , 0, 0x000FAEF8, 0),
- INST(kX86InstShl , "shl" , G(Rot) , F(Special) , O(GqdwbMem) , O(Gb)|O(Imm) , 4, 0 , 0),
- INST(kX86InstShld , "shld" , G(ShldShrd) , F(Special) , O(GqdwbMem) , O(Gb) , 0, 0x00000FA4, 0),
- INST(kX86InstShr , "shr" , G(Rot) , F(Special) , O(GqdwbMem) , O(Gb)|O(Imm) , 5, 0 , 0),
- INST(kX86InstShrd , "shrd" , G(ShldShrd) , F(Special) , O(GqdwbMem) , O(Gqdwb) , 0, 0x00000FAC, 0),
- INST(kX86InstShufPD , "shufpd" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000FC6, 0),
- INST(kX86InstShufPS , "shufps" , G(MmuRmImm8) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000FC6, 0),
- INST(kX86InstSqrtPD , "sqrtpd" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x66000F51, 0),
- INST(kX86InstSqrtPS , "sqrtps" , G(MmuRmI) , F(Mov) , O(Xmm) , O(XmmMem) , 0, 0x00000F51, 0),
- INST(kX86InstSqrtSD , "sqrtsd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF2000F51, 0),
- INST(kX86InstSqrtSS , "sqrtss" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF3000F51, 0),
- INST(kX86InstStc , "stc" , G(Emit) , F(None) , 0 , 0 , 0, 0x000000F9, 0),
- INST(kX86InstStd , "std" , G(Emit) , F(None) , 0 , 0 , 0, 0x000000FD, 0),
- INST(kX86InstStMXCSR , "stmxcsr" , G(Mem) , F(None) , O(Mem) , 0 , 3, 0x00000FAE, 0),
- INST(kX86InstSub , "sub" , G(Arith) , F(Lockable) , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , 5, 0x00000028, 0x00000080),
- INST(kX86InstSubPD , "subpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F5C, 0),
- INST(kX86InstSubPS , "subps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F5C, 0),
- INST(kX86InstSubSD , "subsd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF2000F5C, 0),
- INST(kX86InstSubSS , "subss" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0xF3000F5C, 0),
- INST(kX86InstTest , "test" , G(Test) , F(None) , O(GqdwbMem) , O(Gqdwb)|O(Imm) , 0, 0 , 0),
- INST(kX86InstUComISD , "ucomisd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F2E, 0),
- INST(kX86InstUComISS , "ucomiss" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F2E, 0),
- INST(kX86InstUd2 , "ud2" , G(Emit) , F(None) , 0 , 0 , 0, 0x00000F0B, 0),
- INST(kX86InstUnpckHPD , "unpckhpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F15, 0),
- INST(kX86InstUnpckHPS , "unpckhps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F15, 0),
- INST(kX86InstUnpckLPD , "unpcklpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F14, 0),
- INST(kX86InstUnpckLPS , "unpcklps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F14, 0),
- INST(kX86InstXadd , "xadd" , G(RmReg) , F(Lockable) , O(GqdwbMem) , O(Gqdwb) , 0, 0x00000FC0, 0),
- INST(kX86InstXchg , "xchg" , G(Xchg) , F(Lockable) , O(GqdwbMem) , O(Gqdwb) , 0, 0 , 0),
- INST(kX86InstXor , "xor" , G(Arith) , F(Lockable) , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , 6, 0x00000030, 0x00000080),
- INST(kX86InstXorPD , "xorpd" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x66000F57, 0),
- INST(kX86InstXorPS , "xorps" , G(MmuRmI) , F(None) , O(Xmm) , O(XmmMem) , 0, 0x00000F57, 0)
-};
-
-#undef G
-#undef F
-#undef O
-
-#undef INST
-
-// ============================================================================
-// [AsmJit::x86VarInfo]
-// ============================================================================
-
-#define C(_Class_) kX86VarClass##_Class_
-#define F(_Flag_) kX86VarFlag##_Flag_
-
-const X86VarInfo x86VarInfo[] =
-{
- /* 0 */ { kX86RegTypeGpd , 4 , C(Gp) , 0 , "Gpd" },
- /* 1 */ { kX86RegTypeGpq , 8 , C(Gp) , 0 , "Gpq" },
- /* 2 */ { kX86RegTypeX87 , 4 , C(X87), F(SP) , "X87" },
- /* 3 */ { kX86RegTypeX87 , 4 , C(X87), F(SP) , "X87.SS" },
- /* 4 */ { kX86RegTypeX87 , 8 , C(X87), F(DP) , "X87.SD" },
- /* 5 */ { kX86RegTypeMm , 8 , C(Mm) , 0 , "Mm" },
- /* 6 */ { kX86RegTypeXmm , 16, C(Xmm), 0 , "Xmm" },
- /* 7 */ { kX86RegTypeXmm , 4 , C(Xmm), F(SP) , "Xmm.SS" },
- /* 8 */ { kX86RegTypeXmm , 8 , C(Xmm), F(DP) , "Xmm.SD" },
- /* 9 */ { kX86RegTypeXmm , 16, C(Xmm), F(SP) | F(Packed), "Xmm.PS" },
- /* 10 */ { kX86RegTypeXmm , 16, C(Xmm), F(DP) | F(Packed), "Xmm.PD" }
-};
-
-#undef F
-#undef C
-
-} // AsmJit namespace
-
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86defs.h
+++ /dev/null
@@ -1,2199 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/assert.h"
-#include "../core/defs.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_X86
-//! @{
-
-// ============================================================================
-// [AsmJit::kX86Feature]
-// ============================================================================
-
-//! @brief X86 CPU features.
-enum kX86Feature
-{
- //! @brief Cpu has RDTSC instruction.
- kX86FeatureRdtsc = 1U,
- //! @brief Cpu has RDTSCP instruction.
- kX86FeatureRdtscP = 1U << 1,
- //! @brief Cpu has CMOV instruction (conditional move)
- kX86FeatureCMov = 1U << 2,
- //! @brief Cpu has CMPXCHG8B instruction
- kX86FeatureCmpXchg8B = 1U << 3,
- //! @brief Cpu has CMPXCHG16B instruction (64-bit processors)
- kX86FeatureCmpXchg16B = 1U << 4,
- //! @brief Cpu has CLFUSH instruction
- kX86FeatureClFlush = 1U << 5,
- //! @brief Cpu has PREFETCH instruction
- kX86FeaturePrefetch = 1U << 6,
- //! @brief Cpu supports LAHF and SAHF instrictions.
- kX86FeatureLahfSahf = 1U << 7,
- //! @brief Cpu supports FXSAVE and FXRSTOR instructions.
- kX86FeatureFXSR = 1U << 8,
- //! @brief Cpu supports FXSAVE and FXRSTOR instruction optimizations (FFXSR).
- kX86FeatureFFXSR = 1U << 9,
- //! @brief Cpu has MMX.
- kX86FeatureMmx = 1U << 10,
- //! @brief Cpu has extended MMX.
- kX86FeatureMmxExt = 1U << 11,
- //! @brief Cpu has 3dNow!
- kX86Feature3dNow = 1U << 12,
- //! @brief Cpu has enchanced 3dNow!
- kX86Feature3dNowExt = 1U << 13,
- //! @brief Cpu has SSE.
- kX86FeatureSse = 1U << 14,
- //! @brief Cpu has SSE2.
- kX86FeatureSse2 = 1U << 15,
- //! @brief Cpu has SSE3.
- kX86FeatureSse3 = 1U << 16,
- //! @brief Cpu has Supplemental SSE3 (SSSE3).
- kX86FeatureSsse3 = 1U << 17,
- //! @brief Cpu has SSE4.A.
- kX86FeatureSse4A = 1U << 18,
- //! @brief Cpu has SSE4.1.
- kX86FeatureSse41 = 1U << 19,
- //! @brief Cpu has SSE4.2.
- kX86FeatureSse42 = 1U << 20,
- //! @brief Cpu has AVX.
- kX86FeatureAvx = 1U << 22,
- //! @brief Cpu has Misaligned SSE (MSSE).
- kX86FeatureMSse = 1U << 23,
- //! @brief Cpu supports MONITOR and MWAIT instructions.
- kX86FeatureMonitorMWait = 1U << 24,
- //! @brief Cpu supports MOVBE instruction.
- kX86FeatureMovBE = 1U << 25,
- //! @brief Cpu supports POPCNT instruction.
- kX86FeaturePopCnt = 1U << 26,
- //! @brief Cpu supports LZCNT instruction.
- kX86FeatureLzCnt = 1U << 27,
- //! @brief Cpu supports PCLMULDQ set of instructions.
- kX86FeaturePclMulDQ = 1U << 28,
- //! @brief Cpu supports multithreading.
- kX86FeatureMultiThreading = 1U << 29,
- //! @brief Cpu supports execute disable bit (execute protection).
- kX86FeatureExecuteDisableBit = 1U << 30,
- //! @brief 64-bit CPU.
- kX86Feature64Bit = 1U << 31
-};
-
-// ============================================================================
-// [AsmJit::kX86Bug]
-// ============================================================================
-
-//! @brief X86 CPU bugs.
-enum kX86Bug
-{
- //! @brief Whether the processor contains bug seen in some
- //! AMD-Opteron processors.
- kX86BugAmdLockMB = 1U << 0
-};
-
-// ============================================================================
-// [AsmJit::kX86Property]
-// ============================================================================
-
-//! @brief @ref X86Assembler and @ref X86Compiler properties.
-enum kX86Property
-{
- //! @brief Optimize align for current processor.
- //!
- //! Default: @c true.
- kX86PropertyOptimizedAlign = 0,
-
- //! @brief Emit hints added to jcc() instructions.
- //!
- //! Default: @c true.
- kX86PropertyJumpHints = 1
-};
-
-// ============================================================================
-// [AsmJit::kX86Seg]
-// ============================================================================
-
-//! @brief X86 segment codes.
-enum kX86Seg
-{
- // DO NOT MODIFY INDEX CODES - They are used by _emitSegmentPrefix() and
- // by logger in the following order:
-
- //! @brief ES segment.
- kX86SegEs = 0,
- //! @brief CS segment.
- kX86SegCs = 1,
- //! @brief SS segment.
- kX86SegSs = 2,
- //! @brief DS segment.
- kX86SegDs = 3,
- //! @brief FS segment.
- kX86SegFs = 4,
- //! @brief GS segment.
- kX86SegGs = 5,
- //! @brief Count of segments.
- kX86SegCount = 6,
-
- //! @brief No segment override prefix.
- kX86SegNone = 0xF
-};
-
-// ============================================================================
-// [AsmJit::kX86RegNum]
-// ============================================================================
-
-//! @brief X86 registers count.
-//!
-//! Count of general purpose registers and XMM registers depends on current
-//! mode. If application is compiled for 32-bit platform then this number is 8,
-//! 64-bit platforms have 8 extra general purpose and XMM registers (16 total).
-enum kX86RegNum
-{
- //! @var kX86RegNumBase
- //!
- //! Count of general purpose registers and XMM registers depends on current
- //! bit-mode. If application is compiled for 32-bit platform then this number
- //! is 8, 64-bit platforms have 8 extra general purpose and XMM registers (16
- //! total).
-#ifdef ASMJIT_X86
- kX86RegNumBase = 8,
-#else
- kX86RegNumBase = 16,
-#endif // ASMJIT
-
- //! @brief Count of general purpose registers.
- //!
- //! 8 in 32-bit mode and 16 in 64-bit mode.
- kX86RegNumGp = kX86RegNumBase,
-
- //! @brief Count of FPU stack registers (always 8).
- kX86RegNumX87 = 8,
- //! @brief Count of MM registers (always 8).
- kX86RegNumMm = 8,
-
- //! @brief Count of XMM registers.
- //!
- //! 8 in 32-bit mode and 16 in 64-bit mode.
- kX86RegNumXmm = kX86RegNumBase,
- //! @brief Count of YMM registers.
- //!
- //! 8 in 32-bit mode and 16 in 64-bit mode.
- kX86RegNumYmm = kX86RegNumBase,
-
- //! @brief Count of segment registers, including no segment (AsmJit specific).
- //!
- //! @note There are 6 segment registers, but AsmJit uses 0 as no segment, and
- //! 1...6 as segment registers, this means that there are 7 segment registers
- //! in AsmJit API, but only 6 can be used through @c Assembler or @c Compiler
- //! API.
- kX86RegNumSeg = 7
-};
-
-//! @brief X86 register types.
-enum kX86RegType
-{
- // First byte contains register type (mask 0xFF00), Second byte contains
- // register index code.
-
- // --------------------------------------------------------------------------
- // [GP Register Types]
- // --------------------------------------------------------------------------
-
- //! @brief 8-bit general purpose register type (LO).
- kX86RegTypeGpbLo = 0x0100,
- //! @brief 8-bit general purpose register type (HI, only AH, BH, CH, DH).
- kX86RegTypeGpbHi = 0x0200,
- //! @brief 16-bit general purpose register type.
- kX86RegTypeGpw = 0x1000,
- //! @brief 32-bit general purpose register type.
- kX86RegTypeGpd = 0x2000,
- //! @brief 64-bit general purpose register type.
- kX86RegTypeGpq = 0x3000,
-
- //! @var kX86RegTypeGpz
- //! @brief 32-bit or 64-bit general purpose register type.
-#ifdef ASMJIT_X86
- kX86RegTypeGpz = kX86RegTypeGpd,
-#else
- kX86RegTypeGpz = kX86RegTypeGpq,
-#endif
-
- //! @brief X87 (FPU) register type.
- kX86RegTypeX87 = 0x5000,
- //! @brief 64-bit MM register type.
- kX86RegTypeMm = 0x6000,
-
- //! @brief 128-bit XMM register type.
- kX86RegTypeXmm = 0x7000,
- //! @brief 256-bit YMM register type.
- kX86RegTypeYmm = 0x8000,
-
- //! @brief 16-bit segment register type.
- kX86RegTypeSeg = 0xD000
-};
-
-// ============================================================================
-// [AsmJit::kX86RegIndex]
-// ============================================================================
-
-//! @brief X86 register indices.
-//!
-//! These codes are real, don't miss with @c REG enum! and don't use these
-//! values if you are not writing AsmJit code.
-enum kX86RegIndex
-{
- //! @brief ID for AX/EAX/RAX registers.
- kX86RegIndexEax = 0,
- //! @brief ID for CX/ECX/RCX registers.
- kX86RegIndexEcx = 1,
- //! @brief ID for DX/EDX/RDX registers.
- kX86RegIndexEdx = 2,
- //! @brief ID for BX/EBX/RBX registers.
- kX86RegIndexEbx = 3,
- //! @brief ID for SP/ESP/RSP registers.
- kX86RegIndexEsp = 4,
- //! @brief ID for BP/EBP/RBP registers.
- kX86RegIndexEbp = 5,
- //! @brief ID for SI/ESI/RSI registers.
- kX86RegIndexEsi = 6,
- //! @brief ID for DI/EDI/RDI registers.
- kX86RegIndexEdi = 7,
-
- //! @brief ID for AX/EAX/RAX registers.
- kX86RegIndexRax = 0,
- //! @brief ID for CX/ECX/RCX registers.
- kX86RegIndexRcx = 1,
- //! @brief ID for DX/EDX/RDX registers.
- kX86RegIndexRdx = 2,
- //! @brief ID for BX/EBX/RBX registers.
- kX86RegIndexRbx = 3,
- //! @brief ID for SP/ESP/RSP registers.
- kX86RegIndexRsp = 4,
- //! @brief ID for BP/EBP/RBP registers.
- kX86RegIndexRbp = 5,
- //! @brief ID for SI/ESI/RSI registers.
- kX86RegIndexRsi = 6,
- //! @brief ID for DI/EDI/RDI registers.
- kX86RegIndexRdi = 7,
-
- //! @brief ID for r8 register (additional register introduced by 64-bit architecture).
- kX86RegIndexR8 = 8,
- //! @brief ID for R9 register (additional register introduced by 64-bit architecture).
- kX86RegIndexR9 = 9,
- //! @brief ID for R10 register (additional register introduced by 64-bit architecture).
- kX86RegIndexR10 = 10,
- //! @brief ID for R11 register (additional register introduced by 64-bit architecture).
- kX86RegIndexR11 = 11,
- //! @brief ID for R12 register (additional register introduced by 64-bit architecture).
- kX86RegIndexR12 = 12,
- //! @brief ID for R13 register (additional register introduced by 64-bit architecture).
- kX86RegIndexR13 = 13,
- //! @brief ID for R14 register (additional register introduced by 64-bit architecture).
- kX86RegIndexR14 = 14,
- //! @brief ID for R15 register (additional register introduced by 64-bit architecture).
- kX86RegIndexR15 = 15,
-
- //! @brief ID for mm0 register.
- kX86RegIndexMm0 = 0,
- //! @brief ID for mm1 register.
- kX86RegIndexMm1 = 1,
- //! @brief ID for mm2 register.
- kX86RegIndexMm2 = 2,
- //! @brief ID for mm3 register.
- kX86RegIndexMm3 = 3,
- //! @brief ID for mm4 register.
- kX86RegIndexMm4 = 4,
- //! @brief ID for mm5 register.
- kX86RegIndexMm5 = 5,
- //! @brief ID for mm6 register.
- kX86RegIndexMm6 = 6,
- //! @brief ID for mm7 register.
- kX86RegIndexMm7 = 7,
-
- //! @brief ID for xmm0 register.
- kX86RegIndexXmm0 = 0,
- //! @brief ID for xmm1 register.
- kX86RegIndexXmm1 = 1,
- //! @brief ID for xmm2 register.
- kX86RegIndexXmm2 = 2,
- //! @brief ID for xmm3 register.
- kX86RegIndexXmm3 = 3,
- //! @brief ID for xmm4 register.
- kX86RegIndexXmm4 = 4,
- //! @brief ID for xmm5 register.
- kX86RegIndexXmm5 = 5,
- //! @brief ID for xmm6 register.
- kX86RegIndexXmm6 = 6,
- //! @brief ID for xmm7 register.
- kX86RegIndexXmm7 = 7,
-
- //! @brief ID for xmm8 register (additional register introduced by 64-bit architecture).
- kX86RegIndexXmm8 = 8,
- //! @brief ID for xmm9 register (additional register introduced by 64-bit architecture).
- kX86RegIndexXmm9 = 9,
- //! @brief ID for xmm10 register (additional register introduced by 64-bit architecture).
- kX86RegIndexXmm10 = 10,
- //! @brief ID for xmm11 register (additional register introduced by 64-bit architecture).
- kX86RegIndexXmm11 = 11,
- //! @brief ID for xmm12 register (additional register introduced by 64-bit architecture).
- kX86RegIndexXmm12 = 12,
- //! @brief ID for xmm13 register (additional register introduced by 64-bit architecture).
- kX86RegIndexXmm13 = 13,
- //! @brief ID for xmm14 register (additional register introduced by 64-bit architecture).
- kX86RegIndexXmm14 = 14,
- //! @brief ID for xmm15 register (additional register introduced by 64-bit architecture).
- kX86RegIndexXmm15 = 15,
-
- //! @brief ID for ES segment register.
- kX86RegIndexEs = 0,
- //! @brief ID for CS segment register.
- kX86RegIndexCs = 1,
- //! @brief ID for SS segment register.
- kX86RegIndexSs = 2,
- //! @brief ID for DS segment register.
- kX86RegIndexDs = 3,
- //! @brief ID for FS segment register.
- kX86RegIndexFs = 4,
- //! @brief ID for GS segment register.
- kX86RegIndexGs = 5
-};
-
-// ============================================================================
-// [AsmJit::kX86RegCode]
-// ============================================================================
-
-//! @brief X86 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 kX86RegCode
-{
- // --------------------------------------------------------------------------
- // [8-bit Registers]
- // --------------------------------------------------------------------------
-
- kX86RegAl = kX86RegTypeGpbLo,
- kX86RegCl,
- kX86RegDl,
- kX86RegBl,
-#if defined(ASMJIT_X64)
- kX86RegSpl,
- kX86RegBpl,
- kX86RegSil,
- kX86RegDil,
-#endif // ASMJIT_X64
-
-#if defined(ASMJIT_X64)
- kX86RegR8b,
- kX86RegR9b,
- kX86RegR10b,
- kX86RegR11b,
- kX86RegR12b,
- kX86RegR13b,
- kX86RegR14b,
- kX86RegR15b,
-#endif // ASMJIT_X64
-
- kX86RegAh = kX86RegTypeGpbHi,
- kX86RegCh,
- kX86RegDh,
- kX86RegBh,
-
- // --------------------------------------------------------------------------
- // [16-bit Registers]
- // --------------------------------------------------------------------------
-
- kX86RegAx = kX86RegTypeGpw,
- kX86RegCx,
- kX86RegDx,
- kX86RegBx,
- kX86RegSp,
- kX86RegBp,
- kX86RegSi,
- kX86RegDi,
-#if defined(ASMJIT_X64)
- kX86RegR8w,
- kX86RegR9w,
- kX86RegR10w,
- kX86RegR11w,
- kX86RegR12w,
- kX86RegR13w,
- kX86RegR14w,
- kX86RegR15w,
-#endif // ASMJIT_X64
-
- // --------------------------------------------------------------------------
- // [32-bit Registers]
- // --------------------------------------------------------------------------
-
- kX86RegEax = kX86RegTypeGpd,
- kX86RegEcx,
- kX86RegEdx,
- kX86RegEbx,
- kX86RegEsp,
- kX86RegEbp,
- kX86RegEsi,
- kX86RegEdi,
-#if defined(ASMJIT_X64)
- kX86RegR8d,
- kX86RegR9d,
- kX86RegR10d,
- kX86RegR11d,
- kX86RegR12d,
- kX86RegR13d,
- kX86RegR14d,
- kX86RegR15d,
-#endif // ASMJIT_X64
-
- // --------------------------------------------------------------------------
- // [64-bit Registers]
- // --------------------------------------------------------------------------
-
-#if defined(ASMJIT_X64)
- kX86RegRax = kX86RegTypeGpq,
- kX86RegRcx,
- kX86RegRdx,
- kX86RegRbx,
- kX86RegRsp,
- kX86RegRbp,
- kX86RegRsi,
- kX86RegRdi,
- kX86RegR8,
- kX86RegR9,
- kX86RegR10,
- kX86RegR11,
- kX86RegR12,
- kX86RegR13,
- kX86RegR14,
- kX86RegR15,
-#endif // ASMJIT_X64
-
- // --------------------------------------------------------------------------
- // [MM Registers]
- // --------------------------------------------------------------------------
-
- kX86RegMm0 = kX86RegTypeMm,
- kX86RegMm1,
- kX86RegMm2,
- kX86RegMm3,
- kX86RegMm4,
- kX86RegMm5,
- kX86RegMm6,
- kX86RegMm7,
-
- // --------------------------------------------------------------------------
- // [XMM Registers]
- // --------------------------------------------------------------------------
-
- kX86RegXmm0 = kX86RegTypeXmm,
- kX86RegXmm1,
- kX86RegXmm2,
- kX86RegXmm3,
- kX86RegXmm4,
- kX86RegXmm5,
- kX86RegXmm6,
- kX86RegXmm7,
-#if defined(ASMJIT_X64)
- kX86RegXmm8,
- kX86RegXmm9,
- kX86RegXmm10,
- kX86RegXmm11,
- kX86RegXmm12,
- kX86RegXmm13,
- kX86RegXmm14,
- kX86RegXmm15,
-#endif // ASMJIT_X64
-
- // --------------------------------------------------------------------------
- // [Native registers (depends on 32-bit or 64-bit mode)]
- // --------------------------------------------------------------------------
-
- kX86RegZax = kX86RegTypeGpz,
- kX86RegZcx,
- kX86RegZdx,
- kX86RegZbx,
- kX86RegZsp,
- kX86RegZbp,
- kX86RegZsi,
- kX86RegZdi,
-
- // --------------------------------------------------------------------------
- // [Segment registers]
- // --------------------------------------------------------------------------
-
- //! @brief ES segment register.
- kX86RegEs = kX86RegTypeSeg,
- //! @brief CS segment register.
- kX86RegCs,
- //! @brief SS segment register.
- kX86RegSs,
- //! @brief DS segment register.
- kX86RegDs,
- //! @brief FS segment register.
- kX86RegFs,
- //! @brief GS segment register.
- kX86RegGs
-};
-
-// ============================================================================
-// [AsmJit::kX86Cond]
-// ============================================================================
-
-//! @brief X86 Condition codes.
-enum kX86Cond
-{
- // Condition codes from processor manuals.
- kX86CondA = 0x07,
- kX86CondAE = 0x03,
- kX86CondB = 0x02,
- kX86CondBE = 0x06,
- kX86CondC = 0x02,
- kX86CondE = 0x04,
- kX86CondG = 0x0F,
- kX86CondGE = 0x0D,
- kX86CondL = 0x0C,
- kX86CondLE = 0x0E,
- kX86CondNA = 0x06,
- kX86CondNAE = 0x02,
- kX86CondNB = 0x03,
- kX86CondNBE = 0x07,
- kX86CondNC = 0x03,
- kX86CondNE = 0x05,
- kX86CondNG = 0x0E,
- kX86CondNGE = 0x0C,
- kX86CondNL = 0x0D,
- kX86CondNLE = 0x0F,
- kX86CondNO = 0x01,
- kX86CondNP = 0x0B,
- kX86CondNS = 0x09,
- kX86CondNZ = 0x05,
- kX86CondO = 0x00,
- kX86CondP = 0x0A,
- kX86CondPE = 0x0A,
- kX86CondPO = 0x0B,
- kX86CondS = 0x08,
- kX86CondZ = 0x04,
-
- // Simplified condition codes.
- kX86CondOverflow = 0x00,
- kX86CondNotOverflow = 0x01,
- kX86CondBelow = 0x02,
- kX86CondAboveEqual = 0x03,
- kX86CondEqual = 0x04,
- kX86CondNotEqual = 0x05,
- kX86CondBelowEqual = 0x06,
- kX86CondAbove = 0x07,
- kX86CondSign = 0x08,
- kX86CondNotSign = 0x09,
- kX86CondParityEven = 0x0A,
- kX86CondParityOdd = 0x0B,
- kX86CondLess = 0x0C,
- kX86CondGreaterEqual = 0x0D,
- kX86CondLessEqual = 0x0E,
- kX86CondGreater = 0x0F,
-
- // Aliases.
- kX86CondZero = 0x04,
- kX86CondNotZero = 0x05,
- kX86CondNegative = 0x08,
- kX86CondPositive = 0x09,
-
- // X87 floating point only.
- kX86CondFpuUnordered = 0x10,
- kX86CondFpuNotUnordered = 0x11,
-
- //! @brief No condition code.
- kX86CondNone = 0x12
-};
-
-// ============================================================================
-// [AsmJit::kX86CondPrefix]
-// ============================================================================
-
-//! @brief X86 condition hint prefix code, see @ref kCondHint.
-enum kX86CondPrefix
-{
- //! @brief Condition is likely to be taken.
- kX86CondPrefixLikely = 0x3E,
- //! @brief Condition is unlikely to be taken.
- kX86CondPrefixUnlikely = 0x2E
-};
-
-// ============================================================================
-// [AsmJit::kX86PrefetchHint]
-// ============================================================================
-
-//! @brief X86 Prefetch hints.
-enum kX86PrefetchHint
-{
- //! @brief Prefetch using NT hint.
- kX86PrefetchNta = 0,
- //! @brief Prefetch to L0 cache.
- kX86PrefetchT0 = 1,
- //! @brief Prefetch to L1 cache.
- kX86PrefetchT1 = 2,
- //! @brief Prefetch to L2 cache.
- kX86PrefetchT2 = 3
-};
-
-// ============================================================================
-// [AsmJit::kX86FPSW]
-// ============================================================================
-
-//! @brief X86 FPU status-word.
-enum kX86FPSW
-{
- kX86FPSW_Invalid = 0x0001,
- kX86FPSW_Denormalized = 0x0002,
- kX86FPSW_DivByZero = 0x0004,
- kX86FPSW_Overflow = 0x0008,
- kX86FPSW_Underflow = 0x0010,
- kX86FPSW_Precision = 0x0020,
- kX86FPSW_StackFault = 0x0040,
- kX86FPSW_Interrupt = 0x0080,
- kX86FPSW_C0 = 0x0100,
- kX86FPSW_C1 = 0x0200,
- kX86FPSW_C2 = 0x0400,
- kX86FPSW_Top = 0x3800,
- kX86FPSW_C3 = 0x4000,
- kX86FPSW_Busy = 0x8000
-};
-
-// ============================================================================
-// [AsmJit::kX86FPCW]
-// ============================================================================
-
-//! @brief X86 FPU control-word.
-enum kX86FPCW
-{
- // --------------------------------------------------------------------------
- // [Exception-Mask]
- // --------------------------------------------------------------------------
-
- kX86FPCW_EM_Mask = 0x003F, // Bits 0-5.
-
- kX86FPCW_EM_Invalid = 0x0001,
- kX86FPCW_EM_Denormal = 0x0002,
- kX86FPCW_EM_DivByZero = 0x0004,
- kX86FPCW_EM_Overflow = 0x0008,
- kX86FPCW_EM_Underflow = 0x0010,
- kX86FPCW_EM_Inexact = 0x0020,
-
- // --------------------------------------------------------------------------
- // [Precision-Control]
- // --------------------------------------------------------------------------
-
- kX86FPCW_PC_Mask = 0x0300, // Bits 8-9.
-
- kX86FPCW_PC_Float = 0x0000,
- kX86FPCW_PC_Reserved = 0x0100,
- kX86FPCW_PC_Double = 0x0200,
- kX86FPCW_PC_Extended = 0x0300,
-
- // --------------------------------------------------------------------------
- // [Rounding-Control]
- // --------------------------------------------------------------------------
-
- kX86FPCW_RC_Mask = 0x0C00, // Bits 10-11.
-
- kX86FPCW_RC_Nearest = 0x0000,
- kX86FPCW_RC_Down = 0x0400,
- kX86FPCW_RC_Up = 0x0800,
- kX86FPCW_RC_Truncate = 0x0C00,
-
- // --------------------------------------------------------------------------
- // [Infinity-Control]
- // --------------------------------------------------------------------------
-
- kX86FPCW_IC_Mask = 0x1000, // Bit 12.
-
- kX86FPCW_IC_Projective = 0x0000,
- kX86FPCW_IC_Affine = 0x1000
-};
-
-// ============================================================================
-// [AsmJit::kX86EmitOption]
-// ============================================================================
-
-//! @brief Emit options, mainly for internal purposes.
-enum kX86EmitOption
-{
- //! @brief Force REX prefix to be emitted.
- //!
- //! This option should be used carefully, because there are unencodable
- //! combinations. If you want to access ah, bh, ch or dh registers then you
- //! can't emit REX prefix and it will cause an illegal instruction error.
- kX86EmitOptionRex = 0x1,
-
- //! @brief Tell @c Assembler or @c Compiler to emit and validate lock prefix.
- //!
- //! If this option is used and instruction doesn't support LOCK prefix then
- //! invalid instruction error is generated.
- kX86EmitOptionLock = 0x2,
-
- //! @brief Emit short/near jump or conditional jump instead of far one to
- //! some bytes.
- //!
- //! @note This option could be dangerous in case that the short jump is not
- //! possible (displacement can't fit into signed 8-bit integer). AsmJit can
- //! automatically generate back short jumps, but always generates long forward
- //! jumps, because the information about the code size between the instruction
- //! and target is not known.
- kX86EmitOptionShortJump = 0x4,
-
- //! @brief Emit full immediate instead of BYTE in all cases.
- //!
- //! @note AsmJit is able to emit both forms of immediate value. In case that
- //! the instruction supports short form and immediate can fit into a signed
- //! 8-bit integer short for is preferred, but if for any reason the full form
- //! is required it can be overridden by using this option.
- kX86EmitOptionFullImmediate = 0x8
-};
-
-// ============================================================================
-// [AsmJit::kX86InstCode]
-// ============================================================================
-
-//! @brief X86 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 @ref Assembler::_emitInstruction() or
-//! @ref Compiler::_emitInstruction()
-enum kX86InstCode
-{
- kX86InstAdc = 1, // X86/X64
- kX86InstAdd, // X86/X64
- kX86InstAddPD, // SSE2
- kX86InstAddPS, // SSE
- kX86InstAddSD, // SSE2
- kX86InstAddSS, // SSE
- kX86InstAddSubPD, // SSE3
- kX86InstAddSubPS, // SSE3
- kX86InstAmdPrefetch, // 3dNow!
- kX86InstAmdPrefetchW, // 3dNow!
- kX86InstAnd, // X86/X64
- kX86InstAndnPD, // SSE2
- kX86InstAndnPS, // SSE
- kX86InstAndPD, // SSE2
- kX86InstAndPS, // SSE
- kX86InstBlendPD, // SSE4.1
- kX86InstBlendPS, // SSE4.1
- kX86InstBlendVPD, // SSE4.1
- kX86InstBlendVPS, // SSE4.1
- kX86InstBsf, // X86/X64
- kX86InstBsr, // X86/X64
- kX86InstBSwap, // X86/X64 (i486)
- kX86InstBt, // X86/X64
- kX86InstBtc, // X86/X64
- kX86InstBtr, // X86/X64
- kX86InstBts, // X86/X64
- kX86InstCall, // X86/X64
- kX86InstCbw, // X86/X64
- kX86InstCdq, // X86/X64
- kX86InstCdqe, // X64 only
- kX86InstClc, // X86/X64
- kX86InstCld, // X86/X64
- kX86InstClFlush, // SSE2
- kX86InstCmc, // X86/X64
-
- kX86InstCMov, // Begin (cmovcc) (i586)
- kX86InstCMovA=kX86InstCMov,//X86/X64 (cmovcc) (i586)
- kX86InstCMovAE, // X86/X64 (cmovcc) (i586)
- kX86InstCMovB, // X86/X64 (cmovcc) (i586)
- kX86InstCMovBE, // X86/X64 (cmovcc) (i586)
- kX86InstCMovC, // X86/X64 (cmovcc) (i586)
- kX86InstCMovE, // X86/X64 (cmovcc) (i586)
- kX86InstCMovG, // X86/X64 (cmovcc) (i586)
- kX86InstCMovGE, // X86/X64 (cmovcc) (i586)
- kX86InstCMovL, // X86/X64 (cmovcc) (i586)
- kX86InstCMovLE, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNA, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNAE, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNB, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNBE, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNC, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNE, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNG, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNGE, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNL, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNLE, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNO, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNP, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNS, // X86/X64 (cmovcc) (i586)
- kX86InstCMovNZ, // X86/X64 (cmovcc) (i586)
- kX86InstCMovO, // X86/X64 (cmovcc) (i586)
- kX86InstCMovP, // X86/X64 (cmovcc) (i586)
- kX86InstCMovPE, // X86/X64 (cmovcc) (i586)
- kX86InstCMovPO, // X86/X64 (cmovcc) (i586)
- kX86InstCMovS, // X86/X64 (cmovcc) (i586)
- kX86InstCMovZ, // X86/X64 (cmovcc) (i586)
-
- kX86InstCmp, // X86/X64
- kX86InstCmpPD, // SSE2
- kX86InstCmpPS, // SSE
- kX86InstCmpSD, // SSE2
- kX86InstCmpSS, // SSE
- kX86InstCmpXCHG, // X86/X64 (i486)
- kX86InstCmpXCHG16B, // X64 only
- kX86InstCmpXCHG8B, // X86/X64 (i586)
- kX86InstComISD, // SSE2
- kX86InstComISS, // SSE
- kX86InstCpuId, // X86/X64 (i486)
- kX86InstCqo, // X64 only
- kX86InstCrc32, // SSE4.2
- kX86InstCvtDQ2PD, // SSE2
- kX86InstCvtDQ2PS, // SSE2
- kX86InstCvtPD2DQ, // SSE2
- kX86InstCvtPD2PI, // SSE2
- kX86InstCvtPD2PS, // SSE2
- kX86InstCvtPI2PD, // SSE2
- kX86InstCvtPI2PS, // SSE
- kX86InstCvtPS2DQ, // SSE2
- kX86InstCvtPS2PD, // SSE2
- kX86InstCvtPS2PI, // SSE
- kX86InstCvtSD2SI, // SSE2
- kX86InstCvtSD2SS, // SSE2
- kX86InstCvtSI2SD, // SSE2
- kX86InstCvtSI2SS, // SSE
- kX86InstCvtSS2SD, // SSE2
- kX86InstCvtSS2SI, // SSE
- kX86InstCvttPD2DQ, // SSE2
- kX86InstCvttPD2PI, // SSE2
- kX86InstCvttPS2DQ, // SSE2
- kX86InstCvttPS2PI, // SSE
- kX86InstCvttSD2SI, // SSE2
- kX86InstCvttSS2SI, // SSE
- kX86InstCwd, // X86/X64
- kX86InstCwde, // X86/X64
- kX86InstDaa, // X86 only
- kX86InstDas, // X86 only
- kX86InstDec, // X86/X64
- kX86InstDiv, // X86/X64
- kX86InstDivPD, // SSE2
- kX86InstDivPS, // SSE
- kX86InstDivSD, // SSE2
- kX86InstDivSS, // SSE
- kX86InstDpPD, // SSE4.1
- kX86InstDpPS, // SSE4.1
- kX86InstEmms, // MMX
- kX86InstEnter, // X86/X64
- kX86InstExtractPS, // SSE4.1
- kX86InstF2XM1, // X87
- kX86InstFAbs, // X87
- kX86InstFAdd, // X87
- kX86InstFAddP, // X87
- kX86InstFBLd, // X87
- kX86InstFBStP, // X87
- kX86InstFCHS, // X87
- kX86InstFClex, // X87
- kX86InstFCMovB, // X87
- kX86InstFCMovBE, // X87
- kX86InstFCMovE, // X87
- kX86InstFCMovNB, // X87
- kX86InstFCMovNBE, // X87
- kX86InstFCMovNE, // X87
- kX86InstFCMovNU, // X87
- kX86InstFCMovU, // X87
- kX86InstFCom, // X87
- kX86InstFComI, // X87
- kX86InstFComIP, // X87
- kX86InstFComP, // X87
- kX86InstFComPP, // X87
- kX86InstFCos, // X87
- kX86InstFDecStP, // X87
- kX86InstFDiv, // X87
- kX86InstFDivP, // X87
- kX86InstFDivR, // X87
- kX86InstFDivRP, // X87
- kX86InstFEmms, // 3dNow!
- kX86InstFFree, // X87
- kX86InstFIAdd, // X87
- kX86InstFICom, // X87
- kX86InstFIComP, // X87
- kX86InstFIDiv, // X87
- kX86InstFIDivR, // X87
- kX86InstFILd, // X87
- kX86InstFIMul, // X87
- kX86InstFIncStP, // X87
- kX86InstFInit, // X87
- kX86InstFISt, // X87
- kX86InstFIStP, // X87
- kX86InstFISttP, // SSE3
- kX86InstFISub, // X87
- kX86InstFISubR, // X87
- kX86InstFLd, // X87
- kX86InstFLd1, // X87
- kX86InstFLdCw, // X87
- kX86InstFLdEnv, // X87
- kX86InstFLdL2E, // X87
- kX86InstFLdL2T, // X87
- kX86InstFLdLg2, // X87
- kX86InstFLdLn2, // X87
- kX86InstFLdPi, // X87
- kX86InstFLdZ, // X87
- kX86InstFMul, // X87
- kX86InstFMulP, // X87
- kX86InstFNClex, // X87
- kX86InstFNInit, // X87
- kX86InstFNop, // X87
- kX86InstFNSave, // X87
- kX86InstFNStCw, // X87
- kX86InstFNStEnv, // X87
- kX86InstFNStSw, // X87
- kX86InstFPAtan, // X87
- kX86InstFPRem, // X87
- kX86InstFPRem1, // X87
- kX86InstFPTan, // X87
- kX86InstFRndInt, // X87
- kX86InstFRstor, // X87
- kX86InstFSave, // X87
- kX86InstFScale, // X87
- kX86InstFSin, // X87
- kX86InstFSinCos, // X87
- kX86InstFSqrt, // X87
- kX86InstFSt, // X87
- kX86InstFStCw, // X87
- kX86InstFStEnv, // X87
- kX86InstFStP, // X87
- kX86InstFStSw, // X87
- kX86InstFSub, // X87
- kX86InstFSubP, // X87
- kX86InstFSubR, // X87
- kX86InstFSubRP, // X87
- kX86InstFTst, // X87
- kX86InstFUCom, // X87
- kX86InstFUComI, // X87
- kX86InstFUComIP, // X87
- kX86InstFUComP, // X87
- kX86InstFUComPP, // X87
- kX86InstFWait, // X87
- kX86InstFXam, // X87
- kX86InstFXch, // X87
- kX86InstFXRstor, // X87
- kX86InstFXSave, // X87
- kX86InstFXtract, // X87
- kX86InstFYL2X, // X87
- kX86InstFYL2XP1, // X87
- kX86InstHAddPD, // SSE3
- kX86InstHAddPS, // SSE3
- kX86InstHSubPD, // SSE3
- kX86InstHSubPS, // SSE3
- kX86InstIDiv, // X86/X64
- kX86InstIMul, // X86/X64
- kX86InstInc, // X86/X64
- kX86InstInt3, // X86/X64
- kX86InstJ, // Begin (jcc)
- kX86InstJA = kX86InstJ, // X86/X64 (jcc)
- kX86InstJAE, // X86/X64 (jcc)
- kX86InstJB, // X86/X64 (jcc)
- kX86InstJBE, // X86/X64 (jcc)
- kX86InstJC, // X86/X64 (jcc)
- kX86InstJE, // X86/X64 (jcc)
- kX86InstJG, // X86/X64 (jcc)
- kX86InstJGE, // X86/X64 (jcc)
- kX86InstJL, // X86/X64 (jcc)
- kX86InstJLE, // X86/X64 (jcc)
- kX86InstJNA, // X86/X64 (jcc)
- kX86InstJNAE, // X86/X64 (jcc)
- kX86InstJNB, // X86/X64 (jcc)
- kX86InstJNBE, // X86/X64 (jcc)
- kX86InstJNC, // X86/X64 (jcc)
- kX86InstJNE, // X86/X64 (jcc)
- kX86InstJNG, // X86/X64 (jcc)
- kX86InstJNGE, // X86/X64 (jcc)
- kX86InstJNL, // X86/X64 (jcc)
- kX86InstJNLE, // X86/X64 (jcc)
- kX86InstJNO, // X86/X64 (jcc)
- kX86InstJNP, // X86/X64 (jcc)
- kX86InstJNS, // X86/X64 (jcc)
- kX86InstJNZ, // X86/X64 (jcc)
- kX86InstJO, // X86/X64 (jcc)
- kX86InstJP, // X86/X64 (jcc)
- kX86InstJPE, // X86/X64 (jcc)
- kX86InstJPO, // X86/X64 (jcc)
- kX86InstJS, // X86/X64 (jcc)
- kX86InstJZ, // X86/X64 (jcc)
- kX86InstJmp, // X86/X64 (jmp)
- kX86InstLdDQU, // SSE3
- kX86InstLdMXCSR, // SSE
- kX86InstLahf, // X86/X64 (CPUID NEEDED)
- kX86InstLea, // X86/X64
- kX86InstLeave, // X86/X64
- kX86InstLFence, // SSE2
- kX86InstMaskMovDQU, // SSE2
- kX86InstMaskMovQ, // MMX-Ext
- kX86InstMaxPD, // SSE2
- kX86InstMaxPS, // SSE
- kX86InstMaxSD, // SSE2
- kX86InstMaxSS, // SSE
- kX86InstMFence, // SSE2
- kX86InstMinPD, // SSE2
- kX86InstMinPS, // SSE
- kX86InstMinSD, // SSE2
- kX86InstMinSS, // SSE
- kX86InstMonitor, // SSE3
- kX86InstMov, // X86/X64
- kX86InstMovAPD, // SSE2
- kX86InstMovAPS, // SSE
- kX86InstMovBE, // SSE3 - Intel-Atom
- kX86InstMovD, // MMX/SSE2
- kX86InstMovDDup, // SSE3
- kX86InstMovDQ2Q, // SSE2
- kX86InstMovDQA, // SSE2
- kX86InstMovDQU, // SSE2
- kX86InstMovHLPS, // SSE
- kX86InstMovHPD, // SSE2
- kX86InstMovHPS, // SSE
- kX86InstMovLHPS, // SSE
- kX86InstMovLPD, // SSE2
- kX86InstMovLPS, // SSE
- kX86InstMovMskPD, // SSE2
- kX86InstMovMskPS, // SSE2
- kX86InstMovNTDQ, // SSE2
- kX86InstMovNTDQA, // SSE4.1
- kX86InstMovNTI, // SSE2
- kX86InstMovNTPD, // SSE2
- kX86InstMovNTPS, // SSE
- kX86InstMovNTQ, // MMX-Ext
- kX86InstMovQ, // MMX/SSE/SSE2
- kX86InstMovQ2DQ, // SSE2
- kX86InstMovSD, // SSE2
- kX86InstMovSHDup, // SSE3
- kX86InstMovSLDup, // SSE3
- kX86InstMovSS, // SSE
- kX86InstMovSX, // X86/X64
- kX86InstMovSXD, // X86/X64
- kX86InstMovUPD, // SSE2
- kX86InstMovUPS, // SSE
- kX86InstMovZX, // X86/X64
- kX86InstMovPtr, // X86/X64
- kX86InstMPSADBW, // SSE4.1
- kX86InstMul, // X86/X64
- kX86InstMulPD, // SSE2
- kX86InstMulPS, // SSE
- kX86InstMulSD, // SSE2
- kX86InstMulSS, // SSE
- kX86InstMWait, // SSE3
- kX86InstNeg, // X86/X64
- kX86InstNop, // X86/X64
- kX86InstNot, // X86/X64
- kX86InstOr, // X86/X64
- kX86InstOrPD, // SSE2
- kX86InstOrPS, // SSE
- kX86InstPAbsB, // SSSE3
- kX86InstPAbsD, // SSSE3
- kX86InstPAbsW, // SSSE3
- kX86InstPackSSDW, // MMX/SSE2
- kX86InstPackSSWB, // MMX/SSE2
- kX86InstPackUSDW, // SSE4.1
- kX86InstPackUSWB, // MMX/SSE2
- kX86InstPAddB, // MMX/SSE2
- kX86InstPAddD, // MMX/SSE2
- kX86InstPAddQ, // SSE2
- kX86InstPAddSB, // MMX/SSE2
- kX86InstPAddSW, // MMX/SSE2
- kX86InstPAddUSB, // MMX/SSE2
- kX86InstPAddUSW, // MMX/SSE2
- kX86InstPAddW, // MMX/SSE2
- kX86InstPAlignR, // SSSE3
- kX86InstPAnd, // MMX/SSE2
- kX86InstPAndN, // MMX/SSE2
- kX86InstPause, // SSE2.
- kX86InstPAvgB, // MMX-Ext
- kX86InstPAvgW, // MMX-Ext
- kX86InstPBlendVB, // SSE4.1
- kX86InstPBlendW, // SSE4.1
- kX86InstPCmpEqB, // MMX/SSE2
- kX86InstPCmpEqD, // MMX/SSE2
- kX86InstPCmpEqQ, // SSE4.1
- kX86InstPCmpEqW, // MMX/SSE2
- kX86InstPCmpEStrI, // SSE4.2
- kX86InstPCmpEStrM, // SSE4.2
- kX86InstPCmpGtB, // MMX/SSE2
- kX86InstPCmpGtD, // MMX/SSE2
- kX86InstPCmpGtQ, // SSE4.2
- kX86InstPCmpGtW, // MMX/SSE2
- kX86InstPCmpIStrI, // SSE4.2
- kX86InstPCmpIStrM, // SSE4.2
- kX86InstPExtrB, // SSE4.1
- kX86InstPExtrD, // SSE4.1
- kX86InstPExtrQ, // SSE4.1
- kX86InstPExtrW, // MMX-Ext/SSE2
- kX86InstPF2ID, // 3dNow!
- kX86InstPF2IW, // Enhanced 3dNow!
- kX86InstPFAcc, // 3dNow!
- kX86InstPFAdd, // 3dNow!
- kX86InstPFCmpEQ, // 3dNow!
- kX86InstPFCmpGE, // 3dNow!
- kX86InstPFCmpGT, // 3dNow!
- kX86InstPFMax, // 3dNow!
- kX86InstPFMin, // 3dNow!
- kX86InstPFMul, // 3dNow!
- kX86InstPFNAcc, // Enhanced 3dNow!
- kX86InstPFPNAcc, // Enhanced 3dNow!
- kX86InstPFRcp, // 3dNow!
- kX86InstPFRcpIt1, // 3dNow!
- kX86InstPFRcpIt2, // 3dNow!
- kX86InstPFRSqIt1, // 3dNow!
- kX86InstPFRSqrt, // 3dNow!
- kX86InstPFSub, // 3dNow!
- kX86InstPFSubR, // 3dNow!
- kX86InstPHAddD, // SSSE3
- kX86InstPHAddSW, // SSSE3
- kX86InstPHAddW, // SSSE3
- kX86InstPHMinPOSUW, // SSE4.1
- kX86InstPHSubD, // SSSE3
- kX86InstPHSubSW, // SSSE3
- kX86InstPHSubW, // SSSE3
- kX86InstPI2FD, // 3dNow!
- kX86InstPI2FW, // Enhanced 3dNow!
- kX86InstPInsRB, // SSE4.1
- kX86InstPInsRD, // SSE4.1
- kX86InstPInsRQ, // SSE4.1
- kX86InstPInsRW, // MMX-Ext
- kX86InstPMAddUBSW, // SSSE3
- kX86InstPMAddWD, // MMX/SSE2
- kX86InstPMaxSB, // SSE4.1
- kX86InstPMaxSD, // SSE4.1
- kX86InstPMaxSW, // MMX-Ext
- kX86InstPMaxUB, // MMX-Ext
- kX86InstPMaxUD, // SSE4.1
- kX86InstPMaxUW, // SSE4.1
- kX86InstPMinSB, // SSE4.1
- kX86InstPMinSD, // SSE4.1
- kX86InstPMinSW, // MMX-Ext
- kX86InstPMinUB, // MMX-Ext
- kX86InstPMinUD, // SSE4.1
- kX86InstPMinUW, // SSE4.1
- kX86InstPMovMskB, // MMX-Ext
- kX86InstPMovSXBD, // SSE4.1
- kX86InstPMovSXBQ, // SSE4.1
- kX86InstPMovSXBW, // SSE4.1
- kX86InstPMovSXDQ, // SSE4.1
- kX86InstPMovSXWD, // SSE4.1
- kX86InstPMovSXWQ, // SSE4.1
- kX86InstPMovZXBD, // SSE4.1
- kX86InstPMovZXBQ, // SSE4.1
- kX86InstPMovZXBW, // SSE4.1
- kX86InstPMovZXDQ, // SSE4.1
- kX86InstPMovZXWD, // SSE4.1
- kX86InstPMovZXWQ, // SSE4.1
- kX86InstPMulDQ, // SSE4.1
- kX86InstPMulHRSW, // SSSE3
- kX86InstPMulHUW, // MMX-Ext
- kX86InstPMulHW, // MMX/SSE2
- kX86InstPMulLD, // SSE4.1
- kX86InstPMulLW, // MMX/SSE2
- kX86InstPMulUDQ, // SSE2
- kX86InstPop, // X86/X64
- kX86InstPopAD, // X86 only
- kX86InstPopCnt, // SSE4.2
- kX86InstPopFD, // X86 only
- kX86InstPopFQ, // X64 only
- kX86InstPOr, // MMX/SSE2
- kX86InstPrefetch, // MMX-Ext
- kX86InstPSADBW, // MMX-Ext
- kX86InstPShufB, // SSSE3
- kX86InstPShufD, // SSE2
- kX86InstPShufW, // MMX-Ext
- kX86InstPShufHW, // SSE2
- kX86InstPShufLW, // SSE2
- kX86InstPSignB, // SSSE3
- kX86InstPSignD, // SSSE3
- kX86InstPSignW, // SSSE3
- kX86InstPSllD, // MMX/SSE2
- kX86InstPSllDQ, // SSE2
- kX86InstPSllQ, // MMX/SSE2
- kX86InstPSllW, // MMX/SSE2
- kX86InstPSraD, // MMX/SSE2
- kX86InstPSraW, // MMX/SSE2
- kX86InstPSrlD, // MMX/SSE2
- kX86InstPSrlDQ, // SSE2
- kX86InstPSrlQ, // MMX/SSE2
- kX86InstPSrlW, // MMX/SSE2
- kX86InstPSubB, // MMX/SSE2
- kX86InstPSubD, // MMX/SSE2
- kX86InstPSubQ, // SSE2
- kX86InstPSubSB, // MMX/SSE2
- kX86InstPSubSW, // MMX/SSE2
- kX86InstPSubUSB, // MMX/SSE2
- kX86InstPSubUSW, // MMX/SSE2
- kX86InstPSubW, // MMX/SSE2
- kX86InstPSwapD, // Enhanced 3dNow!
- kX86InstPTest, // SSE4.1
- kX86InstPunpckHBW, // MMX/SSE2
- kX86InstPunpckHDQ, // MMX/SSE2
- kX86InstPunpckHQDQ, // SSE2
- kX86InstPunpckHWD, // MMX/SSE2
- kX86InstPunpckLBW, // MMX/SSE2
- kX86InstPunpckLDQ, // MMX/SSE2
- kX86InstPunpckLQDQ, // SSE2
- kX86InstPunpckLWD, // MMX/SSE2
- kX86InstPush, // X86/X64
- kX86InstPushAD, // X86 only
- kX86InstPushFD, // X86 only
- kX86InstPushFQ, // X64 only
- kX86InstPXor, // MMX/SSE2
- kX86InstRcl, // X86/X64
- kX86InstRcpPS, // SSE
- kX86InstRcpSS, // SSE
- kX86InstRcr, // X86/X64
- kX86InstRdtsc, // X86/X64
- kX86InstRdtscP, // X86/X64
- kX86InstRepLodSB, // X86/X64 (REP)
- kX86InstRepLodSD, // X86/X64 (REP)
- kX86InstRepLodSQ, // X64 only (REP)
- kX86InstRepLodSW, // X86/X64 (REP)
- kX86InstRepMovSB, // X86/X64 (REP)
- kX86InstRepMovSD, // X86/X64 (REP)
- kX86InstRepMovSQ, // X64 only (REP)
- kX86InstRepMovSW, // X86/X64 (REP)
- kX86InstRepStoSB, // X86/X64 (REP)
- kX86InstRepStoSD, // X86/X64 (REP)
- kX86InstRepStoSQ, // X64 only (REP)
- kX86InstRepStoSW, // X86/X64 (REP)
- kX86InstRepECmpSB, // X86/X64 (REP)
- kX86InstRepECmpSD, // X86/X64 (REP)
- kX86InstRepECmpSQ, // X64 only (REP)
- kX86InstRepECmpSW, // X86/X64 (REP)
- kX86InstRepEScaSB, // X86/X64 (REP)
- kX86InstRepEScaSD, // X86/X64 (REP)
- kX86InstRepEScaSQ, // X64 only (REP)
- kX86InstRepEScaSW, // X86/X64 (REP)
- kX86InstRepNECmpSB, // X86/X64 (REP)
- kX86InstRepNECmpSD, // X86/X64 (REP)
- kX86InstRepNECmpSQ, // X64 only (REP)
- kX86InstRepNECmpSW, // X86/X64 (REP)
- kX86InstRepNEScaSB, // X86/X64 (REP)
- kX86InstRepNEScaSD, // X86/X64 (REP)
- kX86InstRepNEScaSQ, // X64 only (REP)
- kX86InstRepNEScaSW, // X86/X64 (REP)
- kX86InstRet, // X86/X64
- kX86InstRol, // X86/X64
- kX86InstRor, // X86/X64
- kX86InstRoundPD, // SSE4.1
- kX86InstRoundPS, // SSE4.1
- kX86InstRoundSD, // SSE4.1
- kX86InstRoundSS, // SSE4.1
- kX86InstRSqrtPS, // SSE
- kX86InstRSqrtSS, // SSE
- kX86InstSahf, // X86/X64 (CPUID NEEDED)
- kX86InstSal, // X86/X64
- kX86InstSar, // X86/X64
- kX86InstSbb, // X86/X64
- kX86InstSet, // Begin (setcc)
- kX86InstSetA=kX86InstSet,// X86/X64 (setcc)
- kX86InstSetAE, // X86/X64 (setcc)
- kX86InstSetB, // X86/X64 (setcc)
- kX86InstSetBE, // X86/X64 (setcc)
- kX86InstSetC, // X86/X64 (setcc)
- kX86InstSetE, // X86/X64 (setcc)
- kX86InstSetG, // X86/X64 (setcc)
- kX86InstSetGE, // X86/X64 (setcc)
- kX86InstSetL, // X86/X64 (setcc)
- kX86InstSetLE, // X86/X64 (setcc)
- kX86InstSetNA, // X86/X64 (setcc)
- kX86InstSetNAE, // X86/X64 (setcc)
- kX86InstSetNB, // X86/X64 (setcc)
- kX86InstSetNBE, // X86/X64 (setcc)
- kX86InstSetNC, // X86/X64 (setcc)
- kX86InstSetNE, // X86/X64 (setcc)
- kX86InstSetNG, // X86/X64 (setcc)
- kX86InstSetNGE, // X86/X64 (setcc)
- kX86InstSetNL, // X86/X64 (setcc)
- kX86InstSetNLE, // X86/X64 (setcc)
- kX86InstSetNO, // X86/X64 (setcc)
- kX86InstSetNP, // X86/X64 (setcc)
- kX86InstSetNS, // X86/X64 (setcc)
- kX86InstSetNZ, // X86/X64 (setcc)
- kX86InstSetO, // X86/X64 (setcc)
- kX86InstSetP, // X86/X64 (setcc)
- kX86InstSetPE, // X86/X64 (setcc)
- kX86InstSetPO, // X86/X64 (setcc)
- kX86InstSetS, // X86/X64 (setcc)
- kX86InstSetZ, // X86/X64 (setcc)
- kX86InstSFence, // MMX-Ext/SSE
- kX86InstShl, // X86/X64
- kX86InstShld, // X86/X64
- kX86InstShr, // X86/X64
- kX86InstShrd, // X86/X64
- kX86InstShufPD, // SSE2
- kX86InstShufPS, // SSE
- kX86InstSqrtPD, // SSE2
- kX86InstSqrtPS, // SSE
- kX86InstSqrtSD, // SSE2
- kX86InstSqrtSS, // SSE
- kX86InstStc, // X86/X64
- kX86InstStd, // X86/X64
- kX86InstStMXCSR, // SSE
- kX86InstSub, // X86/X64
- kX86InstSubPD, // SSE2
- kX86InstSubPS, // SSE
- kX86InstSubSD, // SSE2
- kX86InstSubSS, // SSE
- kX86InstTest, // X86/X64
- kX86InstUComISD, // SSE2
- kX86InstUComISS, // SSE
- kX86InstUd2, // X86/X64
- kX86InstUnpckHPD, // SSE2
- kX86InstUnpckHPS, // SSE
- kX86InstUnpckLPD, // SSE2
- kX86InstUnpckLPS, // SSE
- kX86InstXadd, // X86/X64 (i486)
- kX86InstXchg, // X86/X64 (i386)
- kX86InstXor, // X86/X64
- kX86InstXorPD, // SSE2
- kX86InstXorPS, // SSE
-
- _kX86InstCount,
-
- _kX86InstJBegin = kX86InstJ,
- _kX86InstJEnd = kX86InstJmp
-};
-
-// ============================================================================
-// [AsmJit::kX86InstGroup]
-// ============================================================================
-
-//! @brief X86 instruction groups.
-//!
-//! This should be only used by assembler, because it's @c AsmJit::Assembler
-//! specific grouping. Each group represents one 'case' in the Assembler's
-//! main emit method.
-enum kX86InstGroup
-{
- // Group categories.
- kX86InstGroupNone,
- kX86InstGroupEmit,
-
- kX86InstGroupArith,
- kX86InstGroupBSwap,
- kX86InstGroupBTest,
- kX86InstGroupCall,
- kX86InstGroupCrc32,
- kX86InstGroupEnter,
- kX86InstGroupIMul,
- kX86InstGroupIncDec,
- kX86InstGroupJcc,
- kX86InstGroupJmp,
- kX86InstGroupLea,
- kX86InstGroupMem,
- kX86InstGroupMov,
- kX86InstGroupMovPtr,
- kX86InstGroupMovSxMovZx,
- kX86InstGroupMovSxD,
- kX86InstGroupPush,
- kX86InstGroupPop,
- kX86InstGroupRegRm,
- kX86InstGroupRm,
- kX86InstGroupRmByte,
- kX86InstGroupRmReg,
- kX86InstGroupRep,
- kX86InstGroupRet,
- kX86InstGroupRot,
- kX86InstGroupShldShrd,
- kX86InstGroupTest,
- kX86InstGroupXchg,
-
- // Group for x87 FP instructions in format mem or st(i), st(i) (fadd, fsub, fdiv, ...)
- kX86InstGroupX87StM,
- // Group for x87 FP instructions in format st(i), st(i)
- kX86InstGroupX87StI,
- // Group for fld/fst/fstp instruction, internally uses @ref kX86InstGroupX87StM group.
- kX86InstGroupX87FldFst,
- // Group for x87 FP instructions that uses Word, DWord, QWord or TWord memory pointer.
- kX86InstGroupX87Mem,
- // Group for x87 FSTSW/FNSTSW instructions
- kX86InstGroupX87Status,
-
- // Group for movbe instruction
- kX86InstGroupMovBE,
-
- // Group for MMX/SSE instructions in format (X)MM|Reg|Mem <- (X)MM|Reg|Mem,
- // 0x66 prefix must be set manually in opcodes.
- // - Primary opcode is used for instructions in (X)MM <- (X)MM/Mem format,
- // - Secondary opcode is used for instructions in (X)MM/Mem <- (X)MM format.
- kX86InstGroupMmuMov,
- kX86InstGroupMmuMovD,
- kX86InstGroupMmuMovQ,
-
- // Group for pextrd, pextrq and pextrw instructions (it's special instruction
- // not similar to others)
- kX86InstGroupMmuExtract,
- // Group for prefetch instruction
- kX86InstGroupMmuPrefetch,
-
- // Group for MMX/SSE instructions in format (X)MM|Reg <- (X)MM|Reg|Mem|Imm,
- // 0x66 prefix is added for MMX instructions that used by SSE2 registers.
- // - Primary opcode is used for instructions in (X)MM|Reg <- (X)MM|Reg|Mem format,
- // - Secondary opcode is iused for instructions in (X)MM|Reg <- Imm format.
- kX86InstGroupMmuRmI,
- kX86InstGroupMmuRmImm8,
- // Group for 3dNow instructions
- kX86InstGroupMmuRm3dNow
-};
-
-// ============================================================================
-// [AsmJit::kX86InstFlags]
-// ============================================================================
-
-//! @brief X86 instruction type flags.
-enum kX86InstFlags
-{
- //! @brief No flags.
- kX86InstFlagNone = 0x00,
-
- //! @brief Instruction is jump, conditional jump, call or ret.
- kX86InstFlagJump = 0x01,
-
- //! @brief Instruction will overwrite first operand - o[0].
- kX86InstFlagMov = 0x02,
-
- //! @brief Instruction is X87 FPU.
- kX86InstFlagFpu = 0x04,
-
- //! @brief Instruction can be prepended using LOCK prefix
- //! (usable for multithreaded applications).
- kX86InstFlagLockable = 0x08,
-
- //! @brief Instruction is special, this is for @c Compiler.
- kX86InstFlagSpecial = 0x10,
-
- //! @brief Instruction always performs memory access.
- //!
- //! This flag is always combined with @c kX86InstFlagSpecial and signalizes
- //! that there is an implicit address which is accessed (usually EDI/RDI or
- //! ESI/EDI).
- kX86InstFlagSpecialMem = 0x20
-};
-
-// ============================================================================
-// [AsmJit::kX86InstOp]
-// ============================================================================
-
-//! @brief X86 instruction operand flags.
-enum kX86InstOp
-{
- // X86, MM, XMM
- kX86InstOpGb = 0x0001,
- kX86InstOpGw = 0x0002,
- kX86InstOpGd = 0x0004,
- kX86InstOpGq = 0x0008,
- kX86InstOpMm = 0x0010,
- kX86InstOpXmm = 0x0020,
- kX86InstOpMem = 0x0040,
- kX86InstOpImm = 0x0080,
-
- kX86InstOpGbMem = kX86InstOpGb | kX86InstOpMem,
- kX86InstOpGwMem = kX86InstOpGw | kX86InstOpMem,
- kX86InstOpGdMem = kX86InstOpGd | kX86InstOpMem,
- kX86InstOpGqMem = kX86InstOpGq | kX86InstOpMem,
-
- kX86InstOpGqdwb = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw | kX86InstOpGb,
- kX86InstOpGqdw = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw,
- kX86InstOpGqd = kX86InstOpGq | kX86InstOpGd,
- kX86InstOpGwb = kX86InstOpGw | kX86InstOpGb,
-
- kX86InstOpGqdwbMem = kX86InstOpGqdwb | kX86InstOpMem,
- kX86InstOpGqdwMem = kX86InstOpGqdw | kX86InstOpMem,
- kX86InstOpGqdMem = kX86InstOpGqd | kX86InstOpMem,
- kX86InstOpGwbMem = kX86InstOpGwb | kX86InstOpMem,
-
- // MMX/XMM.
- kX86InstOpMmMem = kX86InstOpMm | kX86InstOpMem,
- kX86InstOpXmmMem = kX86InstOpXmm | kX86InstOpMem,
- kX86InstOpMmXmm = kX86InstOpMm | kX86InstOpXmm,
- kX86InstOpMmXmmMem = kX86InstOpMmXmm | kX86InstOpMem,
-
- // X87.
- kX86InstOpStM2 = kX86InstOpMem | 0x0100,
- kX86InstOpStM4 = kX86InstOpMem | 0x0200,
- kX86InstOpStM8 = kX86InstOpMem | 0x0400,
- kX86InstOpStM10 = kX86InstOpMem | 0x0800,
-
- kX86InstOpStM2_4 = kX86InstOpStM2 | kX86InstOpStM4,
- kX86InstOpStM2_4_8 = kX86InstOpStM2_4 | kX86InstOpStM8,
- kX86InstOpStM4_8 = kX86InstOpStM4 | kX86InstOpStM8,
- kX86InstOpStM4_8_10 = kX86InstOpStM4_8 | kX86InstOpStM10,
-
- // Don't emit REX prefix.
- kX86InstOpNoRex = 0x2000
-};
-
-// ============================================================================
-// [AsmJit::x86InstName]
-// ============================================================================
-
-//! @internal
-//!
-//! @brief X86 instruction names.
-ASMJIT_VAR const char x86InstName[];
-
-// ============================================================================
-// [AsmJit::X86InstInfo]
-// ============================================================================
-
-//! @brief X86 instruction information.
-struct X86InstInfo
-{
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get instruction code, see @ref kX86InstCode.
- uint32_t getCode() const
- { return _code; }
-
- //! @brief Get instruction name string (null terminated string).
- const char* getName() const
- { return x86InstName + static_cast<uint32_t>(_nameIndex); }
-
- //! @brief Get instruction name index (index to @ref x86InstName array).
- uint32_t getNameIndex() const
- { return _nameIndex; }
-
- //! @brief Get instruction group, see @ref kX86InstGroup.
- uint32_t getGroup() const
- { return _group; }
-
- //! @brief Get instruction flags, see @ref kX86InstFlags.
- uint32_t getFlags() const
- { return _group; }
-
- //! @brief Get whether the instruction is conditional or standard jump.
- bool isJump() const
- { return !!(_flags & kX86InstFlagJump); }
-
- //! @brief Get whether the instruction is MOV type.
- bool isMov() const
- { return !!(_flags & kX86InstFlagMov); }
-
- //! @brief Get whether the instruction is X87 FPU type.
- bool isFpu() const
- { return !!(_flags & kX86InstFlagFpu); }
-
- //! @brief Get whether the instruction can be prefixed by LOCK prefix.
- bool isLockable() const
- { return !!(_flags & kX86InstFlagLockable); }
-
- //! @brief Get whether the instruction is special type (this is used by
- //! @c Compiler to manage additional variables or functionality).
- bool isSpecial() const
- { return !!(_flags & kX86InstFlagSpecial); }
-
- //! @brief Get whether the instruction is special type and it performs
- //! memory access.
- bool isSpecialMem() const
- { return !!(_flags & kX86InstFlagSpecialMem); }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Instruction code.
- uint16_t _code;
- //! @brief Instruction name index in x86InstName[] array.
- uint16_t _nameIndex;
- //! @brief Instruction group, used also by @c Compiler.
- uint8_t _group;
- //! @brief Instruction type flags.
- uint8_t _flags;
-
- //! @brief First and second operand flags (some groups depends on these settings, used also by @c Compiler).
- uint16_t _opFlags[2];
- //! @brief If instruction has only memory operand, this is register opcode.
- uint16_t _opCodeR;
- //! @brief Primary and secondary opcodes.
- uint32_t _opCode[2];
-};
-
-// ============================================================================
-// [AsmJit::x86InstInfo]
-// ============================================================================
-
-ASMJIT_VAR const X86InstInfo x86InstInfo[];
-
-// ============================================================================
-// [AsmJit::kX86FuncConv]
-// ============================================================================
-
-//! @brief X86 function calling conventions.
-//!
-//! 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 kX86FuncConvCDecl - Calling convention for C runtime.
-//! - @c kX86FuncConvStdCall - Calling convention for WinAPI functions.
-//! - @c kX86FuncConvMsThisCall - Calling convention for C++ members under
-//! Windows (produced by MSVC and all MSVC compatible compilers).
-//! - @c kX86FuncConvMsFastCall - Fastest calling convention that can be used
-//! by MSVC compiler.
-//! - @c kX86FuncConv_BORNANDFASTCALL - Borland fastcall convention.
-//! - @c kX86FuncConvGccFastCall - GCC fastcall convention (2 register arguments).
-//! - @c kX86FuncConvGccRegParm1 - GCC regparm(1) convention.
-//! - @c kX86FuncConvGccRegParm2 - GCC regparm(2) convention.
-//! - @c kX86FuncConvGccRegParm3 - GCC regparm(3) convention.
-//!
-//! List of calling conventions for 64-bit x86 mode (x64):
-//! - @c kX86FuncConvX64W - Windows 64-bit calling convention (WIN64 ABI).
-//! - @c kX86FuncConvX64U - Unix 64-bit calling convention (AMD64 ABI).
-//!
-//! There is also @c kX86FuncConvDefault that is defined to fit best to your
-//! compiler.
-//!
-//! These types are used together with @c AsmJit::Compiler::newFunc()
-//! method.
-enum kX86FuncConv
-{
- // --------------------------------------------------------------------------
- // [X64]
- // --------------------------------------------------------------------------
-
- //! @brief X64 calling convention for Windows platform (WIN64 ABI).
- //!
- //! 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-byte 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 information about this calling convention can be found on MSDN:
- //! http://msdn.microsoft.com/en-us/library/9b372w95.aspx .
- kX86FuncConvX64W = 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.
- kX86FuncConvX64U = 2,
-
- // --------------------------------------------------------------------------
- // [X86]
- // --------------------------------------------------------------------------
-
- //! @brief Cdecl calling convention (used by C runtime).
- //!
- //! Compatible across MSVC and GCC.
- //!
- //! Arguments direction:
- //! - Right to Left
- //!
- //! Stack is cleaned by:
- //! - Caller.
- kX86FuncConvCDecl = 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.
- kX86FuncConvStdCall = 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.
- kX86FuncConvMsThisCall = 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.
- kX86FuncConvMsFastCall = 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.
- kX86FuncConvBorlandFastCall = 7,
-
- //! @brief GCC specific fastcall convention.
- //!
- //! 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 should be compatible to
- //! @c kX86FuncConvMsFastCall.
- kX86FuncConvGccFastCall = 8,
-
- //! @brief GCC specific regparm(1) convention.
- //!
- //! The first parameter (evaluated from left-to-right) is in EAX register,
- //! all others on the stack in right-to-left order.
- //!
- //! Arguments direction:
- //! - Right to Left (except to first one integer argument in EAX)
- //!
- //! Stack is cleaned by:
- //! - Caller.
- //!
- //! Return value:
- //! - Integer types - EAX:EDX registers.
- //! - Floating points - st(0) register.
- kX86FuncConvGccRegParm1 = 9,
-
- //! @brief GCC specific regparm(2) convention.
- //!
- //! Two first parameters (evaluated from left-to-right) are in EAX:EDX
- //! registers, all others on the stack in right-to-left order.
- //!
- //! Arguments direction:
- //! - Right to Left (except to first two integer arguments in EAX:EDX)
- //!
- //! Stack is cleaned by:
- //! - Caller.
- //!
- //! Return value:
- //! - Integer types - EAX:EDX registers.
- //! - Floating points - st(0) register.
- kX86FuncConvGccRegParm2 = 10,
-
- //! @brief GCC specific fastcall with 3 parameters in registers.
- //!
- //! Three first parameters (evaluated from left-to-right) are in
- //! EAX:EDX:ECX registers, all others on the stack in right-to-left order.
- //!
- //! Arguments direction:
- //! - Right to Left (except to first three integer arguments in EAX:EDX:ECX)
- //!
- //! Stack is cleaned by:
- //! - Caller.
- //!
- //! Return value:
- //! - Integer types - EAX:EDX registers.
- //! - Floating points - st(0) register.
- kX86FuncConvGccRegParm3 = 11,
-
- // --------------------------------------------------------------------------
- // [Detect]
- // --------------------------------------------------------------------------
-
- //! @def kX86FuncConvDefault
- //! @brief Default calling convention for current platform / operating system.
-
- //! @def kX86FuncConvCompatFastCall
- //! @brief Compatibility for __fastcall calling convention.
- //!
- //! @note This enumeration is always set to a value which is compatible to
- //! current compilers __fastcall calling convention. In 64-bit mode the value
- //! is compatible to @ref kX86FuncConvX64W or @ref kX86FuncConvX64U.
-
- //! @def kX86FuncConvCompatStdCall
- //! @brief Compatibility for __stdcall calling convention.
- //!
- //! @note This enumeration is always set to a value which is compatible to
- //! current compilers __stdcall calling convention. In 64-bit mode the value
- //! is compatible to @ref kX86FuncConvX64W or @ref kX86FuncConvX64U.
-
- //! @def kX86FuncConvCompatCDecl
- //! @brief Default C calling convention based on current compiler's settings.
-
-#if defined(ASMJIT_X86)
-
- kX86FuncConvDefault = kX86FuncConvCDecl,
-
-# if defined(_MSC_VER)
- kX86FuncConvCompatFastCall = kX86FuncConvMsFastCall,
-# elif defined(__GNUC__)
- kX86FuncConvCompatFastCall = kX86FuncConvGccFastCall,
-# elif defined(__BORLANDC__)
- kX86FuncConvCompatFastCall = kX86FuncConvBorlandFastCall,
-# else
-# error "AsmJit::kX86FuncConvCompatFastCall not supported."
-# endif
-
- kX86FuncConvCompatStdCall = kX86FuncConvStdCall,
- kX86FuncConvCompatCDecl = kX86FuncConvCDecl
-
-#else
-
-# if defined(ASMJIT_WINDOWS)
- kX86FuncConvDefault = kX86FuncConvX64W,
-# else
- kX86FuncConvDefault = kX86FuncConvX64U,
-# endif
-
- kX86FuncConvCompatFastCall = kX86FuncConvDefault,
- kX86FuncConvCompatStdCall = kX86FuncConvDefault,
- kX86FuncConvCompatCDecl = kX86FuncConvDefault
-
-#endif // ASMJIT_X86
-};
-
-// ============================================================================
-// [AsmJit::kX86FuncHint]
-// ============================================================================
-
-//! @brief X86 function hints.
-enum kX86FuncHint
-{
- //! @brief Use push/pop sequences instead of mov sequences in function prolog
- //! and epilog.
- kX86FuncHintPushPop = 8,
- //! @brief Add emms instruction to the function epilog.
- kX86FuncHintEmms = 9,
- //! @brief Add sfence instruction to the function epilog.
- kX86FuncHintSFence = 10,
- //! @brief Add lfence instruction to the function epilog.
- kX86FuncHintLFence = 11,
- //! @brief Assume that stack is aligned to 16-bytes.
- kX86FuncHintAssume16ByteAlignment = 12,
- //! @brief Perform 16-byte stack alignmend by function.
- kX86FuncHintPerform16ByteAlignment = 13
-};
-
-// ============================================================================
-// [AsmJit::kX86FuncFlags]
-// ============================================================================
-
-//! @brief X86 function flags.
-enum kX86FuncFlags
-{
- //! @brief Whether to emit prolog / epilog sequence using push & pop
- //! instructions (the default).
- kX86FuncFlagPushPop = (1U << 8),
-
- //! @brief Whether to emit EMMS instruction in epilog (auto-detected).
- kX86FuncFlagEmitEmms = (1U << 9),
-
- //! @brief Whether to emit SFence instruction in epilog (auto-detected).
- //!
- //! @note @ref kX86FuncFlagEmitSFence and @ref kX86FuncFlagEmitLFence
- //! combination will result in emitting mfence.
- kX86FuncFlagEmitSFence = (1U << 10),
-
- //! @brief Whether to emit LFence instruction in epilog (auto-detected).
- //!
- //! @note @ref kX86FuncFlagEmitSFence and @ref kX86FuncFlagEmitLFence
- //! combination will result in emitting mfence.
- kX86FuncFlagEmitLFence = (1U << 11),
-
- //! @brief Whether the function stack is aligned by 16-bytes by OS.
- //!
- //! This is always true for 64-bit mode and for linux.
- kX86FuncFlagAssume16ByteAlignment = (1U << 12),
-
- //! @brief Whether the function stack (for variables) is aligned manually
- //! by function to 16-bytes.
- //!
- //! This makes sense only if @ref kX86FuncFlagAssume16ByteAlignment is
- //! false and MOVDQA instruction or other SSE/SSE2 instructions are used to
- //! work with variables stored on the stack.
- //!
- //! Value is determined automatically by these factors, expectations are:
- //!
- //! 1. There is 16-byte wide variable which address was used (alloc, spill,
- //! op).
- //! 2. Function can't be naked.
- kX86FuncFlagPerform16ByteAlignment = (1U << 13),
-
- //! @brief Whether the ESP register is adjusted by the stack size needed
- //! to save registers and function variables.
- //!
- //! Esp is adjusted by 'sub' instruction in prolog and by add function in
- //! epilog (only if function is not naked).
- kX86FuncFlagIsEspAdjusted = (1U << 14)
-};
-
-// ============================================================================
-// [AsmJit::kX86CompilerInst]
-// ============================================================================
-
-//! @brief Instruction flags used by @ref X86CompilerInst item.
-enum kX86CompilerInstFlag
-{
- //! @brief Whether the instruction is special.
- kX86CompilerInstFlagIsSpecial = (1U << 0),
- //! @brief Whether the instruction is FPU.
- kX86CompilerInstFlagIsFpu = (1U << 1),
- //! @brief Whether the one of the operands is GPB.Lo register.
- kX86CompilerInstFlagIsGpbLoUsed = (1U << 2),
- //! @brief Whether the one of the operands is GPB.Hi register.
- kX86CompilerInstFlagIsGpbHiUsed = (1U << 3),
-
- //! @brief Whether the jmp/jcc is likely to be taken.
- kX86CompilerInstFlagIsTaken = (1U << 7)
-};
-
-// ============================================================================
-// [AsmJit::kX86VarClass]
-// ============================================================================
-
-//! @brief X86 variable class.
-enum kX86VarClass
-{
- //! @brief No class (used internally).
- kX86VarClassNone = 0,
- //! @brief General purpose register.
- kX86VarClassGp = 1,
- //! @brief X87 floating point.
- kX86VarClassX87 = 2,
- //! @brief MMX register.
- kX86VarClassMm = 3,
- //! @brief XMM register.
- kX86VarClassXmm = 4,
-
- //! @brief Count of X86 variable classes.
- kX86VarClassCount = 5
-};
-
-// ============================================================================
-// [AsmJit::kX86VarFlags]
-// ============================================================================
-
-//! @brief X86 variable class.
-enum kX86VarFlags
-{
- //! @brief Variable contains single-precision floating-point(s).
- kX86VarFlagSP = 0x10,
- //! @brief Variable contains double-precision floating-point(s).
- kX86VarFlagDP = 0x20,
- //! @brief Variable is packed (for example float4x, double2x, ...).
- kX86VarFlagPacked = 0x40
-};
-
-// ============================================================================
-// [AsmJit::kX86VarType]
-// ============================================================================
-
-//! @brief X86 variable type.
-enum kX86VarType
-{
- // --------------------------------------------------------------------------
- // [Platform Dependent]
- // --------------------------------------------------------------------------
-
- //! @brief Variable is 32-bit general purpose register.
- kX86VarTypeGpd = 0,
- //! @brief Variable is 64-bit general purpose register.
- kX86VarTypeGpq = 1,
-
- //! @var kX86VarTypeGpz
- //! @brief Variable is system wide general purpose register (32-bit or 64-bit).
-#if defined(ASMJIT_X86)
- kX86VarTypeGpz = kX86VarTypeGpd,
-#else
- kX86VarTypeGpz = kX86VarTypeGpq,
-#endif
-
- //! @brief Variable is X87 (FPU).
- kX86VarTypeX87 = 2,
- //! @brief Variable is X87 (FPU) SP-FP number (float).
- kX86VarTypeX87SS = 3,
- //! @brief Variable is X87 (FPU) DP-FP number (double).
- kX86VarTypeX87SD = 4,
-
- //! @brief Variable is MM register / memory location.
- kX86VarTypeMm = 5,
- //! @brief Variable is XMM register / memory location.
- kX86VarTypeXmm = 6,
-
- //! @brief Variable is SSE scalar SP-FP number.
- kX86VarTypeXmmSS = 7,
- //! @brief Variable is SSE packed SP-FP number (4 floats).
- kX86VarTypeXmmPS = 8,
-
- //! @brief Variable is SSE2 scalar DP-FP number.
- kX86VarTypeXmmSD = 9,
- //! @brief Variable is SSE2 packed DP-FP number (2 doubles).
- kX86VarTypeXmmPD = 10,
-
- //! @brief Count of variable types.
- kX86VarTypeCount = 11,
-
- // --------------------------------------------------------------------------
- // [Platform Independent]
- // --------------------------------------------------------------------------
-
- //! @brief Variable is 32-bit integer.
- kX86VarTypeInt32 = kX86VarTypeGpd,
- //! @brief Variable is 64-bit integer.
- kX86VarTypeInt64 = kX86VarTypeGpq,
- //! @brief Variable is system dependent integer / pointer.
- kX86VarTypeIntPtr = kX86VarTypeGpz,
-
-#if defined(ASMJIT_X86)
- kX86VarTypeFloat = kX86VarTypeX87SS,
- kX86VarTypeDouble = kX86VarTypeX87SD
-#else
- kX86VarTypeFloat = kX86VarTypeXmmSS,
- kX86VarTypeDouble = kX86VarTypeXmmSD
-#endif
-};
-
-// ============================================================================
-// [AsmJit::X86VarInfo]
-// ============================================================================
-
-//! @brief X86 variable information.
-struct X86VarInfo
-{
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
-
- //! @brief Get register code base, see @ref kX86RegCode.
- uint32_t getCode() const
- { return _code; }
-
- //! @brief Get register size in bytes.
- uint32_t getSize() const
- { return _size; }
-
- //! @brief Get variable class, see @ref kX86VarClass.
- uint32_t getClass() const
- { return _class; }
-
- //! @brief Get variable flags, see @ref kX86VarFlags.
- uint32_t getFlags() const
- { return _flags; }
-
- //! @brief Get variable type name.
- const char* getName() const
- { return _name; }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Register code base, see @ref kX86RegCode.
- uint32_t _code;
- //! @brief Register size in bytes.
- uint16_t _size;
- //! @brief Variable class, see @ref kX86VarClass.
- uint8_t _class;
- //! @brief Variable flags, see @ref kX86VarFlags.
- uint8_t _flags;
- //! @brief Variable type name.
- char _name[8];
-};
-
-// ============================================================================
-// [AsmJit::x86VarInfo]
-// ============================================================================
-
-ASMJIT_VAR const X86VarInfo x86VarInfo[];
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86func.cpp
+++ /dev/null
@@ -1,587 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../core/assert.h"
-#include "../core/intutil.h"
-#include "../core/stringutil.h"
-
-#include "../x86/x86defs.h"
-#include "../x86/x86func.h"
-#include "../x86/x86util.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::X86FuncDecl - Accessors]
-// ============================================================================
-
-uint32_t X86FuncDecl::findArgumentByRegCode(uint32_t regCode) const
-{
- uint32_t type = regCode & kRegTypeMask;
- uint32_t idx = regCode & kRegIndexMask;
-
- uint32_t clazz;
-
- switch (type)
- {
- case kX86RegTypeGpd:
- case kX86RegTypeGpq:
- clazz = kX86VarClassGp;
- break;
-
- case kX86RegTypeX87:
- clazz = kX86VarClassX87;
- break;
-
- case kX86RegTypeMm:
- clazz = kX86VarClassMm;
- break;
-
- case kX86RegTypeXmm:
- clazz = kX86VarClassXmm;
- break;
-
- default:
- return kInvalidValue;
- }
-
- for (uint32_t i = 0; i < this->_argumentsCount; ++i)
- {
- const FuncArg &arg = this->_arguments[i];
-
- if (arg.getRegIndex() == idx && (X86Util::getVarClassFromVarType(arg.getVarType()) & clazz))
- return i;
- }
-
- return kInvalidValue;
-}
-
-// ============================================================================
-// [AsmJit::X86FuncDecl - SetPrototype - InitCallingConvention]
-// ============================================================================
-
-static void X86FuncDecl_initCallingConvention(X86FuncDecl *self, uint32_t convention)
-{
- uint32_t i;
-
- // --------------------------------------------------------------------------
- // [Inir]
- // --------------------------------------------------------------------------
-
- self->_convention = convention;
- self->_calleePopsStack = false;
- self->_argumentsDirection = kFuncArgsRTL;
-
- for (i = 0; i < ASMJIT_ARRAY_SIZE(self->_gpList); ++i)
- self->_gpList[i] = kRegIndexInvalid;
-
- for (i = 0; i < ASMJIT_ARRAY_SIZE(self->_xmmList); ++i)
- self->_xmmList[i] = kRegIndexInvalid;
-
- self->_gpListMask = 0x0;
- self->_mmListMask = 0x0;
- self->_xmmListMask = 0x0;
-
- self->_gpPreservedMask = 0x0;
- self->_mmPreservedMask = 0x0;
- self->_xmmPreservedMask = 0x0;
-
- // --------------------------------------------------------------------------
- // [X86 Calling Conventions]
- // --------------------------------------------------------------------------
-
-#ifdef ASMJIT_X86
- self->_gpPreservedMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexEbx) | IntUtil::maskFromIndex(kX86RegIndexEsp) | IntUtil::maskFromIndex(kX86RegIndexEbp) |
- IntUtil::maskFromIndex(kX86RegIndexEsi) | IntUtil::maskFromIndex(kX86RegIndexEdi));
- self->_xmmPreservedMask = 0;
-
- switch (convention)
- {
- // ------------------------------------------------------------------------
- // [CDecl]
- // ------------------------------------------------------------------------
-
- case kX86FuncConvCDecl:
- break;
-
- // ------------------------------------------------------------------------
- // [StdCall]
- // ------------------------------------------------------------------------
-
- case kX86FuncConvStdCall:
- self->_calleePopsStack = true;
- break;
-
- // ------------------------------------------------------------------------
- // [MS-ThisCall]
- // ------------------------------------------------------------------------
-
- case kX86FuncConvMsThisCall:
- self->_calleePopsStack = true;
-
- self->_gpList[0] = kX86RegIndexEcx;
-
- self->_gpListMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexEcx));
- break;
-
- // ------------------------------------------------------------------------
- // [MS-FastCall]
- // ------------------------------------------------------------------------
-
- case kX86FuncConvMsFastCall:
- self->_calleePopsStack = true;
-
- self->_gpList[0] = kX86RegIndexEcx;
- self->_gpList[1] = kX86RegIndexEdx;
-
- self->_gpListMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexEcx) | IntUtil::maskFromIndex(kX86RegIndexEdx));
- break;
-
- // ------------------------------------------------------------------------
- // [Borland-FastCall]
- // ------------------------------------------------------------------------
-
- case kX86FuncConvBorlandFastCall:
- self->_calleePopsStack = true;
- self->_argumentsDirection = kFuncArgsLTR;
-
- self->_gpList[0] = kX86RegIndexEax;
- self->_gpList[1] = kX86RegIndexEdx;
- self->_gpList[2] = kX86RegIndexEcx;
-
- self->_gpListMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexEax) | IntUtil::maskFromIndex(kX86RegIndexEdx) | IntUtil::maskFromIndex(kX86RegIndexEcx));
- break;
-
- // ------------------------------------------------------------------------
- // [Gcc-FastCall]
- // ------------------------------------------------------------------------
-
- case kX86FuncConvGccFastCall:
- self->_calleePopsStack = true;
-
- self->_gpList[0] = kX86RegIndexEcx;
- self->_gpList[1] = kX86RegIndexEdx;
-
- self->_gpListMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexEcx) | IntUtil::maskFromIndex(kX86RegIndexEdx));
- break;
-
- // ------------------------------------------------------------------------
- // [Gcc-Regparm(1)]
- // ------------------------------------------------------------------------
-
- case kX86FuncConvGccRegParm1:
- self->_calleePopsStack = false;
-
- self->_gpList[0] = kX86RegIndexEax;
- self->_gpListMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexEax));
- break;
-
- // ------------------------------------------------------------------------
- // [Gcc-Regparm(2)]
- // ------------------------------------------------------------------------
-
- case kX86FuncConvGccRegParm2:
- self->_calleePopsStack = false;
-
- self->_gpList[0] = kX86RegIndexEax;
- self->_gpList[1] = kX86RegIndexEdx;
-
- self->_gpListMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexEax) | IntUtil::maskFromIndex(kX86RegIndexEdx));
- break;
-
- // ------------------------------------------------------------------------
- // [Gcc-Regparm(3)]
- // ------------------------------------------------------------------------
-
- case kX86FuncConvGccRegParm3:
- self->_calleePopsStack = false;
-
- self->_gpList[0] = kX86RegIndexEax;
- self->_gpList[1] = kX86RegIndexEdx;
- self->_gpList[2] = kX86RegIndexEcx;
-
- self->_gpListMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexEax) | IntUtil::maskFromIndex(kX86RegIndexEdx) | IntUtil::maskFromIndex(kX86RegIndexEcx));
- break;
-
- // ------------------------------------------------------------------------
- // [Illegal]
- // ------------------------------------------------------------------------
-
- default:
- // Illegal calling convention.
- ASMJIT_ASSERT(0);
- }
-#endif // ASMJIT_X86
-
- // --------------------------------------------------------------------------
- // [X64 Calling Conventions]
- // --------------------------------------------------------------------------
-
-#ifdef ASMJIT_X64
- switch (convention)
- {
- // ------------------------------------------------------------------------
- // [X64-Windows]
- // ------------------------------------------------------------------------
-
- case kX86FuncConvX64W:
- self->_gpList[0] = kX86RegIndexRcx;
- self->_gpList[1] = kX86RegIndexRdx;
- self->_gpList[2] = kX86RegIndexR8;
- self->_gpList[3] = kX86RegIndexR9;
-
- self->_xmmList[0] = kX86RegIndexXmm0;
- self->_xmmList[1] = kX86RegIndexXmm1;
- self->_xmmList[2] = kX86RegIndexXmm2;
- self->_xmmList[3] = kX86RegIndexXmm3;
-
- self->_gpListMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexRcx) | IntUtil::maskFromIndex(kX86RegIndexRdx) | IntUtil::maskFromIndex(kX86RegIndexR8) |
- IntUtil::maskFromIndex(kX86RegIndexR9));
-
- self->_xmmListMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexXmm0) | IntUtil::maskFromIndex(kX86RegIndexXmm1) | IntUtil::maskFromIndex(kX86RegIndexXmm2) |
- IntUtil::maskFromIndex(kX86RegIndexXmm3));
-
- self->_gpPreservedMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexRbx) | IntUtil::maskFromIndex(kX86RegIndexRsp) | IntUtil::maskFromIndex(kX86RegIndexRbp) |
- IntUtil::maskFromIndex(kX86RegIndexRsi) | IntUtil::maskFromIndex(kX86RegIndexRdi) | IntUtil::maskFromIndex(kX86RegIndexR12) | IntUtil::maskFromIndex(kX86RegIndexR13) |
- IntUtil::maskFromIndex(kX86RegIndexR14) | IntUtil::maskFromIndex(kX86RegIndexR15));
-
- self->_xmmPreservedMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexXmm6) | IntUtil::maskFromIndex(kX86RegIndexXmm7) | IntUtil::maskFromIndex(kX86RegIndexXmm8) |
- IntUtil::maskFromIndex(kX86RegIndexXmm9) | IntUtil::maskFromIndex(kX86RegIndexXmm10) | IntUtil::maskFromIndex(kX86RegIndexXmm11) | IntUtil::maskFromIndex(kX86RegIndexXmm12) |
- IntUtil::maskFromIndex(kX86RegIndexXmm13) | IntUtil::maskFromIndex(kX86RegIndexXmm14) | IntUtil::maskFromIndex(kX86RegIndexXmm15));
- break;
-
- // ------------------------------------------------------------------------
- // [X64-Unix]
- // ------------------------------------------------------------------------
-
- case kX86FuncConvX64U:
- self->_gpList[0] = kX86RegIndexRdi;
- self->_gpList[1] = kX86RegIndexRsi;
- self->_gpList[2] = kX86RegIndexRdx;
- self->_gpList[3] = kX86RegIndexRcx;
- self->_gpList[4] = kX86RegIndexR8;
- self->_gpList[5] = kX86RegIndexR9;
-
- self->_xmmList[0] = kX86RegIndexXmm0;
- self->_xmmList[1] = kX86RegIndexXmm1;
- self->_xmmList[2] = kX86RegIndexXmm2;
- self->_xmmList[3] = kX86RegIndexXmm3;
- self->_xmmList[4] = kX86RegIndexXmm4;
- self->_xmmList[5] = kX86RegIndexXmm5;
- self->_xmmList[6] = kX86RegIndexXmm6;
- self->_xmmList[7] = kX86RegIndexXmm7;
-
- self->_gpListMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexRdi) | IntUtil::maskFromIndex(kX86RegIndexRsi) | IntUtil::maskFromIndex(kX86RegIndexRdx) |
- IntUtil::maskFromIndex(kX86RegIndexRcx) | IntUtil::maskFromIndex(kX86RegIndexR8) | IntUtil::maskFromIndex(kX86RegIndexR9));
-
- self->_xmmListMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexXmm0) | IntUtil::maskFromIndex(kX86RegIndexXmm1) | IntUtil::maskFromIndex(kX86RegIndexXmm2) |
- IntUtil::maskFromIndex(kX86RegIndexXmm3) | IntUtil::maskFromIndex(kX86RegIndexXmm4) | IntUtil::maskFromIndex(kX86RegIndexXmm5) | IntUtil::maskFromIndex(kX86RegIndexXmm6) |
- IntUtil::maskFromIndex(kX86RegIndexXmm7));
-
- self->_gpPreservedMask = static_cast<uint16_t>(IntUtil::maskFromIndex(kX86RegIndexRbx) | IntUtil::maskFromIndex(kX86RegIndexRsp) | IntUtil::maskFromIndex(kX86RegIndexRbp) |
- IntUtil::maskFromIndex(kX86RegIndexR12) | IntUtil::maskFromIndex(kX86RegIndexR13) | IntUtil::maskFromIndex(kX86RegIndexR14) | IntUtil::maskFromIndex(kX86RegIndexR15));
- break;
-
- // ------------------------------------------------------------------------
- // [Illegal]
- // ------------------------------------------------------------------------
-
- default:
- // Illegal calling convention.
- ASMJIT_ASSERT(0);
- }
-#endif // ASMJIT_X64
-}
-
-// ============================================================================
-// [AsmJit::X86FuncDecl - SetPrototype - InitDefinition]
-// ============================================================================
-
-static void X86FuncDecl_initDefinition(X86FuncDecl *self, uint32_t returnType, const uint32_t *argumentsData, uint32_t argumentsCount)
-{
- ASMJIT_ASSERT(argumentsCount <= kFuncArgsMax);
-
- // --------------------------------------------------------------------------
- // [Init]
- // --------------------------------------------------------------------------
-
- int32_t i = 0;
- int32_t gpPos = 0;
- int32_t stackOffset = 0;
-
- self->_returnType = returnType;
- self->_argumentsCount = static_cast<uint8_t>(argumentsCount);
-
- while (i < static_cast<int32_t>(argumentsCount))
- {
- FuncArg &arg = self->_arguments[i];
-
- arg._varType = static_cast<uint8_t>(argumentsData[i]);
- arg._regIndex = kRegIndexInvalid;
- arg._stackOffset = kFuncStackInvalid;
-
- ++i;
- }
-
- while (i < kFuncArgsMax)
- {
- FuncArg &arg = self->_arguments[i];
- arg.reset();
-
- ++i;
- }
-
- self->_argumentsStackSize = 0;
- self->_gpArgumentsMask = 0x0;
- self->_mmArgumentsMask = 0x0;
- self->_xmmArgumentsMask = 0x0;
-
- if (!self->_argumentsCount)
- return;
-
- // --------------------------------------------------------------------------
- // [X86 Calling Conventions (32-bit)]
- // --------------------------------------------------------------------------
-
-#ifdef ASMJIT_X86
- // Register arguments (Integer), always left-to-right.
- for (i = 0; i != static_cast<int32_t>(argumentsCount); ++i)
- {
- FuncArg &arg = self->_arguments[i];
- uint32_t varType = arg.getVarType();
-
- if (X86Util::isVarTypeInt(varType) && gpPos < 16 && self->_gpList[gpPos] != kRegIndexInvalid)
- {
- arg._regIndex = self->_gpList[gpPos++];
- self->_gpArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
- }
- }
-
- // Stack arguments.
- int32_t iStart = static_cast<int32_t>(argumentsCount - 1);
- int32_t iEnd = -1;
- int32_t iStep = -1;
-
- if (self->_argumentsDirection == kFuncArgsLTR)
- {
- iStart = 0;
- iEnd = static_cast<int32_t>(argumentsCount);
- iStep = 1;
- }
-
- for (i = iStart; i != iEnd; i += iStep)
- {
- FuncArg &arg = self->_arguments[i];
- uint32_t varType = arg.getVarType();
-
- if (arg.hasRegIndex())
- continue;
-
- if (X86Util::isVarTypeInt(varType))
- {
- stackOffset -= 4;
- arg._stackOffset = static_cast<int16_t>(stackOffset);
- }
- else if (X86Util::isVarTypeFloat(varType))
- {
- int32_t size = static_cast<int32_t>(x86VarInfo[varType].getSize());
- stackOffset -= size;
- arg._stackOffset = static_cast<int16_t>(stackOffset);
- }
- }
-#endif // ASMJIT_X86
-
- // --------------------------------------------------------------------------
- // [X64 Calling Conventions (64-bit)]
- // --------------------------------------------------------------------------
-
-#ifdef ASMJIT_X64
- // Windows 64-bit specific.
- if (self->_convention == kX86FuncConvX64W)
- {
- int32_t max = argumentsCount < 4 ? argumentsCount : 4;
-
- // Register arguments (Integer / FP), always left-to-right.
- for (i = 0; i != max; ++i)
- {
- FuncArg &arg = self->_arguments[i];
- uint32_t varType = arg.getVarType();
-
- if (X86Util::isVarTypeInt(varType))
- {
- arg._regIndex = self->_gpList[i];
- self->_gpArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
- }
- else if (X86Util::isVarTypeFloat(varType))
- {
- arg._regIndex = self->_xmmList[i];
- self->_xmmArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
- }
- }
-
- // Stack arguments (always right-to-left).
- for (i = argumentsCount - 1; i != -1; --i)
- {
- FuncArg &arg = self->_arguments[i];
- uint32_t varType = arg.getVarType();
-
- if (arg.isAssigned())
- continue;
-
- if (X86Util::isVarTypeInt(varType))
- {
- stackOffset -= 8; // Always 8 bytes.
- arg._stackOffset = stackOffset;
- }
- else if (X86Util::isVarTypeFloat(varType))
- {
- int32_t size = static_cast<int32_t>(x86VarInfo[varType].getSize());
- stackOffset -= size;
- arg._stackOffset = stackOffset;
- }
- }
-
- // 32 bytes shadow space (X64W calling convention specific).
- stackOffset -= 4 * 8;
- }
- // Linux/Unix 64-bit (AMD64 calling convention).
- else
- {
- // Register arguments (Integer), always left-to-right.
- for (i = 0; i != static_cast<int32_t>(argumentsCount); ++i)
- {
- FuncArg &arg = self->_arguments[i];
- uint32_t varType = arg.getVarType();
-
- if (X86Util::isVarTypeInt(varType) && gpPos < 32 && self->_gpList[gpPos] != kRegIndexInvalid)
- {
- arg._regIndex = self->_gpList[gpPos++];
- self->_gpArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
- }
- }
-
- // Register arguments (FP), always left-to-right.
- for (i = 0; i != static_cast<int32_t>(argumentsCount); ++i)
- {
- FuncArg &arg = self->_arguments[i];
- uint32_t varType = arg.getVarType();
-
- if (X86Util::isVarTypeFloat(varType))
- {
- arg._regIndex = self->_xmmList[xmmPos++];
- self->_xmmArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
- }
- }
-
- // Stack arguments.
- for (i = argumentsCount - 1; i != -1; --i)
- {
- FuncArg &arg = self->_arguments[i];
- uint32_t varType = arg.getVarType();
-
- if (arg.isAssigned())
- continue;
-
- if (X86Util::isVarTypeInt(varType))
- {
- stackOffset -= 8;
- arg._stackOffset = static_cast<int16_t>(stackOffset);
- }
- else if (X86Util::isVarTypeFloat(varType))
- {
- int32_t size = static_cast<int32_t>(x86VarInfo[varType].getSize());
-
- stackOffset -= size;
- arg._stackOffset = static_cast<int16_t>(stackOffset);
- }
- }
- }
-#endif // ASMJIT_X64
-
- // Modify stack offset (all function parameters will be in positive stack
- // offset that is never zero).
- for (i = 0; i < (int32_t)argumentsCount; ++i)
- {
- FuncArg &arg = self->_arguments[i];
- if (!arg.hasRegIndex())
- arg._stackOffset += static_cast<uint16_t>(static_cast<int32_t>(sizeof(uintptr_t)) - stackOffset);
- }
-
- self->_argumentsStackSize = static_cast<uint32_t>(-stackOffset);
-}
-
-void X86FuncDecl::setPrototype(uint32_t convention, uint32_t returnType, const uint32_t *arguments, uint32_t argumentsCount)
-{
- // Limit maximum function arguments to kFuncArgsMax.
- if (argumentsCount > kFuncArgsMax)
- argumentsCount = kFuncArgsMax;
-
- X86FuncDecl_initCallingConvention(this, convention);
- X86FuncDecl_initDefinition(this, returnType, arguments, argumentsCount);
-}
-
-// ============================================================================
-// [AsmJit::X86FuncDecl - Reset]
-// ============================================================================
-
-void X86FuncDecl::reset()
-{
- uint32_t i;
-
- // --------------------------------------------------------------------------
- // [Core]
- // --------------------------------------------------------------------------
-
- this->_returnType = kVarTypeInvalid;
- this->_argumentsCount = 0;
-
- this->_reserved0[0] = 0;
- this->_reserved0[1] = 0;
-
- for (i = 0; i < ASMJIT_ARRAY_SIZE(this->_arguments); ++i)
- this->_arguments[i].reset();
-
- this->_argumentsStackSize = 0;
- this->_gpArgumentsMask = 0x0;
- this->_mmArgumentsMask = 0x0;
- this->_xmmArgumentsMask = 0x0;
-
- // --------------------------------------------------------------------------
- // [Convention]
- // --------------------------------------------------------------------------
-
- this->_convention = kFuncConvNone;
- this->_calleePopsStack = false;
- this->_argumentsDirection = kFuncArgsRTL;
- this->_reserved1 = 0;
-
- for (i = 0; i < ASMJIT_ARRAY_SIZE(this->_gpList); ++i)
- this->_gpList[i] = kRegIndexInvalid;
-
- for (i = 0; i < ASMJIT_ARRAY_SIZE(this->_xmmList); ++i)
- this->_xmmList[i] = kRegIndexInvalid;
-
- this->_gpListMask = 0x0;
- this->_mmListMask = 0x0;
- this->_xmmListMask = 0x0;
-
- this->_gpPreservedMask = 0x0;
- this->_mmPreservedMask = 0x0;
- this->_xmmPreservedMask = 0x0;
-}
-
-} // AsmJit namespace
-
-// [Api-Begin]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86func.h
+++ /dev/null
@@ -1,237 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../core/defs.h"
-#include "../core/func.h"
-
-#include "../x86/x86defs.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_X86
-//! @{
-
-// ============================================================================
-// [AsmJit::TypeId]
-// ============================================================================
-
-ASMJIT_DECLARE_TYPE_CORE(kX86VarTypeIntPtr);
-ASMJIT_DECLARE_TYPE_ID(void, kVarTypeInvalid);
-
-ASMJIT_DECLARE_TYPE_ID(int8_t, kX86VarTypeGpd);
-ASMJIT_DECLARE_TYPE_ID(uint8_t, kX86VarTypeGpd);
-
-ASMJIT_DECLARE_TYPE_ID(int16_t, kX86VarTypeGpd);
-ASMJIT_DECLARE_TYPE_ID(uint16_t, kX86VarTypeGpd);
-
-ASMJIT_DECLARE_TYPE_ID(int32_t, kX86VarTypeGpd);
-ASMJIT_DECLARE_TYPE_ID(uint32_t, kX86VarTypeGpd);
-
-#ifdef ASMJIT_X64
-ASMJIT_DECLARE_TYPE_ID(int64_t, kX86VarTypeGpq);
-ASMJIT_DECLARE_TYPE_ID(uint64_t, kX86VarTypeGpq);
-#endif // ASMJIT_X64
-
-ASMJIT_DECLARE_TYPE_ID(float, kX86VarTypeFloat);
-ASMJIT_DECLARE_TYPE_ID(double, kX86VarTypeDouble);
-
-// ============================================================================
-// [AsmJit::X86FuncDecl]
-// ============================================================================
-
-//! @brief X86 function, including calling convention, arguments and their
-//! register indices or stack positions.
-struct X86FuncDecl : public FuncDecl
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create a new @ref FunctionX86 instance.
- X86FuncDecl() { this->reset(); }
-
- // --------------------------------------------------------------------------
- // [Accessors - Core]
- // --------------------------------------------------------------------------
-
- //! @brief Get stack size needed for function arguments passed on the stack.
- uint32_t getArgumentsStackSize() const { return this->_argumentsStackSize; }
-
- //! @brief Get bit-mask of GP registers used to pass function arguments.
- uint32_t getGpArgumentsMask() const { return this->_gpArgumentsMask; }
-
- //! @brief Get bit-mask of MM registers used to pass function arguments.
- uint32_t getMmArgumentsMask() const { return this->_mmArgumentsMask; }
-
- //! @brief Get bit-mask of XMM registers used to pass function arguments.
- uint32_t getXmmArgumentsMask() const { return this->_xmmArgumentsMask; }
-
- // --------------------------------------------------------------------------
- // [Accessors - Convention]
- // --------------------------------------------------------------------------
-
- //! @brief Get function calling convention, see @c kX86FuncConv.
- uint32_t getConvention() const { return this->_convention; }
-
- //! @brief Get whether the callee pops the stack.
- uint32_t getCalleePopsStack() const { return this->_calleePopsStack; }
-
- //! @brief Get direction of arguments passed on the stack.
- //!
- //! Direction should be always @c kFuncArgsRTL.
- //!
- //! @note This is related to used calling convention, it's not affected by
- //! number of function arguments or their types.
- uint32_t getArgumentsDirection() const { return this->_argumentsDirection; }
-
- //! @brief Get 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.
- const uint8_t *getGpList() const { return this->_gpList; }
-
- //! @brief Get 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.
- const uint8_t *getXmmList() const { return this->_xmmList; }
-
- //! @brief Get bit-mask of GP registers which might be used for arguments.
- uint32_t getGpListMask() const { return this->_gpListMask; }
-
- //! @brief Get bit-mask of MM registers which might be used for arguments.
- uint32_t getMmListMask() const { return this->_mmListMask; }
-
- //! @brief Get bit-mask of XMM registers which might be used for arguments.
- uint32_t getXmmListMask() const { return this->_xmmListMask; }
-
- //! @brief Get bit-mask 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.
- uint32_t getGpPreservedMask() const { return this->_gpPreservedMask; }
-
- //! @brief Get bit-mask of MM registers that's preserved (non-volatile).
- //!
- //! @note No standardized calling function is not preserving MM registers.
- //! This member is here for extension writers who need for some reason custom
- //! calling convention that can be called through code generated by AsmJit
- //! (or other runtime code generator).
- uint32_t getMmPreservedMask() const { return this->_mmPreservedMask; }
-
- //! @brief Get bit-mask of XMM 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.
- uint32_t getXmmPreservedMask() const { return this->_xmmPreservedMask; }
-
- // --------------------------------------------------------------------------
- // [Methods]
- // --------------------------------------------------------------------------
-
- //! @brief Find argument ID by the register code.
- ASMJIT_API uint32_t findArgumentByRegCode(uint32_t regCode) const;
-
- // --------------------------------------------------------------------------
- // [SetPrototype]
- // --------------------------------------------------------------------------
-
- //! @brief Set function prototype.
- //!
- //! This will set function calling convention and setup arguments variables.
- //!
- //! @note This function will allocate variables, it can be called only once.
- ASMJIT_API void setPrototype(uint32_t convention, uint32_t returnType, const uint32_t *arguments, uint32_t argumentsCount);
-
- // --------------------------------------------------------------------------
- // [Reset]
- // --------------------------------------------------------------------------
-
- ASMJIT_API void reset();
-
- // --------------------------------------------------------------------------
- // [Members - Core]
- // --------------------------------------------------------------------------
-
- //! @brief Count of bytes consumed by arguments on the stack.
- uint16_t _argumentsStackSize;
- //! @brief Bitmask for GP registers used as passed function arguments.
- uint16_t _gpArgumentsMask;
- //! @brief Bitmask for MM registers used as passed function arguments.
- uint16_t _mmArgumentsMask;
- //! @brief Bitmask for XMM registers used as passed function arguments.
- uint16_t _xmmArgumentsMask;
-
- // --------------------------------------------------------------------------
- // [Membes - Convention]
- //
- // This section doesn't depend on function arguments or return type. It
- // depends only on function calling convention and it's filled according to
- // that value.
- // --------------------------------------------------------------------------
-
- //! @brief Calling convention.
- uint8_t _convention;
- //! @brief Whether a callee pops stack.
- uint8_t _calleePopsStack;
- //! @brief Direction for arguments passed on the stack, see @c kFuncArgsDirection.
- uint8_t _argumentsDirection;
- //! @brief Reserved for future use #1 (alignment).
- uint8_t _reserved1;
-
- //! @brief List of register IDs used for GP arguments (order is important).
- //!
- //! @note All registers in _gpList are also specified in @ref _gpListMask.
- //! Unused fields are filled by @ref kRegIndexInvalid.
- uint8_t _gpList[16];
- //! @brief List of register IDs used for XMM arguments (order is important).
- //!
- //! @note All registers in _gpList are also specified in @ref _xmmListMask.
- //! Unused fields are filled by @ref kRegIndexInvalid.
- uint8_t _xmmList[16];
-
- //! @brief Bitmask for GP registers which might be used by arguments.
- //!
- //! @note All registers in _gpListMask are also specified in @ref _gpList.
- uint16_t _gpListMask;
- //! @brief Bitmask for MM registers which might be used by arguments.
- uint16_t _mmListMask;
- //! @brief Bitmask for XMM registers which might be used by arguments.
- //!
- //! @note All registers in _xmmListMask are also specified in @ref _xmmList.
- uint16_t _xmmListMask;
-
- //! @brief Bitmask for GP registers preserved across the function call.
- //!
- //! @note Preserved register mask is complement to @ref _gpListMask.
- uint16_t _gpPreservedMask;
- //! @brief Bitmask for MM registers preserved across the function call.
- //!
- //! @note Preserved register mask is complement to @ref _mmListMask.
- uint16_t _mmPreservedMask;
- //! @brief Bitmask for XMM registers preserved across the function call.
- //!
- //! @note Preserved register mask is complement to @ref _xmmListMask.
- uint16_t _xmmPreservedMask;
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86inst.cpp
@@ -1,1 +1,4820 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Guard]
+#include "../build.h"
+#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
+
+// [Dependencies - AsmJit]
+#include "../x86/x86inst.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [Macros]
+// ============================================================================
+
+#ifndef ASMJIT_DISABLE_NAMES
+# define INST_NAME_INDEX(_Code_) _Code_##_NameIndex
+#else
+# define INST_NAME_INDEX(_Code_) 0
+#endif
+
+#define G(_Group_) kX86InstGroup##_Group_
+#define F(_Flags_) kX86InstFlag##_Flags_
+#define O(_Op_) kX86InstOp##_Op_
+#define E(_Flags_) 0
+
+#define U 0
+#define L kX86InstOpCode_L_True
+
+#define O_000000(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_000F00(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_000F01(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F01 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_000F0F(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_000F38(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_000F3A(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_660000(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_660F00(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_660F38(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_660F3A(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_9B0000(_OpCode_, _R_) (kX86InstOpCode_PP_9B | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_F20000(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_F20F00(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_F20F38(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_F20F3A(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_F30000(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_F30F00(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_F30F38(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_F30F3A(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+
+#define O_00_M03(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_00011| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_00_M08(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_01000| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_00_M09(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_01001| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+
+#define O_66_M03(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_00011| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_66_M08(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_01000| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_66_M09(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_01001| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+
+#define O_00_X(_OpCode_, _R_) (kX86InstOpCode_PP_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+#define O_9B_X(_OpCode_, _R_) (kX86InstOpCode_PP_9B | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift))
+
+#define INST(_Code_, _Name_, _Group_, _Flags_, _MoveSize_, _OpFlags0_, _OpFlags1_, _OpFlags2_, _OpFlags3_, _EFlags_, _OpCode0_, _OpCode1_) \
+ { INST_NAME_INDEX(_Code_), _Code_##_ExtendedIndex, _OpCode0_ }
+
+// ============================================================================
+// [asmjit::X86Inst]
+// ============================================================================
+
+// ${X86InstData:Begin}
+// Automatically generated, do not edit.
+#ifndef ASMJIT_DISABLE_NAMES
+const char _x86InstName[] =
+ "\0"
+ "adc\0"
+ "add\0"
+ "addpd\0"
+ "addps\0"
+ "addsd\0"
+ "addss\0"
+ "addsubpd\0"
+ "addsubps\0"
+ "aesdec\0"
+ "aesdeclast\0"
+ "aesenc\0"
+ "aesenclast\0"
+ "aesimc\0"
+ "aeskeygenassist\0"
+ "and\0"
+ "andn\0"
+ "andnpd\0"
+ "andnps\0"
+ "andpd\0"
+ "andps\0"
+ "bextr\0"
+ "blendpd\0"
+ "blendps\0"
+ "blendvpd\0"
+ "blendvps\0"
+ "blsi\0"
+ "blsmsk\0"
+ "blsr\0"
+ "bsf\0"
+ "bsr\0"
+ "bswap\0"
+ "bt\0"
+ "btc\0"
+ "btr\0"
+ "bts\0"
+ "bzhi\0"
+ "call\0"
+ "cbw\0"
+ "cdq\0"
+ "cdqe\0"
+ "clc\0"
+ "cld\0"
+ "clflush\0"
+ "cmc\0"
+ "cmova\0"
+ "cmovae\0"
+ "cmovb\0"
+ "cmovbe\0"
+ "cmovc\0"
+ "cmove\0"
+ "cmovg\0"
+ "cmovge\0"
+ "cmovl\0"
+ "cmovle\0"
+ "cmovna\0"
+ "cmovnae\0"
+ "cmovnb\0"
+ "cmovnbe\0"
+ "cmovnc\0"
+ "cmovne\0"
+ "cmovng\0"
+ "cmovnge\0"
+ "cmovnl\0"
+ "cmovnle\0"
+ "cmovno\0"
+ "cmovnp\0"
+ "cmovns\0"
+ "cmovnz\0"
+ "cmovo\0"
+ "cmovp\0"
+ "cmovpe\0"
+ "cmovpo\0"
+ "cmovs\0"
+ "cmovz\0"
+ "cmp\0"
+ "cmppd\0"
+ "cmpps\0"
+ "cmps_b\0"
+ "cmps_d\0"
+ "cmps_q\0"
+ "cmps_w\0"
+ "cmpsd\0"
+ "cmpss\0"
+ "cmpxchg\0"
+ "cmpxchg16b\0"
+ "cmpxchg8b\0"
+ "comisd\0"
+ "comiss\0"
+ "cpuid\0"
+ "cqo\0"
+ "crc32\0"
+ "cvtdq2pd\0"
+ "cvtdq2ps\0"
+ "cvtpd2dq\0"
+ "cvtpd2pi\0"
+ "cvtpd2ps\0"
+ "cvtpi2pd\0"
+ "cvtpi2ps\0"
+ "cvtps2dq\0"
+ "cvtps2pd\0"
+ "cvtps2pi\0"
+ "cvtsd2si\0"
+ "cvtsd2ss\0"
+ "cvtsi2sd\0"
+ "cvtsi2ss\0"
+ "cvtss2sd\0"
+ "cvtss2si\0"
+ "cvttpd2dq\0"
+ "cvttpd2pi\0"
+ "cvttps2dq\0"
+ "cvttps2pi\0"
+ "cvttsd2si\0"
+ "cvttss2si\0"
+ "cwd\0"
+ "cwde\0"
+ "daa\0"
+ "das\0"
+ "dec\0"
+ "div\0"
+ "divpd\0"
+ "divps\0"
+ "divsd\0"
+ "divss\0"
+ "dppd\0"
+ "dpps\0"
+ "emms\0"
+ "enter\0"
+ "extractps\0"
+ "f2xm1\0"
+ "fabs\0"
+ "fadd\0"
+ "faddp\0"
+ "fbld\0"
+ "fbstp\0"
+ "fchs\0"
+ "fclex\0"
+ "fcmovb\0"
+ "fcmovbe\0"
+ "fcmove\0"
+ "fcmovnb\0"
+ "fcmovnbe\0"
+ "fcmovne\0"
+ "fcmovnu\0"
+ "fcmovu\0"
+ "fcom\0"
+ "fcomi\0"
+ "fcomip\0"
+ "fcomp\0"
+ "fcompp\0"
+ "fcos\0"
+ "fdecstp\0"
+ "fdiv\0"
+ "fdivp\0"
+ "fdivr\0"
+ "fdivrp\0"
+ "femms\0"
+ "ffree\0"
+ "fiadd\0"
+ "ficom\0"
+ "ficomp\0"
+ "fidiv\0"
+ "fidivr\0"
+ "fild\0"
+ "fimul\0"
+ "fincstp\0"
+ "finit\0"
+ "fist\0"
+ "fistp\0"
+ "fisttp\0"
+ "fisub\0"
+ "fisubr\0"
+ "fld\0"
+ "fld1\0"
+ "fldcw\0"
+ "fldenv\0"
+ "fldl2e\0"
+ "fldl2t\0"
+ "fldlg2\0"
+ "fldln2\0"
+ "fldpi\0"
+ "fldz\0"
+ "fmul\0"
+ "fmulp\0"
+ "fnclex\0"
+ "fninit\0"
+ "fnop\0"
+ "fnsave\0"
+ "fnstcw\0"
+ "fnstenv\0"
+ "fnstsw\0"
+ "fpatan\0"
+ "fprem\0"
+ "fprem1\0"
+ "fptan\0"
+ "frndint\0"
+ "frstor\0"
+ "fsave\0"
+ "fscale\0"
+ "fsin\0"
+ "fsincos\0"
+ "fsqrt\0"
+ "fst\0"
+ "fstcw\0"
+ "fstenv\0"
+ "fstp\0"
+ "fstsw\0"
+ "fsub\0"
+ "fsubp\0"
+ "fsubr\0"
+ "fsubrp\0"
+ "ftst\0"
+ "fucom\0"
+ "fucomi\0"
+ "fucomip\0"
+ "fucomp\0"
+ "fucompp\0"
+ "fwait\0"
+ "fxam\0"
+ "fxch\0"
+ "fxrstor\0"
+ "fxsave\0"
+ "fxtract\0"
+ "fyl2x\0"
+ "fyl2xp1\0"
+ "haddpd\0"
+ "haddps\0"
+ "hsubpd\0"
+ "hsubps\0"
+ "idiv\0"
+ "imul\0"
+ "inc\0"
+ "insertps\0"
+ "int\0"
+ "ja\0"
+ "jae\0"
+ "jb\0"
+ "jbe\0"
+ "jc\0"
+ "je\0"
+ "jg\0"
+ "jge\0"
+ "jl\0"
+ "jle\0"
+ "jna\0"
+ "jnae\0"
+ "jnb\0"
+ "jnbe\0"
+ "jnc\0"
+ "jne\0"
+ "jng\0"
+ "jnge\0"
+ "jnl\0"
+ "jnle\0"
+ "jno\0"
+ "jnp\0"
+ "jns\0"
+ "jnz\0"
+ "jo\0"
+ "jp\0"
+ "jpe\0"
+ "jpo\0"
+ "js\0"
+ "jz\0"
+ "jecxz\0"
+ "jmp\0"
+ "lahf\0"
+ "lddqu\0"
+ "ldmxcsr\0"
+ "lea\0"
+ "leave\0"
+ "lfence\0"
+ "lods_b\0"
+ "lods_d\0"
+ "lods_q\0"
+ "lods_w\0"
+ "lzcnt\0"
+ "maskmovdqu\0"
+ "maskmovq\0"
+ "maxpd\0"
+ "maxps\0"
+ "maxsd\0"
+ "maxss\0"
+ "mfence\0"
+ "minpd\0"
+ "minps\0"
+ "minsd\0"
+ "minss\0"
+ "monitor\0"
+ "mov\0"
+ "mov_ptr\0"
+ "movapd\0"
+ "movaps\0"
+ "movbe\0"
+ "movd\0"
+ "movddup\0"
+ "movdq2q\0"
+ "movdqa\0"
+ "movdqu\0"
+ "movhlps\0"
+ "movhpd\0"
+ "movhps\0"
+ "movlhps\0"
+ "movlpd\0"
+ "movlps\0"
+ "movmskpd\0"
+ "movmskps\0"
+ "movntdq\0"
+ "movntdqa\0"
+ "movnti\0"
+ "movntpd\0"
+ "movntps\0"
+ "movntq\0"
+ "movq\0"
+ "movq2dq\0"
+ "movs_b\0"
+ "movs_d\0"
+ "movs_q\0"
+ "movs_w\0"
+ "movsd\0"
+ "movshdup\0"
+ "movsldup\0"
+ "movss\0"
+ "movsx\0"
+ "movsxd\0"
+ "movupd\0"
+ "movups\0"
+ "movzx\0"
+ "mpsadbw\0"
+ "mul\0"
+ "mulpd\0"
+ "mulps\0"
+ "mulsd\0"
+ "mulss\0"
+ "mulx\0"
+ "mwait\0"
+ "neg\0"
+ "nop\0"
+ "not\0"
+ "or\0"
+ "orpd\0"
+ "orps\0"
+ "pabsb\0"
+ "pabsd\0"
+ "pabsw\0"
+ "packssdw\0"
+ "packsswb\0"
+ "packusdw\0"
+ "packuswb\0"
+ "paddb\0"
+ "paddd\0"
+ "paddq\0"
+ "paddsb\0"
+ "paddsw\0"
+ "paddusb\0"
+ "paddusw\0"
+ "paddw\0"
+ "palignr\0"
+ "pand\0"
+ "pandn\0"
+ "pause\0"
+ "pavgb\0"
+ "pavgw\0"
+ "pblendvb\0"
+ "pblendw\0"
+ "pclmulqdq\0"
+ "pcmpeqb\0"
+ "pcmpeqd\0"
+ "pcmpeqq\0"
+ "pcmpeqw\0"
+ "pcmpestri\0"
+ "pcmpestrm\0"
+ "pcmpgtb\0"
+ "pcmpgtd\0"
+ "pcmpgtq\0"
+ "pcmpgtw\0"
+ "pcmpistri\0"
+ "pcmpistrm\0"
+ "pdep\0"
+ "pext\0"
+ "pextrb\0"
+ "pextrd\0"
+ "pextrq\0"
+ "pextrw\0"
+ "pf2id\0"
+ "pf2iw\0"
+ "pfacc\0"
+ "pfadd\0"
+ "pfcmpeq\0"
+ "pfcmpge\0"
+ "pfcmpgt\0"
+ "pfmax\0"
+ "pfmin\0"
+ "pfmul\0"
+ "pfnacc\0"
+ "pfpnacc\0"
+ "pfrcp\0"
+ "pfrcpit1\0"
+ "pfrcpit2\0"
+ "pfrsqit1\0"
+ "pfrsqrt\0"
+ "pfsub\0"
+ "pfsubr\0"
+ "phaddd\0"
+ "phaddsw\0"
+ "phaddw\0"
+ "phminposuw\0"
+ "phsubd\0"
+ "phsubsw\0"
+ "phsubw\0"
+ "pi2fd\0"
+ "pi2fw\0"
+ "pinsrb\0"
+ "pinsrd\0"
+ "pinsrq\0"
+ "pinsrw\0"
+ "pmaddubsw\0"
+ "pmaddwd\0"
+ "pmaxsb\0"
+ "pmaxsd\0"
+ "pmaxsw\0"
+ "pmaxub\0"
+ "pmaxud\0"
+ "pmaxuw\0"
+ "pminsb\0"
+ "pminsd\0"
+ "pminsw\0"
+ "pminub\0"
+ "pminud\0"
+ "pminuw\0"
+ "pmovmskb\0"
+ "pmovsxbd\0"
+ "pmovsxbq\0"
+ "pmovsxbw\0"
+ "pmovsxdq\0"
+ "pmovsxwd\0"
+ "pmovsxwq\0"
+ "pmovzxbd\0"
+ "pmovzxbq\0"
+ "pmovzxbw\0"
+ "pmovzxdq\0"
+ "pmovzxwd\0"
+ "pmovzxwq\0"
+ "pmuldq\0"
+ "pmulhrsw\0"
+ "pmulhuw\0"
+ "pmulhw\0"
+ "pmulld\0"
+ "pmullw\0"
+ "pmuludq\0"
+ "pop\0"
+ "popa\0"
+ "popcnt\0"
+ "popf\0"
+ "por\0"
+ "prefetch\0"
+ "prefetch_3dnow\0"
+ "prefetchw_3dnow\0"
+ "psadbw\0"
+ "pshufb\0"
+ "pshufd\0"
+ "pshufhw\0"
+ "pshuflw\0"
+ "pshufw\0"
+ "psignb\0"
+ "psignd\0"
+ "psignw\0"
+ "pslld\0"
+ "pslldq\0"
+ "psllq\0"
+ "psllw\0"
+ "psrad\0"
+ "psraw\0"
+ "psrld\0"
+ "psrldq\0"
+ "psrlq\0"
+ "psrlw\0"
+ "psubb\0"
+ "psubd\0"
+ "psubq\0"
+ "psubsb\0"
+ "psubsw\0"
+ "psubusb\0"
+ "psubusw\0"
+ "psubw\0"
+ "pswapd\0"
+ "ptest\0"
+ "punpckhbw\0"
+ "punpckhdq\0"
+ "punpckhqdq\0"
+ "punpckhwd\0"
+ "punpcklbw\0"
+ "punpckldq\0"
+ "punpcklqdq\0"
+ "punpcklwd\0"
+ "push\0"
+ "pusha\0"
+ "pushf\0"
+ "pxor\0"
+ "rcl\0"
+ "rcpps\0"
+ "rcpss\0"
+ "rcr\0"
+ "rdfsbase\0"
+ "rdgsbase\0"
+ "rdrand\0"
+ "rdtsc\0"
+ "rdtscp\0"
+ "rep lods_b\0"
+ "rep lods_d\0"
+ "rep lods_q\0"
+ "rep lods_w\0"
+ "rep movs_b\0"
+ "rep movs_d\0"
+ "rep movs_q\0"
+ "rep movs_w\0"
+ "rep stos_b\0"
+ "rep stos_d\0"
+ "rep stos_q\0"
+ "rep stos_w\0"
+ "repe cmps_b\0"
+ "repe cmps_d\0"
+ "repe cmps_q\0"
+ "repe cmps_w\0"
+ "repe scas_b\0"
+ "repe scas_d\0"
+ "repe scas_q\0"
+ "repe scas_w\0"
+ "repne cmps_b\0"
+ "repne cmps_d\0"
+ "repne cmps_q\0"
+ "repne cmps_w\0"
+ "repne scas_b\0"
+ "repne scas_d\0"
+ "repne scas_q\0"
+ "repne scas_w\0"
+ "ret\0"
+ "rol\0"
+ "ror\0"
+ "rorx\0"
+ "roundpd\0"
+ "roundps\0"
+ "roundsd\0"
+ "roundss\0"
+ "rsqrtps\0"
+ "rsqrtss\0"
+ "sahf\0"
+ "sal\0"
+ "sar\0"
+ "sarx\0"
+ "sbb\0"
+ "scas_b\0"
+ "scas_d\0"
+ "scas_q\0"
+ "scas_w\0"
+ "seta\0"
+ "setae\0"
+ "setb\0"
+ "setbe\0"
+ "setc\0"
+ "sete\0"
+ "setg\0"
+ "setge\0"
+ "setl\0"
+ "setle\0"
+ "setna\0"
+ "setnae\0"
+ "setnb\0"
+ "setnbe\0"
+ "setnc\0"
+ "setne\0"
+ "setng\0"
+ "setnge\0"
+ "setnl\0"
+ "setnle\0"
+ "setno\0"
+ "setnp\0"
+ "setns\0"
+ "setnz\0"
+ "seto\0"
+ "setp\0"
+ "setpe\0"
+ "setpo\0"
+ "sets\0"
+ "setz\0"
+ "sfence\0"
+ "shl\0"
+ "shld\0"
+ "shlx\0"
+ "shr\0"
+ "shrd\0"
+ "shrx\0"
+ "shufpd\0"
+ "shufps\0"
+ "sqrtpd\0"
+ "sqrtps\0"
+ "sqrtsd\0"
+ "sqrtss\0"
+ "stc\0"
+ "std\0"
+ "stmxcsr\0"
+ "stos_b\0"
+ "stos_d\0"
+ "stos_q\0"
+ "stos_w\0"
+ "sub\0"
+ "subpd\0"
+ "subps\0"
+ "subsd\0"
+ "subss\0"
+ "test\0"
+ "tzcnt\0"
+ "ucomisd\0"
+ "ucomiss\0"
+ "ud2\0"
+ "unpckhpd\0"
+ "unpckhps\0"
+ "unpcklpd\0"
+ "unpcklps\0"
+ "vaddpd\0"
+ "vaddps\0"
+ "vaddsd\0"
+ "vaddss\0"
+ "vaddsubpd\0"
+ "vaddsubps\0"
+ "vaesdec\0"
+ "vaesdeclast\0"
+ "vaesenc\0"
+ "vaesenclast\0"
+ "vaesimc\0"
+ "vaeskeygenassist\0"
+ "vandnpd\0"
+ "vandnps\0"
+ "vandpd\0"
+ "vandps\0"
+ "vblendpd\0"
+ "vblendps\0"
+ "vblendvpd\0"
+ "vblendvps\0"
+ "vbroadcastf128\0"
+ "vbroadcasti128\0"
+ "vbroadcastsd\0"
+ "vbroadcastss\0"
+ "vcmppd\0"
+ "vcmpps\0"
+ "vcmpsd\0"
+ "vcmpss\0"
+ "vcomisd\0"
+ "vcomiss\0"
+ "vcvtdq2pd\0"
+ "vcvtdq2ps\0"
+ "vcvtpd2dq\0"
+ "vcvtpd2ps\0"
+ "vcvtph2ps\0"
+ "vcvtps2dq\0"
+ "vcvtps2pd\0"
+ "vcvtps2ph\0"
+ "vcvtsd2si\0"
+ "vcvtsd2ss\0"
+ "vcvtsi2sd\0"
+ "vcvtsi2ss\0"
+ "vcvtss2sd\0"
+ "vcvtss2si\0"
+ "vcvttpd2dq\0"
+ "vcvttps2dq\0"
+ "vcvttsd2si\0"
+ "vcvttss2si\0"
+ "vdivpd\0"
+ "vdivps\0"
+ "vdivsd\0"
+ "vdivss\0"
+ "vdppd\0"
+ "vdpps\0"
+ "vextractf128\0"
+ "vextracti128\0"
+ "vextractps\0"
+ "vfmadd132pd\0"
+ "vfmadd132ps\0"
+ "vfmadd132sd\0"
+ "vfmadd132ss\0"
+ "vfmadd213pd\0"
+ "vfmadd213ps\0"
+ "vfmadd213sd\0"
+ "vfmadd213ss\0"
+ "vfmadd231pd\0"
+ "vfmadd231ps\0"
+ "vfmadd231sd\0"
+ "vfmadd231ss\0"
+ "vfmaddpd\0"
+ "vfmaddps\0"
+ "vfmaddsd\0"
+ "vfmaddss\0"
+ "vfmaddsub132pd\0"
+ "vfmaddsub132ps\0"
+ "vfmaddsub213pd\0"
+ "vfmaddsub213ps\0"
+ "vfmaddsub231pd\0"
+ "vfmaddsub231ps\0"
+ "vfmaddsubpd\0"
+ "vfmaddsubps\0"
+ "vfmsub132pd\0"
+ "vfmsub132ps\0"
+ "vfmsub132sd\0"
+ "vfmsub132ss\0"
+ "vfmsub213pd\0"
+ "vfmsub213ps\0"
+ "vfmsub213sd\0"
+ "vfmsub213ss\0"
+ "vfmsub231pd\0"
+ "vfmsub231ps\0"
+ "vfmsub231sd\0"
+ "vfmsub231ss\0"
+ "vfmsubadd132pd\0"
+ "vfmsubadd132ps\0"
+ "vfmsubadd213pd\0"
+ "vfmsubadd213ps\0"
+ "vfmsubadd231pd\0"
+ "vfmsubadd231ps\0"
+ "vfmsubaddpd\0"
+ "vfmsubaddps\0"
+ "vfmsubpd\0"
+ "vfmsubps\0"
+ "vfmsubsd\0"
+ "vfmsubss\0"
+ "vfnmadd132pd\0"
+ "vfnmadd132ps\0"
+ "vfnmadd132sd\0"
+ "vfnmadd132ss\0"
+ "vfnmadd213pd\0"
+ "vfnmadd213ps\0"
+ "vfnmadd213sd\0"
+ "vfnmadd213ss\0"
+ "vfnmadd231pd\0"
+ "vfnmadd231ps\0"
+ "vfnmadd231sd\0"
+ "vfnmadd231ss\0"
+ "vfnmaddpd\0"
+ "vfnmaddps\0"
+ "vfnmaddsd\0"
+ "vfnmaddss\0"
+ "vfnmsub132pd\0"
+ "vfnmsub132ps\0"
+ "vfnmsub132sd\0"
+ "vfnmsub132ss\0"
+ "vfnmsub213pd\0"
+ "vfnmsub213ps\0"
+ "vfnmsub213sd\0"
+ "vfnmsub213ss\0"
+ "vfnmsub231pd\0"
+ "vfnmsub231ps\0"
+ "vfnmsub231sd\0"
+ "vfnmsub231ss\0"
+ "vfnmsubpd\0"
+ "vfnmsubps\0"
+ "vfnmsubsd\0"
+ "vfnmsubss\0"
+ "vfrczpd\0"
+ "vfrczps\0"
+ "vfrczsd\0"
+ "vfrczss\0"
+ "vgatherdpd\0"
+ "vgatherdps\0"
+ "vgatherqpd\0"
+ "vgatherqps\0"
+ "vhaddpd\0"
+ "vhaddps\0"
+ "vhsubpd\0"
+ "vhsubps\0"
+ "vinsertf128\0"
+ "vinserti128\0"
+ "vinsertps\0"
+ "vlddqu\0"
+ "vldmxcsr\0"
+ "vmaskmovdqu\0"
+ "vmaskmovpd\0"
+ "vmaskmovps\0"
+ "vmaxpd\0"
+ "vmaxps\0"
+ "vmaxsd\0"
+ "vmaxss\0"
+ "vminpd\0"
+ "vminps\0"
+ "vminsd\0"
+ "vminss\0"
+ "vmovapd\0"
+ "vmovaps\0"
+ "vmovd\0"
+ "vmovddup\0"
+ "vmovdqa\0"
+ "vmovdqu\0"
+ "vmovhlps\0"
+ "vmovhpd\0"
+ "vmovhps\0"
+ "vmovlhps\0"
+ "vmovlpd\0"
+ "vmovlps\0"
+ "vmovmskpd\0"
+ "vmovmskps\0"
+ "vmovntdq\0"
+ "vmovntdqa\0"
+ "vmovntpd\0"
+ "vmovntps\0"
+ "vmovq\0"
+ "vmovsd\0"
+ "vmovshdup\0"
+ "vmovsldup\0"
+ "vmovss\0"
+ "vmovupd\0"
+ "vmovups\0"
+ "vmpsadbw\0"
+ "vmulpd\0"
+ "vmulps\0"
+ "vmulsd\0"
+ "vmulss\0"
+ "vorpd\0"
+ "vorps\0"
+ "vpabsb\0"
+ "vpabsd\0"
+ "vpabsw\0"
+ "vpackssdw\0"
+ "vpacksswb\0"
+ "vpackusdw\0"
+ "vpackuswb\0"
+ "vpaddb\0"
+ "vpaddd\0"
+ "vpaddq\0"
+ "vpaddsb\0"
+ "vpaddsw\0"
+ "vpaddusb\0"
+ "vpaddusw\0"
+ "vpaddw\0"
+ "vpalignr\0"
+ "vpand\0"
+ "vpandn\0"
+ "vpavgb\0"
+ "vpavgw\0"
+ "vpblendd\0"
+ "vpblendvb\0"
+ "vpblendw\0"
+ "vpbroadcastb\0"
+ "vpbroadcastd\0"
+ "vpbroadcastq\0"
+ "vpbroadcastw\0"
+ "vpclmulqdq\0"
+ "vpcmov\0"
+ "vpcmpeqb\0"
+ "vpcmpeqd\0"
+ "vpcmpeqq\0"
+ "vpcmpeqw\0"
+ "vpcmpestri\0"
+ "vpcmpestrm\0"
+ "vpcmpgtb\0"
+ "vpcmpgtd\0"
+ "vpcmpgtq\0"
+ "vpcmpgtw\0"
+ "vpcmpistri\0"
+ "vpcmpistrm\0"
+ "vpcomb\0"
+ "vpcomd\0"
+ "vpcomq\0"
+ "vpcomub\0"
+ "vpcomud\0"
+ "vpcomuq\0"
+ "vpcomuw\0"
+ "vpcomw\0"
+ "vperm2f128\0"
+ "vperm2i128\0"
+ "vpermd\0"
+ "vpermil2pd\0"
+ "vpermil2ps\0"
+ "vpermilpd\0"
+ "vpermilps\0"
+ "vpermpd\0"
+ "vpermps\0"
+ "vpermq\0"
+ "vpextrb\0"
+ "vpextrd\0"
+ "vpextrq\0"
+ "vpextrw\0"
+ "vpgatherdd\0"
+ "vpgatherdq\0"
+ "vpgatherqd\0"
+ "vpgatherqq\0"
+ "vphaddbd\0"
+ "vphaddbq\0"
+ "vphaddbw\0"
+ "vphaddd\0"
+ "vphadddq\0"
+ "vphaddsw\0"
+ "vphaddubd\0"
+ "vphaddubq\0"
+ "vphaddubw\0"
+ "vphaddudq\0"
+ "vphadduwd\0"
+ "vphadduwq\0"
+ "vphaddw\0"
+ "vphaddwd\0"
+ "vphaddwq\0"
+ "vphminposuw\0"
+ "vphsubbw\0"
+ "vphsubd\0"
+ "vphsubdq\0"
+ "vphsubsw\0"
+ "vphsubw\0"
+ "vphsubwd\0"
+ "vpinsrb\0"
+ "vpinsrd\0"
+ "vpinsrq\0"
+ "vpinsrw\0"
+ "vpmacsdd\0"
+ "vpmacsdqh\0"
+ "vpmacsdql\0"
+ "vpmacssdd\0"
+ "vpmacssdqh\0"
+ "vpmacssdql\0"
+ "vpmacsswd\0"
+ "vpmacssww\0"
+ "vpmacswd\0"
+ "vpmacsww\0"
+ "vpmadcsswd\0"
+ "vpmadcswd\0"
+ "vpmaddubsw\0"
+ "vpmaddwd\0"
+ "vpmaskmovd\0"
+ "vpmaskmovq\0"
+ "vpmaxsb\0"
+ "vpmaxsd\0"
+ "vpmaxsw\0"
+ "vpmaxub\0"
+ "vpmaxud\0"
+ "vpmaxuw\0"
+ "vpminsb\0"
+ "vpminsd\0"
+ "vpminsw\0"
+ "vpminub\0"
+ "vpminud\0"
+ "vpminuw\0"
+ "vpmovmskb\0"
+ "vpmovsxbd\0"
+ "vpmovsxbq\0"
+ "vpmovsxbw\0"
+ "vpmovsxdq\0"
+ "vpmovsxwd\0"
+ "vpmovsxwq\0"
+ "vpmovzxbd\0"
+ "vpmovzxbq\0"
+ "vpmovzxbw\0"
+ "vpmovzxdq\0"
+ "vpmovzxwd\0"
+ "vpmovzxwq\0"
+ "vpmuldq\0"
+ "vpmulhrsw\0"
+ "vpmulhuw\0"
+ "vpmulhw\0"
+ "vpmulld\0"
+ "vpmullw\0"
+ "vpmuludq\0"
+ "vpor\0"
+ "vpperm\0"
+ "vprotb\0"
+ "vprotd\0"
+ "vprotq\0"
+ "vprotw\0"
+ "vpsadbw\0"
+ "vpshab\0"
+ "vpshad\0"
+ "vpshaq\0"
+ "vpshaw\0"
+ "vpshlb\0"
+ "vpshld\0"
+ "vpshlq\0"
+ "vpshlw\0"
+ "vpshufb\0"
+ "vpshufd\0"
+ "vpshufhw\0"
+ "vpshuflw\0"
+ "vpsignb\0"
+ "vpsignd\0"
+ "vpsignw\0"
+ "vpslld\0"
+ "vpslldq\0"
+ "vpsllq\0"
+ "vpsllvd\0"
+ "vpsllvq\0"
+ "vpsllw\0"
+ "vpsrad\0"
+ "vpsravd\0"
+ "vpsraw\0"
+ "vpsrld\0"
+ "vpsrldq\0"
+ "vpsrlq\0"
+ "vpsrlvd\0"
+ "vpsrlvq\0"
+ "vpsrlw\0"
+ "vpsubb\0"
+ "vpsubd\0"
+ "vpsubq\0"
+ "vpsubsb\0"
+ "vpsubsw\0"
+ "vpsubusb\0"
+ "vpsubusw\0"
+ "vpsubw\0"
+ "vptest\0"
+ "vpunpckhbw\0"
+ "vpunpckhdq\0"
+ "vpunpckhqdq\0"
+ "vpunpckhwd\0"
+ "vpunpcklbw\0"
+ "vpunpckldq\0"
+ "vpunpcklqdq\0"
+ "vpunpcklwd\0"
+ "vpxor\0"
+ "vrcpps\0"
+ "vrcpss\0"
+ "vroundpd\0"
+ "vroundps\0"
+ "vroundsd\0"
+ "vroundss\0"
+ "vrsqrtps\0"
+ "vrsqrtss\0"
+ "vshufpd\0"
+ "vshufps\0"
+ "vsqrtpd\0"
+ "vsqrtps\0"
+ "vsqrtsd\0"
+ "vsqrtss\0"
+ "vstmxcsr\0"
+ "vsubpd\0"
+ "vsubps\0"
+ "vsubsd\0"
+ "vsubss\0"
+ "vtestpd\0"
+ "vtestps\0"
+ "vucomisd\0"
+ "vucomiss\0"
+ "vunpckhpd\0"
+ "vunpckhps\0"
+ "vunpcklpd\0"
+ "vunpcklps\0"
+ "vxorpd\0"
+ "vxorps\0"
+ "vzeroall\0"
+ "vzeroupper\0"
+ "wrfsbase\0"
+ "wrgsbase\0"
+ "xadd\0"
+ "xchg\0"
+ "xor\0"
+ "xorpd\0"
+ "xorps\0";
+
+// Automatically generated, do not edit.
+enum kX86InstAlphaIndex {
+ kX86InstAlphaIndexFirst = 'a',
+ kX86InstAlphaIndexLast = 'z',
+ kX86InstAlphaIndexInvalid = 0xFFFF
+};
+
+// Automatically generated, do not edit.
+static const uint16_t _x86InstAlphaIndex[26] = {
+ kX86InstIdAdc,
+ kX86InstIdBextr,
+ kX86InstIdCall,
+ kX86InstIdDaa,
+ kX86InstIdEmms,
+ kX86InstIdF2xm1,
+ 0xFFFF,
+ kX86InstIdHaddpd,
+ kX86InstIdIdiv,
+ kX86InstIdJa,
+ 0xFFFF,
+ kX86InstIdLahf,
+ kX86InstIdMaskmovdqu,
+ kX86InstIdNeg,
+ kX86InstIdOr,
+ kX86InstIdPabsb,
+ 0xFFFF,
+ kX86InstIdRcl,
+ kX86InstIdSahf,
+ kX86InstIdTest,
+ kX86InstIdUcomisd,
+ kX86InstIdVaddpd,
+ kX86InstIdWrfsbase,
+ kX86InstIdXadd,
+ 0xFFFF,
+ 0xFFFF
+};
+
+// Automatically generated, do not edit.
+enum kX86InstData_NameIndex {
+ kInstIdNone_NameIndex = 0,
+ kX86InstIdAdc_NameIndex = 1,
+ kX86InstIdAdd_NameIndex = 5,
+ kX86InstIdAddpd_NameIndex = 9,
+ kX86InstIdAddps_NameIndex = 15,
+ kX86InstIdAddsd_NameIndex = 21,
+ kX86InstIdAddss_NameIndex = 27,
+ kX86InstIdAddsubpd_NameIndex = 33,
+ kX86InstIdAddsubps_NameIndex = 42,
+ kX86InstIdAesdec_NameIndex = 51,
+ kX86InstIdAesdeclast_NameIndex = 58,
+ kX86InstIdAesenc_NameIndex = 69,
+ kX86InstIdAesenclast_NameIndex = 76,
+ kX86InstIdAesimc_NameIndex = 87,
+ kX86InstIdAeskeygenassist_NameIndex = 94,
+ kX86InstIdAnd_NameIndex = 110,
+ kX86InstIdAndn_NameIndex = 114,
+ kX86InstIdAndnpd_NameIndex = 119,
+ kX86InstIdAndnps_NameIndex = 126,
+ kX86InstIdAndpd_NameIndex = 133,
+ kX86InstIdAndps_NameIndex = 139,
+ kX86InstIdBextr_NameIndex = 145,
+ kX86InstIdBlendpd_NameIndex = 151,
+ kX86InstIdBlendps_NameIndex = 159,
+ kX86InstIdBlendvpd_NameIndex = 167,
+ kX86InstIdBlendvps_NameIndex = 176,
+ kX86InstIdBlsi_NameIndex = 185,
+ kX86InstIdBlsmsk_NameIndex = 190,
+ kX86InstIdBlsr_NameIndex = 197,
+ kX86InstIdBsf_NameIndex = 202,
+ kX86InstIdBsr_NameIndex = 206,
+ kX86InstIdBswap_NameIndex = 210,
+ kX86InstIdBt_NameIndex = 216,
+ kX86InstIdBtc_NameIndex = 219,
+ kX86InstIdBtr_NameIndex = 223,
+ kX86InstIdBts_NameIndex = 227,
+ kX86InstIdBzhi_NameIndex = 231,
+ kX86InstIdCall_NameIndex = 236,
+ kX86InstIdCbw_NameIndex = 241,
+ kX86InstIdCdq_NameIndex = 245,
+ kX86InstIdCdqe_NameIndex = 249,
+ kX86InstIdClc_NameIndex = 254,
+ kX86InstIdCld_NameIndex = 258,
+ kX86InstIdClflush_NameIndex = 262,
+ kX86InstIdCmc_NameIndex = 270,
+ kX86InstIdCmova_NameIndex = 274,
+ kX86InstIdCmovae_NameIndex = 280,
+ kX86InstIdCmovb_NameIndex = 287,
+ kX86InstIdCmovbe_NameIndex = 293,
+ kX86InstIdCmovc_NameIndex = 300,
+ kX86InstIdCmove_NameIndex = 306,
+ kX86InstIdCmovg_NameIndex = 312,
+ kX86InstIdCmovge_NameIndex = 318,
+ kX86InstIdCmovl_NameIndex = 325,
+ kX86InstIdCmovle_NameIndex = 331,
+ kX86InstIdCmovna_NameIndex = 338,
+ kX86InstIdCmovnae_NameIndex = 345,
+ kX86InstIdCmovnb_NameIndex = 353,
+ kX86InstIdCmovnbe_NameIndex = 360,
+ kX86InstIdCmovnc_NameIndex = 368,
+ kX86InstIdCmovne_NameIndex = 375,
+ kX86InstIdCmovng_NameIndex = 382,
+ kX86InstIdCmovnge_NameIndex = 389,
+ kX86InstIdCmovnl_NameIndex = 397,
+ kX86InstIdCmovnle_NameIndex = 404,
+ kX86InstIdCmovno_NameIndex = 412,
+ kX86InstIdCmovnp_NameIndex = 419,
+ kX86InstIdCmovns_NameIndex = 426,
+ kX86InstIdCmovnz_NameIndex = 433,
+ kX86InstIdCmovo_NameIndex = 440,
+ kX86InstIdCmovp_NameIndex = 446,
+ kX86InstIdCmovpe_NameIndex = 452,
+ kX86InstIdCmovpo_NameIndex = 459,
+ kX86InstIdCmovs_NameIndex = 466,
+ kX86InstIdCmovz_NameIndex = 472,
+ kX86InstIdCmp_NameIndex = 478,
+ kX86InstIdCmppd_NameIndex = 482,
+ kX86InstIdCmpps_NameIndex = 488,
+ kX86InstIdCmpsB_NameIndex = 494,
+ kX86InstIdCmpsD_NameIndex = 501,
+ kX86InstIdCmpsQ_NameIndex = 508,
+ kX86InstIdCmpsW_NameIndex = 515,
+ kX86InstIdCmpsd_NameIndex = 522,
+ kX86InstIdCmpss_NameIndex = 528,
+ kX86InstIdCmpxchg_NameIndex = 534,
+ kX86InstIdCmpxchg16b_NameIndex = 542,
+ kX86InstIdCmpxchg8b_NameIndex = 553,
+ kX86InstIdComisd_NameIndex = 563,
+ kX86InstIdComiss_NameIndex = 570,
+ kX86InstIdCpuid_NameIndex = 577,
+ kX86InstIdCqo_NameIndex = 583,
+ kX86InstIdCrc32_NameIndex = 587,
+ kX86InstIdCvtdq2pd_NameIndex = 593,
+ kX86InstIdCvtdq2ps_NameIndex = 602,
+ kX86InstIdCvtpd2dq_NameIndex = 611,
+ kX86InstIdCvtpd2pi_NameIndex = 620,
+ kX86InstIdCvtpd2ps_NameIndex = 629,
+ kX86InstIdCvtpi2pd_NameIndex = 638,
+ kX86InstIdCvtpi2ps_NameIndex = 647,
+ kX86InstIdCvtps2dq_NameIndex = 656,
+ kX86InstIdCvtps2pd_NameIndex = 665,
+ kX86InstIdCvtps2pi_NameIndex = 674,
+ kX86InstIdCvtsd2si_NameIndex = 683,
+ kX86InstIdCvtsd2ss_NameIndex = 692,
+ kX86InstIdCvtsi2sd_NameIndex = 701,
+ kX86InstIdCvtsi2ss_NameIndex = 710,
+ kX86InstIdCvtss2sd_NameIndex = 719,
+ kX86InstIdCvtss2si_NameIndex = 728,
+ kX86InstIdCvttpd2dq_NameIndex = 737,
+ kX86InstIdCvttpd2pi_NameIndex = 747,
+ kX86InstIdCvttps2dq_NameIndex = 757,
+ kX86InstIdCvttps2pi_NameIndex = 767,
+ kX86InstIdCvttsd2si_NameIndex = 777,
+ kX86InstIdCvttss2si_NameIndex = 787,
+ kX86InstIdCwd_NameIndex = 797,
+ kX86InstIdCwde_NameIndex = 801,
+ kX86InstIdDaa_NameIndex = 806,
+ kX86InstIdDas_NameIndex = 810,
+ kX86InstIdDec_NameIndex = 814,
+ kX86InstIdDiv_NameIndex = 818,
+ kX86InstIdDivpd_NameIndex = 822,
+ kX86InstIdDivps_NameIndex = 828,
+ kX86InstIdDivsd_NameIndex = 834,
+ kX86InstIdDivss_NameIndex = 840,
+ kX86InstIdDppd_NameIndex = 846,
+ kX86InstIdDpps_NameIndex = 851,
+ kX86InstIdEmms_NameIndex = 856,
+ kX86InstIdEnter_NameIndex = 861,
+ kX86InstIdExtractps_NameIndex = 867,
+ kX86InstIdF2xm1_NameIndex = 877,
+ kX86InstIdFabs_NameIndex = 883,
+ kX86InstIdFadd_NameIndex = 888,
+ kX86InstIdFaddp_NameIndex = 893,
+ kX86InstIdFbld_NameIndex = 899,
+ kX86InstIdFbstp_NameIndex = 904,
+ kX86InstIdFchs_NameIndex = 910,
+ kX86InstIdFclex_NameIndex = 915,
+ kX86InstIdFcmovb_NameIndex = 921,
+ kX86InstIdFcmovbe_NameIndex = 928,
+ kX86InstIdFcmove_NameIndex = 936,
+ kX86InstIdFcmovnb_NameIndex = 943,
+ kX86InstIdFcmovnbe_NameIndex = 951,
+ kX86InstIdFcmovne_NameIndex = 960,
+ kX86InstIdFcmovnu_NameIndex = 968,
+ kX86InstIdFcmovu_NameIndex = 976,
+ kX86InstIdFcom_NameIndex = 983,
+ kX86InstIdFcomi_NameIndex = 988,
+ kX86InstIdFcomip_NameIndex = 994,
+ kX86InstIdFcomp_NameIndex = 1001,
+ kX86InstIdFcompp_NameIndex = 1007,
+ kX86InstIdFcos_NameIndex = 1014,
+ kX86InstIdFdecstp_NameIndex = 1019,
+ kX86InstIdFdiv_NameIndex = 1027,
+ kX86InstIdFdivp_NameIndex = 1032,
+ kX86InstIdFdivr_NameIndex = 1038,
+ kX86InstIdFdivrp_NameIndex = 1044,
+ kX86InstIdFemms_NameIndex = 1051,
+ kX86InstIdFfree_NameIndex = 1057,
+ kX86InstIdFiadd_NameIndex = 1063,
+ kX86InstIdFicom_NameIndex = 1069,
+ kX86InstIdFicomp_NameIndex = 1075,
+ kX86InstIdFidiv_NameIndex = 1082,
+ kX86InstIdFidivr_NameIndex = 1088,
+ kX86InstIdFild_NameIndex = 1095,
+ kX86InstIdFimul_NameIndex = 1100,
+ kX86InstIdFincstp_NameIndex = 1106,
+ kX86InstIdFinit_NameIndex = 1114,
+ kX86InstIdFist_NameIndex = 1120,
+ kX86InstIdFistp_NameIndex = 1125,
+ kX86InstIdFisttp_NameIndex = 1131,
+ kX86InstIdFisub_NameIndex = 1138,
+ kX86InstIdFisubr_NameIndex = 1144,
+ kX86InstIdFld_NameIndex = 1151,
+ kX86InstIdFld1_NameIndex = 1155,
+ kX86InstIdFldcw_NameIndex = 1160,
+ kX86InstIdFldenv_NameIndex = 1166,
+ kX86InstIdFldl2e_NameIndex = 1173,
+ kX86InstIdFldl2t_NameIndex = 1180,
+ kX86InstIdFldlg2_NameIndex = 1187,
+ kX86InstIdFldln2_NameIndex = 1194,
+ kX86InstIdFldpi_NameIndex = 1201,
+ kX86InstIdFldz_NameIndex = 1207,
+ kX86InstIdFmul_NameIndex = 1212,
+ kX86InstIdFmulp_NameIndex = 1217,
+ kX86InstIdFnclex_NameIndex = 1223,
+ kX86InstIdFninit_NameIndex = 1230,
+ kX86InstIdFnop_NameIndex = 1237,
+ kX86InstIdFnsave_NameIndex = 1242,
+ kX86InstIdFnstcw_NameIndex = 1249,
+ kX86InstIdFnstenv_NameIndex = 1256,
+ kX86InstIdFnstsw_NameIndex = 1264,
+ kX86InstIdFpatan_NameIndex = 1271,
+ kX86InstIdFprem_NameIndex = 1278,
+ kX86InstIdFprem1_NameIndex = 1284,
+ kX86InstIdFptan_NameIndex = 1291,
+ kX86InstIdFrndint_NameIndex = 1297,
+ kX86InstIdFrstor_NameIndex = 1305,
+ kX86InstIdFsave_NameIndex = 1312,
+ kX86InstIdFscale_NameIndex = 1318,
+ kX86InstIdFsin_NameIndex = 1325,
+ kX86InstIdFsincos_NameIndex = 1330,
+ kX86InstIdFsqrt_NameIndex = 1338,
+ kX86InstIdFst_NameIndex = 1344,
+ kX86InstIdFstcw_NameIndex = 1348,
+ kX86InstIdFstenv_NameIndex = 1354,
+ kX86InstIdFstp_NameIndex = 1361,
+ kX86InstIdFstsw_NameIndex = 1366,
+ kX86InstIdFsub_NameIndex = 1372,
+ kX86InstIdFsubp_NameIndex = 1377,
+ kX86InstIdFsubr_NameIndex = 1383,
+ kX86InstIdFsubrp_NameIndex = 1389,
+ kX86InstIdFtst_NameIndex = 1396,
+ kX86InstIdFucom_NameIndex = 1401,
+ kX86InstIdFucomi_NameIndex = 1407,
+ kX86InstIdFucomip_NameIndex = 1414,
+ kX86InstIdFucomp_NameIndex = 1422,
+ kX86InstIdFucompp_NameIndex = 1429,
+ kX86InstIdFwait_NameIndex = 1437,
+ kX86InstIdFxam_NameIndex = 1443,
+ kX86InstIdFxch_NameIndex = 1448,
+ kX86InstIdFxrstor_NameIndex = 1453,
+ kX86InstIdFxsave_NameIndex = 1461,
+ kX86InstIdFxtract_NameIndex = 1468,
+ kX86InstIdFyl2x_NameIndex = 1476,
+ kX86InstIdFyl2xp1_NameIndex = 1482,
+ kX86InstIdHaddpd_NameIndex = 1490,
+ kX86InstIdHaddps_NameIndex = 1497,
+ kX86InstIdHsubpd_NameIndex = 1504,
+ kX86InstIdHsubps_NameIndex = 1511,
+ kX86InstIdIdiv_NameIndex = 1518,
+ kX86InstIdImul_NameIndex = 1523,
+ kX86InstIdInc_NameIndex = 1528,
+ kX86InstIdInsertps_NameIndex = 1532,
+ kX86InstIdInt_NameIndex = 1541,
+ kX86InstIdJa_NameIndex = 1545,
+ kX86InstIdJae_NameIndex = 1548,
+ kX86InstIdJb_NameIndex = 1552,
+ kX86InstIdJbe_NameIndex = 1555,
+ kX86InstIdJc_NameIndex = 1559,
+ kX86InstIdJe_NameIndex = 1562,
+ kX86InstIdJg_NameIndex = 1565,
+ kX86InstIdJge_NameIndex = 1568,
+ kX86InstIdJl_NameIndex = 1572,
+ kX86InstIdJle_NameIndex = 1575,
+ kX86InstIdJna_NameIndex = 1579,
+ kX86InstIdJnae_NameIndex = 1583,
+ kX86InstIdJnb_NameIndex = 1588,
+ kX86InstIdJnbe_NameIndex = 1592,
+ kX86InstIdJnc_NameIndex = 1597,
+ kX86InstIdJne_NameIndex = 1601,
+ kX86InstIdJng_NameIndex = 1605,
+ kX86InstIdJnge_NameIndex = 1609,
+ kX86InstIdJnl_NameIndex = 1614,
+ kX86InstIdJnle_NameIndex = 1618,
+ kX86InstIdJno_NameIndex = 1623,
+ kX86InstIdJnp_NameIndex = 1627,
+ kX86InstIdJns_NameIndex = 1631,
+ kX86InstIdJnz_NameIndex = 1635,
+ kX86InstIdJo_NameIndex = 1639,
+ kX86InstIdJp_NameIndex = 1642,
+ kX86InstIdJpe_NameIndex = 1645,
+ kX86InstIdJpo_NameIndex = 1649,
+ kX86InstIdJs_NameIndex = 1653,
+ kX86InstIdJz_NameIndex = 1656,
+ kX86InstIdJecxz_NameIndex = 1659,
+ kX86InstIdJmp_NameIndex = 1665,
+ kX86InstIdLahf_NameIndex = 1669,
+ kX86InstIdLddqu_NameIndex = 1674,
+ kX86InstIdLdmxcsr_NameIndex = 1680,
+ kX86InstIdLea_NameIndex = 1688,
+ kX86InstIdLeave_NameIndex = 1692,
+ kX86InstIdLfence_NameIndex = 1698,
+ kX86InstIdLodsB_NameIndex = 1705,
+ kX86InstIdLodsD_NameIndex = 1712,
+ kX86InstIdLodsQ_NameIndex = 1719,
+ kX86InstIdLodsW_NameIndex = 1726,
+ kX86InstIdLzcnt_NameIndex = 1733,
+ kX86InstIdMaskmovdqu_NameIndex = 1739,
+ kX86InstIdMaskmovq_NameIndex = 1750,
+ kX86InstIdMaxpd_NameIndex = 1759,
+ kX86InstIdMaxps_NameIndex = 1765,
+ kX86InstIdMaxsd_NameIndex = 1771,
+ kX86InstIdMaxss_NameIndex = 1777,
+ kX86InstIdMfence_NameIndex = 1783,
+ kX86InstIdMinpd_NameIndex = 1790,
+ kX86InstIdMinps_NameIndex = 1796,
+ kX86InstIdMinsd_NameIndex = 1802,
+ kX86InstIdMinss_NameIndex = 1808,
+ kX86InstIdMonitor_NameIndex = 1814,
+ kX86InstIdMov_NameIndex = 1822,
+ kX86InstIdMovPtr_NameIndex = 1826,
+ kX86InstIdMovapd_NameIndex = 1834,
+ kX86InstIdMovaps_NameIndex = 1841,
+ kX86InstIdMovbe_NameIndex = 1848,
+ kX86InstIdMovd_NameIndex = 1854,
+ kX86InstIdMovddup_NameIndex = 1859,
+ kX86InstIdMovdq2q_NameIndex = 1867,
+ kX86InstIdMovdqa_NameIndex = 1875,
+ kX86InstIdMovdqu_NameIndex = 1882,
+ kX86InstIdMovhlps_NameIndex = 1889,
+ kX86InstIdMovhpd_NameIndex = 1897,
+ kX86InstIdMovhps_NameIndex = 1904,
+ kX86InstIdMovlhps_NameIndex = 1911,
+ kX86InstIdMovlpd_NameIndex = 1919,
+ kX86InstIdMovlps_NameIndex = 1926,
+ kX86InstIdMovmskpd_NameIndex = 1933,
+ kX86InstIdMovmskps_NameIndex = 1942,
+ kX86InstIdMovntdq_NameIndex = 1951,
+ kX86InstIdMovntdqa_NameIndex = 1959,
+ kX86InstIdMovnti_NameIndex = 1968,
+ kX86InstIdMovntpd_NameIndex = 1975,
+ kX86InstIdMovntps_NameIndex = 1983,
+ kX86InstIdMovntq_NameIndex = 1991,
+ kX86InstIdMovq_NameIndex = 1998,
+ kX86InstIdMovq2dq_NameIndex = 2003,
+ kX86InstIdMovsB_NameIndex = 2011,
+ kX86InstIdMovsD_NameIndex = 2018,
+ kX86InstIdMovsQ_NameIndex = 2025,
+ kX86InstIdMovsW_NameIndex = 2032,
+ kX86InstIdMovsd_NameIndex = 2039,
+ kX86InstIdMovshdup_NameIndex = 2045,
+ kX86InstIdMovsldup_NameIndex = 2054,
+ kX86InstIdMovss_NameIndex = 2063,
+ kX86InstIdMovsx_NameIndex = 2069,
+ kX86InstIdMovsxd_NameIndex = 2075,
+ kX86InstIdMovupd_NameIndex = 2082,
+ kX86InstIdMovups_NameIndex = 2089,
+ kX86InstIdMovzx_NameIndex = 2096,
+ kX86InstIdMpsadbw_NameIndex = 2102,
+ kX86InstIdMul_NameIndex = 2110,
+ kX86InstIdMulpd_NameIndex = 2114,
+ kX86InstIdMulps_NameIndex = 2120,
+ kX86InstIdMulsd_NameIndex = 2126,
+ kX86InstIdMulss_NameIndex = 2132,
+ kX86InstIdMulx_NameIndex = 2138,
+ kX86InstIdMwait_NameIndex = 2143,
+ kX86InstIdNeg_NameIndex = 2149,
+ kX86InstIdNop_NameIndex = 2153,
+ kX86InstIdNot_NameIndex = 2157,
+ kX86InstIdOr_NameIndex = 2161,
+ kX86InstIdOrpd_NameIndex = 2164,
+ kX86InstIdOrps_NameIndex = 2169,
+ kX86InstIdPabsb_NameIndex = 2174,
+ kX86InstIdPabsd_NameIndex = 2180,
+ kX86InstIdPabsw_NameIndex = 2186,
+ kX86InstIdPackssdw_NameIndex = 2192,
+ kX86InstIdPacksswb_NameIndex = 2201,
+ kX86InstIdPackusdw_NameIndex = 2210,
+ kX86InstIdPackuswb_NameIndex = 2219,
+ kX86InstIdPaddb_NameIndex = 2228,
+ kX86InstIdPaddd_NameIndex = 2234,
+ kX86InstIdPaddq_NameIndex = 2240,
+ kX86InstIdPaddsb_NameIndex = 2246,
+ kX86InstIdPaddsw_NameIndex = 2253,
+ kX86InstIdPaddusb_NameIndex = 2260,
+ kX86InstIdPaddusw_NameIndex = 2268,
+ kX86InstIdPaddw_NameIndex = 2276,
+ kX86InstIdPalignr_NameIndex = 2282,
+ kX86InstIdPand_NameIndex = 2290,
+ kX86InstIdPandn_NameIndex = 2295,
+ kX86InstIdPause_NameIndex = 2301,
+ kX86InstIdPavgb_NameIndex = 2307,
+ kX86InstIdPavgw_NameIndex = 2313,
+ kX86InstIdPblendvb_NameIndex = 2319,
+ kX86InstIdPblendw_NameIndex = 2328,
+ kX86InstIdPclmulqdq_NameIndex = 2336,
+ kX86InstIdPcmpeqb_NameIndex = 2346,
+ kX86InstIdPcmpeqd_NameIndex = 2354,
+ kX86InstIdPcmpeqq_NameIndex = 2362,
+ kX86InstIdPcmpeqw_NameIndex = 2370,
+ kX86InstIdPcmpestri_NameIndex = 2378,
+ kX86InstIdPcmpestrm_NameIndex = 2388,
+ kX86InstIdPcmpgtb_NameIndex = 2398,
+ kX86InstIdPcmpgtd_NameIndex = 2406,
+ kX86InstIdPcmpgtq_NameIndex = 2414,
+ kX86InstIdPcmpgtw_NameIndex = 2422,
+ kX86InstIdPcmpistri_NameIndex = 2430,
+ kX86InstIdPcmpistrm_NameIndex = 2440,
+ kX86InstIdPdep_NameIndex = 2450,
+ kX86InstIdPext_NameIndex = 2455,
+ kX86InstIdPextrb_NameIndex = 2460,
+ kX86InstIdPextrd_NameIndex = 2467,
+ kX86InstIdPextrq_NameIndex = 2474,
+ kX86InstIdPextrw_NameIndex = 2481,
+ kX86InstIdPf2id_NameIndex = 2488,
+ kX86InstIdPf2iw_NameIndex = 2494,
+ kX86InstIdPfacc_NameIndex = 2500,
+ kX86InstIdPfadd_NameIndex = 2506,
+ kX86InstIdPfcmpeq_NameIndex = 2512,
+ kX86InstIdPfcmpge_NameIndex = 2520,
+ kX86InstIdPfcmpgt_NameIndex = 2528,
+ kX86InstIdPfmax_NameIndex = 2536,
+ kX86InstIdPfmin_NameIndex = 2542,
+ kX86InstIdPfmul_NameIndex = 2548,
+ kX86InstIdPfnacc_NameIndex = 2554,
+ kX86InstIdPfpnacc_NameIndex = 2561,
+ kX86InstIdPfrcp_NameIndex = 2569,
+ kX86InstIdPfrcpit1_NameIndex = 2575,
+ kX86InstIdPfrcpit2_NameIndex = 2584,
+ kX86InstIdPfrsqit1_NameIndex = 2593,
+ kX86InstIdPfrsqrt_NameIndex = 2602,
+ kX86InstIdPfsub_NameIndex = 2610,
+ kX86InstIdPfsubr_NameIndex = 2616,
+ kX86InstIdPhaddd_NameIndex = 2623,
+ kX86InstIdPhaddsw_NameIndex = 2630,
+ kX86InstIdPhaddw_NameIndex = 2638,
+ kX86InstIdPhminposuw_NameIndex = 2645,
+ kX86InstIdPhsubd_NameIndex = 2656,
+ kX86InstIdPhsubsw_NameIndex = 2663,
+ kX86InstIdPhsubw_NameIndex = 2671,
+ kX86InstIdPi2fd_NameIndex = 2678,
+ kX86InstIdPi2fw_NameIndex = 2684,
+ kX86InstIdPinsrb_NameIndex = 2690,
+ kX86InstIdPinsrd_NameIndex = 2697,
+ kX86InstIdPinsrq_NameIndex = 2704,
+ kX86InstIdPinsrw_NameIndex = 2711,
+ kX86InstIdPmaddubsw_NameIndex = 2718,
+ kX86InstIdPmaddwd_NameIndex = 2728,
+ kX86InstIdPmaxsb_NameIndex = 2736,
+ kX86InstIdPmaxsd_NameIndex = 2743,
+ kX86InstIdPmaxsw_NameIndex = 2750,
+ kX86InstIdPmaxub_NameIndex = 2757,
+ kX86InstIdPmaxud_NameIndex = 2764,
+ kX86InstIdPmaxuw_NameIndex = 2771,
+ kX86InstIdPminsb_NameIndex = 2778,
+ kX86InstIdPminsd_NameIndex = 2785,
+ kX86InstIdPminsw_NameIndex = 2792,
+ kX86InstIdPminub_NameIndex = 2799,
+ kX86InstIdPminud_NameIndex = 2806,
+ kX86InstIdPminuw_NameIndex = 2813,
+ kX86InstIdPmovmskb_NameIndex = 2820,
+ kX86InstIdPmovsxbd_NameIndex = 2829,
+ kX86InstIdPmovsxbq_NameIndex = 2838,
+ kX86InstIdPmovsxbw_NameIndex = 2847,
+ kX86InstIdPmovsxdq_NameIndex = 2856,
+ kX86InstIdPmovsxwd_NameIndex = 2865,
+ kX86InstIdPmovsxwq_NameIndex = 2874,
+ kX86InstIdPmovzxbd_NameIndex = 2883,
+ kX86InstIdPmovzxbq_NameIndex = 2892,
+ kX86InstIdPmovzxbw_NameIndex = 2901,
+ kX86InstIdPmovzxdq_NameIndex = 2910,
+ kX86InstIdPmovzxwd_NameIndex = 2919,
+ kX86InstIdPmovzxwq_NameIndex = 2928,
+ kX86InstIdPmuldq_NameIndex = 2937,
+ kX86InstIdPmulhrsw_NameIndex = 2944,
+ kX86InstIdPmulhuw_NameIndex = 2953,
+ kX86InstIdPmulhw_NameIndex = 2961,
+ kX86InstIdPmulld_NameIndex = 2968,
+ kX86InstIdPmullw_NameIndex = 2975,
+ kX86InstIdPmuludq_NameIndex = 2982,
+ kX86InstIdPop_NameIndex = 2990,
+ kX86InstIdPopa_NameIndex = 2994,
+ kX86InstIdPopcnt_NameIndex = 2999,
+ kX86InstIdPopf_NameIndex = 3006,
+ kX86InstIdPor_NameIndex = 3011,
+ kX86InstIdPrefetch_NameIndex = 3015,
+ kX86InstIdPrefetch3dNow_NameIndex = 3024,
+ kX86InstIdPrefetchw3dNow_NameIndex = 3039,
+ kX86InstIdPsadbw_NameIndex = 3055,
+ kX86InstIdPshufb_NameIndex = 3062,
+ kX86InstIdPshufd_NameIndex = 3069,
+ kX86InstIdPshufhw_NameIndex = 3076,
+ kX86InstIdPshuflw_NameIndex = 3084,
+ kX86InstIdPshufw_NameIndex = 3092,
+ kX86InstIdPsignb_NameIndex = 3099,
+ kX86InstIdPsignd_NameIndex = 3106,
+ kX86InstIdPsignw_NameIndex = 3113,
+ kX86InstIdPslld_NameIndex = 3120,
+ kX86InstIdPslldq_NameIndex = 3126,
+ kX86InstIdPsllq_NameIndex = 3133,
+ kX86InstIdPsllw_NameIndex = 3139,
+ kX86InstIdPsrad_NameIndex = 3145,
+ kX86InstIdPsraw_NameIndex = 3151,
+ kX86InstIdPsrld_NameIndex = 3157,
+ kX86InstIdPsrldq_NameIndex = 3163,
+ kX86InstIdPsrlq_NameIndex = 3170,
+ kX86InstIdPsrlw_NameIndex = 3176,
+ kX86InstIdPsubb_NameIndex = 3182,
+ kX86InstIdPsubd_NameIndex = 3188,
+ kX86InstIdPsubq_NameIndex = 3194,
+ kX86InstIdPsubsb_NameIndex = 3200,
+ kX86InstIdPsubsw_NameIndex = 3207,
+ kX86InstIdPsubusb_NameIndex = 3214,
+ kX86InstIdPsubusw_NameIndex = 3222,
+ kX86InstIdPsubw_NameIndex = 3230,
+ kX86InstIdPswapd_NameIndex = 3236,
+ kX86InstIdPtest_NameIndex = 3243,
+ kX86InstIdPunpckhbw_NameIndex = 3249,
+ kX86InstIdPunpckhdq_NameIndex = 3259,
+ kX86InstIdPunpckhqdq_NameIndex = 3269,
+ kX86InstIdPunpckhwd_NameIndex = 3280,
+ kX86InstIdPunpcklbw_NameIndex = 3290,
+ kX86InstIdPunpckldq_NameIndex = 3300,
+ kX86InstIdPunpcklqdq_NameIndex = 3310,
+ kX86InstIdPunpcklwd_NameIndex = 3321,
+ kX86InstIdPush_NameIndex = 3331,
+ kX86InstIdPusha_NameIndex = 3336,
+ kX86InstIdPushf_NameIndex = 3342,
+ kX86InstIdPxor_NameIndex = 3348,
+ kX86InstIdRcl_NameIndex = 3353,
+ kX86InstIdRcpps_NameIndex = 3357,
+ kX86InstIdRcpss_NameIndex = 3363,
+ kX86InstIdRcr_NameIndex = 3369,
+ kX86InstIdRdfsbase_NameIndex = 3373,
+ kX86InstIdRdgsbase_NameIndex = 3382,
+ kX86InstIdRdrand_NameIndex = 3391,
+ kX86InstIdRdtsc_NameIndex = 3398,
+ kX86InstIdRdtscp_NameIndex = 3404,
+ kX86InstIdRepLodsB_NameIndex = 3411,
+ kX86InstIdRepLodsD_NameIndex = 3422,
+ kX86InstIdRepLodsQ_NameIndex = 3433,
+ kX86InstIdRepLodsW_NameIndex = 3444,
+ kX86InstIdRepMovsB_NameIndex = 3455,
+ kX86InstIdRepMovsD_NameIndex = 3466,
+ kX86InstIdRepMovsQ_NameIndex = 3477,
+ kX86InstIdRepMovsW_NameIndex = 3488,
+ kX86InstIdRepStosB_NameIndex = 3499,
+ kX86InstIdRepStosD_NameIndex = 3510,
+ kX86InstIdRepStosQ_NameIndex = 3521,
+ kX86InstIdRepStosW_NameIndex = 3532,
+ kX86InstIdRepeCmpsB_NameIndex = 3543,
+ kX86InstIdRepeCmpsD_NameIndex = 3555,
+ kX86InstIdRepeCmpsQ_NameIndex = 3567,
+ kX86InstIdRepeCmpsW_NameIndex = 3579,
+ kX86InstIdRepeScasB_NameIndex = 3591,
+ kX86InstIdRepeScasD_NameIndex = 3603,
+ kX86InstIdRepeScasQ_NameIndex = 3615,
+ kX86InstIdRepeScasW_NameIndex = 3627,
+ kX86InstIdRepneCmpsB_NameIndex = 3639,
+ kX86InstIdRepneCmpsD_NameIndex = 3652,
+ kX86InstIdRepneCmpsQ_NameIndex = 3665,
+ kX86InstIdRepneCmpsW_NameIndex = 3678,
+ kX86InstIdRepneScasB_NameIndex = 3691,
+ kX86InstIdRepneScasD_NameIndex = 3704,
+ kX86InstIdRepneScasQ_NameIndex = 3717,
+ kX86InstIdRepneScasW_NameIndex = 3730,
+ kX86InstIdRet_NameIndex = 3743,
+ kX86InstIdRol_NameIndex = 3747,
+ kX86InstIdRor_NameIndex = 3751,
+ kX86InstIdRorx_NameIndex = 3755,
+ kX86InstIdRoundpd_NameIndex = 3760,
+ kX86InstIdRoundps_NameIndex = 3768,
+ kX86InstIdRoundsd_NameIndex = 3776,
+ kX86InstIdRoundss_NameIndex = 3784,
+ kX86InstIdRsqrtps_NameIndex = 3792,
+ kX86InstIdRsqrtss_NameIndex = 3800,
+ kX86InstIdSahf_NameIndex = 3808,
+ kX86InstIdSal_NameIndex = 3813,
+ kX86InstIdSar_NameIndex = 3817,
+ kX86InstIdSarx_NameIndex = 3821,
+ kX86InstIdSbb_NameIndex = 3826,
+ kX86InstIdScasB_NameIndex = 3830,
+ kX86InstIdScasD_NameIndex = 3837,
+ kX86InstIdScasQ_NameIndex = 3844,
+ kX86InstIdScasW_NameIndex = 3851,
+ kX86InstIdSeta_NameIndex = 3858,
+ kX86InstIdSetae_NameIndex = 3863,
+ kX86InstIdSetb_NameIndex = 3869,
+ kX86InstIdSetbe_NameIndex = 3874,
+ kX86InstIdSetc_NameIndex = 3880,
+ kX86InstIdSete_NameIndex = 3885,
+ kX86InstIdSetg_NameIndex = 3890,
+ kX86InstIdSetge_NameIndex = 3895,
+ kX86InstIdSetl_NameIndex = 3901,
+ kX86InstIdSetle_NameIndex = 3906,
+ kX86InstIdSetna_NameIndex = 3912,
+ kX86InstIdSetnae_NameIndex = 3918,
+ kX86InstIdSetnb_NameIndex = 3925,
+ kX86InstIdSetnbe_NameIndex = 3931,
+ kX86InstIdSetnc_NameIndex = 3938,
+ kX86InstIdSetne_NameIndex = 3944,
+ kX86InstIdSetng_NameIndex = 3950,
+ kX86InstIdSetnge_NameIndex = 3956,
+ kX86InstIdSetnl_NameIndex = 3963,
+ kX86InstIdSetnle_NameIndex = 3969,
+ kX86InstIdSetno_NameIndex = 3976,
+ kX86InstIdSetnp_NameIndex = 3982,
+ kX86InstIdSetns_NameIndex = 3988,
+ kX86InstIdSetnz_NameIndex = 3994,
+ kX86InstIdSeto_NameIndex = 4000,
+ kX86InstIdSetp_NameIndex = 4005,
+ kX86InstIdSetpe_NameIndex = 4010,
+ kX86InstIdSetpo_NameIndex = 4016,
+ kX86InstIdSets_NameIndex = 4022,
+ kX86InstIdSetz_NameIndex = 4027,
+ kX86InstIdSfence_NameIndex = 4032,
+ kX86InstIdShl_NameIndex = 4039,
+ kX86InstIdShld_NameIndex = 4043,
+ kX86InstIdShlx_NameIndex = 4048,
+ kX86InstIdShr_NameIndex = 4053,
+ kX86InstIdShrd_NameIndex = 4057,
+ kX86InstIdShrx_NameIndex = 4062,
+ kX86InstIdShufpd_NameIndex = 4067,
+ kX86InstIdShufps_NameIndex = 4074,
+ kX86InstIdSqrtpd_NameIndex = 4081,
+ kX86InstIdSqrtps_NameIndex = 4088,
+ kX86InstIdSqrtsd_NameIndex = 4095,
+ kX86InstIdSqrtss_NameIndex = 4102,
+ kX86InstIdStc_NameIndex = 4109,
+ kX86InstIdStd_NameIndex = 4113,
+ kX86InstIdStmxcsr_NameIndex = 4117,
+ kX86InstIdStosB_NameIndex = 4125,
+ kX86InstIdStosD_NameIndex = 4132,
+ kX86InstIdStosQ_NameIndex = 4139,
+ kX86InstIdStosW_NameIndex = 4146,
+ kX86InstIdSub_NameIndex = 4153,
+ kX86InstIdSubpd_NameIndex = 4157,
+ kX86InstIdSubps_NameIndex = 4163,
+ kX86InstIdSubsd_NameIndex = 4169,
+ kX86InstIdSubss_NameIndex = 4175,
+ kX86InstIdTest_NameIndex = 4181,
+ kX86InstIdTzcnt_NameIndex = 4186,
+ kX86InstIdUcomisd_NameIndex = 4192,
+ kX86InstIdUcomiss_NameIndex = 4200,
+ kX86InstIdUd2_NameIndex = 4208,
+ kX86InstIdUnpckhpd_NameIndex = 4212,
+ kX86InstIdUnpckhps_NameIndex = 4221,
+ kX86InstIdUnpcklpd_NameIndex = 4230,
+ kX86InstIdUnpcklps_NameIndex = 4239,
+ kX86InstIdVaddpd_NameIndex = 4248,
+ kX86InstIdVaddps_NameIndex = 4255,
+ kX86InstIdVaddsd_NameIndex = 4262,
+ kX86InstIdVaddss_NameIndex = 4269,
+ kX86InstIdVaddsubpd_NameIndex = 4276,
+ kX86InstIdVaddsubps_NameIndex = 4286,
+ kX86InstIdVaesdec_NameIndex = 4296,
+ kX86InstIdVaesdeclast_NameIndex = 4304,
+ kX86InstIdVaesenc_NameIndex = 4316,
+ kX86InstIdVaesenclast_NameIndex = 4324,
+ kX86InstIdVaesimc_NameIndex = 4336,
+ kX86InstIdVaeskeygenassist_NameIndex = 4344,
+ kX86InstIdVandnpd_NameIndex = 4361,
+ kX86InstIdVandnps_NameIndex = 4369,
+ kX86InstIdVandpd_NameIndex = 4377,
+ kX86InstIdVandps_NameIndex = 4384,
+ kX86InstIdVblendpd_NameIndex = 4391,
+ kX86InstIdVblendps_NameIndex = 4400,
+ kX86InstIdVblendvpd_NameIndex = 4409,
+ kX86InstIdVblendvps_NameIndex = 4419,
+ kX86InstIdVbroadcastf128_NameIndex = 4429,
+ kX86InstIdVbroadcasti128_NameIndex = 4444,
+ kX86InstIdVbroadcastsd_NameIndex = 4459,
+ kX86InstIdVbroadcastss_NameIndex = 4472,
+ kX86InstIdVcmppd_NameIndex = 4485,
+ kX86InstIdVcmpps_NameIndex = 4492,
+ kX86InstIdVcmpsd_NameIndex = 4499,
+ kX86InstIdVcmpss_NameIndex = 4506,
+ kX86InstIdVcomisd_NameIndex = 4513,
+ kX86InstIdVcomiss_NameIndex = 4521,
+ kX86InstIdVcvtdq2pd_NameIndex = 4529,
+ kX86InstIdVcvtdq2ps_NameIndex = 4539,
+ kX86InstIdVcvtpd2dq_NameIndex = 4549,
+ kX86InstIdVcvtpd2ps_NameIndex = 4559,
+ kX86InstIdVcvtph2ps_NameIndex = 4569,
+ kX86InstIdVcvtps2dq_NameIndex = 4579,
+ kX86InstIdVcvtps2pd_NameIndex = 4589,
+ kX86InstIdVcvtps2ph_NameIndex = 4599,
+ kX86InstIdVcvtsd2si_NameIndex = 4609,
+ kX86InstIdVcvtsd2ss_NameIndex = 4619,
+ kX86InstIdVcvtsi2sd_NameIndex = 4629,
+ kX86InstIdVcvtsi2ss_NameIndex = 4639,
+ kX86InstIdVcvtss2sd_NameIndex = 4649,
+ kX86InstIdVcvtss2si_NameIndex = 4659,
+ kX86InstIdVcvttpd2dq_NameIndex = 4669,
+ kX86InstIdVcvttps2dq_NameIndex = 4680,
+ kX86InstIdVcvttsd2si_NameIndex = 4691,
+ kX86InstIdVcvttss2si_NameIndex = 4702,
+ kX86InstIdVdivpd_NameIndex = 4713,
+ kX86InstIdVdivps_NameIndex = 4720,
+ kX86InstIdVdivsd_NameIndex = 4727,
+ kX86InstIdVdivss_NameIndex = 4734,
+ kX86InstIdVdppd_NameIndex = 4741,
+ kX86InstIdVdpps_NameIndex = 4747,
+ kX86InstIdVextractf128_NameIndex = 4753,
+ kX86InstIdVextracti128_NameIndex = 4766,
+ kX86InstIdVextractps_NameIndex = 4779,
+ kX86InstIdVfmadd132pd_NameIndex = 4790,
+ kX86InstIdVfmadd132ps_NameIndex = 4802,
+ kX86InstIdVfmadd132sd_NameIndex = 4814,
+ kX86InstIdVfmadd132ss_NameIndex = 4826,
+ kX86InstIdVfmadd213pd_NameIndex = 4838,
+ kX86InstIdVfmadd213ps_NameIndex = 4850,
+ kX86InstIdVfmadd213sd_NameIndex = 4862,
+ kX86InstIdVfmadd213ss_NameIndex = 4874,
+ kX86InstIdVfmadd231pd_NameIndex = 4886,
+ kX86InstIdVfmadd231ps_NameIndex = 4898,
+ kX86InstIdVfmadd231sd_NameIndex = 4910,
+ kX86InstIdVfmadd231ss_NameIndex = 4922,
+ kX86InstIdVfmaddpd_NameIndex = 4934,
+ kX86InstIdVfmaddps_NameIndex = 4943,
+ kX86InstIdVfmaddsd_NameIndex = 4952,
+ kX86InstIdVfmaddss_NameIndex = 4961,
+ kX86InstIdVfmaddsub132pd_NameIndex = 4970,
+ kX86InstIdVfmaddsub132ps_NameIndex = 4985,
+ kX86InstIdVfmaddsub213pd_NameIndex = 5000,
+ kX86InstIdVfmaddsub213ps_NameIndex = 5015,
+ kX86InstIdVfmaddsub231pd_NameIndex = 5030,
+ kX86InstIdVfmaddsub231ps_NameIndex = 5045,
+ kX86InstIdVfmaddsubpd_NameIndex = 5060,
+ kX86InstIdVfmaddsubps_NameIndex = 5072,
+ kX86InstIdVfmsub132pd_NameIndex = 5084,
+ kX86InstIdVfmsub132ps_NameIndex = 5096,
+ kX86InstIdVfmsub132sd_NameIndex = 5108,
+ kX86InstIdVfmsub132ss_NameIndex = 5120,
+ kX86InstIdVfmsub213pd_NameIndex = 5132,
+ kX86InstIdVfmsub213ps_NameIndex = 5144,
+ kX86InstIdVfmsub213sd_NameIndex = 5156,
+ kX86InstIdVfmsub213ss_NameIndex = 5168,
+ kX86InstIdVfmsub231pd_NameIndex = 5180,
+ kX86InstIdVfmsub231ps_NameIndex = 5192,
+ kX86InstIdVfmsub231sd_NameIndex = 5204,
+ kX86InstIdVfmsub231ss_NameIndex = 5216,
+ kX86InstIdVfmsubadd132pd_NameIndex = 5228,
+ kX86InstIdVfmsubadd132ps_NameIndex = 5243,
+ kX86InstIdVfmsubadd213pd_NameIndex = 5258,
+ kX86InstIdVfmsubadd213ps_NameIndex = 5273,
+ kX86InstIdVfmsubadd231pd_NameIndex = 5288,
+ kX86InstIdVfmsubadd231ps_NameIndex = 5303,
+ kX86InstIdVfmsubaddpd_NameIndex = 5318,
+ kX86InstIdVfmsubaddps_NameIndex = 5330,
+ kX86InstIdVfmsubpd_NameIndex = 5342,
+ kX86InstIdVfmsubps_NameIndex = 5351,
+ kX86InstIdVfmsubsd_NameIndex = 5360,
+ kX86InstIdVfmsubss_NameIndex = 5369,
+ kX86InstIdVfnmadd132pd_NameIndex = 5378,
+ kX86InstIdVfnmadd132ps_NameIndex = 5391,
+ kX86InstIdVfnmadd132sd_NameIndex = 5404,
+ kX86InstIdVfnmadd132ss_NameIndex = 5417,
+ kX86InstIdVfnmadd213pd_NameIndex = 5430,
+ kX86InstIdVfnmadd213ps_NameIndex = 5443,
+ kX86InstIdVfnmadd213sd_NameIndex = 5456,
+ kX86InstIdVfnmadd213ss_NameIndex = 5469,
+ kX86InstIdVfnmadd231pd_NameIndex = 5482,
+ kX86InstIdVfnmadd231ps_NameIndex = 5495,
+ kX86InstIdVfnmadd231sd_NameIndex = 5508,
+ kX86InstIdVfnmadd231ss_NameIndex = 5521,
+ kX86InstIdVfnmaddpd_NameIndex = 5534,
+ kX86InstIdVfnmaddps_NameIndex = 5544,
+ kX86InstIdVfnmaddsd_NameIndex = 5554,
+ kX86InstIdVfnmaddss_NameIndex = 5564,
+ kX86InstIdVfnmsub132pd_NameIndex = 5574,
+ kX86InstIdVfnmsub132ps_NameIndex = 5587,
+ kX86InstIdVfnmsub132sd_NameIndex = 5600,
+ kX86InstIdVfnmsub132ss_NameIndex = 5613,
+ kX86InstIdVfnmsub213pd_NameIndex = 5626,
+ kX86InstIdVfnmsub213ps_NameIndex = 5639,
+ kX86InstIdVfnmsub213sd_NameIndex = 5652,
+ kX86InstIdVfnmsub213ss_NameIndex = 5665,
+ kX86InstIdVfnmsub231pd_NameIndex = 5678,
+ kX86InstIdVfnmsub231ps_NameIndex = 5691,
+ kX86InstIdVfnmsub231sd_NameIndex = 5704,
+ kX86InstIdVfnmsub231ss_NameIndex = 5717,
+ kX86InstIdVfnmsubpd_NameIndex = 5730,
+ kX86InstIdVfnmsubps_NameIndex = 5740,
+ kX86InstIdVfnmsubsd_NameIndex = 5750,
+ kX86InstIdVfnmsubss_NameIndex = 5760,
+ kX86InstIdVfrczpd_NameIndex = 5770,
+ kX86InstIdVfrczps_NameIndex = 5778,
+ kX86InstIdVfrczsd_NameIndex = 5786,
+ kX86InstIdVfrczss_NameIndex = 5794,
+ kX86InstIdVgatherdpd_NameIndex = 5802,
+ kX86InstIdVgatherdps_NameIndex = 5813,
+ kX86InstIdVgatherqpd_NameIndex = 5824,
+ kX86InstIdVgatherqps_NameIndex = 5835,
+ kX86InstIdVhaddpd_NameIndex = 5846,
+ kX86InstIdVhaddps_NameIndex = 5854,
+ kX86InstIdVhsubpd_NameIndex = 5862,
+ kX86InstIdVhsubps_NameIndex = 5870,
+ kX86InstIdVinsertf128_NameIndex = 5878,
+ kX86InstIdVinserti128_NameIndex = 5890,
+ kX86InstIdVinsertps_NameIndex = 5902,
+ kX86InstIdVlddqu_NameIndex = 5912,
+ kX86InstIdVldmxcsr_NameIndex = 5919,
+ kX86InstIdVmaskmovdqu_NameIndex = 5928,
+ kX86InstIdVmaskmovpd_NameIndex = 5940,
+ kX86InstIdVmaskmovps_NameIndex = 5951,
+ kX86InstIdVmaxpd_NameIndex = 5962,
+ kX86InstIdVmaxps_NameIndex = 5969,
+ kX86InstIdVmaxsd_NameIndex = 5976,
+ kX86InstIdVmaxss_NameIndex = 5983,
+ kX86InstIdVminpd_NameIndex = 5990,
+ kX86InstIdVminps_NameIndex = 5997,
+ kX86InstIdVminsd_NameIndex = 6004,
+ kX86InstIdVminss_NameIndex = 6011,
+ kX86InstIdVmovapd_NameIndex = 6018,
+ kX86InstIdVmovaps_NameIndex = 6026,
+ kX86InstIdVmovd_NameIndex = 6034,
+ kX86InstIdVmovddup_NameIndex = 6040,
+ kX86InstIdVmovdqa_NameIndex = 6049,
+ kX86InstIdVmovdqu_NameIndex = 6057,
+ kX86InstIdVmovhlps_NameIndex = 6065,
+ kX86InstIdVmovhpd_NameIndex = 6074,
+ kX86InstIdVmovhps_NameIndex = 6082,
+ kX86InstIdVmovlhps_NameIndex = 6090,
+ kX86InstIdVmovlpd_NameIndex = 6099,
+ kX86InstIdVmovlps_NameIndex = 6107,
+ kX86InstIdVmovmskpd_NameIndex = 6115,
+ kX86InstIdVmovmskps_NameIndex = 6125,
+ kX86InstIdVmovntdq_NameIndex = 6135,
+ kX86InstIdVmovntdqa_NameIndex = 6144,
+ kX86InstIdVmovntpd_NameIndex = 6154,
+ kX86InstIdVmovntps_NameIndex = 6163,
+ kX86InstIdVmovq_NameIndex = 6172,
+ kX86InstIdVmovsd_NameIndex = 6178,
+ kX86InstIdVmovshdup_NameIndex = 6185,
+ kX86InstIdVmovsldup_NameIndex = 6195,
+ kX86InstIdVmovss_NameIndex = 6205,
+ kX86InstIdVmovupd_NameIndex = 6212,
+ kX86InstIdVmovups_NameIndex = 6220,
+ kX86InstIdVmpsadbw_NameIndex = 6228,
+ kX86InstIdVmulpd_NameIndex = 6237,
+ kX86InstIdVmulps_NameIndex = 6244,
+ kX86InstIdVmulsd_NameIndex = 6251,
+ kX86InstIdVmulss_NameIndex = 6258,
+ kX86InstIdVorpd_NameIndex = 6265,
+ kX86InstIdVorps_NameIndex = 6271,
+ kX86InstIdVpabsb_NameIndex = 6277,
+ kX86InstIdVpabsd_NameIndex = 6284,
+ kX86InstIdVpabsw_NameIndex = 6291,
+ kX86InstIdVpackssdw_NameIndex = 6298,
+ kX86InstIdVpacksswb_NameIndex = 6308,
+ kX86InstIdVpackusdw_NameIndex = 6318,
+ kX86InstIdVpackuswb_NameIndex = 6328,
+ kX86InstIdVpaddb_NameIndex = 6338,
+ kX86InstIdVpaddd_NameIndex = 6345,
+ kX86InstIdVpaddq_NameIndex = 6352,
+ kX86InstIdVpaddsb_NameIndex = 6359,
+ kX86InstIdVpaddsw_NameIndex = 6367,
+ kX86InstIdVpaddusb_NameIndex = 6375,
+ kX86InstIdVpaddusw_NameIndex = 6384,
+ kX86InstIdVpaddw_NameIndex = 6393,
+ kX86InstIdVpalignr_NameIndex = 6400,
+ kX86InstIdVpand_NameIndex = 6409,
+ kX86InstIdVpandn_NameIndex = 6415,
+ kX86InstIdVpavgb_NameIndex = 6422,
+ kX86InstIdVpavgw_NameIndex = 6429,
+ kX86InstIdVpblendd_NameIndex = 6436,
+ kX86InstIdVpblendvb_NameIndex = 6445,
+ kX86InstIdVpblendw_NameIndex = 6455,
+ kX86InstIdVpbroadcastb_NameIndex = 6464,
+ kX86InstIdVpbroadcastd_NameIndex = 6477,
+ kX86InstIdVpbroadcastq_NameIndex = 6490,
+ kX86InstIdVpbroadcastw_NameIndex = 6503,
+ kX86InstIdVpclmulqdq_NameIndex = 6516,
+ kX86InstIdVpcmov_NameIndex = 6527,
+ kX86InstIdVpcmpeqb_NameIndex = 6534,
+ kX86InstIdVpcmpeqd_NameIndex = 6543,
+ kX86InstIdVpcmpeqq_NameIndex = 6552,
+ kX86InstIdVpcmpeqw_NameIndex = 6561,
+ kX86InstIdVpcmpestri_NameIndex = 6570,
+ kX86InstIdVpcmpestrm_NameIndex = 6581,
+ kX86InstIdVpcmpgtb_NameIndex = 6592,
+ kX86InstIdVpcmpgtd_NameIndex = 6601,
+ kX86InstIdVpcmpgtq_NameIndex = 6610,
+ kX86InstIdVpcmpgtw_NameIndex = 6619,
+ kX86InstIdVpcmpistri_NameIndex = 6628,
+ kX86InstIdVpcmpistrm_NameIndex = 6639,
+ kX86InstIdVpcomb_NameIndex = 6650,
+ kX86InstIdVpcomd_NameIndex = 6657,
+ kX86InstIdVpcomq_NameIndex = 6664,
+ kX86InstIdVpcomub_NameIndex = 6671,
+ kX86InstIdVpcomud_NameIndex = 6679,
+ kX86InstIdVpcomuq_NameIndex = 6687,
+ kX86InstIdVpcomuw_NameIndex = 6695,
+ kX86InstIdVpcomw_NameIndex = 6703,
+ kX86InstIdVperm2f128_NameIndex = 6710,
+ kX86InstIdVperm2i128_NameIndex = 6721,
+ kX86InstIdVpermd_NameIndex = 6732,
+ kX86InstIdVpermil2pd_NameIndex = 6739,
+ kX86InstIdVpermil2ps_NameIndex = 6750,
+ kX86InstIdVpermilpd_NameIndex = 6761,
+ kX86InstIdVpermilps_NameIndex = 6771,
+ kX86InstIdVpermpd_NameIndex = 6781,
+ kX86InstIdVpermps_NameIndex = 6789,
+ kX86InstIdVpermq_NameIndex = 6797,
+ kX86InstIdVpextrb_NameIndex = 6804,
+ kX86InstIdVpextrd_NameIndex = 6812,
+ kX86InstIdVpextrq_NameIndex = 6820,
+ kX86InstIdVpextrw_NameIndex = 6828,
+ kX86InstIdVpgatherdd_NameIndex = 6836,
+ kX86InstIdVpgatherdq_NameIndex = 6847,
+ kX86InstIdVpgatherqd_NameIndex = 6858,
+ kX86InstIdVpgatherqq_NameIndex = 6869,
+ kX86InstIdVphaddbd_NameIndex = 6880,
+ kX86InstIdVphaddbq_NameIndex = 6889,
+ kX86InstIdVphaddbw_NameIndex = 6898,
+ kX86InstIdVphaddd_NameIndex = 6907,
+ kX86InstIdVphadddq_NameIndex = 6915,
+ kX86InstIdVphaddsw_NameIndex = 6924,
+ kX86InstIdVphaddubd_NameIndex = 6933,
+ kX86InstIdVphaddubq_NameIndex = 6943,
+ kX86InstIdVphaddubw_NameIndex = 6953,
+ kX86InstIdVphaddudq_NameIndex = 6963,
+ kX86InstIdVphadduwd_NameIndex = 6973,
+ kX86InstIdVphadduwq_NameIndex = 6983,
+ kX86InstIdVphaddw_NameIndex = 6993,
+ kX86InstIdVphaddwd_NameIndex = 7001,
+ kX86InstIdVphaddwq_NameIndex = 7010,
+ kX86InstIdVphminposuw_NameIndex = 7019,
+ kX86InstIdVphsubbw_NameIndex = 7031,
+ kX86InstIdVphsubd_NameIndex = 7040,
+ kX86InstIdVphsubdq_NameIndex = 7048,
+ kX86InstIdVphsubsw_NameIndex = 7057,
+ kX86InstIdVphsubw_NameIndex = 7066,
+ kX86InstIdVphsubwd_NameIndex = 7074,
+ kX86InstIdVpinsrb_NameIndex = 7083,
+ kX86InstIdVpinsrd_NameIndex = 7091,
+ kX86InstIdVpinsrq_NameIndex = 7099,
+ kX86InstIdVpinsrw_NameIndex = 7107,
+ kX86InstIdVpmacsdd_NameIndex = 7115,
+ kX86InstIdVpmacsdqh_NameIndex = 7124,
+ kX86InstIdVpmacsdql_NameIndex = 7134,
+ kX86InstIdVpmacssdd_NameIndex = 7144,
+ kX86InstIdVpmacssdqh_NameIndex = 7154,
+ kX86InstIdVpmacssdql_NameIndex = 7165,
+ kX86InstIdVpmacsswd_NameIndex = 7176,
+ kX86InstIdVpmacssww_NameIndex = 7186,
+ kX86InstIdVpmacswd_NameIndex = 7196,
+ kX86InstIdVpmacsww_NameIndex = 7205,
+ kX86InstIdVpmadcsswd_NameIndex = 7214,
+ kX86InstIdVpmadcswd_NameIndex = 7225,
+ kX86InstIdVpmaddubsw_NameIndex = 7235,
+ kX86InstIdVpmaddwd_NameIndex = 7246,
+ kX86InstIdVpmaskmovd_NameIndex = 7255,
+ kX86InstIdVpmaskmovq_NameIndex = 7266,
+ kX86InstIdVpmaxsb_NameIndex = 7277,
+ kX86InstIdVpmaxsd_NameIndex = 7285,
+ kX86InstIdVpmaxsw_NameIndex = 7293,
+ kX86InstIdVpmaxub_NameIndex = 7301,
+ kX86InstIdVpmaxud_NameIndex = 7309,
+ kX86InstIdVpmaxuw_NameIndex = 7317,
+ kX86InstIdVpminsb_NameIndex = 7325,
+ kX86InstIdVpminsd_NameIndex = 7333,
+ kX86InstIdVpminsw_NameIndex = 7341,
+ kX86InstIdVpminub_NameIndex = 7349,
+ kX86InstIdVpminud_NameIndex = 7357,
+ kX86InstIdVpminuw_NameIndex = 7365,
+ kX86InstIdVpmovmskb_NameIndex = 7373,
+ kX86InstIdVpmovsxbd_NameIndex = 7383,
+ kX86InstIdVpmovsxbq_NameIndex = 7393,
+ kX86InstIdVpmovsxbw_NameIndex = 7403,
+ kX86InstIdVpmovsxdq_NameIndex = 7413,
+ kX86InstIdVpmovsxwd_NameIndex = 7423,
+ kX86InstIdVpmovsxwq_NameIndex = 7433,
+ kX86InstIdVpmovzxbd_NameIndex = 7443,
+ kX86InstIdVpmovzxbq_NameIndex = 7453,
+ kX86InstIdVpmovzxbw_NameIndex = 7463,
+ kX86InstIdVpmovzxdq_NameIndex = 7473,
+ kX86InstIdVpmovzxwd_NameIndex = 7483,
+ kX86InstIdVpmovzxwq_NameIndex = 7493,
+ kX86InstIdVpmuldq_NameIndex = 7503,
+ kX86InstIdVpmulhrsw_NameIndex = 7511,
+ kX86InstIdVpmulhuw_NameIndex = 7521,
+ kX86InstIdVpmulhw_NameIndex = 7530,
+ kX86InstIdVpmulld_NameIndex = 7538,
+ kX86InstIdVpmullw_NameIndex = 7546,
+ kX86InstIdVpmuludq_NameIndex = 7554,
+ kX86InstIdVpor_NameIndex = 7563,
+ kX86InstIdVpperm_NameIndex = 7568,
+ kX86InstIdVprotb_NameIndex = 7575,
+ kX86InstIdVprotd_NameIndex = 7582,
+ kX86InstIdVprotq_NameIndex = 7589,
+ kX86InstIdVprotw_NameIndex = 7596,
+ kX86InstIdVpsadbw_NameIndex = 7603,
+ kX86InstIdVpshab_NameIndex = 7611,
+ kX86InstIdVpshad_NameIndex = 7618,
+ kX86InstIdVpshaq_NameIndex = 7625,
+ kX86InstIdVpshaw_NameIndex = 7632,
+ kX86InstIdVpshlb_NameIndex = 7639,
+ kX86InstIdVpshld_NameIndex = 7646,
+ kX86InstIdVpshlq_NameIndex = 7653,
+ kX86InstIdVpshlw_NameIndex = 7660,
+ kX86InstIdVpshufb_NameIndex = 7667,
+ kX86InstIdVpshufd_NameIndex = 7675,
+ kX86InstIdVpshufhw_NameIndex = 7683,
+ kX86InstIdVpshuflw_NameIndex = 7692,
+ kX86InstIdVpsignb_NameIndex = 7701,
+ kX86InstIdVpsignd_NameIndex = 7709,
+ kX86InstIdVpsignw_NameIndex = 7717,
+ kX86InstIdVpslld_NameIndex = 7725,
+ kX86InstIdVpslldq_NameIndex = 7732,
+ kX86InstIdVpsllq_NameIndex = 7740,
+ kX86InstIdVpsllvd_NameIndex = 7747,
+ kX86InstIdVpsllvq_NameIndex = 7755,
+ kX86InstIdVpsllw_NameIndex = 7763,
+ kX86InstIdVpsrad_NameIndex = 7770,
+ kX86InstIdVpsravd_NameIndex = 7777,
+ kX86InstIdVpsraw_NameIndex = 7785,
+ kX86InstIdVpsrld_NameIndex = 7792,
+ kX86InstIdVpsrldq_NameIndex = 7799,
+ kX86InstIdVpsrlq_NameIndex = 7807,
+ kX86InstIdVpsrlvd_NameIndex = 7814,
+ kX86InstIdVpsrlvq_NameIndex = 7822,
+ kX86InstIdVpsrlw_NameIndex = 7830,
+ kX86InstIdVpsubb_NameIndex = 7837,
+ kX86InstIdVpsubd_NameIndex = 7844,
+ kX86InstIdVpsubq_NameIndex = 7851,
+ kX86InstIdVpsubsb_NameIndex = 7858,
+ kX86InstIdVpsubsw_NameIndex = 7866,
+ kX86InstIdVpsubusb_NameIndex = 7874,
+ kX86InstIdVpsubusw_NameIndex = 7883,
+ kX86InstIdVpsubw_NameIndex = 7892,
+ kX86InstIdVptest_NameIndex = 7899,
+ kX86InstIdVpunpckhbw_NameIndex = 7906,
+ kX86InstIdVpunpckhdq_NameIndex = 7917,
+ kX86InstIdVpunpckhqdq_NameIndex = 7928,
+ kX86InstIdVpunpckhwd_NameIndex = 7940,
+ kX86InstIdVpunpcklbw_NameIndex = 7951,
+ kX86InstIdVpunpckldq_NameIndex = 7962,
+ kX86InstIdVpunpcklqdq_NameIndex = 7973,
+ kX86InstIdVpunpcklwd_NameIndex = 7985,
+ kX86InstIdVpxor_NameIndex = 7996,
+ kX86InstIdVrcpps_NameIndex = 8002,
+ kX86InstIdVrcpss_NameIndex = 8009,
+ kX86InstIdVroundpd_NameIndex = 8016,
+ kX86InstIdVroundps_NameIndex = 8025,
+ kX86InstIdVroundsd_NameIndex = 8034,
+ kX86InstIdVroundss_NameIndex = 8043,
+ kX86InstIdVrsqrtps_NameIndex = 8052,
+ kX86InstIdVrsqrtss_NameIndex = 8061,
+ kX86InstIdVshufpd_NameIndex = 8070,
+ kX86InstIdVshufps_NameIndex = 8078,
+ kX86InstIdVsqrtpd_NameIndex = 8086,
+ kX86InstIdVsqrtps_NameIndex = 8094,
+ kX86InstIdVsqrtsd_NameIndex = 8102,
+ kX86InstIdVsqrtss_NameIndex = 8110,
+ kX86InstIdVstmxcsr_NameIndex = 8118,
+ kX86InstIdVsubpd_NameIndex = 8127,
+ kX86InstIdVsubps_NameIndex = 8134,
+ kX86InstIdVsubsd_NameIndex = 8141,
+ kX86InstIdVsubss_NameIndex = 8148,
+ kX86InstIdVtestpd_NameIndex = 8155,
+ kX86InstIdVtestps_NameIndex = 8163,
+ kX86InstIdVucomisd_NameIndex = 8171,
+ kX86InstIdVucomiss_NameIndex = 8180,
+ kX86InstIdVunpckhpd_NameIndex = 8189,
+ kX86InstIdVunpckhps_NameIndex = 8199,
+ kX86InstIdVunpcklpd_NameIndex = 8209,
+ kX86InstIdVunpcklps_NameIndex = 8219,
+ kX86InstIdVxorpd_NameIndex = 8229,
+ kX86InstIdVxorps_NameIndex = 8236,
+ kX86InstIdVzeroall_NameIndex = 8243,
+ kX86InstIdVzeroupper_NameIndex = 8252,
+ kX86InstIdWrfsbase_NameIndex = 8263,
+ kX86InstIdWrgsbase_NameIndex = 8272,
+ kX86InstIdXadd_NameIndex = 8281,
+ kX86InstIdXchg_NameIndex = 8286,
+ kX86InstIdXor_NameIndex = 8291,
+ kX86InstIdXorpd_NameIndex = 8295,
+ kX86InstIdXorps_NameIndex = 8301
+};
+#endif // !ASMJIT_DISABLE_NAMES
+
+// Automatically generated, do not edit.
+const X86InstExtendedInfo _x86InstExtendedInfo[] = {
+ { G(None) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U },
+ { G(X86Arith) , 0 , 0x20, 0x3F, F(Lock) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U },
+ { G(X86Arith) , 0 , 0x00, 0x3F, F(Lock) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U },
+ { G(ExtRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U },
+ { G(ExtRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U },
+ { G(AvxRvm) , 0 , 0x00, 0x3F, F(None) , { O(Gqd) , O(Gqd) , O(GqdMem) , U , U }, U },
+ { G(AvxRmv) , 0 , 0x00, 0x3F, F(None) , { O(Gqd) , O(GqdMem) , O(Gqd) , U , U }, U },
+ { G(ExtRm) , 0 , 0x00, 0x00, F(None)|F(Special) , { O(Xmm) , O(XmmMem) , U , U , U }, U },
+ { G(AvxVm) , 0 , 0x00, 0x3F, F(None) , { O(Gqd) , O(GqdMem) , U , U , U }, U },
+ { G(X86RegRm) , 0 , 0x00, 0x3F, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U },
+ { G(X86BSwap) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , U , U , U , U }, U },
+ { G(X86BTest) , 0 , 0x00, 0x3B, F(Test) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,4) },
+ { G(X86BTest) , 0 , 0x00, 0x3B, F(Lock) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,7) },
+ { G(X86BTest) , 0 , 0x00, 0x3B, F(Lock) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,6) },
+ { G(X86BTest) , 0 , 0x00, 0x3B, F(Lock) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,5) },
+ { G(X86Call) , 0 , 0x00, 0x00, F(Flow) , { O(GqdMem)|O(Imm)|O(Label), U , U , U , U }, O_000000(E8,U) },
+ { G(X86Op) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86Op) , 0 , 0x00, 0x00, F(None)|F(Special)|F(W), { U , U , U , U , U }, U },
+ { G(X86Op) , 0 , 0x00, 0x20, F(None) , { U , U , U , U , U }, U },
+ { G(X86Op) , 0 , 0x00, 0x40, F(None) , { U , U , U , U , U }, U },
+ { G(X86M) , 0 , 0x00, 0x00, F(None) , { O(Mem) , U , U , U , U }, U },
+ { G(X86Op) , 0 , 0x20, 0x20, F(None) , { U , U , U , U , U }, U },
+ { G(X86RegRm) , 0 , 0x24, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U },
+ { G(X86RegRm) , 0 , 0x20, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U },
+ { G(X86RegRm) , 0 , 0x04, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U },
+ { G(X86RegRm) , 0 , 0x07, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U },
+ { G(X86RegRm) , 0 , 0x03, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U },
+ { G(X86RegRm) , 0 , 0x01, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U },
+ { G(X86RegRm) , 0 , 0x10, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U },
+ { G(X86RegRm) , 0 , 0x02, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U },
+ { G(X86Arith) , 0 , 0x00, 0x3F, F(Test) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U },
+ { G(X86Op) , 0 , 0x40, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86Op) , 0 , 0x40, 0x3F, F(None)|F(Special)|F(W), { U , U , U , U , U }, U },
+ { G(X86Op_66H) , 0 , 0x40, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86RmReg) , 0 , 0x00, 0x3F, F(Lock)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86M) , 0 , 0x00, 0x04, F(None)|F(Special)|F(W), { O(Mem) , U , U , U , U }, U },
+ { G(X86M) , 0 , 0x00, 0x04, F(None)|F(Special) , { O(Mem) , U , U , U , U }, U },
+ { G(ExtRm) , 0 , 0x00, 0x3F, F(Test) , { O(Xmm) , O(XmmMem) , U , U , U }, U },
+ { G(ExtCrc) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(GqdwbMem) , U , U , U }, U },
+ { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U },
+ { G(ExtRm) , 8 , 0x00, 0x00, F(Move) , { O(Mm) , O(XmmMem) , U , U , U }, U },
+ { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(MmMem) , U , U , U }, U },
+ { G(ExtRm) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(MmMem) , U , U , U }, U },
+ { G(ExtRm_Q) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , O(XmmMem) , U , U , U }, U },
+ { G(ExtRm) , 4 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U },
+ { G(ExtRm_Q) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(GqdMem) , U , U , U }, U },
+ { G(ExtRm_Q) , 4 , 0x00, 0x00, F(Move) , { O(Xmm) , O(GqdMem) , U , U , U }, U },
+ { G(ExtRm) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U },
+ { G(X86Op) , 0 , 0x28, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86IncDec) , 0 , 0x00, 0x1F, F(Lock) , { O(GqdwbMem) , U , U , U , U }, O_000000(48,U) },
+ { G(X86Rm_B) , 0 , 0x00, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86Op) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U },
+ { G(X86Enter) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(GqdMem) , O(Xmm) , U , U , U }, O_660F3A(17,U) },
+ { G(FpuOp) , 0 , 0x00, 0x00, F(Fp) , { U , U , U , U , U }, U },
+ { G(FpuArith) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8) , { O(FpMem) , O(Fp) , U , U , U }, U },
+ { G(FpuRDef) , 0 , 0x00, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U },
+ { G(X86M) , 0 , 0x00, 0x00, F(Fp) , { O(Mem) , U , U , U , U }, U },
+ { G(FpuR) , 0 , 0x20, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U },
+ { G(FpuR) , 0 , 0x24, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U },
+ { G(FpuR) , 0 , 0x04, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U },
+ { G(FpuR) , 0 , 0x10, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U },
+ { G(FpuCom) , 0 , 0x00, 0x00, F(Fp) , { O(Fp)|O(Mem) , O(Fp) , U , U , U }, U },
+ { G(FpuR) , 0 , 0x00, 0x3F, F(Fp) , { O(Fp) , U , U , U , U }, U },
+ { G(X86Op) , 0 , 0x00, 0x00, F(Fp) , { U , U , U , U , U }, U },
+ { G(FpuR) , 0 , 0x00, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U },
+ { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4) , { O(Mem) , U , U , U , U }, U },
+ { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4_8) , { O(Mem) , U , U , U , U }, O_000000(DF,5) },
+ { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4_8) , { O(Mem) , U , U , U , U }, O_000000(DF,7) },
+ { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4_8) , { O(Mem) , U , U , U , U }, O_000000(DD,1) },
+ { G(FpuFldFst) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8_10) , { O(Mem) , U , U , U , U }, O_000000(DB,5) },
+ { G(FpuStsw) , 0 , 0x00, 0x00, F(Fp) , { O(Mem) , U , U , U , U }, O_00_X(DFE0,U) },
+ { G(FpuFldFst) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8) , { O(Mem) , U , U , U , U }, U },
+ { G(FpuFldFst) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8_10) , { O(Mem) , U , U , U , U }, O_000000(DB,7) },
+ { G(FpuStsw) , 0 , 0x00, 0x00, F(Fp) , { O(Mem) , U , U , U , U }, O_9B_X(DFE0,U) },
+ { G(X86Rm_B) , 0 , 0x00, 0x3F, F(None)|F(Special) , { 0 , 0 , U , U , U }, U },
+ { G(X86Imul) , 0 , 0x00, 0x3F, F(None)|F(Special) , { 0 , 0 , U , U , U }, U },
+ { G(X86IncDec) , 0 , 0x00, 0x1F, F(Lock) , { O(GqdwbMem) , U , U , U , U }, O_000000(40,U) },
+ { G(X86Int) , 0 , 0x00, 0x80, F(None) , { U , U , U , U , U }, U },
+ { G(X86Jcc) , 0 , 0x24, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U },
+ { G(X86Jcc) , 0 , 0x20, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U },
+ { G(X86Jcc) , 0 , 0x04, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U },
+ { G(X86Jcc) , 0 , 0x07, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U },
+ { G(X86Jcc) , 0 , 0x03, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U },
+ { G(X86Jcc) , 0 , 0x01, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U },
+ { G(X86Jcc) , 0 , 0x10, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U },
+ { G(X86Jcc) , 0 , 0x02, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U },
+ { G(X86Jecxz) , 0 , 0x00, 0x00, F(Flow)|F(Special) , { O(Gqdw) , O(Label) , U , U , U }, U },
+ { G(X86Jmp) , 0 , 0x00, 0x00, F(Flow) , { O(Imm)|O(Label) , U , U , U , U }, O_000000(E9,U) },
+ { G(X86Op) , 0 , 0x3E, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(Mem) , U , U , U }, U },
+ { G(X86Lea) , 0 , 0x00, 0x00, F(Move) , { O(Gqd) , O(Mem) , U , U , U }, U },
+ { G(ExtFence) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U },
+ { G(X86Op) , 1 , 0x40, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86Op) , 4 , 0x40, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86Op) , 8 , 0x40, 0x00, F(Move)|F(Special)|F(W), { U , U , U , U , U }, U },
+ { G(X86Op_66H) , 2 , 0x40, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U },
+ { G(ExtRm) , 0 , 0x00, 0x00, F(None)|F(Special) , { O(Xmm) , O(Xmm) , U , U , U }, U },
+ { G(ExtRm) , 0 , 0x00, 0x00, F(None)|F(Special) , { O(Mm) , O(Mm) , U , U , U }, U },
+ { G(X86Mov) , 0 , 0x00, 0x00, F(Move) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U },
+ { G(X86MovPtr) , 0 , 0x00, 0x00, F(Move)|F(Special) , { O(Gqdwb) , O(Imm) , U , U , U }, O_000000(A2,U) },
+ { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(29,U) },
+ { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(29,U) },
+ { G(ExtMovBe) , 0 , 0x00, 0x00, F(Move) , { O(GqdwMem) , O(GqdwMem) , U , U , U }, O_000F38(F1,U) },
+ { G(ExtMovD) , 16, 0x00, 0x00, F(Move) , { O(Gd)|O(MmXmmMem) , O(Gd)|O(MmXmmMem) , U , U , U }, O_000F00(7E,U) },
+ { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U },
+ { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Mm) , O(Xmm) , U , U , U }, U },
+ { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(7F,U) },
+ { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_F30F00(7F,U) },
+ { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(Xmm) , U , U , U }, U },
+ { G(ExtMov) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(17,U) },
+ { G(ExtMov) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(17,U) },
+ { G(ExtMov) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , U , U , U }, U },
+ { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(13,U) },
+ { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(13,U) },
+ { G(ExtMovNoRexW) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , O(Xmm) , U , U , U }, U },
+ { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Mem) , O(Xmm) , U , U , U }, O_660F00(E7,U) },
+ { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(Mem) , U , U , U }, U },
+ { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Mem) , O(Gqd) , U , U , U }, O_000F00(C3,U) },
+ { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Mem) , O(Xmm) , U , U , U }, O_660F00(2B,U) },
+ { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Mem) , O(Xmm) , U , U , U }, O_000F00(2B,U) },
+ { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Mem) , O(Mm) , U , U , U }, O_000F00(E7,U) },
+ { G(ExtMovQ) , 16, 0x00, 0x00, F(Move) , { O(Gq)|O(MmXmmMem) , O(Gq)|O(MmXmmMem) , U , U , U }, U },
+ { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(Mm) , U , U , U }, U },
+ { G(X86Op) , 0 , 0x00, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86Op_66H) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(ExtMov) , 8 , 0x00, 0x00, F(Move) |F(Z), { O(XmmMem) , O(XmmMem) , U , U , U }, O_F20F00(11,U) },
+ { G(ExtMov) , 4 , 0x00, 0x00, F(Move) |F(Z), { O(XmmMem) , O(XmmMem) , U , U , U }, O_F30F00(11,U) },
+ { G(X86MovSxZx) , 0 , 0x00, 0x00, F(Move) , { O(Gqdw) , O(GwbMem) , U , U , U }, U },
+ { G(X86MovSxd) , 0 , 0x00, 0x00, F(Move) , { O(Gq) , O(GdMem) , U , U , U }, U },
+ { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(11,U) },
+ { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(11,U) },
+ { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(Gqd) , O(GqdMem) , U , U }, U },
+ { G(X86Rm_B) , 0 , 0x00, 0x3F, F(Lock) , { O(GqdwbMem) , U , U , U , U }, U },
+ { G(X86Rm_B) , 0 , 0x00, 0x00, F(Lock) , { O(GqdwbMem) , U , U , U , U }, U },
+ { G(ExtRm_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem) , U , U , U }, U },
+ { G(ExtRmi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem) , O(Imm) , U , U }, U },
+ { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(Gd)|O(Gb)|O(Mem) , O(Xmm) , U , U , U }, O_000F3A(14,U) },
+ { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(GdMem) , O(Xmm) , U , U , U }, O_000F3A(16,U) },
+ { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) |F(W), { O(GqdMem) , O(Xmm) , U , U , U }, O_000F3A(16,U) },
+ { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(GdMem) , O(MmXmm) , U , U , U }, O_000F3A(15,U) },
+ { G(3dNow) , 0 , 0x00, 0x00, F(None) , { O(Mm) , O(MmMem) , U , U , U }, U },
+ { G(ExtRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(GdMem) , O(Imm) , U , U }, U },
+ { G(ExtRmi) , 0 , 0x00, 0x00, F(None) |F(W), { O(Xmm) , O(GqMem) , O(Imm) , U , U }, U },
+ { G(ExtRmi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(GdMem) , O(Imm) , U , U }, U },
+ { G(ExtRm_PQ) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , O(MmXmm) , U , U , U }, U },
+ { G(X86Pop) , 0 , 0x00, 0x00, F(None)|F(Special) , { 0 , U , U , U , U }, O_000000(58,U) },
+ { G(X86Op) , 0 , 0x00, 0xFF, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(ExtPrefetch) , 0 , 0x00, 0x00, F(None) , { O(Mem) , O(Imm) , U , U , U }, U },
+ { G(ExtRmi) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U },
+ { G(ExtRmi_P) , 8 , 0x00, 0x00, F(Move) , { O(Mm) , O(MmMem) , O(Imm) , U , U }, U },
+ { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(72,6) },
+ { G(ExtRmRi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Imm) , U , U , U }, O_660F00(73,7) },
+ { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(73,6) },
+ { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(71,6) },
+ { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(72,4) },
+ { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(71,4) },
+ { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(72,2) },
+ { G(ExtRmRi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Imm) , U , U , U }, O_660F00(73,3) },
+ { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(73,2) },
+ { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(71,2) },
+ { G(X86Push) , 0 , 0x00, 0x00, F(None)|F(Special) , { 0 , U , U , U , U }, O_000000(50,U) },
+ { G(X86Op) , 0 , 0xFF, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86Rot) , 0 , 0x20, 0x21, F(None)|F(Special) , { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, U },
+ { G(X86Rm) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , U , U , U , U }, U },
+ { G(X86Rm) , 8 , 0x00, 0x3F, F(Move) , { O(Gqdw) , U , U , U , U }, U },
+ { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special) , { O(Mem) , U , U , U , U }, U },
+ { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special)|F(W), { O(Mem) , U , U , U , U }, U },
+ { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special) , { O(Mem) , O(Mem) , U , U , U }, U },
+ { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special)|F(W), { O(Mem) , O(Mem) , U , U , U }, U },
+ { G(X86Rep) , 0 , 0x40, 0x3F, F(None)|F(Special) , { O(Mem) , O(Mem) , U , U , U }, U },
+ { G(X86Rep) , 0 , 0x40, 0x3F, F(None)|F(Special)|F(W), { O(Mem) , O(Mem) , U , U , U }, U },
+ { G(X86Ret) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86Rot) , 0 , 0x00, 0x21, F(None)|F(Special) , { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, U },
+ { G(AvxRmi) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(GqdMem) , O(Imm) , U , U }, U },
+ { G(ExtRmi) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U },
+ { G(ExtRmi) , 4 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U },
+ { G(X86Op) , 0 , 0x00, 0x3E, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86Rot) , 0 , 0x00, 0x3F, F(None)|F(Special) , { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, U },
+ { G(AvxRmv) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(GqdMem) , O(Gqd) , U , U }, U },
+ { G(X86Set) , 1 , 0x24, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U },
+ { G(X86Set) , 1 , 0x20, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U },
+ { G(X86Set) , 1 , 0x04, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U },
+ { G(X86Set) , 1 , 0x07, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U },
+ { G(X86Set) , 1 , 0x03, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U },
+ { G(X86Set) , 1 , 0x01, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U },
+ { G(X86Set) , 1 , 0x10, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U },
+ { G(X86Set) , 1 , 0x02, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U },
+ { G(X86Shlrd) , 0 , 0x00, 0x3F, F(None)|F(Special) , { O(GqdwbMem) , O(Gb) , U , U , U }, U },
+ { G(X86Shlrd) , 0 , 0x00, 0x3F, F(None)|F(Special) , { O(GqdwbMem) , O(Gqdwb) , U , U , U }, U },
+ { G(X86Op) , 0 , 0x40, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86Op) , 0 , 0x40, 0x00, F(None)|F(Special)|F(W), { U , U , U , U , U }, U },
+ { G(X86Op_66H) , 0 , 0x40, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U },
+ { G(X86Test) , 0 , 0x00, 0x3F, F(Test) , { O(GqdwbMem) , O(Gqdwb)|O(Imm) , U , U , U }, O_000000(F6,U) },
+ { G(X86RegRm) , 0 , 0x00, 0x3F, F(Move) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U },
+ { G(AvxRvm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , U }, U },
+ { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , U , U }, U },
+ { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U },
+ { G(AvxRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U },
+ { G(AvxRvmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U }, U },
+ { G(AvxRvmr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , U }, U },
+ { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Mem) , U , U , U }, U },
+ { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(XmmMem) , U , U , U }, U },
+ { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U }, U },
+ { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmMem) , U , U , U }, U },
+ { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U },
+ { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmYmmMem) , U , U , U }, U },
+ { G(AvxMri_P) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmYmm) , O(Imm) , U , U }, U },
+ { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(XmmMem) , U , U , U }, U },
+ { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdMem) , U , U }, U },
+ { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmYmmMem) , U , U , U }, U },
+ { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Ymm) , O(Imm) , U , U }, U },
+ { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(GqdMem) , O(Xmm) , O(Imm) , U , U }, U },
+ { G(AvxRvm_P) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , U }, U },
+ { G(AvxRvm) , 0 , 0x00, 0x00, F(None) |F(W), { O(Xmm) , O(Xmm) , O(XmmMem) , U , U }, U },
+ { G(Fma4_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , U }, U },
+ { G(Fma4) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U }, U },
+ { G(XopRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U },
+ { G(XopRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U },
+ { G(AvxGather) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmYmm) , O(Mem) , O(XmmYmm) , U , U }, U },
+ { G(AvxGather) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(Mem) , O(XmmYmm) , U , U }, U },
+ { G(AvxGatherEx) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Mem) , O(Xmm) , U , U }, U },
+ { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , U }, U },
+ { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(Mem) , U , U , U }, U },
+ { G(AvxM) , 0 , 0x00, 0x00, F(None) , { O(Mem) , U , U , U , U }, U },
+ { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , U , U , U }, U },
+ { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(2F,U) },
+ { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(2E,U) },
+ { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_660F00(29,U) },
+ { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_000F00(29,U) },
+ { G(AvxRmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(7E,U) },
+ { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_660F00(7F,U) },
+ { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_F30F00(7F,U) },
+ { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(Xmm) , U , U }, U },
+ { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_660F00(17,U) },
+ { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_000F00(17,U) },
+ { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_660F00(13,U) },
+ { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_000F00(13,U) },
+ { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(XmmYmm) , U , U , U }, U },
+ { G(AvxMr) , 0 , 0x00, 0x00, F(None) , { O(Mem) , O(XmmYmm) , U , U , U }, U },
+ { G(AvxMr_P) , 0 , 0x00, 0x00, F(None) , { O(Mem) , O(XmmYmm) , U , U , U }, U },
+ { G(AvxRmMr) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(7E,U) },
+ { G(AvxMovSsSd) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , O(Xmm) , U , U }, O_F20F00(11,U) },
+ { G(AvxMovSsSd) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Xmm) , U , U }, O_F30F00(11,U) },
+ { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_660F00(11,U) },
+ { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_000F00(11,U) },
+ { G(AvxRvmr) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , U }, U },
+ { G(XopRvrmRvmr_P), 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , U }, U },
+ { G(XopRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U }, U },
+ { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , U }, U },
+ { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Ymm) , O(YmmMem) , U , U }, U },
+ { G(AvxRvrmRvmr_P), 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , U }, U },
+ { G(AvxRvmRmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F3A(05,U) },
+ { G(AvxRvmRmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F3A(04,U) },
+ { G(AvxRmi) , 0 , 0x00, 0x00, F(None) |F(W), { O(Ymm) , O(YmmMem) , O(Imm) , U , U }, U },
+ { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(GqdwbMem) , O(Xmm) , O(Imm) , U , U }, U },
+ { G(AvxMri) , 0 , 0x00, 0x00, F(None) |F(W), { O(GqMem) , O(Xmm) , O(Imm) , U , U }, U },
+ { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(GqdwMem) , O(Xmm) , O(Imm) , U , U }, U },
+ { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdwbMem) , O(Imm) , U }, U },
+ { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdMem) , O(Imm) , U }, U },
+ { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) |F(W), { O(Xmm) , O(Xmm) , O(GqMem) , O(Imm) , U }, U },
+ { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdwMem) , O(Imm) , U }, U },
+ { G(XopRvmr) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U }, U },
+ { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(8E,U) },
+ { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(8E,U) },
+ { G(XopRvrmRvmr) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U }, U },
+ { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C0,U) },
+ { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C2,U) },
+ { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C3,U) },
+ { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C1,U) },
+ { G(XopRvmRmv) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem) , U , U }, U },
+ { G(AvxRmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , U }, U },
+ { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(72,6) },
+ { G(AvxVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , U }, U },
+ { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(73,6) },
+ { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(71,6) },
+ { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(72,4) },
+ { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(71,4) },
+ { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(72,2) },
+ { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(73,2) },
+ { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(71,2) },
+ { G(AvxRm_P) , 0 , 0x00, 0x3F, F(None) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U },
+ { G(AvxRm_P) , 0 , 0x00, 0x3F, F(Test) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U },
+ { G(AvxRm) , 0 , 0x00, 0x3F, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U },
+ { G(AvxOp) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U },
+ { G(X86Rm) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , U , U , U , U }, U },
+ { G(X86Xadd) , 0 , 0x00, 0x3F, F(Xchg)|F(Lock) , { O(GqdwbMem) , O(Gqdwb) , U , U , U }, U },
+ { G(X86Xchg) , 0 , 0x00, 0x00, F(Xchg)|F(Lock) , { O(GqdwbMem) , O(Gqdwb) , U , U , U }, U }
+};
+
+// Automatically generated, do not edit.
+enum kX86InstData_ExtendedIndex {
+ kInstIdNone_ExtendedIndex = 0,
+ kX86InstIdAdc_ExtendedIndex = 1,
+ kX86InstIdAdd_ExtendedIndex = 2,
+ kX86InstIdAddpd_ExtendedIndex = 3,
+ kX86InstIdAddps_ExtendedIndex = 3,
+ kX86InstIdAddsd_ExtendedIndex = 3,
+ kX86InstIdAddss_ExtendedIndex = 3,
+ kX86InstIdAddsubpd_ExtendedIndex = 3,
+ kX86InstIdAddsubps_ExtendedIndex = 3,
+ kX86InstIdAesdec_ExtendedIndex = 3,
+ kX86InstIdAesdeclast_ExtendedIndex = 3,
+ kX86InstIdAesenc_ExtendedIndex = 3,
+ kX86InstIdAesenclast_ExtendedIndex = 3,
+ kX86InstIdAesimc_ExtendedIndex = 3,
+ kX86InstIdAeskeygenassist_ExtendedIndex = 4,
+ kX86InstIdAnd_ExtendedIndex = 2,
+ kX86InstIdAndn_ExtendedIndex = 5,
+ kX86InstIdAndnpd_ExtendedIndex = 3,
+ kX86InstIdAndnps_ExtendedIndex = 3,
+ kX86InstIdAndpd_ExtendedIndex = 3,
+ kX86InstIdAndps_ExtendedIndex = 3,
+ kX86InstIdBextr_ExtendedIndex = 6,
+ kX86InstIdBlendpd_ExtendedIndex = 4,
+ kX86InstIdBlendps_ExtendedIndex = 4,
+ kX86InstIdBlendvpd_ExtendedIndex = 7,
+ kX86InstIdBlendvps_ExtendedIndex = 7,
+ kX86InstIdBlsi_ExtendedIndex = 8,
+ kX86InstIdBlsmsk_ExtendedIndex = 8,
+ kX86InstIdBlsr_ExtendedIndex = 8,
+ kX86InstIdBsf_ExtendedIndex = 9,
+ kX86InstIdBsr_ExtendedIndex = 9,
+ kX86InstIdBswap_ExtendedIndex = 10,
+ kX86InstIdBt_ExtendedIndex = 11,
+ kX86InstIdBtc_ExtendedIndex = 12,
+ kX86InstIdBtr_ExtendedIndex = 13,
+ kX86InstIdBts_ExtendedIndex = 14,
+ kX86InstIdBzhi_ExtendedIndex = 6,
+ kX86InstIdCall_ExtendedIndex = 15,
+ kX86InstIdCbw_ExtendedIndex = 16,
+ kX86InstIdCdq_ExtendedIndex = 16,
+ kX86InstIdCdqe_ExtendedIndex = 17,
+ kX86InstIdClc_ExtendedIndex = 18,
+ kX86InstIdCld_ExtendedIndex = 19,
+ kX86InstIdClflush_ExtendedIndex = 20,
+ kX86InstIdCmc_ExtendedIndex = 21,
+ kX86InstIdCmova_ExtendedIndex = 22,
+ kX86InstIdCmovae_ExtendedIndex = 23,
+ kX86InstIdCmovb_ExtendedIndex = 23,
+ kX86InstIdCmovbe_ExtendedIndex = 22,
+ kX86InstIdCmovc_ExtendedIndex = 23,
+ kX86InstIdCmove_ExtendedIndex = 24,
+ kX86InstIdCmovg_ExtendedIndex = 25,
+ kX86InstIdCmovge_ExtendedIndex = 26,
+ kX86InstIdCmovl_ExtendedIndex = 26,
+ kX86InstIdCmovle_ExtendedIndex = 25,
+ kX86InstIdCmovna_ExtendedIndex = 22,
+ kX86InstIdCmovnae_ExtendedIndex = 23,
+ kX86InstIdCmovnb_ExtendedIndex = 23,
+ kX86InstIdCmovnbe_ExtendedIndex = 22,
+ kX86InstIdCmovnc_ExtendedIndex = 23,
+ kX86InstIdCmovne_ExtendedIndex = 24,
+ kX86InstIdCmovng_ExtendedIndex = 25,
+ kX86InstIdCmovnge_ExtendedIndex = 26,
+ kX86InstIdCmovnl_ExtendedIndex = 26,
+ kX86InstIdCmovnle_ExtendedIndex = 25,
+ kX86InstIdCmovno_ExtendedIndex = 27,
+ kX86InstIdCmovnp_ExtendedIndex = 28,
+ kX86InstIdCmovns_ExtendedIndex = 29,
+ kX86InstIdCmovnz_ExtendedIndex = 24,
+ kX86InstIdCmovo_ExtendedIndex = 27,
+ kX86InstIdCmovp_ExtendedIndex = 28,
+ kX86InstIdCmovpe_ExtendedIndex = 28,
+ kX86InstIdCmovpo_ExtendedIndex = 28,
+ kX86InstIdCmovs_ExtendedIndex = 29,
+ kX86InstIdCmovz_ExtendedIndex = 24,
+ kX86InstIdCmp_ExtendedIndex = 30,
+ kX86InstIdCmppd_ExtendedIndex = 4,
+ kX86InstIdCmpps_ExtendedIndex = 4,
+ kX86InstIdCmpsB_ExtendedIndex = 31,
+ kX86InstIdCmpsD_ExtendedIndex = 31,
+ kX86InstIdCmpsQ_ExtendedIndex = 32,
+ kX86InstIdCmpsW_ExtendedIndex = 33,
+ kX86InstIdCmpsd_ExtendedIndex = 4,
+ kX86InstIdCmpss_ExtendedIndex = 4,
+ kX86InstIdCmpxchg_ExtendedIndex = 34,
+ kX86InstIdCmpxchg16b_ExtendedIndex = 35,
+ kX86InstIdCmpxchg8b_ExtendedIndex = 36,
+ kX86InstIdComisd_ExtendedIndex = 37,
+ kX86InstIdComiss_ExtendedIndex = 37,
+ kX86InstIdCpuid_ExtendedIndex = 16,
+ kX86InstIdCqo_ExtendedIndex = 17,
+ kX86InstIdCrc32_ExtendedIndex = 38,
+ kX86InstIdCvtdq2pd_ExtendedIndex = 39,
+ kX86InstIdCvtdq2ps_ExtendedIndex = 39,
+ kX86InstIdCvtpd2dq_ExtendedIndex = 39,
+ kX86InstIdCvtpd2pi_ExtendedIndex = 40,
+ kX86InstIdCvtpd2ps_ExtendedIndex = 39,
+ kX86InstIdCvtpi2pd_ExtendedIndex = 41,
+ kX86InstIdCvtpi2ps_ExtendedIndex = 42,
+ kX86InstIdCvtps2dq_ExtendedIndex = 39,
+ kX86InstIdCvtps2pd_ExtendedIndex = 39,
+ kX86InstIdCvtps2pi_ExtendedIndex = 40,
+ kX86InstIdCvtsd2si_ExtendedIndex = 43,
+ kX86InstIdCvtsd2ss_ExtendedIndex = 44,
+ kX86InstIdCvtsi2sd_ExtendedIndex = 45,
+ kX86InstIdCvtsi2ss_ExtendedIndex = 46,
+ kX86InstIdCvtss2sd_ExtendedIndex = 47,
+ kX86InstIdCvtss2si_ExtendedIndex = 43,
+ kX86InstIdCvttpd2dq_ExtendedIndex = 39,
+ kX86InstIdCvttpd2pi_ExtendedIndex = 40,
+ kX86InstIdCvttps2dq_ExtendedIndex = 39,
+ kX86InstIdCvttps2pi_ExtendedIndex = 40,
+ kX86InstIdCvttsd2si_ExtendedIndex = 43,
+ kX86InstIdCvttss2si_ExtendedIndex = 43,
+ kX86InstIdCwd_ExtendedIndex = 16,
+ kX86InstIdCwde_ExtendedIndex = 16,
+ kX86InstIdDaa_ExtendedIndex = 48,
+ kX86InstIdDas_ExtendedIndex = 48,
+ kX86InstIdDec_ExtendedIndex = 49,
+ kX86InstIdDiv_ExtendedIndex = 50,
+ kX86InstIdDivpd_ExtendedIndex = 3,
+ kX86InstIdDivps_ExtendedIndex = 3,
+ kX86InstIdDivsd_ExtendedIndex = 3,
+ kX86InstIdDivss_ExtendedIndex = 3,
+ kX86InstIdDppd_ExtendedIndex = 4,
+ kX86InstIdDpps_ExtendedIndex = 4,
+ kX86InstIdEmms_ExtendedIndex = 51,
+ kX86InstIdEnter_ExtendedIndex = 52,
+ kX86InstIdExtractps_ExtendedIndex = 53,
+ kX86InstIdF2xm1_ExtendedIndex = 54,
+ kX86InstIdFabs_ExtendedIndex = 54,
+ kX86InstIdFadd_ExtendedIndex = 55,
+ kX86InstIdFaddp_ExtendedIndex = 56,
+ kX86InstIdFbld_ExtendedIndex = 57,
+ kX86InstIdFbstp_ExtendedIndex = 57,
+ kX86InstIdFchs_ExtendedIndex = 54,
+ kX86InstIdFclex_ExtendedIndex = 54,
+ kX86InstIdFcmovb_ExtendedIndex = 58,
+ kX86InstIdFcmovbe_ExtendedIndex = 59,
+ kX86InstIdFcmove_ExtendedIndex = 60,
+ kX86InstIdFcmovnb_ExtendedIndex = 58,
+ kX86InstIdFcmovnbe_ExtendedIndex = 59,
+ kX86InstIdFcmovne_ExtendedIndex = 60,
+ kX86InstIdFcmovnu_ExtendedIndex = 61,
+ kX86InstIdFcmovu_ExtendedIndex = 61,
+ kX86InstIdFcom_ExtendedIndex = 62,
+ kX86InstIdFcomi_ExtendedIndex = 63,
+ kX86InstIdFcomip_ExtendedIndex = 63,
+ kX86InstIdFcomp_ExtendedIndex = 62,
+ kX86InstIdFcompp_ExtendedIndex = 54,
+ kX86InstIdFcos_ExtendedIndex = 54,
+ kX86InstIdFdecstp_ExtendedIndex = 54,
+ kX86InstIdFdiv_ExtendedIndex = 55,
+ kX86InstIdFdivp_ExtendedIndex = 56,
+ kX86InstIdFdivr_ExtendedIndex = 55,
+ kX86InstIdFdivrp_ExtendedIndex = 56,
+ kX86InstIdFemms_ExtendedIndex = 64,
+ kX86InstIdFfree_ExtendedIndex = 65,
+ kX86InstIdFiadd_ExtendedIndex = 66,
+ kX86InstIdFicom_ExtendedIndex = 66,
+ kX86InstIdFicomp_ExtendedIndex = 66,
+ kX86InstIdFidiv_ExtendedIndex = 66,
+ kX86InstIdFidivr_ExtendedIndex = 66,
+ kX86InstIdFild_ExtendedIndex = 67,
+ kX86InstIdFimul_ExtendedIndex = 66,
+ kX86InstIdFincstp_ExtendedIndex = 54,
+ kX86InstIdFinit_ExtendedIndex = 54,
+ kX86InstIdFist_ExtendedIndex = 66,
+ kX86InstIdFistp_ExtendedIndex = 68,
+ kX86InstIdFisttp_ExtendedIndex = 69,
+ kX86InstIdFisub_ExtendedIndex = 66,
+ kX86InstIdFisubr_ExtendedIndex = 66,
+ kX86InstIdFld_ExtendedIndex = 70,
+ kX86InstIdFld1_ExtendedIndex = 54,
+ kX86InstIdFldcw_ExtendedIndex = 57,
+ kX86InstIdFldenv_ExtendedIndex = 57,
+ kX86InstIdFldl2e_ExtendedIndex = 54,
+ kX86InstIdFldl2t_ExtendedIndex = 54,
+ kX86InstIdFldlg2_ExtendedIndex = 54,
+ kX86InstIdFldln2_ExtendedIndex = 54,
+ kX86InstIdFldpi_ExtendedIndex = 54,
+ kX86InstIdFldz_ExtendedIndex = 54,
+ kX86InstIdFmul_ExtendedIndex = 55,
+ kX86InstIdFmulp_ExtendedIndex = 56,
+ kX86InstIdFnclex_ExtendedIndex = 54,
+ kX86InstIdFninit_ExtendedIndex = 54,
+ kX86InstIdFnop_ExtendedIndex = 54,
+ kX86InstIdFnsave_ExtendedIndex = 57,
+ kX86InstIdFnstcw_ExtendedIndex = 57,
+ kX86InstIdFnstenv_ExtendedIndex = 57,
+ kX86InstIdFnstsw_ExtendedIndex = 71,
+ kX86InstIdFpatan_ExtendedIndex = 54,
+ kX86InstIdFprem_ExtendedIndex = 54,
+ kX86InstIdFprem1_ExtendedIndex = 54,
+ kX86InstIdFptan_ExtendedIndex = 54,
+ kX86InstIdFrndint_ExtendedIndex = 54,
+ kX86InstIdFrstor_ExtendedIndex = 57,
+ kX86InstIdFsave_ExtendedIndex = 57,
+ kX86InstIdFscale_ExtendedIndex = 54,
+ kX86InstIdFsin_ExtendedIndex = 54,
+ kX86InstIdFsincos_ExtendedIndex = 54,
+ kX86InstIdFsqrt_ExtendedIndex = 54,
+ kX86InstIdFst_ExtendedIndex = 72,
+ kX86InstIdFstcw_ExtendedIndex = 57,
+ kX86InstIdFstenv_ExtendedIndex = 57,
+ kX86InstIdFstp_ExtendedIndex = 73,
+ kX86InstIdFstsw_ExtendedIndex = 74,
+ kX86InstIdFsub_ExtendedIndex = 55,
+ kX86InstIdFsubp_ExtendedIndex = 56,
+ kX86InstIdFsubr_ExtendedIndex = 55,
+ kX86InstIdFsubrp_ExtendedIndex = 56,
+ kX86InstIdFtst_ExtendedIndex = 54,
+ kX86InstIdFucom_ExtendedIndex = 56,
+ kX86InstIdFucomi_ExtendedIndex = 63,
+ kX86InstIdFucomip_ExtendedIndex = 63,
+ kX86InstIdFucomp_ExtendedIndex = 56,
+ kX86InstIdFucompp_ExtendedIndex = 54,
+ kX86InstIdFwait_ExtendedIndex = 64,
+ kX86InstIdFxam_ExtendedIndex = 54,
+ kX86InstIdFxch_ExtendedIndex = 65,
+ kX86InstIdFxrstor_ExtendedIndex = 57,
+ kX86InstIdFxsave_ExtendedIndex = 57,
+ kX86InstIdFxtract_ExtendedIndex = 54,
+ kX86InstIdFyl2x_ExtendedIndex = 54,
+ kX86InstIdFyl2xp1_ExtendedIndex = 54,
+ kX86InstIdHaddpd_ExtendedIndex = 3,
+ kX86InstIdHaddps_ExtendedIndex = 3,
+ kX86InstIdHsubpd_ExtendedIndex = 3,
+ kX86InstIdHsubps_ExtendedIndex = 3,
+ kX86InstIdIdiv_ExtendedIndex = 75,
+ kX86InstIdImul_ExtendedIndex = 76,
+ kX86InstIdInc_ExtendedIndex = 77,
+ kX86InstIdInsertps_ExtendedIndex = 4,
+ kX86InstIdInt_ExtendedIndex = 78,
+ kX86InstIdJa_ExtendedIndex = 79,
+ kX86InstIdJae_ExtendedIndex = 80,
+ kX86InstIdJb_ExtendedIndex = 80,
+ kX86InstIdJbe_ExtendedIndex = 79,
+ kX86InstIdJc_ExtendedIndex = 80,
+ kX86InstIdJe_ExtendedIndex = 81,
+ kX86InstIdJg_ExtendedIndex = 82,
+ kX86InstIdJge_ExtendedIndex = 83,
+ kX86InstIdJl_ExtendedIndex = 83,
+ kX86InstIdJle_ExtendedIndex = 82,
+ kX86InstIdJna_ExtendedIndex = 79,
+ kX86InstIdJnae_ExtendedIndex = 80,
+ kX86InstIdJnb_ExtendedIndex = 80,
+ kX86InstIdJnbe_ExtendedIndex = 79,
+ kX86InstIdJnc_ExtendedIndex = 80,
+ kX86InstIdJne_ExtendedIndex = 81,
+ kX86InstIdJng_ExtendedIndex = 82,
+ kX86InstIdJnge_ExtendedIndex = 83,
+ kX86InstIdJnl_ExtendedIndex = 83,
+ kX86InstIdJnle_ExtendedIndex = 82,
+ kX86InstIdJno_ExtendedIndex = 84,
+ kX86InstIdJnp_ExtendedIndex = 85,
+ kX86InstIdJns_ExtendedIndex = 86,
+ kX86InstIdJnz_ExtendedIndex = 81,
+ kX86InstIdJo_ExtendedIndex = 84,
+ kX86InstIdJp_ExtendedIndex = 85,
+ kX86InstIdJpe_ExtendedIndex = 85,
+ kX86InstIdJpo_ExtendedIndex = 85,
+ kX86InstIdJs_ExtendedIndex = 86,
+ kX86InstIdJz_ExtendedIndex = 81,
+ kX86InstIdJecxz_ExtendedIndex = 87,
+ kX86InstIdJmp_ExtendedIndex = 88,
+ kX86InstIdLahf_ExtendedIndex = 89,
+ kX86InstIdLddqu_ExtendedIndex = 90,
+ kX86InstIdLdmxcsr_ExtendedIndex = 20,
+ kX86InstIdLea_ExtendedIndex = 91,
+ kX86InstIdLeave_ExtendedIndex = 16,
+ kX86InstIdLfence_ExtendedIndex = 92,
+ kX86InstIdLodsB_ExtendedIndex = 93,
+ kX86InstIdLodsD_ExtendedIndex = 94,
+ kX86InstIdLodsQ_ExtendedIndex = 95,
+ kX86InstIdLodsW_ExtendedIndex = 96,
+ kX86InstIdLzcnt_ExtendedIndex = 9,
+ kX86InstIdMaskmovdqu_ExtendedIndex = 97,
+ kX86InstIdMaskmovq_ExtendedIndex = 98,
+ kX86InstIdMaxpd_ExtendedIndex = 3,
+ kX86InstIdMaxps_ExtendedIndex = 3,
+ kX86InstIdMaxsd_ExtendedIndex = 3,
+ kX86InstIdMaxss_ExtendedIndex = 3,
+ kX86InstIdMfence_ExtendedIndex = 92,
+ kX86InstIdMinpd_ExtendedIndex = 3,
+ kX86InstIdMinps_ExtendedIndex = 3,
+ kX86InstIdMinsd_ExtendedIndex = 3,
+ kX86InstIdMinss_ExtendedIndex = 3,
+ kX86InstIdMonitor_ExtendedIndex = 16,
+ kX86InstIdMov_ExtendedIndex = 99,
+ kX86InstIdMovPtr_ExtendedIndex = 100,
+ kX86InstIdMovapd_ExtendedIndex = 101,
+ kX86InstIdMovaps_ExtendedIndex = 102,
+ kX86InstIdMovbe_ExtendedIndex = 103,
+ kX86InstIdMovd_ExtendedIndex = 104,
+ kX86InstIdMovddup_ExtendedIndex = 105,
+ kX86InstIdMovdq2q_ExtendedIndex = 106,
+ kX86InstIdMovdqa_ExtendedIndex = 107,
+ kX86InstIdMovdqu_ExtendedIndex = 108,
+ kX86InstIdMovhlps_ExtendedIndex = 109,
+ kX86InstIdMovhpd_ExtendedIndex = 110,
+ kX86InstIdMovhps_ExtendedIndex = 111,
+ kX86InstIdMovlhps_ExtendedIndex = 112,
+ kX86InstIdMovlpd_ExtendedIndex = 113,
+ kX86InstIdMovlps_ExtendedIndex = 114,
+ kX86InstIdMovmskpd_ExtendedIndex = 115,
+ kX86InstIdMovmskps_ExtendedIndex = 115,
+ kX86InstIdMovntdq_ExtendedIndex = 116,
+ kX86InstIdMovntdqa_ExtendedIndex = 117,
+ kX86InstIdMovnti_ExtendedIndex = 118,
+ kX86InstIdMovntpd_ExtendedIndex = 119,
+ kX86InstIdMovntps_ExtendedIndex = 120,
+ kX86InstIdMovntq_ExtendedIndex = 121,
+ kX86InstIdMovq_ExtendedIndex = 122,
+ kX86InstIdMovq2dq_ExtendedIndex = 123,
+ kX86InstIdMovsB_ExtendedIndex = 16,
+ kX86InstIdMovsD_ExtendedIndex = 124,
+ kX86InstIdMovsQ_ExtendedIndex = 17,
+ kX86InstIdMovsW_ExtendedIndex = 125,
+ kX86InstIdMovsd_ExtendedIndex = 126,
+ kX86InstIdMovshdup_ExtendedIndex = 39,
+ kX86InstIdMovsldup_ExtendedIndex = 39,
+ kX86InstIdMovss_ExtendedIndex = 127,
+ kX86InstIdMovsx_ExtendedIndex = 128,
+ kX86InstIdMovsxd_ExtendedIndex = 129,
+ kX86InstIdMovupd_ExtendedIndex = 130,
+ kX86InstIdMovups_ExtendedIndex = 131,
+ kX86InstIdMovzx_ExtendedIndex = 128,
+ kX86InstIdMpsadbw_ExtendedIndex = 4,
+ kX86InstIdMul_ExtendedIndex = 75,
+ kX86InstIdMulpd_ExtendedIndex = 3,
+ kX86InstIdMulps_ExtendedIndex = 3,
+ kX86InstIdMulsd_ExtendedIndex = 3,
+ kX86InstIdMulss_ExtendedIndex = 3,
+ kX86InstIdMulx_ExtendedIndex = 132,
+ kX86InstIdMwait_ExtendedIndex = 16,
+ kX86InstIdNeg_ExtendedIndex = 133,
+ kX86InstIdNop_ExtendedIndex = 51,
+ kX86InstIdNot_ExtendedIndex = 134,
+ kX86InstIdOr_ExtendedIndex = 2,
+ kX86InstIdOrpd_ExtendedIndex = 3,
+ kX86InstIdOrps_ExtendedIndex = 3,
+ kX86InstIdPabsb_ExtendedIndex = 135,
+ kX86InstIdPabsd_ExtendedIndex = 135,
+ kX86InstIdPabsw_ExtendedIndex = 135,
+ kX86InstIdPackssdw_ExtendedIndex = 135,
+ kX86InstIdPacksswb_ExtendedIndex = 135,
+ kX86InstIdPackusdw_ExtendedIndex = 3,
+ kX86InstIdPackuswb_ExtendedIndex = 135,
+ kX86InstIdPaddb_ExtendedIndex = 135,
+ kX86InstIdPaddd_ExtendedIndex = 135,
+ kX86InstIdPaddq_ExtendedIndex = 135,
+ kX86InstIdPaddsb_ExtendedIndex = 135,
+ kX86InstIdPaddsw_ExtendedIndex = 135,
+ kX86InstIdPaddusb_ExtendedIndex = 135,
+ kX86InstIdPaddusw_ExtendedIndex = 135,
+ kX86InstIdPaddw_ExtendedIndex = 135,
+ kX86InstIdPalignr_ExtendedIndex = 136,
+ kX86InstIdPand_ExtendedIndex = 135,
+ kX86InstIdPandn_ExtendedIndex = 135,
+ kX86InstIdPause_ExtendedIndex = 51,
+ kX86InstIdPavgb_ExtendedIndex = 135,
+ kX86InstIdPavgw_ExtendedIndex = 135,
+ kX86InstIdPblendvb_ExtendedIndex = 7,
+ kX86InstIdPblendw_ExtendedIndex = 4,
+ kX86InstIdPclmulqdq_ExtendedIndex = 4,
+ kX86InstIdPcmpeqb_ExtendedIndex = 135,
+ kX86InstIdPcmpeqd_ExtendedIndex = 135,
+ kX86InstIdPcmpeqq_ExtendedIndex = 3,
+ kX86InstIdPcmpeqw_ExtendedIndex = 135,
+ kX86InstIdPcmpestri_ExtendedIndex = 4,
+ kX86InstIdPcmpestrm_ExtendedIndex = 4,
+ kX86InstIdPcmpgtb_ExtendedIndex = 135,
+ kX86InstIdPcmpgtd_ExtendedIndex = 135,
+ kX86InstIdPcmpgtq_ExtendedIndex = 3,
+ kX86InstIdPcmpgtw_ExtendedIndex = 135,
+ kX86InstIdPcmpistri_ExtendedIndex = 4,
+ kX86InstIdPcmpistrm_ExtendedIndex = 4,
+ kX86InstIdPdep_ExtendedIndex = 132,
+ kX86InstIdPext_ExtendedIndex = 132,
+ kX86InstIdPextrb_ExtendedIndex = 137,
+ kX86InstIdPextrd_ExtendedIndex = 138,
+ kX86InstIdPextrq_ExtendedIndex = 139,
+ kX86InstIdPextrw_ExtendedIndex = 140,
+ kX86InstIdPf2id_ExtendedIndex = 141,
+ kX86InstIdPf2iw_ExtendedIndex = 141,
+ kX86InstIdPfacc_ExtendedIndex = 141,
+ kX86InstIdPfadd_ExtendedIndex = 141,
+ kX86InstIdPfcmpeq_ExtendedIndex = 141,
+ kX86InstIdPfcmpge_ExtendedIndex = 141,
+ kX86InstIdPfcmpgt_ExtendedIndex = 141,
+ kX86InstIdPfmax_ExtendedIndex = 141,
+ kX86InstIdPfmin_ExtendedIndex = 141,
+ kX86InstIdPfmul_ExtendedIndex = 141,
+ kX86InstIdPfnacc_ExtendedIndex = 141,
+ kX86InstIdPfpnacc_ExtendedIndex = 141,
+ kX86InstIdPfrcp_ExtendedIndex = 141,
+ kX86InstIdPfrcpit1_ExtendedIndex = 141,
+ kX86InstIdPfrcpit2_ExtendedIndex = 141,
+ kX86InstIdPfrsqit1_ExtendedIndex = 141,
+ kX86InstIdPfrsqrt_ExtendedIndex = 141,
+ kX86InstIdPfsub_ExtendedIndex = 141,
+ kX86InstIdPfsubr_ExtendedIndex = 141,
+ kX86InstIdPhaddd_ExtendedIndex = 135,
+ kX86InstIdPhaddsw_ExtendedIndex = 135,
+ kX86InstIdPhaddw_ExtendedIndex = 135,
+ kX86InstIdPhminposuw_ExtendedIndex = 3,
+ kX86InstIdPhsubd_ExtendedIndex = 135,
+ kX86InstIdPhsubsw_ExtendedIndex = 135,
+ kX86InstIdPhsubw_ExtendedIndex = 135,
+ kX86InstIdPi2fd_ExtendedIndex = 141,
+ kX86InstIdPi2fw_ExtendedIndex = 141,
+ kX86InstIdPinsrb_ExtendedIndex = 142,
+ kX86InstIdPinsrd_ExtendedIndex = 142,
+ kX86InstIdPinsrq_ExtendedIndex = 143,
+ kX86InstIdPinsrw_ExtendedIndex = 144,
+ kX86InstIdPmaddubsw_ExtendedIndex = 135,
+ kX86InstIdPmaddwd_ExtendedIndex = 135,
+ kX86InstIdPmaxsb_ExtendedIndex = 3,
+ kX86InstIdPmaxsd_ExtendedIndex = 3,
+ kX86InstIdPmaxsw_ExtendedIndex = 135,
+ kX86InstIdPmaxub_ExtendedIndex = 135,
+ kX86InstIdPmaxud_ExtendedIndex = 3,
+ kX86InstIdPmaxuw_ExtendedIndex = 3,
+ kX86InstIdPminsb_ExtendedIndex = 3,
+ kX86InstIdPminsd_ExtendedIndex = 3,
+ kX86InstIdPminsw_ExtendedIndex = 135,
+ kX86InstIdPminub_ExtendedIndex = 135,
+ kX86InstIdPminud_ExtendedIndex = 3,
+ kX86InstIdPminuw_ExtendedIndex = 3,
+ kX86InstIdPmovmskb_ExtendedIndex = 145,
+ kX86InstIdPmovsxbd_ExtendedIndex = 39,
+ kX86InstIdPmovsxbq_ExtendedIndex = 39,
+ kX86InstIdPmovsxbw_ExtendedIndex = 39,
+ kX86InstIdPmovsxdq_ExtendedIndex = 39,
+ kX86InstIdPmovsxwd_ExtendedIndex = 39,
+ kX86InstIdPmovsxwq_ExtendedIndex = 39,
+ kX86InstIdPmovzxbd_ExtendedIndex = 39,
+ kX86InstIdPmovzxbq_ExtendedIndex = 39,
+ kX86InstIdPmovzxbw_ExtendedIndex = 39,
+ kX86InstIdPmovzxdq_ExtendedIndex = 39,
+ kX86InstIdPmovzxwd_ExtendedIndex = 39,
+ kX86InstIdPmovzxwq_ExtendedIndex = 39,
+ kX86InstIdPmuldq_ExtendedIndex = 3,
+ kX86InstIdPmulhrsw_ExtendedIndex = 135,
+ kX86InstIdPmulhuw_ExtendedIndex = 135,
+ kX86InstIdPmulhw_ExtendedIndex = 135,
+ kX86InstIdPmulld_ExtendedIndex = 3,
+ kX86InstIdPmullw_ExtendedIndex = 135,
+ kX86InstIdPmuludq_ExtendedIndex = 135,
+ kX86InstIdPop_ExtendedIndex = 146,
+ kX86InstIdPopa_ExtendedIndex = 16,
+ kX86InstIdPopcnt_ExtendedIndex = 9,
+ kX86InstIdPopf_ExtendedIndex = 147,
+ kX86InstIdPor_ExtendedIndex = 135,
+ kX86InstIdPrefetch_ExtendedIndex = 148,
+ kX86InstIdPrefetch3dNow_ExtendedIndex = 20,
+ kX86InstIdPrefetchw3dNow_ExtendedIndex = 20,
+ kX86InstIdPsadbw_ExtendedIndex = 135,
+ kX86InstIdPshufb_ExtendedIndex = 135,
+ kX86InstIdPshufd_ExtendedIndex = 149,
+ kX86InstIdPshufhw_ExtendedIndex = 149,
+ kX86InstIdPshuflw_ExtendedIndex = 149,
+ kX86InstIdPshufw_ExtendedIndex = 150,
+ kX86InstIdPsignb_ExtendedIndex = 135,
+ kX86InstIdPsignd_ExtendedIndex = 135,
+ kX86InstIdPsignw_ExtendedIndex = 135,
+ kX86InstIdPslld_ExtendedIndex = 151,
+ kX86InstIdPslldq_ExtendedIndex = 152,
+ kX86InstIdPsllq_ExtendedIndex = 153,
+ kX86InstIdPsllw_ExtendedIndex = 154,
+ kX86InstIdPsrad_ExtendedIndex = 155,
+ kX86InstIdPsraw_ExtendedIndex = 156,
+ kX86InstIdPsrld_ExtendedIndex = 157,
+ kX86InstIdPsrldq_ExtendedIndex = 158,
+ kX86InstIdPsrlq_ExtendedIndex = 159,
+ kX86InstIdPsrlw_ExtendedIndex = 160,
+ kX86InstIdPsubb_ExtendedIndex = 135,
+ kX86InstIdPsubd_ExtendedIndex = 135,
+ kX86InstIdPsubq_ExtendedIndex = 135,
+ kX86InstIdPsubsb_ExtendedIndex = 135,
+ kX86InstIdPsubsw_ExtendedIndex = 135,
+ kX86InstIdPsubusb_ExtendedIndex = 135,
+ kX86InstIdPsubusw_ExtendedIndex = 135,
+ kX86InstIdPsubw_ExtendedIndex = 135,
+ kX86InstIdPswapd_ExtendedIndex = 141,
+ kX86InstIdPtest_ExtendedIndex = 37,
+ kX86InstIdPunpckhbw_ExtendedIndex = 135,
+ kX86InstIdPunpckhdq_ExtendedIndex = 135,
+ kX86InstIdPunpckhqdq_ExtendedIndex = 3,
+ kX86InstIdPunpckhwd_ExtendedIndex = 135,
+ kX86InstIdPunpcklbw_ExtendedIndex = 135,
+ kX86InstIdPunpckldq_ExtendedIndex = 135,
+ kX86InstIdPunpcklqdq_ExtendedIndex = 3,
+ kX86InstIdPunpcklwd_ExtendedIndex = 135,
+ kX86InstIdPush_ExtendedIndex = 161,
+ kX86InstIdPusha_ExtendedIndex = 16,
+ kX86InstIdPushf_ExtendedIndex = 162,
+ kX86InstIdPxor_ExtendedIndex = 135,
+ kX86InstIdRcl_ExtendedIndex = 163,
+ kX86InstIdRcpps_ExtendedIndex = 39,
+ kX86InstIdRcpss_ExtendedIndex = 44,
+ kX86InstIdRcr_ExtendedIndex = 163,
+ kX86InstIdRdfsbase_ExtendedIndex = 164,
+ kX86InstIdRdgsbase_ExtendedIndex = 164,
+ kX86InstIdRdrand_ExtendedIndex = 165,
+ kX86InstIdRdtsc_ExtendedIndex = 16,
+ kX86InstIdRdtscp_ExtendedIndex = 16,
+ kX86InstIdRepLodsB_ExtendedIndex = 166,
+ kX86InstIdRepLodsD_ExtendedIndex = 166,
+ kX86InstIdRepLodsQ_ExtendedIndex = 167,
+ kX86InstIdRepLodsW_ExtendedIndex = 166,
+ kX86InstIdRepMovsB_ExtendedIndex = 168,
+ kX86InstIdRepMovsD_ExtendedIndex = 168,
+ kX86InstIdRepMovsQ_ExtendedIndex = 169,
+ kX86InstIdRepMovsW_ExtendedIndex = 168,
+ kX86InstIdRepStosB_ExtendedIndex = 166,
+ kX86InstIdRepStosD_ExtendedIndex = 166,
+ kX86InstIdRepStosQ_ExtendedIndex = 167,
+ kX86InstIdRepStosW_ExtendedIndex = 166,
+ kX86InstIdRepeCmpsB_ExtendedIndex = 170,
+ kX86InstIdRepeCmpsD_ExtendedIndex = 170,
+ kX86InstIdRepeCmpsQ_ExtendedIndex = 171,
+ kX86InstIdRepeCmpsW_ExtendedIndex = 170,
+ kX86InstIdRepeScasB_ExtendedIndex = 170,
+ kX86InstIdRepeScasD_ExtendedIndex = 170,
+ kX86InstIdRepeScasQ_ExtendedIndex = 171,
+ kX86InstIdRepeScasW_ExtendedIndex = 170,
+ kX86InstIdRepneCmpsB_ExtendedIndex = 170,
+ kX86InstIdRepneCmpsD_ExtendedIndex = 170,
+ kX86InstIdRepneCmpsQ_ExtendedIndex = 171,
+ kX86InstIdRepneCmpsW_ExtendedIndex = 170,
+ kX86InstIdRepneScasB_ExtendedIndex = 170,
+ kX86InstIdRepneScasD_ExtendedIndex = 170,
+ kX86InstIdRepneScasQ_ExtendedIndex = 171,
+ kX86InstIdRepneScasW_ExtendedIndex = 170,
+ kX86InstIdRet_ExtendedIndex = 172,
+ kX86InstIdRol_ExtendedIndex = 173,
+ kX86InstIdRor_ExtendedIndex = 173,
+ kX86InstIdRorx_ExtendedIndex = 174,
+ kX86InstIdRoundpd_ExtendedIndex = 149,
+ kX86InstIdRoundps_ExtendedIndex = 149,
+ kX86InstIdRoundsd_ExtendedIndex = 175,
+ kX86InstIdRoundss_ExtendedIndex = 176,
+ kX86InstIdRsqrtps_ExtendedIndex = 39,
+ kX86InstIdRsqrtss_ExtendedIndex = 44,
+ kX86InstIdSahf_ExtendedIndex = 177,
+ kX86InstIdSal_ExtendedIndex = 178,
+ kX86InstIdSar_ExtendedIndex = 178,
+ kX86InstIdSarx_ExtendedIndex = 179,
+ kX86InstIdSbb_ExtendedIndex = 1,
+ kX86InstIdScasB_ExtendedIndex = 31,
+ kX86InstIdScasD_ExtendedIndex = 31,
+ kX86InstIdScasQ_ExtendedIndex = 32,
+ kX86InstIdScasW_ExtendedIndex = 33,
+ kX86InstIdSeta_ExtendedIndex = 180,
+ kX86InstIdSetae_ExtendedIndex = 181,
+ kX86InstIdSetb_ExtendedIndex = 181,
+ kX86InstIdSetbe_ExtendedIndex = 180,
+ kX86InstIdSetc_ExtendedIndex = 181,
+ kX86InstIdSete_ExtendedIndex = 182,
+ kX86InstIdSetg_ExtendedIndex = 183,
+ kX86InstIdSetge_ExtendedIndex = 184,
+ kX86InstIdSetl_ExtendedIndex = 184,
+ kX86InstIdSetle_ExtendedIndex = 183,
+ kX86InstIdSetna_ExtendedIndex = 180,
+ kX86InstIdSetnae_ExtendedIndex = 181,
+ kX86InstIdSetnb_ExtendedIndex = 181,
+ kX86InstIdSetnbe_ExtendedIndex = 180,
+ kX86InstIdSetnc_ExtendedIndex = 181,
+ kX86InstIdSetne_ExtendedIndex = 182,
+ kX86InstIdSetng_ExtendedIndex = 183,
+ kX86InstIdSetnge_ExtendedIndex = 184,
+ kX86InstIdSetnl_ExtendedIndex = 184,
+ kX86InstIdSetnle_ExtendedIndex = 183,
+ kX86InstIdSetno_ExtendedIndex = 185,
+ kX86InstIdSetnp_ExtendedIndex = 186,
+ kX86InstIdSetns_ExtendedIndex = 187,
+ kX86InstIdSetnz_ExtendedIndex = 182,
+ kX86InstIdSeto_ExtendedIndex = 185,
+ kX86InstIdSetp_ExtendedIndex = 186,
+ kX86InstIdSetpe_ExtendedIndex = 186,
+ kX86InstIdSetpo_ExtendedIndex = 186,
+ kX86InstIdSets_ExtendedIndex = 187,
+ kX86InstIdSetz_ExtendedIndex = 182,
+ kX86InstIdSfence_ExtendedIndex = 92,
+ kX86InstIdShl_ExtendedIndex = 178,
+ kX86InstIdShld_ExtendedIndex = 188,
+ kX86InstIdShlx_ExtendedIndex = 179,
+ kX86InstIdShr_ExtendedIndex = 178,
+ kX86InstIdShrd_ExtendedIndex = 189,
+ kX86InstIdShrx_ExtendedIndex = 179,
+ kX86InstIdShufpd_ExtendedIndex = 4,
+ kX86InstIdShufps_ExtendedIndex = 4,
+ kX86InstIdSqrtpd_ExtendedIndex = 39,
+ kX86InstIdSqrtps_ExtendedIndex = 39,
+ kX86InstIdSqrtsd_ExtendedIndex = 47,
+ kX86InstIdSqrtss_ExtendedIndex = 44,
+ kX86InstIdStc_ExtendedIndex = 18,
+ kX86InstIdStd_ExtendedIndex = 19,
+ kX86InstIdStmxcsr_ExtendedIndex = 20,
+ kX86InstIdStosB_ExtendedIndex = 190,
+ kX86InstIdStosD_ExtendedIndex = 190,
+ kX86InstIdStosQ_ExtendedIndex = 191,
+ kX86InstIdStosW_ExtendedIndex = 192,
+ kX86InstIdSub_ExtendedIndex = 2,
+ kX86InstIdSubpd_ExtendedIndex = 3,
+ kX86InstIdSubps_ExtendedIndex = 3,
+ kX86InstIdSubsd_ExtendedIndex = 3,
+ kX86InstIdSubss_ExtendedIndex = 3,
+ kX86InstIdTest_ExtendedIndex = 193,
+ kX86InstIdTzcnt_ExtendedIndex = 194,
+ kX86InstIdUcomisd_ExtendedIndex = 37,
+ kX86InstIdUcomiss_ExtendedIndex = 37,
+ kX86InstIdUd2_ExtendedIndex = 51,
+ kX86InstIdUnpckhpd_ExtendedIndex = 3,
+ kX86InstIdUnpckhps_ExtendedIndex = 3,
+ kX86InstIdUnpcklpd_ExtendedIndex = 3,
+ kX86InstIdUnpcklps_ExtendedIndex = 3,
+ kX86InstIdVaddpd_ExtendedIndex = 195,
+ kX86InstIdVaddps_ExtendedIndex = 195,
+ kX86InstIdVaddsd_ExtendedIndex = 195,
+ kX86InstIdVaddss_ExtendedIndex = 195,
+ kX86InstIdVaddsubpd_ExtendedIndex = 195,
+ kX86InstIdVaddsubps_ExtendedIndex = 195,
+ kX86InstIdVaesdec_ExtendedIndex = 196,
+ kX86InstIdVaesdeclast_ExtendedIndex = 196,
+ kX86InstIdVaesenc_ExtendedIndex = 196,
+ kX86InstIdVaesenclast_ExtendedIndex = 196,
+ kX86InstIdVaesimc_ExtendedIndex = 197,
+ kX86InstIdVaeskeygenassist_ExtendedIndex = 198,
+ kX86InstIdVandnpd_ExtendedIndex = 195,
+ kX86InstIdVandnps_ExtendedIndex = 195,
+ kX86InstIdVandpd_ExtendedIndex = 195,
+ kX86InstIdVandps_ExtendedIndex = 195,
+ kX86InstIdVblendpd_ExtendedIndex = 199,
+ kX86InstIdVblendps_ExtendedIndex = 199,
+ kX86InstIdVblendvpd_ExtendedIndex = 200,
+ kX86InstIdVblendvps_ExtendedIndex = 200,
+ kX86InstIdVbroadcastf128_ExtendedIndex = 201,
+ kX86InstIdVbroadcasti128_ExtendedIndex = 201,
+ kX86InstIdVbroadcastsd_ExtendedIndex = 202,
+ kX86InstIdVbroadcastss_ExtendedIndex = 202,
+ kX86InstIdVcmppd_ExtendedIndex = 199,
+ kX86InstIdVcmpps_ExtendedIndex = 199,
+ kX86InstIdVcmpsd_ExtendedIndex = 203,
+ kX86InstIdVcmpss_ExtendedIndex = 203,
+ kX86InstIdVcomisd_ExtendedIndex = 197,
+ kX86InstIdVcomiss_ExtendedIndex = 197,
+ kX86InstIdVcvtdq2pd_ExtendedIndex = 204,
+ kX86InstIdVcvtdq2ps_ExtendedIndex = 205,
+ kX86InstIdVcvtpd2dq_ExtendedIndex = 206,
+ kX86InstIdVcvtpd2ps_ExtendedIndex = 206,
+ kX86InstIdVcvtph2ps_ExtendedIndex = 204,
+ kX86InstIdVcvtps2dq_ExtendedIndex = 205,
+ kX86InstIdVcvtps2pd_ExtendedIndex = 204,
+ kX86InstIdVcvtps2ph_ExtendedIndex = 207,
+ kX86InstIdVcvtsd2si_ExtendedIndex = 208,
+ kX86InstIdVcvtsd2ss_ExtendedIndex = 196,
+ kX86InstIdVcvtsi2sd_ExtendedIndex = 209,
+ kX86InstIdVcvtsi2ss_ExtendedIndex = 209,
+ kX86InstIdVcvtss2sd_ExtendedIndex = 196,
+ kX86InstIdVcvtss2si_ExtendedIndex = 208,
+ kX86InstIdVcvttpd2dq_ExtendedIndex = 210,
+ kX86InstIdVcvttps2dq_ExtendedIndex = 205,
+ kX86InstIdVcvttsd2si_ExtendedIndex = 208,
+ kX86InstIdVcvttss2si_ExtendedIndex = 208,
+ kX86InstIdVdivpd_ExtendedIndex = 195,
+ kX86InstIdVdivps_ExtendedIndex = 195,
+ kX86InstIdVdivsd_ExtendedIndex = 196,
+ kX86InstIdVdivss_ExtendedIndex = 196,
+ kX86InstIdVdppd_ExtendedIndex = 203,
+ kX86InstIdVdpps_ExtendedIndex = 199,
+ kX86InstIdVextractf128_ExtendedIndex = 211,
+ kX86InstIdVextracti128_ExtendedIndex = 211,
+ kX86InstIdVextractps_ExtendedIndex = 212,
+ kX86InstIdVfmadd132pd_ExtendedIndex = 213,
+ kX86InstIdVfmadd132ps_ExtendedIndex = 195,
+ kX86InstIdVfmadd132sd_ExtendedIndex = 214,
+ kX86InstIdVfmadd132ss_ExtendedIndex = 196,
+ kX86InstIdVfmadd213pd_ExtendedIndex = 213,
+ kX86InstIdVfmadd213ps_ExtendedIndex = 195,
+ kX86InstIdVfmadd213sd_ExtendedIndex = 214,
+ kX86InstIdVfmadd213ss_ExtendedIndex = 196,
+ kX86InstIdVfmadd231pd_ExtendedIndex = 213,
+ kX86InstIdVfmadd231ps_ExtendedIndex = 195,
+ kX86InstIdVfmadd231sd_ExtendedIndex = 214,
+ kX86InstIdVfmadd231ss_ExtendedIndex = 196,
+ kX86InstIdVfmaddpd_ExtendedIndex = 215,
+ kX86InstIdVfmaddps_ExtendedIndex = 215,
+ kX86InstIdVfmaddsd_ExtendedIndex = 216,
+ kX86InstIdVfmaddss_ExtendedIndex = 216,
+ kX86InstIdVfmaddsub132pd_ExtendedIndex = 213,
+ kX86InstIdVfmaddsub132ps_ExtendedIndex = 195,
+ kX86InstIdVfmaddsub213pd_ExtendedIndex = 213,
+ kX86InstIdVfmaddsub213ps_ExtendedIndex = 195,
+ kX86InstIdVfmaddsub231pd_ExtendedIndex = 213,
+ kX86InstIdVfmaddsub231ps_ExtendedIndex = 195,
+ kX86InstIdVfmaddsubpd_ExtendedIndex = 215,
+ kX86InstIdVfmaddsubps_ExtendedIndex = 215,
+ kX86InstIdVfmsub132pd_ExtendedIndex = 213,
+ kX86InstIdVfmsub132ps_ExtendedIndex = 195,
+ kX86InstIdVfmsub132sd_ExtendedIndex = 214,
+ kX86InstIdVfmsub132ss_ExtendedIndex = 196,
+ kX86InstIdVfmsub213pd_ExtendedIndex = 213,
+ kX86InstIdVfmsub213ps_ExtendedIndex = 195,
+ kX86InstIdVfmsub213sd_ExtendedIndex = 214,
+ kX86InstIdVfmsub213ss_ExtendedIndex = 196,
+ kX86InstIdVfmsub231pd_ExtendedIndex = 213,
+ kX86InstIdVfmsub231ps_ExtendedIndex = 195,
+ kX86InstIdVfmsub231sd_ExtendedIndex = 214,
+ kX86InstIdVfmsub231ss_ExtendedIndex = 196,
+ kX86InstIdVfmsubadd132pd_ExtendedIndex = 213,
+ kX86InstIdVfmsubadd132ps_ExtendedIndex = 195,
+ kX86InstIdVfmsubadd213pd_ExtendedIndex = 213,
+ kX86InstIdVfmsubadd213ps_ExtendedIndex = 195,
+ kX86InstIdVfmsubadd231pd_ExtendedIndex = 213,
+ kX86InstIdVfmsubadd231ps_ExtendedIndex = 195,
+ kX86InstIdVfmsubaddpd_ExtendedIndex = 215,
+ kX86InstIdVfmsubaddps_ExtendedIndex = 215,
+ kX86InstIdVfmsubpd_ExtendedIndex = 215,
+ kX86InstIdVfmsubps_ExtendedIndex = 215,
+ kX86InstIdVfmsubsd_ExtendedIndex = 216,
+ kX86InstIdVfmsubss_ExtendedIndex = 216,
+ kX86InstIdVfnmadd132pd_ExtendedIndex = 213,
+ kX86InstIdVfnmadd132ps_ExtendedIndex = 195,
+ kX86InstIdVfnmadd132sd_ExtendedIndex = 214,
+ kX86InstIdVfnmadd132ss_ExtendedIndex = 196,
+ kX86InstIdVfnmadd213pd_ExtendedIndex = 213,
+ kX86InstIdVfnmadd213ps_ExtendedIndex = 195,
+ kX86InstIdVfnmadd213sd_ExtendedIndex = 214,
+ kX86InstIdVfnmadd213ss_ExtendedIndex = 196,
+ kX86InstIdVfnmadd231pd_ExtendedIndex = 213,
+ kX86InstIdVfnmadd231ps_ExtendedIndex = 195,
+ kX86InstIdVfnmadd231sd_ExtendedIndex = 214,
+ kX86InstIdVfnmadd231ss_ExtendedIndex = 196,
+ kX86InstIdVfnmaddpd_ExtendedIndex = 215,
+ kX86InstIdVfnmaddps_ExtendedIndex = 215,
+ kX86InstIdVfnmaddsd_ExtendedIndex = 216,
+ kX86InstIdVfnmaddss_ExtendedIndex = 216,
+ kX86InstIdVfnmsub132pd_ExtendedIndex = 213,
+ kX86InstIdVfnmsub132ps_ExtendedIndex = 195,
+ kX86InstIdVfnmsub132sd_ExtendedIndex = 214,
+ kX86InstIdVfnmsub132ss_ExtendedIndex = 196,
+ kX86InstIdVfnmsub213pd_ExtendedIndex = 213,
+ kX86InstIdVfnmsub213ps_ExtendedIndex = 195,
+ kX86InstIdVfnmsub213sd_ExtendedIndex = 214,
+ kX86InstIdVfnmsub213ss_ExtendedIndex = 196,
+ kX86InstIdVfnmsub231pd_ExtendedIndex = 213,
+ kX86InstIdVfnmsub231ps_ExtendedIndex = 195,
+ kX86InstIdVfnmsub231sd_ExtendedIndex = 214,
+ kX86InstIdVfnmsub231ss_ExtendedIndex = 196,
+ kX86InstIdVfnmsubpd_ExtendedIndex = 215,
+ kX86InstIdVfnmsubps_ExtendedIndex = 215,
+ kX86InstIdVfnmsubsd_ExtendedIndex = 216,
+ kX86InstIdVfnmsubss_ExtendedIndex = 216,
+ kX86InstIdVfrczpd_ExtendedIndex = 217,
+ kX86InstIdVfrczps_ExtendedIndex = 217,
+ kX86InstIdVfrczsd_ExtendedIndex = 218,
+ kX86InstIdVfrczss_ExtendedIndex = 218,
+ kX86InstIdVgatherdpd_ExtendedIndex = 219,
+ kX86InstIdVgatherdps_ExtendedIndex = 220,
+ kX86InstIdVgatherqpd_ExtendedIndex = 219,
+ kX86InstIdVgatherqps_ExtendedIndex = 221,
+ kX86InstIdVhaddpd_ExtendedIndex = 195,
+ kX86InstIdVhaddps_ExtendedIndex = 195,
+ kX86InstIdVhsubpd_ExtendedIndex = 195,
+ kX86InstIdVhsubps_ExtendedIndex = 195,
+ kX86InstIdVinsertf128_ExtendedIndex = 222,
+ kX86InstIdVinserti128_ExtendedIndex = 222,
+ kX86InstIdVinsertps_ExtendedIndex = 203,
+ kX86InstIdVlddqu_ExtendedIndex = 223,
+ kX86InstIdVldmxcsr_ExtendedIndex = 224,
+ kX86InstIdVmaskmovdqu_ExtendedIndex = 225,
+ kX86InstIdVmaskmovpd_ExtendedIndex = 226,
+ kX86InstIdVmaskmovps_ExtendedIndex = 227,
+ kX86InstIdVmaxpd_ExtendedIndex = 195,
+ kX86InstIdVmaxps_ExtendedIndex = 195,
+ kX86InstIdVmaxsd_ExtendedIndex = 195,
+ kX86InstIdVmaxss_ExtendedIndex = 195,
+ kX86InstIdVminpd_ExtendedIndex = 195,
+ kX86InstIdVminps_ExtendedIndex = 195,
+ kX86InstIdVminsd_ExtendedIndex = 195,
+ kX86InstIdVminss_ExtendedIndex = 195,
+ kX86InstIdVmovapd_ExtendedIndex = 228,
+ kX86InstIdVmovaps_ExtendedIndex = 229,
+ kX86InstIdVmovd_ExtendedIndex = 230,
+ kX86InstIdVmovddup_ExtendedIndex = 205,
+ kX86InstIdVmovdqa_ExtendedIndex = 231,
+ kX86InstIdVmovdqu_ExtendedIndex = 232,
+ kX86InstIdVmovhlps_ExtendedIndex = 233,
+ kX86InstIdVmovhpd_ExtendedIndex = 234,
+ kX86InstIdVmovhps_ExtendedIndex = 235,
+ kX86InstIdVmovlhps_ExtendedIndex = 233,
+ kX86InstIdVmovlpd_ExtendedIndex = 236,
+ kX86InstIdVmovlps_ExtendedIndex = 237,
+ kX86InstIdVmovmskpd_ExtendedIndex = 238,
+ kX86InstIdVmovmskps_ExtendedIndex = 238,
+ kX86InstIdVmovntdq_ExtendedIndex = 239,
+ kX86InstIdVmovntdqa_ExtendedIndex = 223,
+ kX86InstIdVmovntpd_ExtendedIndex = 240,
+ kX86InstIdVmovntps_ExtendedIndex = 240,
+ kX86InstIdVmovq_ExtendedIndex = 241,
+ kX86InstIdVmovsd_ExtendedIndex = 242,
+ kX86InstIdVmovshdup_ExtendedIndex = 205,
+ kX86InstIdVmovsldup_ExtendedIndex = 205,
+ kX86InstIdVmovss_ExtendedIndex = 243,
+ kX86InstIdVmovupd_ExtendedIndex = 244,
+ kX86InstIdVmovups_ExtendedIndex = 245,
+ kX86InstIdVmpsadbw_ExtendedIndex = 199,
+ kX86InstIdVmulpd_ExtendedIndex = 195,
+ kX86InstIdVmulps_ExtendedIndex = 195,
+ kX86InstIdVmulsd_ExtendedIndex = 195,
+ kX86InstIdVmulss_ExtendedIndex = 195,
+ kX86InstIdVorpd_ExtendedIndex = 195,
+ kX86InstIdVorps_ExtendedIndex = 195,
+ kX86InstIdVpabsb_ExtendedIndex = 205,
+ kX86InstIdVpabsd_ExtendedIndex = 205,
+ kX86InstIdVpabsw_ExtendedIndex = 205,
+ kX86InstIdVpackssdw_ExtendedIndex = 195,
+ kX86InstIdVpacksswb_ExtendedIndex = 195,
+ kX86InstIdVpackusdw_ExtendedIndex = 195,
+ kX86InstIdVpackuswb_ExtendedIndex = 195,
+ kX86InstIdVpaddb_ExtendedIndex = 195,
+ kX86InstIdVpaddd_ExtendedIndex = 195,
+ kX86InstIdVpaddq_ExtendedIndex = 195,
+ kX86InstIdVpaddsb_ExtendedIndex = 195,
+ kX86InstIdVpaddsw_ExtendedIndex = 195,
+ kX86InstIdVpaddusb_ExtendedIndex = 195,
+ kX86InstIdVpaddusw_ExtendedIndex = 195,
+ kX86InstIdVpaddw_ExtendedIndex = 195,
+ kX86InstIdVpalignr_ExtendedIndex = 199,
+ kX86InstIdVpand_ExtendedIndex = 195,
+ kX86InstIdVpandn_ExtendedIndex = 195,
+ kX86InstIdVpavgb_ExtendedIndex = 195,
+ kX86InstIdVpavgw_ExtendedIndex = 195,
+ kX86InstIdVpblendd_ExtendedIndex = 199,
+ kX86InstIdVpblendvb_ExtendedIndex = 246,
+ kX86InstIdVpblendw_ExtendedIndex = 199,
+ kX86InstIdVpbroadcastb_ExtendedIndex = 204,
+ kX86InstIdVpbroadcastd_ExtendedIndex = 204,
+ kX86InstIdVpbroadcastq_ExtendedIndex = 204,
+ kX86InstIdVpbroadcastw_ExtendedIndex = 204,
+ kX86InstIdVpclmulqdq_ExtendedIndex = 203,
+ kX86InstIdVpcmov_ExtendedIndex = 247,
+ kX86InstIdVpcmpeqb_ExtendedIndex = 195,
+ kX86InstIdVpcmpeqd_ExtendedIndex = 195,
+ kX86InstIdVpcmpeqq_ExtendedIndex = 195,
+ kX86InstIdVpcmpeqw_ExtendedIndex = 195,
+ kX86InstIdVpcmpestri_ExtendedIndex = 198,
+ kX86InstIdVpcmpestrm_ExtendedIndex = 198,
+ kX86InstIdVpcmpgtb_ExtendedIndex = 195,
+ kX86InstIdVpcmpgtd_ExtendedIndex = 195,
+ kX86InstIdVpcmpgtq_ExtendedIndex = 195,
+ kX86InstIdVpcmpgtw_ExtendedIndex = 195,
+ kX86InstIdVpcmpistri_ExtendedIndex = 198,
+ kX86InstIdVpcmpistrm_ExtendedIndex = 198,
+ kX86InstIdVpcomb_ExtendedIndex = 248,
+ kX86InstIdVpcomd_ExtendedIndex = 248,
+ kX86InstIdVpcomq_ExtendedIndex = 248,
+ kX86InstIdVpcomub_ExtendedIndex = 248,
+ kX86InstIdVpcomud_ExtendedIndex = 248,
+ kX86InstIdVpcomuq_ExtendedIndex = 248,
+ kX86InstIdVpcomuw_ExtendedIndex = 248,
+ kX86InstIdVpcomw_ExtendedIndex = 248,
+ kX86InstIdVperm2f128_ExtendedIndex = 249,
+ kX86InstIdVperm2i128_ExtendedIndex = 249,
+ kX86InstIdVpermd_ExtendedIndex = 250,
+ kX86InstIdVpermil2pd_ExtendedIndex = 251,
+ kX86InstIdVpermil2ps_ExtendedIndex = 251,
+ kX86InstIdVpermilpd_ExtendedIndex = 252,
+ kX86InstIdVpermilps_ExtendedIndex = 253,
+ kX86InstIdVpermpd_ExtendedIndex = 254,
+ kX86InstIdVpermps_ExtendedIndex = 250,
+ kX86InstIdVpermq_ExtendedIndex = 254,
+ kX86InstIdVpextrb_ExtendedIndex = 255,
+ kX86InstIdVpextrd_ExtendedIndex = 212,
+ kX86InstIdVpextrq_ExtendedIndex = 256,
+ kX86InstIdVpextrw_ExtendedIndex = 257,
+ kX86InstIdVpgatherdd_ExtendedIndex = 220,
+ kX86InstIdVpgatherdq_ExtendedIndex = 219,
+ kX86InstIdVpgatherqd_ExtendedIndex = 221,
+ kX86InstIdVpgatherqq_ExtendedIndex = 219,
+ kX86InstIdVphaddbd_ExtendedIndex = 218,
+ kX86InstIdVphaddbq_ExtendedIndex = 218,
+ kX86InstIdVphaddbw_ExtendedIndex = 218,
+ kX86InstIdVphaddd_ExtendedIndex = 195,
+ kX86InstIdVphadddq_ExtendedIndex = 218,
+ kX86InstIdVphaddsw_ExtendedIndex = 195,
+ kX86InstIdVphaddubd_ExtendedIndex = 218,
+ kX86InstIdVphaddubq_ExtendedIndex = 218,
+ kX86InstIdVphaddubw_ExtendedIndex = 218,
+ kX86InstIdVphaddudq_ExtendedIndex = 218,
+ kX86InstIdVphadduwd_ExtendedIndex = 218,
+ kX86InstIdVphadduwq_ExtendedIndex = 218,
+ kX86InstIdVphaddw_ExtendedIndex = 195,
+ kX86InstIdVphaddwd_ExtendedIndex = 218,
+ kX86InstIdVphaddwq_ExtendedIndex = 218,
+ kX86InstIdVphminposuw_ExtendedIndex = 197,
+ kX86InstIdVphsubbw_ExtendedIndex = 218,
+ kX86InstIdVphsubd_ExtendedIndex = 195,
+ kX86InstIdVphsubdq_ExtendedIndex = 218,
+ kX86InstIdVphsubsw_ExtendedIndex = 195,
+ kX86InstIdVphsubw_ExtendedIndex = 195,
+ kX86InstIdVphsubwd_ExtendedIndex = 218,
+ kX86InstIdVpinsrb_ExtendedIndex = 258,
+ kX86InstIdVpinsrd_ExtendedIndex = 259,
+ kX86InstIdVpinsrq_ExtendedIndex = 260,
+ kX86InstIdVpinsrw_ExtendedIndex = 261,
+ kX86InstIdVpmacsdd_ExtendedIndex = 262,
+ kX86InstIdVpmacsdqh_ExtendedIndex = 262,
+ kX86InstIdVpmacsdql_ExtendedIndex = 262,
+ kX86InstIdVpmacssdd_ExtendedIndex = 262,
+ kX86InstIdVpmacssdqh_ExtendedIndex = 262,
+ kX86InstIdVpmacssdql_ExtendedIndex = 262,
+ kX86InstIdVpmacsswd_ExtendedIndex = 262,
+ kX86InstIdVpmacssww_ExtendedIndex = 262,
+ kX86InstIdVpmacswd_ExtendedIndex = 262,
+ kX86InstIdVpmacsww_ExtendedIndex = 262,
+ kX86InstIdVpmadcsswd_ExtendedIndex = 262,
+ kX86InstIdVpmadcswd_ExtendedIndex = 262,
+ kX86InstIdVpmaddubsw_ExtendedIndex = 195,
+ kX86InstIdVpmaddwd_ExtendedIndex = 195,
+ kX86InstIdVpmaskmovd_ExtendedIndex = 263,
+ kX86InstIdVpmaskmovq_ExtendedIndex = 264,
+ kX86InstIdVpmaxsb_ExtendedIndex = 195,
+ kX86InstIdVpmaxsd_ExtendedIndex = 195,
+ kX86InstIdVpmaxsw_ExtendedIndex = 195,
+ kX86InstIdVpmaxub_ExtendedIndex = 195,
+ kX86InstIdVpmaxud_ExtendedIndex = 195,
+ kX86InstIdVpmaxuw_ExtendedIndex = 195,
+ kX86InstIdVpminsb_ExtendedIndex = 195,
+ kX86InstIdVpminsd_ExtendedIndex = 195,
+ kX86InstIdVpminsw_ExtendedIndex = 195,
+ kX86InstIdVpminub_ExtendedIndex = 195,
+ kX86InstIdVpminud_ExtendedIndex = 195,
+ kX86InstIdVpminuw_ExtendedIndex = 195,
+ kX86InstIdVpmovmskb_ExtendedIndex = 238,
+ kX86InstIdVpmovsxbd_ExtendedIndex = 205,
+ kX86InstIdVpmovsxbq_ExtendedIndex = 205,
+ kX86InstIdVpmovsxbw_ExtendedIndex = 205,
+ kX86InstIdVpmovsxdq_ExtendedIndex = 205,
+ kX86InstIdVpmovsxwd_ExtendedIndex = 205,
+ kX86InstIdVpmovsxwq_ExtendedIndex = 205,
+ kX86InstIdVpmovzxbd_ExtendedIndex = 205,
+ kX86InstIdVpmovzxbq_ExtendedIndex = 205,
+ kX86InstIdVpmovzxbw_ExtendedIndex = 205,
+ kX86InstIdVpmovzxdq_ExtendedIndex = 205,
+ kX86InstIdVpmovzxwd_ExtendedIndex = 205,
+ kX86InstIdVpmovzxwq_ExtendedIndex = 205,
+ kX86InstIdVpmuldq_ExtendedIndex = 195,
+ kX86InstIdVpmulhrsw_ExtendedIndex = 195,
+ kX86InstIdVpmulhuw_ExtendedIndex = 195,
+ kX86InstIdVpmulhw_ExtendedIndex = 195,
+ kX86InstIdVpmulld_ExtendedIndex = 195,
+ kX86InstIdVpmullw_ExtendedIndex = 195,
+ kX86InstIdVpmuludq_ExtendedIndex = 195,
+ kX86InstIdVpor_ExtendedIndex = 195,
+ kX86InstIdVpperm_ExtendedIndex = 265,
+ kX86InstIdVprotb_ExtendedIndex = 266,
+ kX86InstIdVprotd_ExtendedIndex = 267,
+ kX86InstIdVprotq_ExtendedIndex = 268,
+ kX86InstIdVprotw_ExtendedIndex = 269,
+ kX86InstIdVpsadbw_ExtendedIndex = 195,
+ kX86InstIdVpshab_ExtendedIndex = 270,
+ kX86InstIdVpshad_ExtendedIndex = 270,
+ kX86InstIdVpshaq_ExtendedIndex = 270,
+ kX86InstIdVpshaw_ExtendedIndex = 270,
+ kX86InstIdVpshlb_ExtendedIndex = 270,
+ kX86InstIdVpshld_ExtendedIndex = 270,
+ kX86InstIdVpshlq_ExtendedIndex = 270,
+ kX86InstIdVpshlw_ExtendedIndex = 270,
+ kX86InstIdVpshufb_ExtendedIndex = 195,
+ kX86InstIdVpshufd_ExtendedIndex = 271,
+ kX86InstIdVpshufhw_ExtendedIndex = 271,
+ kX86InstIdVpshuflw_ExtendedIndex = 271,
+ kX86InstIdVpsignb_ExtendedIndex = 195,
+ kX86InstIdVpsignd_ExtendedIndex = 195,
+ kX86InstIdVpsignw_ExtendedIndex = 195,
+ kX86InstIdVpslld_ExtendedIndex = 272,
+ kX86InstIdVpslldq_ExtendedIndex = 273,
+ kX86InstIdVpsllq_ExtendedIndex = 274,
+ kX86InstIdVpsllvd_ExtendedIndex = 195,
+ kX86InstIdVpsllvq_ExtendedIndex = 213,
+ kX86InstIdVpsllw_ExtendedIndex = 275,
+ kX86InstIdVpsrad_ExtendedIndex = 276,
+ kX86InstIdVpsravd_ExtendedIndex = 195,
+ kX86InstIdVpsraw_ExtendedIndex = 277,
+ kX86InstIdVpsrld_ExtendedIndex = 278,
+ kX86InstIdVpsrldq_ExtendedIndex = 273,
+ kX86InstIdVpsrlq_ExtendedIndex = 279,
+ kX86InstIdVpsrlvd_ExtendedIndex = 195,
+ kX86InstIdVpsrlvq_ExtendedIndex = 213,
+ kX86InstIdVpsrlw_ExtendedIndex = 280,
+ kX86InstIdVpsubb_ExtendedIndex = 195,
+ kX86InstIdVpsubd_ExtendedIndex = 195,
+ kX86InstIdVpsubq_ExtendedIndex = 195,
+ kX86InstIdVpsubsb_ExtendedIndex = 195,
+ kX86InstIdVpsubsw_ExtendedIndex = 195,
+ kX86InstIdVpsubusb_ExtendedIndex = 195,
+ kX86InstIdVpsubusw_ExtendedIndex = 195,
+ kX86InstIdVpsubw_ExtendedIndex = 195,
+ kX86InstIdVptest_ExtendedIndex = 281,
+ kX86InstIdVpunpckhbw_ExtendedIndex = 195,
+ kX86InstIdVpunpckhdq_ExtendedIndex = 195,
+ kX86InstIdVpunpckhqdq_ExtendedIndex = 195,
+ kX86InstIdVpunpckhwd_ExtendedIndex = 195,
+ kX86InstIdVpunpcklbw_ExtendedIndex = 195,
+ kX86InstIdVpunpckldq_ExtendedIndex = 195,
+ kX86InstIdVpunpcklqdq_ExtendedIndex = 195,
+ kX86InstIdVpunpcklwd_ExtendedIndex = 195,
+ kX86InstIdVpxor_ExtendedIndex = 195,
+ kX86InstIdVrcpps_ExtendedIndex = 205,
+ kX86InstIdVrcpss_ExtendedIndex = 196,
+ kX86InstIdVroundpd_ExtendedIndex = 271,
+ kX86InstIdVroundps_ExtendedIndex = 271,
+ kX86InstIdVroundsd_ExtendedIndex = 203,
+ kX86InstIdVroundss_ExtendedIndex = 203,
+ kX86InstIdVrsqrtps_ExtendedIndex = 205,
+ kX86InstIdVrsqrtss_ExtendedIndex = 196,
+ kX86InstIdVshufpd_ExtendedIndex = 199,
+ kX86InstIdVshufps_ExtendedIndex = 199,
+ kX86InstIdVsqrtpd_ExtendedIndex = 205,
+ kX86InstIdVsqrtps_ExtendedIndex = 205,
+ kX86InstIdVsqrtsd_ExtendedIndex = 196,
+ kX86InstIdVsqrtss_ExtendedIndex = 196,
+ kX86InstIdVstmxcsr_ExtendedIndex = 224,
+ kX86InstIdVsubpd_ExtendedIndex = 195,
+ kX86InstIdVsubps_ExtendedIndex = 195,
+ kX86InstIdVsubsd_ExtendedIndex = 196,
+ kX86InstIdVsubss_ExtendedIndex = 196,
+ kX86InstIdVtestpd_ExtendedIndex = 282,
+ kX86InstIdVtestps_ExtendedIndex = 282,
+ kX86InstIdVucomisd_ExtendedIndex = 283,
+ kX86InstIdVucomiss_ExtendedIndex = 283,
+ kX86InstIdVunpckhpd_ExtendedIndex = 195,
+ kX86InstIdVunpckhps_ExtendedIndex = 195,
+ kX86InstIdVunpcklpd_ExtendedIndex = 195,
+ kX86InstIdVunpcklps_ExtendedIndex = 195,
+ kX86InstIdVxorpd_ExtendedIndex = 195,
+ kX86InstIdVxorps_ExtendedIndex = 195,
+ kX86InstIdVzeroall_ExtendedIndex = 284,
+ kX86InstIdVzeroupper_ExtendedIndex = 284,
+ kX86InstIdWrfsbase_ExtendedIndex = 285,
+ kX86InstIdWrgsbase_ExtendedIndex = 285,
+ kX86InstIdXadd_ExtendedIndex = 286,
+ kX86InstIdXchg_ExtendedIndex = 287,
+ kX86InstIdXor_ExtendedIndex = 2,
+ kX86InstIdXorpd_ExtendedIndex = 3,
+ kX86InstIdXorps_ExtendedIndex = 3
+};
+// ${X86InstData:End}
+
+// Instruction data.
+//
+// Please rerun tools/src-gendefs.js (by using node.js) to regenerate instruction
+// names and extended info tables.
+const X86InstInfo _x86InstInfo[] = {
+ // Inst-Code | Inst-Name | Inst-Group | Inst-Flags | M | Op-Flags[0] | Op-Flags[1] | Op-Flags[2] | Op-Flags[2] | E-OSZAPCDX | OpCode[0] | OpCode[1] |
+ INST(kInstIdNone , "" , G(None) , F(None) , 0 , U , U , U , U , E(________) , U , U ),
+ INST(kX86InstIdAdc , "adc" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWX__) , O_000000(10,2) , U ),
+ INST(kX86InstIdAdd , "add" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWW__) , O_000000(00,0) , U ),
+ INST(kX86InstIdAddpd , "addpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(58,U) , U ),
+ INST(kX86InstIdAddps , "addps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(58,U) , U ),
+ INST(kX86InstIdAddsd , "addsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(58,U) , U ),
+ INST(kX86InstIdAddss , "addss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(58,U) , U ),
+ INST(kX86InstIdAddsubpd , "addsubpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(D0,U) , U ),
+ INST(kX86InstIdAddsubps , "addsubps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(D0,U) , U ),
+ INST(kX86InstIdAesdec , "aesdec" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DE,U) , U ),
+ INST(kX86InstIdAesdeclast , "aesdeclast" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DF,U) , U ),
+ INST(kX86InstIdAesenc , "aesenc" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DC,U) , U ),
+ INST(kX86InstIdAesenclast , "aesenclast" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DD,U) , U ),
+ INST(kX86InstIdAesimc , "aesimc" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DB,U) , U ),
+ INST(kX86InstIdAeskeygenassist , "aeskeygenassist" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(DF,U) , U ),
+ INST(kX86InstIdAnd , "and" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWUWW__) , O_000000(20,4) , U ),
+ INST(kX86InstIdAndn , "andn" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(WWWUUW__) , O_000F38(F2,U) , U ),
+ INST(kX86InstIdAndnpd , "andnpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(55,U) , U ),
+ INST(kX86InstIdAndnps , "andnps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(55,U) , U ),
+ INST(kX86InstIdAndpd , "andpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(54,U) , U ),
+ INST(kX86InstIdAndps , "andps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(54,U) , U ),
+ INST(kX86InstIdBextr , "bextr" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(WUWUUW__) , O_000F38(F7,U) , U ),
+ INST(kX86InstIdBlendpd , "blendpd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0D,U) , U ),
+ INST(kX86InstIdBlendps , "blendps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0C,U) , U ),
+ INST(kX86InstIdBlendvpd , "blendvpd" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(15,U) , U ),
+ INST(kX86InstIdBlendvps , "blendvps" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(14,U) , U ),
+ INST(kX86InstIdBlsi , "blsi" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , E(WWWUUW__) , O_000F38(F3,3) , U ),
+ INST(kX86InstIdBlsmsk , "blsmsk" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , E(WWWUUW__) , O_000F38(F3,2) , U ),
+ INST(kX86InstIdBlsr , "blsr" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , E(WWWUUW__) , O_000F38(F3,1) , U ),
+ INST(kX86InstIdBsf , "bsf" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUU__) , O_000F00(BC,U) , U ),
+ INST(kX86InstIdBsr , "bsr" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUU__) , O_000F00(BD,U) , U ),
+ INST(kX86InstIdBswap , "bswap" , G(X86BSwap) , F(None) , 0 , O(Gqd) , U , U , U , E(________) , O_000F00(C8,U) , U ),
+ INST(kX86InstIdBt , "bt" , G(X86BTest) , F(Test) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(A3,U) , O_000F00(BA,4) ),
+ INST(kX86InstIdBtc , "btc" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(BB,U) , O_000F00(BA,7) ),
+ INST(kX86InstIdBtr , "btr" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(B3,U) , O_000F00(BA,6) ),
+ INST(kX86InstIdBts , "bts" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(AB,U) , O_000F00(BA,5) ),
+ INST(kX86InstIdBzhi , "bzhi" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(WWWUUW__) , O_000F38(F5,U) , U ),
+ INST(kX86InstIdCall , "call" , G(X86Call) , F(Flow) , 0 , O(GqdMem)|O(Imm)|O(Label), U , U , U , E(________) , O_000000(FF,2) , O_000000(E8,U) ),
+ INST(kX86InstIdCbw , "cbw" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_660000(98,U) , U ),
+ INST(kX86InstIdCdq , "cdq" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(99,U) , U ),
+ INST(kX86InstIdCdqe , "cdqe" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(________) , O_000000(98,U) , U ),
+ INST(kX86InstIdClc , "clc" , G(X86Op) , F(None) , 0 , U , U , U , U , E(_____W__) , O_000000(F8,U) , U ),
+ INST(kX86InstIdCld , "cld" , G(X86Op) , F(None) , 0 , U , U , U , U , E(______W_) , O_000000(FC,U) , U ),
+ INST(kX86InstIdClflush , "clflush" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,7) , U ),
+ INST(kX86InstIdCmc , "cmc" , G(X86Op) , F(None) , 0 , U , U , U , U , E(_____X__) , O_000000(F5,U) , U ),
+ INST(kX86InstIdCmova , "cmova" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(47,U) , U ),
+ INST(kX86InstIdCmovae , "cmovae" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(43,U) , U ),
+ INST(kX86InstIdCmovb , "cmovb" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(42,U) , U ),
+ INST(kX86InstIdCmovbe , "cmovbe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(46,U) , U ),
+ INST(kX86InstIdCmovc , "cmovc" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(42,U) , U ),
+ INST(kX86InstIdCmove , "cmove" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(44,U) , U ),
+ INST(kX86InstIdCmovg , "cmovg" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4F,U) , U ),
+ INST(kX86InstIdCmovge , "cmovge" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4D,U) , U ),
+ INST(kX86InstIdCmovl , "cmovl" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4C,U) , U ),
+ INST(kX86InstIdCmovle , "cmovle" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4E,U) , U ),
+ INST(kX86InstIdCmovna , "cmovna" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(46,U) , U ),
+ INST(kX86InstIdCmovnae , "cmovnae" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(42,U) , U ),
+ INST(kX86InstIdCmovnb , "cmovnb" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(43,U) , U ),
+ INST(kX86InstIdCmovnbe , "cmovnbe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(47,U) , U ),
+ INST(kX86InstIdCmovnc , "cmovnc" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(43,U) , U ),
+ INST(kX86InstIdCmovne , "cmovne" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(45,U) , U ),
+ INST(kX86InstIdCmovng , "cmovng" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4E,U) , U ),
+ INST(kX86InstIdCmovnge , "cmovnge" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4C,U) , U ),
+ INST(kX86InstIdCmovnl , "cmovnl" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4D,U) , U ),
+ INST(kX86InstIdCmovnle , "cmovnle" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4F,U) , U ),
+ INST(kX86InstIdCmovno , "cmovno" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(R_______) , O_000F00(41,U) , U ),
+ INST(kX86InstIdCmovnp , "cmovnp" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4B,U) , U ),
+ INST(kX86InstIdCmovns , "cmovns" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_R______) , O_000F00(49,U) , U ),
+ INST(kX86InstIdCmovnz , "cmovnz" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(45,U) , U ),
+ INST(kX86InstIdCmovo , "cmovo" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(R_______) , O_000F00(40,U) , U ),
+ INST(kX86InstIdCmovp , "cmovp" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4A,U) , U ),
+ INST(kX86InstIdCmovpe , "cmovpe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4A,U) , U ),
+ INST(kX86InstIdCmovpo , "cmovpo" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4B,U) , U ),
+ INST(kX86InstIdCmovs , "cmovs" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_R______) , O_000F00(48,U) , U ),
+ INST(kX86InstIdCmovz , "cmovz" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(44,U) , U ),
+ INST(kX86InstIdCmp , "cmp" , G(X86Arith) , F(Test) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWW__) , O_000000(38,7) , U ),
+ INST(kX86InstIdCmppd , "cmppd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F00(C2,U) , U ),
+ INST(kX86InstIdCmpps , "cmpps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_000F00(C2,U) , U ),
+ INST(kX86InstIdCmpsB , "cmps_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A6,U) , U ),
+ INST(kX86InstIdCmpsD , "cmps_d" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A7,U) , U ),
+ INST(kX86InstIdCmpsQ , "cmps_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A7,U) , U ),
+ INST(kX86InstIdCmpsW , "cmps_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A7,U) , U ),
+ INST(kX86InstIdCmpsd , "cmpsd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F20F00(C2,U) , U ),
+ INST(kX86InstIdCmpss , "cmpss" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F30F00(C2,U) , U ),
+ INST(kX86InstIdCmpxchg , "cmpxchg" , G(X86RmReg) , F(Lock)|F(Special) , 0 , U , U , U , U , E(WWWWWW__) , O_000F00(B0,U) , U ),
+ INST(kX86InstIdCmpxchg16b , "cmpxchg16b" , G(X86M) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , E(__W_____) , O_000F00(C7,1) , U ),
+ INST(kX86InstIdCmpxchg8b , "cmpxchg8b" , G(X86M) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(__W_____) , O_000F00(C7,1) , U ),
+ INST(kX86InstIdComisd , "comisd" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F00(2F,U) , U ),
+ INST(kX86InstIdComiss , "comiss" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_000F00(2F,U) , U ),
+ INST(kX86InstIdCpuid , "cpuid" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F00(A2,U) , U ),
+ INST(kX86InstIdCqo , "cqo" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(________) , O_000000(99,U) , U ),
+ INST(kX86InstIdCrc32 , "crc32" , G(ExtCrc) , F(None) , 0 , O(Gqd) , O(GqdwbMem) , U , U , E(________) , O_F20F38(F0,U) , U ),
+ INST(kX86InstIdCvtdq2pd , "cvtdq2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(E6,U) , U ),
+ INST(kX86InstIdCvtdq2ps , "cvtdq2ps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5B,U) , U ),
+ INST(kX86InstIdCvtpd2dq , "cvtpd2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(E6,U) , U ),
+ INST(kX86InstIdCvtpd2pi , "cvtpd2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_660F00(2D,U) , U ),
+ INST(kX86InstIdCvtpd2ps , "cvtpd2ps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5A,U) , U ),
+ INST(kX86InstIdCvtpi2pd , "cvtpi2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(MmMem) , U , U , E(________) , O_660F00(2A,U) , U ),
+ INST(kX86InstIdCvtpi2ps , "cvtpi2ps" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(MmMem) , U , U , E(________) , O_000F00(2A,U) , U ),
+ INST(kX86InstIdCvtps2dq , "cvtps2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5B,U) , U ),
+ INST(kX86InstIdCvtps2pd , "cvtps2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5A,U) , U ),
+ INST(kX86InstIdCvtps2pi , "cvtps2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_000F00(2D,U) , U ),
+ INST(kX86InstIdCvtsd2si , "cvtsd2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2D,U) , U ),
+ INST(kX86InstIdCvtsd2ss , "cvtsd2ss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5A,U) , U ),
+ INST(kX86InstIdCvtsi2sd , "cvtsi2sd" , G(ExtRm_Q) , F(Move) , 8 , O(Xmm) , O(GqdMem) , U , U , E(________) , O_F20F00(2A,U) , U ),
+ INST(kX86InstIdCvtsi2ss , "cvtsi2ss" , G(ExtRm_Q) , F(Move) , 4 , O(Xmm) , O(GqdMem) , U , U , E(________) , O_F30F00(2A,U) , U ),
+ INST(kX86InstIdCvtss2sd , "cvtss2sd" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5A,U) , U ),
+ INST(kX86InstIdCvtss2si , "cvtss2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F30F00(2D,U) , U ),
+ INST(kX86InstIdCvttpd2dq , "cvttpd2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(E6,U) , U ),
+ INST(kX86InstIdCvttpd2pi , "cvttpd2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_660F00(2C,U) , U ),
+ INST(kX86InstIdCvttps2dq , "cvttps2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5B,U) , U ),
+ INST(kX86InstIdCvttps2pi , "cvttps2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_000F00(2C,U) , U ),
+ INST(kX86InstIdCvttsd2si , "cvttsd2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2C,U) , U ),
+ INST(kX86InstIdCvttss2si , "cvttss2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F30F00(2C,U) , U ),
+ INST(kX86InstIdCwd , "cwd" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_660000(99,U) , U ),
+ INST(kX86InstIdCwde , "cwde" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(98,U) , U ),
+ INST(kX86InstIdDaa , "daa" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(UWWXWX__) , O_000000(27,U) , U ),
+ INST(kX86InstIdDas , "das" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(UWWXWX__) , O_000000(2F,U) , U ),
+ INST(kX86InstIdDec , "dec" , G(X86IncDec) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(WWWWW___) , O_000000(FE,1) , O_000000(48,U) ),
+ INST(kX86InstIdDiv , "div" , G(X86Rm_B) , F(None)|F(Special) , 0 , U , U , U , U , E(UUUUUU__) , O_000000(F6,6) , U ),
+ INST(kX86InstIdDivpd , "divpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5E,U) , U ),
+ INST(kX86InstIdDivps , "divps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5E,U) , U ),
+ INST(kX86InstIdDivsd , "divsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5E,U) , U ),
+ INST(kX86InstIdDivss , "divss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5E,U) , U ),
+ INST(kX86InstIdDppd , "dppd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(41,U) , U ),
+ INST(kX86InstIdDpps , "dpps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(40,U) , U ),
+ INST(kX86InstIdEmms , "emms" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(77,U) , U ),
+ INST(kX86InstIdEnter , "enter" , G(X86Enter) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(C8,U) , U ),
+ INST(kX86InstIdExtractps , "extractps" , G(ExtExtract) , F(Move) , 8 , O(GqdMem) , O(Xmm) , U , U , E(________) , O_660F3A(17,U) , O_660F3A(17,U) ),
+ INST(kX86InstIdF2xm1 , "f2xm1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F0,U) , U ),
+ INST(kX86InstIdFabs , "fabs" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E1,U) , U ),
+ INST(kX86InstIdFadd , "fadd" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(C0C0,0) , U ),
+ INST(kX86InstIdFaddp , "faddp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEC0,U) , U ),
+ INST(kX86InstIdFbld , "fbld" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DF,4) , U ),
+ INST(kX86InstIdFbstp , "fbstp" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DF,6) , U ),
+ INST(kX86InstIdFchs , "fchs" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E0,U) , U ),
+ INST(kX86InstIdFclex , "fclex" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_9B_X(DBE2,U) , U ),
+ INST(kX86InstIdFcmovb , "fcmovb" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(_____R__) , O_00_X(DAC0,U) , U ),
+ INST(kX86InstIdFcmovbe , "fcmovbe" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R__R__) , O_00_X(DAD0,U) , U ),
+ INST(kX86InstIdFcmove , "fcmove" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R_____) , O_00_X(DAC8,U) , U ),
+ INST(kX86InstIdFcmovnb , "fcmovnb" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(_____R__) , O_00_X(DBC0,U) , U ),
+ INST(kX86InstIdFcmovnbe , "fcmovnbe" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R__R__) , O_00_X(DBD0,U) , U ),
+ INST(kX86InstIdFcmovne , "fcmovne" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R_____) , O_00_X(DBC8,U) , U ),
+ INST(kX86InstIdFcmovnu , "fcmovnu" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(____R___) , O_00_X(DBD8,U) , U ),
+ INST(kX86InstIdFcmovu , "fcmovu" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(____R___) , O_00_X(DAD8,U) , U ),
+ INST(kX86InstIdFcom , "fcom" , G(FpuCom) , F(Fp) , 0 , O(Fp)|O(Mem) , O(Fp) , U , U , E(________) , O_00_X(D0D0,2) , U ),
+ INST(kX86InstIdFcomi , "fcomi" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DBF0,U) , U ),
+ INST(kX86InstIdFcomip , "fcomip" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DFF0,U) , U ),
+ INST(kX86InstIdFcomp , "fcomp" , G(FpuCom) , F(Fp) , 0 , O(Fp)|O(Mem) , O(Fp) , U , U , E(________) , O_00_X(D8D8,3) , U ),
+ INST(kX86InstIdFcompp , "fcompp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DED9,U) , U ),
+ INST(kX86InstIdFcos , "fcos" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FF,U) , U ),
+ INST(kX86InstIdFdecstp , "fdecstp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F6,U) , U ),
+ INST(kX86InstIdFdiv , "fdiv" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(F0F8,6) , U ),
+ INST(kX86InstIdFdivp , "fdivp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEF8,U) , U ),
+ INST(kX86InstIdFdivr , "fdivr" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(F8F0,7) , U ),
+ INST(kX86InstIdFdivrp , "fdivrp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEF0,U) , U ),
+ INST(kX86InstIdFemms , "femms" , G(X86Op) , F(Fp) , 0 , U , U , U , U , E(________) , O_000F00(0E,U) , U ),
+ INST(kX86InstIdFfree , "ffree" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DDC0,U) , U ),
+ INST(kX86InstIdFiadd , "fiadd" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,0) , U ),
+ INST(kX86InstIdFicom , "ficom" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,2) , U ),
+ INST(kX86InstIdFicomp , "ficomp" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,3) , U ),
+ INST(kX86InstIdFidiv , "fidiv" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,6) , U ),
+ INST(kX86InstIdFidivr , "fidivr" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,7) , U ),
+ INST(kX86InstIdFild , "fild" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,0) , O_000000(DF,5) ),
+ INST(kX86InstIdFimul , "fimul" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,1) , U ),
+ INST(kX86InstIdFincstp , "fincstp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F7,U) , U ),
+ INST(kX86InstIdFinit , "finit" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_9B_X(DBE3,U) , U ),
+ INST(kX86InstIdFist , "fist" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,2) , U ),
+ INST(kX86InstIdFistp , "fistp" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,3) , O_000000(DF,7) ),
+ INST(kX86InstIdFisttp , "fisttp" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,1) , O_000000(DD,1) ),
+ INST(kX86InstIdFisub , "fisub" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,4) , U ),
+ INST(kX86InstIdFisubr , "fisubr" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,5) , U ),
+ INST(kX86InstIdFld , "fld" , G(FpuFldFst) , F(Fp)|F(Mem4_8_10) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,0) , O_000000(DB,5) ),
+ INST(kX86InstIdFld1 , "fld1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E8,U) , U ),
+ INST(kX86InstIdFldcw , "fldcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,5) , U ),
+ INST(kX86InstIdFldenv , "fldenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,4) , U ),
+ INST(kX86InstIdFldl2e , "fldl2e" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EA,U) , U ),
+ INST(kX86InstIdFldl2t , "fldl2t" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E9,U) , U ),
+ INST(kX86InstIdFldlg2 , "fldlg2" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EC,U) , U ),
+ INST(kX86InstIdFldln2 , "fldln2" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9ED,U) , U ),
+ INST(kX86InstIdFldpi , "fldpi" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EB,U) , U ),
+ INST(kX86InstIdFldz , "fldz" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EE,U) , U ),
+ INST(kX86InstIdFmul , "fmul" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(C8C8,1) , U ),
+ INST(kX86InstIdFmulp , "fmulp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEC8,U) , U ),
+ INST(kX86InstIdFnclex , "fnclex" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DBE2,U) , U ),
+ INST(kX86InstIdFninit , "fninit" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DBE3,U) , U ),
+ INST(kX86InstIdFnop , "fnop" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9D0,U) , U ),
+ INST(kX86InstIdFnsave , "fnsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DD,6) , U ),
+ INST(kX86InstIdFnstcw , "fnstcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,7) , U ),
+ INST(kX86InstIdFnstenv , "fnstenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,6) , U ),
+ INST(kX86InstIdFnstsw , "fnstsw" , G(FpuStsw) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DD,7) , O_00_X(DFE0,U) ),
+ INST(kX86InstIdFpatan , "fpatan" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F3,U) , U ),
+ INST(kX86InstIdFprem , "fprem" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F8,U) , U ),
+ INST(kX86InstIdFprem1 , "fprem1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F5,U) , U ),
+ INST(kX86InstIdFptan , "fptan" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F2,U) , U ),
+ INST(kX86InstIdFrndint , "frndint" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FC,U) , U ),
+ INST(kX86InstIdFrstor , "frstor" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DD,4) , U ),
+ INST(kX86InstIdFsave , "fsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(DD,6) , U ),
+ INST(kX86InstIdFscale , "fscale" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FD,U) , U ),
+ INST(kX86InstIdFsin , "fsin" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FE,U) , U ),
+ INST(kX86InstIdFsincos , "fsincos" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FB,U) , U ),
+ INST(kX86InstIdFsqrt , "fsqrt" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FA,U) , U ),
+ INST(kX86InstIdFst , "fst" , G(FpuFldFst) , F(Fp)|F(Mem4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,2) , U ),
+ INST(kX86InstIdFstcw , "fstcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(D9,7) , U ),
+ INST(kX86InstIdFstenv , "fstenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(D9,6) , U ),
+ INST(kX86InstIdFstp , "fstp" , G(FpuFldFst) , F(Fp)|F(Mem4_8_10) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,3) , O_000000(DB,7) ),
+ INST(kX86InstIdFstsw , "fstsw" , G(FpuStsw) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(DD,7) , O_9B_X(DFE0,U) ),
+ INST(kX86InstIdFsub , "fsub" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(E0E8,4) , U ),
+ INST(kX86InstIdFsubp , "fsubp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEE8,U) , U ),
+ INST(kX86InstIdFsubr , "fsubr" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(E8E0,5) , U ),
+ INST(kX86InstIdFsubrp , "fsubrp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEE0,U) , U ),
+ INST(kX86InstIdFtst , "ftst" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E4,U) , U ),
+ INST(kX86InstIdFucom , "fucom" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DDE0,U) , U ),
+ INST(kX86InstIdFucomi , "fucomi" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DBE8,U) , U ),
+ INST(kX86InstIdFucomip , "fucomip" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DFE8,U) , U ),
+ INST(kX86InstIdFucomp , "fucomp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DDE8,U) , U ),
+ INST(kX86InstIdFucompp , "fucompp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DAE9,U) , U ),
+ INST(kX86InstIdFwait , "fwait" , G(X86Op) , F(Fp) , 0 , U , U , U , U , E(________) , O_000000(DB,U) , U ),
+ INST(kX86InstIdFxam , "fxam" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E5,U) , U ),
+ INST(kX86InstIdFxch , "fxch" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(D9C8,U) , U ),
+ INST(kX86InstIdFxrstor , "fxrstor" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,1) , U ),
+ INST(kX86InstIdFxsave , "fxsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,0) , U ),
+ INST(kX86InstIdFxtract , "fxtract" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F4,U) , U ),
+ INST(kX86InstIdFyl2x , "fyl2x" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F1,U) , U ),
+ INST(kX86InstIdFyl2xp1 , "fyl2xp1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F9,U) , U ),
+ INST(kX86InstIdHaddpd , "haddpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(7C,U) , U ),
+ INST(kX86InstIdHaddps , "haddps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(7C,U) , U ),
+ INST(kX86InstIdHsubpd , "hsubpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(7D,U) , U ),
+ INST(kX86InstIdHsubps , "hsubps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(7D,U) , U ),
+ INST(kX86InstIdIdiv , "idiv" , G(X86Rm_B) , F(None)|F(Special) , 0 , 0 , 0 , U , U , E(UUUUUU__) , O_000000(F6,7) , U ),
+ INST(kX86InstIdImul , "imul" , G(X86Imul) , F(None)|F(Special) , 0 , 0 , 0 , U , U , E(WUUUUW__) , U , U ),
+ INST(kX86InstIdInc , "inc" , G(X86IncDec) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(WWWWW___) , O_000000(FE,0) , O_000000(40,U) ),
+ INST(kX86InstIdInsertps , "insertps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(21,U) , U ),
+ INST(kX86InstIdInt , "int" , G(X86Int) , F(None) , 0 , U , U , U , U , E(_______W) , O_000000(CC,U) , U ),
+ INST(kX86InstIdJa , "ja" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(77,U) , U ),
+ INST(kX86InstIdJae , "jae" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(73,U) , U ),
+ INST(kX86InstIdJb , "jb" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(72,U) , U ),
+ INST(kX86InstIdJbe , "jbe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(76,U) , U ),
+ INST(kX86InstIdJc , "jc" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(72,U) , U ),
+ INST(kX86InstIdJe , "je" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(74,U) , U ),
+ INST(kX86InstIdJg , "jg" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7F,U) , U ),
+ INST(kX86InstIdJge , "jge" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7D,U) , U ),
+ INST(kX86InstIdJl , "jl" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7C,U) , U ),
+ INST(kX86InstIdJle , "jle" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7E,U) , U ),
+ INST(kX86InstIdJna , "jna" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(76,U) , U ),
+ INST(kX86InstIdJnae , "jnae" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(72,U) , U ),
+ INST(kX86InstIdJnb , "jnb" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(73,U) , U ),
+ INST(kX86InstIdJnbe , "jnbe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(77,U) , U ),
+ INST(kX86InstIdJnc , "jnc" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(73,U) , U ),
+ INST(kX86InstIdJne , "jne" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(75,U) , U ),
+ INST(kX86InstIdJng , "jng" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7E,U) , U ),
+ INST(kX86InstIdJnge , "jnge" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7C,U) , U ),
+ INST(kX86InstIdJnl , "jnl" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7D,U) , U ),
+ INST(kX86InstIdJnle , "jnle" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7F,U) , U ),
+ INST(kX86InstIdJno , "jno" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(R_______) , O_000000(71,U) , U ),
+ INST(kX86InstIdJnp , "jnp" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7B,U) , U ),
+ INST(kX86InstIdJns , "jns" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_R______) , O_000000(79,U) , U ),
+ INST(kX86InstIdJnz , "jnz" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(75,U) , U ),
+ INST(kX86InstIdJo , "jo" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(R_______) , O_000000(70,U) , U ),
+ INST(kX86InstIdJp , "jp" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7A,U) , U ),
+ INST(kX86InstIdJpe , "jpe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7A,U) , U ),
+ INST(kX86InstIdJpo , "jpo" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7B,U) , U ),
+ INST(kX86InstIdJs , "js" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_R______) , O_000000(78,U) , U ),
+ INST(kX86InstIdJz , "jz" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(74,U) , U ),
+ INST(kX86InstIdJecxz , "jecxz" , G(X86Jecxz) , F(Flow)|F(Special) , 0 , O(Gqdw) , O(Label) , U , U , E(________) , O_000000(E3,U) , U ),
+ INST(kX86InstIdJmp , "jmp" , G(X86Jmp) , F(Flow) , 0 , O(Imm)|O(Label) , U , U , U , E(________) , O_000000(FF,4) , O_000000(E9,U) ),
+ INST(kX86InstIdLahf , "lahf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(_RRRRR__) , O_000000(9F,U) , U ),
+ INST(kX86InstIdLddqu , "lddqu" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(Mem) , U , U , E(________) , O_F20F00(F0,U) , U ),
+ INST(kX86InstIdLdmxcsr , "ldmxcsr" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,2) , U ),
+ INST(kX86InstIdLea , "lea" , G(X86Lea) , F(Move) , 0 , O(Gqd) , O(Mem) , U , U , E(________) , O_000000(8D,U) , U ),
+ INST(kX86InstIdLeave , "leave" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(C9,U) , U ),
+ INST(kX86InstIdLfence , "lfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(AE,5) , U ),
+ INST(kX86InstIdLodsB , "lods_b" , G(X86Op) , F(Move)|F(Special) , 1 , U , U , U , U , E(______R_) , O_000000(AC,U) , U ),
+ INST(kX86InstIdLodsD , "lods_d" , G(X86Op) , F(Move)|F(Special) , 4 , U , U , U , U , E(______R_) , O_000000(AD,U) , U ),
+ INST(kX86InstIdLodsQ , "lods_q" , G(X86Op) , F(Move)|F(Special)|F(W), 8 , U , U , U , U , E(______R_) , O_000000(AD,U) , U ),
+ INST(kX86InstIdLodsW , "lods_w" , G(X86Op_66H) , F(Move)|F(Special) , 2 , U , U , U , U , E(______R_) , O_000000(AD,U) , U ),
+ INST(kX86InstIdLzcnt , "lzcnt" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUW__) , O_F30F00(BD,U) , U ),
+ INST(kX86InstIdMaskmovdqu , "maskmovdqu" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(Xmm) , U , U , E(________) , O_660F00(57,U) , U ),
+ INST(kX86InstIdMaskmovq , "maskmovq" , G(ExtRm) , F(None)|F(Special) , 0 , O(Mm) , O(Mm) , U , U , E(________) , O_000F00(F7,U) , U ),
+ INST(kX86InstIdMaxpd , "maxpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5F,U) , U ),
+ INST(kX86InstIdMaxps , "maxps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5F,U) , U ),
+ INST(kX86InstIdMaxsd , "maxsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5F,U) , U ),
+ INST(kX86InstIdMaxss , "maxss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5F,U) , U ),
+ INST(kX86InstIdMfence , "mfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(AE,6) , U ),
+ INST(kX86InstIdMinpd , "minpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5D,U) , U ),
+ INST(kX86InstIdMinps , "minps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5D,U) , U ),
+ INST(kX86InstIdMinsd , "minsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5D,U) , U ),
+ INST(kX86InstIdMinss , "minss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5D,U) , U ),
+ INST(kX86InstIdMonitor , "monitor" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F01(C8,U) , U ),
+ INST(kX86InstIdMov , "mov" , G(X86Mov) , F(Move) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(________) , U , U ),
+ INST(kX86InstIdMovPtr , "mov_ptr" , G(X86MovPtr) , F(Move)|F(Special) , 0 , O(Gqdwb) , O(Imm) , U , U , E(________) , O_000000(A0,U) , O_000000(A2,U) ),
+ INST(kX86InstIdMovapd , "movapd" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(28,U) , O_660F00(29,U) ),
+ INST(kX86InstIdMovaps , "movaps" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(28,U) , O_000F00(29,U) ),
+ INST(kX86InstIdMovbe , "movbe" , G(ExtMovBe) , F(Move) , 0 , O(GqdwMem) , O(GqdwMem) , U , U , E(________) , O_000F38(F0,U) , O_000F38(F1,U) ),
+ INST(kX86InstIdMovd , "movd" , G(ExtMovD) , F(Move) , 16, O(Gd)|O(MmXmmMem) , O(Gd)|O(MmXmmMem) , U , U , E(________) , O_000F00(6E,U) , O_000F00(7E,U) ),
+ INST(kX86InstIdMovddup , "movddup" , G(ExtMov) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(12,U) , U ),
+ INST(kX86InstIdMovdq2q , "movdq2q" , G(ExtMov) , F(Move) , 8 , O(Mm) , O(Xmm) , U , U , E(________) , O_F20F00(D6,U) , U ),
+ INST(kX86InstIdMovdqa , "movdqa" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(6F,U) , O_660F00(7F,U) ),
+ INST(kX86InstIdMovdqu , "movdqu" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_F30F00(6F,U) , O_F30F00(7F,U) ),
+ INST(kX86InstIdMovhlps , "movhlps" , G(ExtMov) , F(Move) , 8 , O(Xmm) , O(Xmm) , U , U , E(________) , O_000F00(12,U) , U ),
+ INST(kX86InstIdMovhpd , "movhpd" , G(ExtMov) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(16,U) , O_660F00(17,U) ),
+ INST(kX86InstIdMovhps , "movhps" , G(ExtMov) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(16,U) , O_000F00(17,U) ),
+ INST(kX86InstIdMovlhps , "movlhps" , G(ExtMov) , F(None) , 0 , O(Xmm) , O(Xmm) , U , U , E(________) , O_000F00(16,U) , U ),
+ INST(kX86InstIdMovlpd , "movlpd" , G(ExtMov) , F(Move) , 8 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(12,U) , O_660F00(13,U) ),
+ INST(kX86InstIdMovlps , "movlps" , G(ExtMov) , F(Move) , 8 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(12,U) , O_000F00(13,U) ),
+ INST(kX86InstIdMovmskpd , "movmskpd" , G(ExtMovNoRexW) , F(Move) , 8 , O(Gqd) , O(Xmm) , U , U , E(________) , O_660F00(50,U) , U ),
+ INST(kX86InstIdMovmskps , "movmskps" , G(ExtMovNoRexW) , F(Move) , 8 , O(Gqd) , O(Xmm) , U , U , E(________) , O_000F00(50,U) , U ),
+ INST(kX86InstIdMovntdq , "movntdq" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , E(________) , U , O_660F00(E7,U) ),
+ INST(kX86InstIdMovntdqa , "movntdqa" , G(ExtMov) , F(Move) , 16, O(Xmm) , O(Mem) , U , U , E(________) , O_660F38(2A,U) , U ),
+ INST(kX86InstIdMovnti , "movnti" , G(ExtMov) , F(Move) , 8 , O(Mem) , O(Gqd) , U , U , E(________) , U , O_000F00(C3,U) ),
+ INST(kX86InstIdMovntpd , "movntpd" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , E(________) , U , O_660F00(2B,U) ),
+ INST(kX86InstIdMovntps , "movntps" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , E(________) , U , O_000F00(2B,U) ),
+ INST(kX86InstIdMovntq , "movntq" , G(ExtMov) , F(Move) , 8 , O(Mem) , O(Mm) , U , U , E(________) , U , O_000F00(E7,U) ),
+ INST(kX86InstIdMovq , "movq" , G(ExtMovQ) , F(Move) , 16, O(Gq)|O(MmXmmMem) , O(Gq)|O(MmXmmMem) , U , U , E(________) , U , U ),
+ INST(kX86InstIdMovq2dq , "movq2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(Mm) , U , U , E(________) , O_F30F00(D6,U) , U ),
+ INST(kX86InstIdMovsB , "movs_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(A4,U) , U ),
+ INST(kX86InstIdMovsD , "movs_d" , G(X86Op) , F(Move)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(A5,U) , U ),
+ INST(kX86InstIdMovsQ , "movs_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(________) , O_000000(A5,U) , U ),
+ INST(kX86InstIdMovsW , "movs_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(A5,U) , U ),
+ INST(kX86InstIdMovsd , "movsd" , G(ExtMov) , F(Move) |F(Z), 8 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_F20F00(10,U) , O_F20F00(11,U) ),
+ INST(kX86InstIdMovshdup , "movshdup" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(16,U) , U ),
+ INST(kX86InstIdMovsldup , "movsldup" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(12,U) , U ),
+ INST(kX86InstIdMovss , "movss" , G(ExtMov) , F(Move) |F(Z), 4 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_F30F00(10,U) , O_F30F00(11,U) ),
+ INST(kX86InstIdMovsx , "movsx" , G(X86MovSxZx) , F(Move) , 0 , O(Gqdw) , O(GwbMem) , U , U , E(________) , O_000F00(BE,U) , U ),
+ INST(kX86InstIdMovsxd , "movsxd" , G(X86MovSxd) , F(Move) , 0 , O(Gq) , O(GdMem) , U , U , E(________) , O_000000(63,U) , U ),
+ INST(kX86InstIdMovupd , "movupd" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(10,U) , O_660F00(11,U) ),
+ INST(kX86InstIdMovups , "movups" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(10,U) , O_000F00(11,U) ),
+ INST(kX86InstIdMovzx , "movzx" , G(X86MovSxZx) , F(Move) , 0 , O(Gqdw) , O(GwbMem) , U , U , E(________) , O_000F00(B6,U) , U ),
+ INST(kX86InstIdMpsadbw , "mpsadbw" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(42,U) , U ),
+ INST(kX86InstIdMul , "mul" , G(X86Rm_B) , F(None)|F(Special) , 0 , 0 , 0 , U , U , E(WUUUUW__) , O_000000(F6,4) , U ),
+ INST(kX86InstIdMulpd , "mulpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(59,U) , U ),
+ INST(kX86InstIdMulps , "mulps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(59,U) , U ),
+ INST(kX86InstIdMulsd , "mulsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(59,U) , U ),
+ INST(kX86InstIdMulss , "mulss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(59,U) , U ),
+ INST(kX86InstIdMulx , "mulx" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(________) , O_F20F38(F6,U) , U ),
+ INST(kX86InstIdMwait , "mwait" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F01(C9,U) , U ),
+ INST(kX86InstIdNeg , "neg" , G(X86Rm_B) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(WWWWWW__) , O_000000(F6,3) , U ),
+ INST(kX86InstIdNop , "nop" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_000000(90,U) , U ),
+ INST(kX86InstIdNot , "not" , G(X86Rm_B) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(________) , O_000000(F6,2) , U ),
+ INST(kX86InstIdOr , "or" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWUWW__) , O_000000(08,1) , U ),
+ INST(kX86InstIdOrpd , "orpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(56,U) , U ),
+ INST(kX86InstIdOrps , "orps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(56,U) , U ),
+ INST(kX86InstIdPabsb , "pabsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(1C,U) , U ),
+ INST(kX86InstIdPabsd , "pabsd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(1E,U) , U ),
+ INST(kX86InstIdPabsw , "pabsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(1D,U) , U ),
+ INST(kX86InstIdPackssdw , "packssdw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(6B,U) , U ),
+ INST(kX86InstIdPacksswb , "packsswb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(63,U) , U ),
+ INST(kX86InstIdPackusdw , "packusdw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(2B,U) , U ),
+ INST(kX86InstIdPackuswb , "packuswb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(67,U) , U ),
+ INST(kX86InstIdPaddb , "paddb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FC,U) , U ),
+ INST(kX86InstIdPaddd , "paddd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FE,U) , U ),
+ INST(kX86InstIdPaddq , "paddq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D4,U) , U ),
+ INST(kX86InstIdPaddsb , "paddsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EC,U) , U ),
+ INST(kX86InstIdPaddsw , "paddsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(ED,U) , U ),
+ INST(kX86InstIdPaddusb , "paddusb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DC,U) , U ),
+ INST(kX86InstIdPaddusw , "paddusw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DD,U) , U ),
+ INST(kX86InstIdPaddw , "paddw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FD,U) , U ),
+ INST(kX86InstIdPalignr , "palignr" , G(ExtRmi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , O(Imm) , U , E(________) , O_000F3A(0F,U) , U ),
+ INST(kX86InstIdPand , "pand" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DB,U) , U ),
+ INST(kX86InstIdPandn , "pandn" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DF,U) , U ),
+ INST(kX86InstIdPause , "pause" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_F30000(90,U) , U ),
+ INST(kX86InstIdPavgb , "pavgb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E0,U) , U ),
+ INST(kX86InstIdPavgw , "pavgw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E3,U) , U ),
+ INST(kX86InstIdPblendvb , "pblendvb" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(10,U) , U ),
+ INST(kX86InstIdPblendw , "pblendw" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0E,U) , U ),
+ INST(kX86InstIdPclmulqdq , "pclmulqdq" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(44,U) , U ),
+ INST(kX86InstIdPcmpeqb , "pcmpeqb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(74,U) , U ),
+ INST(kX86InstIdPcmpeqd , "pcmpeqd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(76,U) , U ),
+ INST(kX86InstIdPcmpeqq , "pcmpeqq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(29,U) , U ),
+ INST(kX86InstIdPcmpeqw , "pcmpeqw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(75,U) , U ),
+ INST(kX86InstIdPcmpestri , "pcmpestri" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(61,U) , U ),
+ INST(kX86InstIdPcmpestrm , "pcmpestrm" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(60,U) , U ),
+ INST(kX86InstIdPcmpgtb , "pcmpgtb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(64,U) , U ),
+ INST(kX86InstIdPcmpgtd , "pcmpgtd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(66,U) , U ),
+ INST(kX86InstIdPcmpgtq , "pcmpgtq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(37,U) , U ),
+ INST(kX86InstIdPcmpgtw , "pcmpgtw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(65,U) , U ),
+ INST(kX86InstIdPcmpistri , "pcmpistri" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(63,U) , U ),
+ INST(kX86InstIdPcmpistrm , "pcmpistrm" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(62,U) , U ),
+ INST(kX86InstIdPdep , "pdep" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(________) , O_F20F38(F5,U) , U ),
+ INST(kX86InstIdPext , "pext" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(________) , O_F30F38(F5,U) , U ),
+ INST(kX86InstIdPextrb , "pextrb" , G(ExtExtract) , F(Move) , 8 , O(Gd)|O(Gb)|O(Mem) , O(Xmm) , U , U , E(________) , O_000F3A(14,U) , O_000F3A(14,U) ),
+ INST(kX86InstIdPextrd , "pextrd" , G(ExtExtract) , F(Move) , 8 , O(GdMem) , O(Xmm) , U , U , E(________) , O_000F3A(16,U) , O_000F3A(16,U) ),
+ INST(kX86InstIdPextrq , "pextrq" , G(ExtExtract) , F(Move) |F(W), 8 , O(GqdMem) , O(Xmm) , U , U , E(________) , O_000F3A(16,U) , O_000F3A(16,U) ),
+ INST(kX86InstIdPextrw , "pextrw" , G(ExtExtract) , F(Move) , 8 , O(GdMem) , O(MmXmm) , U , U , E(________) , O_000F00(C5,U) , O_000F3A(15,U) ),
+ INST(kX86InstIdPf2id , "pf2id" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(1D,U) , U ),
+ INST(kX86InstIdPf2iw , "pf2iw" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(1C,U) , U ),
+ INST(kX86InstIdPfacc , "pfacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(AE,U) , U ),
+ INST(kX86InstIdPfadd , "pfadd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(9E,U) , U ),
+ INST(kX86InstIdPfcmpeq , "pfcmpeq" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(B0,U) , U ),
+ INST(kX86InstIdPfcmpge , "pfcmpge" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(90,U) , U ),
+ INST(kX86InstIdPfcmpgt , "pfcmpgt" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A0,U) , U ),
+ INST(kX86InstIdPfmax , "pfmax" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A4,U) , U ),
+ INST(kX86InstIdPfmin , "pfmin" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(94,U) , U ),
+ INST(kX86InstIdPfmul , "pfmul" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(B4,U) , U ),
+ INST(kX86InstIdPfnacc , "pfnacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(8A,U) , U ),
+ INST(kX86InstIdPfpnacc , "pfpnacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(8E,U) , U ),
+ INST(kX86InstIdPfrcp , "pfrcp" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(96,U) , U ),
+ INST(kX86InstIdPfrcpit1 , "pfrcpit1" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A6,U) , U ),
+ INST(kX86InstIdPfrcpit2 , "pfrcpit2" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(B6,U) , U ),
+ INST(kX86InstIdPfrsqit1 , "pfrsqit1" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A7,U) , U ),
+ INST(kX86InstIdPfrsqrt , "pfrsqrt" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(97,U) , U ),
+ INST(kX86InstIdPfsub , "pfsub" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(9A,U) , U ),
+ INST(kX86InstIdPfsubr , "pfsubr" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(AA,U) , U ),
+ INST(kX86InstIdPhaddd , "phaddd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(02,U) , U ),
+ INST(kX86InstIdPhaddsw , "phaddsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(03,U) , U ),
+ INST(kX86InstIdPhaddw , "phaddw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(01,U) , U ),
+ INST(kX86InstIdPhminposuw , "phminposuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(41,U) , U ),
+ INST(kX86InstIdPhsubd , "phsubd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(06,U) , U ),
+ INST(kX86InstIdPhsubsw , "phsubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(07,U) , U ),
+ INST(kX86InstIdPhsubw , "phsubw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(05,U) , U ),
+ INST(kX86InstIdPi2fd , "pi2fd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(0D,U) , U ),
+ INST(kX86InstIdPi2fw , "pi2fw" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(0C,U) , U ),
+ INST(kX86InstIdPinsrb , "pinsrb" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(GdMem) , O(Imm) , U , E(________) , O_660F3A(20,U) , U ),
+ INST(kX86InstIdPinsrd , "pinsrd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(GdMem) , O(Imm) , U , E(________) , O_660F3A(22,U) , U ),
+ INST(kX86InstIdPinsrq , "pinsrq" , G(ExtRmi) , F(None) |F(W), 0 , O(Xmm) , O(GqMem) , O(Imm) , U , E(________) , O_660F3A(22,U) , U ),
+ INST(kX86InstIdPinsrw , "pinsrw" , G(ExtRmi_P) , F(None) , 0 , O(MmXmm) , O(GdMem) , O(Imm) , U , E(________) , O_000F00(C4,U) , U ),
+ INST(kX86InstIdPmaddubsw , "pmaddubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(04,U) , U ),
+ INST(kX86InstIdPmaddwd , "pmaddwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F5,U) , U ),
+ INST(kX86InstIdPmaxsb , "pmaxsb" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3C,U) , U ),
+ INST(kX86InstIdPmaxsd , "pmaxsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3D,U) , U ),
+ INST(kX86InstIdPmaxsw , "pmaxsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EE,U) , U ),
+ INST(kX86InstIdPmaxub , "pmaxub" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DE,U) , U ),
+ INST(kX86InstIdPmaxud , "pmaxud" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3F,U) , U ),
+ INST(kX86InstIdPmaxuw , "pmaxuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3E,U) , U ),
+ INST(kX86InstIdPminsb , "pminsb" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(38,U) , U ),
+ INST(kX86InstIdPminsd , "pminsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(39,U) , U ),
+ INST(kX86InstIdPminsw , "pminsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EA,U) , U ),
+ INST(kX86InstIdPminub , "pminub" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DA,U) , U ),
+ INST(kX86InstIdPminud , "pminud" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3B,U) , U ),
+ INST(kX86InstIdPminuw , "pminuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3A,U) , U ),
+ INST(kX86InstIdPmovmskb , "pmovmskb" , G(ExtRm_PQ) , F(Move) , 8 , O(Gqd) , O(MmXmm) , U , U , E(________) , O_000F00(D7,U) , U ),
+ INST(kX86InstIdPmovsxbd , "pmovsxbd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(21,U) , U ),
+ INST(kX86InstIdPmovsxbq , "pmovsxbq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(22,U) , U ),
+ INST(kX86InstIdPmovsxbw , "pmovsxbw" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(20,U) , U ),
+ INST(kX86InstIdPmovsxdq , "pmovsxdq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(25,U) , U ),
+ INST(kX86InstIdPmovsxwd , "pmovsxwd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(23,U) , U ),
+ INST(kX86InstIdPmovsxwq , "pmovsxwq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(24,U) , U ),
+ INST(kX86InstIdPmovzxbd , "pmovzxbd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(31,U) , U ),
+ INST(kX86InstIdPmovzxbq , "pmovzxbq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(32,U) , U ),
+ INST(kX86InstIdPmovzxbw , "pmovzxbw" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(30,U) , U ),
+ INST(kX86InstIdPmovzxdq , "pmovzxdq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(35,U) , U ),
+ INST(kX86InstIdPmovzxwd , "pmovzxwd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(33,U) , U ),
+ INST(kX86InstIdPmovzxwq , "pmovzxwq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(34,U) , U ),
+ INST(kX86InstIdPmuldq , "pmuldq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(28,U) , U ),
+ INST(kX86InstIdPmulhrsw , "pmulhrsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(0B,U) , U ),
+ INST(kX86InstIdPmulhuw , "pmulhuw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E4,U) , U ),
+ INST(kX86InstIdPmulhw , "pmulhw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E5,U) , U ),
+ INST(kX86InstIdPmulld , "pmulld" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(40,U) , U ),
+ INST(kX86InstIdPmullw , "pmullw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D5,U) , U ),
+ INST(kX86InstIdPmuludq , "pmuludq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F4,U) , U ),
+ INST(kX86InstIdPop , "pop" , G(X86Pop) , F(None)|F(Special) , 0 , 0 , U , U , U , E(________) , O_000000(8F,0) , O_000000(58,U) ),
+ INST(kX86InstIdPopa , "popa" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(61,U) , U ),
+ INST(kX86InstIdPopcnt , "popcnt" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(WWWWWW__) , O_F30F00(B8,U) , U ),
+ INST(kX86InstIdPopf , "popf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWWW) , O_000000(9D,U) , U ),
+ INST(kX86InstIdPor , "por" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EB,U) , U ),
+ INST(kX86InstIdPrefetch , "prefetch" , G(ExtPrefetch) , F(None) , 0 , O(Mem) , O(Imm) , U , U , E(________) , O_000F00(18,U) , U ),
+ INST(kX86InstIdPrefetch3dNow , "prefetch_3dnow" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(0D,0) , U ),
+ INST(kX86InstIdPrefetchw3dNow , "prefetchw_3dnow" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(0D,1) , U ),
+ INST(kX86InstIdPsadbw , "psadbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F6,U) , U ),
+ INST(kX86InstIdPshufb , "pshufb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(00,U) , U ),
+ INST(kX86InstIdPshufd , "pshufd" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F00(70,U) , U ),
+ INST(kX86InstIdPshufhw , "pshufhw" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F30F00(70,U) , U ),
+ INST(kX86InstIdPshuflw , "pshuflw" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F20F00(70,U) , U ),
+ INST(kX86InstIdPshufw , "pshufw" , G(ExtRmi_P) , F(Move) , 8 , O(Mm) , O(MmMem) , O(Imm) , U , E(________) , O_000F00(70,U) , U ),
+ INST(kX86InstIdPsignb , "psignb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(08,U) , U ),
+ INST(kX86InstIdPsignd , "psignd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(0A,U) , U ),
+ INST(kX86InstIdPsignw , "psignw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(09,U) , U ),
+ INST(kX86InstIdPslld , "pslld" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(F2,U) , O_000F00(72,6) ),
+ INST(kX86InstIdPslldq , "pslldq" , G(ExtRmRi) , F(None) , 0 , O(Xmm) , O(Imm) , U , U , E(________) , U , O_660F00(73,7) ),
+ INST(kX86InstIdPsllq , "psllq" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(F3,U) , O_000F00(73,6) ),
+ INST(kX86InstIdPsllw , "psllw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(F1,U) , O_000F00(71,6) ),
+ INST(kX86InstIdPsrad , "psrad" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(E2,U) , O_000F00(72,4) ),
+ INST(kX86InstIdPsraw , "psraw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(E1,U) , O_000F00(71,4) ),
+ INST(kX86InstIdPsrld , "psrld" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(D2,U) , O_000F00(72,2) ),
+ INST(kX86InstIdPsrldq , "psrldq" , G(ExtRmRi) , F(None) , 0 , O(Xmm) , O(Imm) , U , U , E(________) , U , O_660F00(73,3) ),
+ INST(kX86InstIdPsrlq , "psrlq" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(D3,U) , O_000F00(73,2) ),
+ INST(kX86InstIdPsrlw , "psrlw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(D1,U) , O_000F00(71,2) ),
+ INST(kX86InstIdPsubb , "psubb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F8,U) , U ),
+ INST(kX86InstIdPsubd , "psubd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FA,U) , U ),
+ INST(kX86InstIdPsubq , "psubq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FB,U) , U ),
+ INST(kX86InstIdPsubsb , "psubsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E8,U) , U ),
+ INST(kX86InstIdPsubsw , "psubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E9,U) , U ),
+ INST(kX86InstIdPsubusb , "psubusb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D8,U) , U ),
+ INST(kX86InstIdPsubusw , "psubusw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D9,U) , U ),
+ INST(kX86InstIdPsubw , "psubw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F9,U) , U ),
+ INST(kX86InstIdPswapd , "pswapd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(BB,U) , U ),
+ INST(kX86InstIdPtest , "ptest" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F38(17,U) , U ),
+ INST(kX86InstIdPunpckhbw , "punpckhbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(68,U) , U ),
+ INST(kX86InstIdPunpckhdq , "punpckhdq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(6A,U) , U ),
+ INST(kX86InstIdPunpckhqdq , "punpckhqdq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(6D,U) , U ),
+ INST(kX86InstIdPunpckhwd , "punpckhwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(69,U) , U ),
+ INST(kX86InstIdPunpcklbw , "punpcklbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(60,U) , U ),
+ INST(kX86InstIdPunpckldq , "punpckldq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(62,U) , U ),
+ INST(kX86InstIdPunpcklqdq , "punpcklqdq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(6C,U) , U ),
+ INST(kX86InstIdPunpcklwd , "punpcklwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(61,U) , U ),
+ INST(kX86InstIdPush , "push" , G(X86Push) , F(None)|F(Special) , 0 , 0 , U , U , U , E(________) , O_000000(FF,6) , O_000000(50,U) ),
+ INST(kX86InstIdPusha , "pusha" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(60,U) , U ),
+ INST(kX86InstIdPushf , "pushf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(RRRRRRRR) , O_000000(9C,U) , U ),
+ INST(kX86InstIdPxor , "pxor" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EF,U) , U ),
+ INST(kX86InstIdRcl , "rcl" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____X__) , O_000000(D0,2) , U ),
+ INST(kX86InstIdRcpps , "rcpps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(53,U) , U ),
+ INST(kX86InstIdRcpss , "rcpss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(53,U) , U ),
+ INST(kX86InstIdRcr , "rcr" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____X__) , O_000000(D0,3) , U ),
+ INST(kX86InstIdRdfsbase , "rdfsbase" , G(X86Rm) , F(Move) , 8 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,0) , U ),
+ INST(kX86InstIdRdgsbase , "rdgsbase" , G(X86Rm) , F(Move) , 8 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,1) , U ),
+ INST(kX86InstIdRdrand , "rdrand" , G(X86Rm) , F(Move) , 8 , O(Gqdw) , U , U , U , E(WWWWWW__) , O_000F00(C7,6) , U ),
+ INST(kX86InstIdRdtsc , "rdtsc" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F00(31,U) , U ),
+ INST(kX86InstIdRdtscp , "rdtscp" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F01(F9,U) , U ),
+ INST(kX86InstIdRepLodsB , "rep lods_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AC,1) , U ),
+ INST(kX86InstIdRepLodsD , "rep lods_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AD,1) , U ),
+ INST(kX86InstIdRepLodsQ , "rep lods_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AD,1) , U ),
+ INST(kX86InstIdRepLodsW , "rep lods_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_660000(AD,1) , U ),
+ INST(kX86InstIdRepMovsB , "rep movs_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_000000(A4,1) , U ),
+ INST(kX86InstIdRepMovsD , "rep movs_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_000000(A5,1) , U ),
+ INST(kX86InstIdRepMovsQ , "rep movs_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_000000(A5,1) , U ),
+ INST(kX86InstIdRepMovsW , "rep movs_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_660000(A5,1) , U ),
+ INST(kX86InstIdRepStosB , "rep stos_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AA,1) , U ),
+ INST(kX86InstIdRepStosD , "rep stos_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AB,1) , U ),
+ INST(kX86InstIdRepStosQ , "rep stos_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AB,1) , U ),
+ INST(kX86InstIdRepStosW , "rep stos_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_660000(AB,1) , U ),
+ INST(kX86InstIdRepeCmpsB , "repe cmps_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A6,1) , U ),
+ INST(kX86InstIdRepeCmpsD , "repe cmps_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,1) , U ),
+ INST(kX86InstIdRepeCmpsQ , "repe cmps_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,1) , U ),
+ INST(kX86InstIdRepeCmpsW , "repe cmps_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(A7,1) , U ),
+ INST(kX86InstIdRepeScasB , "repe scas_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AE,1) , U ),
+ INST(kX86InstIdRepeScasD , "repe scas_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,1) , U ),
+ INST(kX86InstIdRepeScasQ , "repe scas_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,1) , U ),
+ INST(kX86InstIdRepeScasW , "repe scas_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(AF,1) , U ),
+ INST(kX86InstIdRepneCmpsB , "repne cmps_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A6,0) , U ),
+ INST(kX86InstIdRepneCmpsD , "repne cmps_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,0) , U ),
+ INST(kX86InstIdRepneCmpsQ , "repne cmps_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,0) , U ),
+ INST(kX86InstIdRepneCmpsW , "repne cmps_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(A7,0) , U ),
+ INST(kX86InstIdRepneScasB , "repne scas_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AE,0) , U ),
+ INST(kX86InstIdRepneScasD , "repne scas_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,0) , U ),
+ INST(kX86InstIdRepneScasQ , "repne scas_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,0) , U ),
+ INST(kX86InstIdRepneScasW , "repne scas_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(AF,0) , U ),
+ INST(kX86InstIdRet , "ret" , G(X86Ret) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(C2,U) , U ),
+ INST(kX86InstIdRol , "rol" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____W__) , O_000000(D0,0) , U ),
+ INST(kX86InstIdRor , "ror" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____W__) , O_000000(D0,1) , U ),
+ INST(kX86InstIdRorx , "rorx" , G(AvxRmi) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Imm) , U , E(________) , O_F20F3A(F0,U) , U ),
+ INST(kX86InstIdRoundpd , "roundpd" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(09,U) , U ),
+ INST(kX86InstIdRoundps , "roundps" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(08,U) , U ),
+ INST(kX86InstIdRoundsd , "roundsd" , G(ExtRmi) , F(Move) , 8 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0B,U) , U ),
+ INST(kX86InstIdRoundss , "roundss" , G(ExtRmi) , F(Move) , 4 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0A,U) , U ),
+ INST(kX86InstIdRsqrtps , "rsqrtps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(52,U) , U ),
+ INST(kX86InstIdRsqrtss , "rsqrtss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(52,U) , U ),
+ INST(kX86InstIdSahf , "sahf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(_WWWWW__) , O_000000(9E,U) , U ),
+ INST(kX86InstIdSal , "sal" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,4) , U ),
+ INST(kX86InstIdSar , "sar" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,7) , U ),
+ INST(kX86InstIdSarx , "sarx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(________) , O_F30F38(F7,U) , U ),
+ INST(kX86InstIdSbb , "sbb" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWX__) , O_000000(18,3) , U ),
+ INST(kX86InstIdScasB , "scas_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AE,U) , U ),
+ INST(kX86InstIdScasD , "scas_d" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AF,U) , U ),
+ INST(kX86InstIdScasQ , "scas_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AF,U) , U ),
+ INST(kX86InstIdScasW , "scas_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AF,U) , U ),
+ INST(kX86InstIdSeta , "seta" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(97,U) , U ),
+ INST(kX86InstIdSetae , "setae" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(93,U) , U ),
+ INST(kX86InstIdSetb , "setb" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(92,U) , U ),
+ INST(kX86InstIdSetbe , "setbe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(96,U) , U ),
+ INST(kX86InstIdSetc , "setc" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(92,U) , U ),
+ INST(kX86InstIdSete , "sete" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(94,U) , U ),
+ INST(kX86InstIdSetg , "setg" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9F,U) , U ),
+ INST(kX86InstIdSetge , "setge" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9D,U) , U ),
+ INST(kX86InstIdSetl , "setl" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9C,U) , U ),
+ INST(kX86InstIdSetle , "setle" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9E,U) , U ),
+ INST(kX86InstIdSetna , "setna" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(96,U) , U ),
+ INST(kX86InstIdSetnae , "setnae" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(92,U) , U ),
+ INST(kX86InstIdSetnb , "setnb" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(93,U) , U ),
+ INST(kX86InstIdSetnbe , "setnbe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(97,U) , U ),
+ INST(kX86InstIdSetnc , "setnc" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(93,U) , U ),
+ INST(kX86InstIdSetne , "setne" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(95,U) , U ),
+ INST(kX86InstIdSetng , "setng" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9E,U) , U ),
+ INST(kX86InstIdSetnge , "setnge" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9C,U) , U ),
+ INST(kX86InstIdSetnl , "setnl" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9D,U) , U ),
+ INST(kX86InstIdSetnle , "setnle" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9F,U) , U ),
+ INST(kX86InstIdSetno , "setno" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(R_______) , O_000F00(91,U) , U ),
+ INST(kX86InstIdSetnp , "setnp" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9B,U) , U ),
+ INST(kX86InstIdSetns , "setns" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_R______) , O_000F00(99,U) , U ),
+ INST(kX86InstIdSetnz , "setnz" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(95,U) , U ),
+ INST(kX86InstIdSeto , "seto" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(R_______) , O_000F00(90,U) , U ),
+ INST(kX86InstIdSetp , "setp" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9A,U) , U ),
+ INST(kX86InstIdSetpe , "setpe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9A,U) , U ),
+ INST(kX86InstIdSetpo , "setpo" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9B,U) , U ),
+ INST(kX86InstIdSets , "sets" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_R______) , O_000F00(98,U) , U ),
+ INST(kX86InstIdSetz , "setz" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(94,U) , U ),
+ INST(kX86InstIdSfence , "sfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(AE,7) , U ),
+ INST(kX86InstIdShl , "shl" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,4) , U ),
+ INST(kX86InstIdShld , "shld" , G(X86Shlrd) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb) , U , U , E(UWWUWW__) , O_000F00(A4,U) , U ),
+ INST(kX86InstIdShlx , "shlx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(________) , O_660F38(F7,U) , U ),
+ INST(kX86InstIdShr , "shr" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,5) , U ),
+ INST(kX86InstIdShrd , "shrd" , G(X86Shlrd) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , E(UWWUWW__) , O_000F00(AC,U) , U ),
+ INST(kX86InstIdShrx , "shrx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(________) , O_F20F38(F7,U) , U ),
+ INST(kX86InstIdShufpd , "shufpd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F00(C6,U) , U ),
+ INST(kX86InstIdShufps , "shufps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_000F00(C6,U) , U ),
+ INST(kX86InstIdSqrtpd , "sqrtpd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(51,U) , U ),
+ INST(kX86InstIdSqrtps , "sqrtps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(51,U) , U ),
+ INST(kX86InstIdSqrtsd , "sqrtsd" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(51,U) , U ),
+ INST(kX86InstIdSqrtss , "sqrtss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(51,U) , U ),
+ INST(kX86InstIdStc , "stc" , G(X86Op) , F(None) , 0 , U , U , U , U , E(_____W__) , O_000000(F9,U) , U ),
+ INST(kX86InstIdStd , "std" , G(X86Op) , F(None) , 0 , U , U , U , U , E(______W_) , O_000000(FD,U) , U ),
+ INST(kX86InstIdStmxcsr , "stmxcsr" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,3) , U ),
+ INST(kX86InstIdStosB , "stos_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(______R_) , O_000000(AA,U) , U ),
+ INST(kX86InstIdStosD , "stos_d" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(______R_) , O_000000(AB,U) , U ),
+ INST(kX86InstIdStosQ , "stos_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(______R_) , O_000000(AB,U) , U ),
+ INST(kX86InstIdStosW , "stos_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(______R_) , O_000000(AB,U) , U ),
+ INST(kX86InstIdSub , "sub" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWW__) , O_000000(28,5) , U ),
+ INST(kX86InstIdSubpd , "subpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5C,U) , U ),
+ INST(kX86InstIdSubps , "subps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5C,U) , U ),
+ INST(kX86InstIdSubsd , "subsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5C,U) , U ),
+ INST(kX86InstIdSubss , "subss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5C,U) , U ),
+ INST(kX86InstIdTest , "test" , G(X86Test) , F(Test) , 0 , O(GqdwbMem) , O(Gqdwb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(84,U) , O_000000(F6,U) ),
+ INST(kX86InstIdTzcnt , "tzcnt" , G(X86RegRm) , F(Move) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUW__) , O_F30F00(BC,U) , U ),
+ INST(kX86InstIdUcomisd , "ucomisd" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F00(2E,U) , U ),
+ INST(kX86InstIdUcomiss , "ucomiss" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_000F00(2E,U) , U ),
+ INST(kX86InstIdUd2 , "ud2" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(0B,U) , U ),
+ INST(kX86InstIdUnpckhpd , "unpckhpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(15,U) , U ),
+ INST(kX86InstIdUnpckhps , "unpckhps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(15,U) , U ),
+ INST(kX86InstIdUnpcklpd , "unpcklpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(14,U) , U ),
+ INST(kX86InstIdUnpcklps , "unpcklps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(14,U) , U ),
+ INST(kX86InstIdVaddpd , "vaddpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(58,U) , U ),
+ INST(kX86InstIdVaddps , "vaddps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(58,U) , U ),
+ INST(kX86InstIdVaddsd , "vaddsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(58,U) , U ),
+ INST(kX86InstIdVaddss , "vaddss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(58,U) , U ),
+ INST(kX86InstIdVaddsubpd , "vaddsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D0,U) , U ),
+ INST(kX86InstIdVaddsubps , "vaddsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(D0,U) , U ),
+ INST(kX86InstIdVaesdec , "vaesdec" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DE,U) , U ),
+ INST(kX86InstIdVaesdeclast , "vaesdeclast" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DF,U) , U ),
+ INST(kX86InstIdVaesenc , "vaesenc" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DC,U) , U ),
+ INST(kX86InstIdVaesenclast , "vaesenclast" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DD,U) , U ),
+ INST(kX86InstIdVaesimc , "vaesimc" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DB,U) , U ),
+ INST(kX86InstIdVaeskeygenassist , "vaeskeygenassist" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(DF,U) , U ),
+ INST(kX86InstIdVandnpd , "vandnpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(55,U) , U ),
+ INST(kX86InstIdVandnps , "vandnps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(55,U) , U ),
+ INST(kX86InstIdVandpd , "vandpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(54,U) , U ),
+ INST(kX86InstIdVandps , "vandps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(54,U) , U ),
+ INST(kX86InstIdVblendpd , "vblendpd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0D,U) , U ),
+ INST(kX86InstIdVblendps , "vblendps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0C,U) , U ),
+ INST(kX86InstIdVblendvpd , "vblendvpd" , G(AvxRvmr_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , E(________) , O_660F3A(4B,U) , U ),
+ INST(kX86InstIdVblendvps , "vblendvps" , G(AvxRvmr_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , E(________) , O_660F3A(4A,U) , U ),
+ INST(kX86InstIdVbroadcastf128 , "vbroadcastf128" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(Mem) , U , U , E(________) , O_660F38(1A,U)|L, U ),
+ INST(kX86InstIdVbroadcasti128 , "vbroadcasti128" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(Mem) , U , U , E(________) , O_660F38(5A,U)|L, U ),
+ INST(kX86InstIdVbroadcastsd , "vbroadcastsd" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(XmmMem) , U , U , E(________) , O_660F38(19,U)|L, U ),
+ INST(kX86InstIdVbroadcastss , "vbroadcastss" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(XmmMem) , U , U , E(________) , O_660F38(18,U) , U ),
+ INST(kX86InstIdVcmppd , "vcmppd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F00(C2,U) , U ),
+ INST(kX86InstIdVcmpps , "vcmpps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_000F00(C2,U) , U ),
+ INST(kX86InstIdVcmpsd , "vcmpsd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_F20F00(C2,U) , U ),
+ INST(kX86InstIdVcmpss , "vcmpss" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_F30F00(C2,U) , U ),
+ INST(kX86InstIdVcomisd , "vcomisd" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(2F,U) , U ),
+ INST(kX86InstIdVcomiss , "vcomiss" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(2F,U) , U ),
+ INST(kX86InstIdVcvtdq2pd , "vcvtdq2pd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_F30F00(E6,U) , U ),
+ INST(kX86InstIdVcvtdq2ps , "vcvtdq2ps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(5B,U) , U ),
+ INST(kX86InstIdVcvtpd2dq , "vcvtpd2dq" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , E(________) , O_F20F00(E6,U) , U ),
+ INST(kX86InstIdVcvtpd2ps , "vcvtpd2ps" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(5A,U) , U ),
+ INST(kX86InstIdVcvtph2ps , "vcvtph2ps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(13,U) , U ),
+ INST(kX86InstIdVcvtps2dq , "vcvtps2dq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(5B,U) , U ),
+ INST(kX86InstIdVcvtps2pd , "vcvtps2pd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_000F00(5A,U) , U ),
+ INST(kX86InstIdVcvtps2ph , "vcvtps2ph" , G(AvxMri_P) , F(None) , 0 , O(XmmMem) , O(XmmYmm) , O(Imm) , U , E(________) , O_660F3A(1D,U) , U ),
+ INST(kX86InstIdVcvtsd2si , "vcvtsd2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2D,U) , U ),
+ INST(kX86InstIdVcvtsd2ss , "vcvtsd2ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(5A,U) , U ),
+ INST(kX86InstIdVcvtsi2sd , "vcvtsi2sd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , U , E(________) , O_F20F00(2A,U) , U ),
+ INST(kX86InstIdVcvtsi2ss , "vcvtsi2ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , U , E(________) , O_F30F00(2A,U) , U ),
+ INST(kX86InstIdVcvtss2sd , "vcvtss2sd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(5A,U) , U ),
+ INST(kX86InstIdVcvtss2si , "vcvtss2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2D,U) , U ),
+ INST(kX86InstIdVcvttpd2dq , "vcvttpd2dq" , G(AvxRm_P) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(E6,U) , U ),
+ INST(kX86InstIdVcvttps2dq , "vcvttps2dq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(5B,U) , U ),
+ INST(kX86InstIdVcvttsd2si , "vcvttsd2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2C,U) , U ),
+ INST(kX86InstIdVcvttss2si , "vcvttss2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F30F00(2C,U) , U ),
+ INST(kX86InstIdVdivpd , "vdivpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5E,U) , U ),
+ INST(kX86InstIdVdivps , "vdivps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5E,U) , U ),
+ INST(kX86InstIdVdivsd , "vdivsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(5E,U) , U ),
+ INST(kX86InstIdVdivss , "vdivss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(5E,U) , U ),
+ INST(kX86InstIdVdppd , "vdppd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(41,U) , U ),
+ INST(kX86InstIdVdpps , "vdpps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(40,U) , U ),
+ INST(kX86InstIdVextractf128 , "vextractf128" , G(AvxMri) , F(None) , 0 , O(XmmMem) , O(Ymm) , O(Imm) , U , E(________) , O_660F3A(19,U)|L, U ),
+ INST(kX86InstIdVextracti128 , "vextracti128" , G(AvxMri) , F(None) , 0 , O(XmmMem) , O(Ymm) , O(Imm) , U , E(________) , O_660F3A(39,U)|L, U ),
+ INST(kX86InstIdVextractps , "vextractps" , G(AvxMri) , F(None) , 0 , O(GqdMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(17,U) , U ),
+ INST(kX86InstIdVfmadd132pd , "vfmadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(98,U) , U ),
+ INST(kX86InstIdVfmadd132ps , "vfmadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(98,U) , U ),
+ INST(kX86InstIdVfmadd132sd , "vfmadd132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(99,U) , U ),
+ INST(kX86InstIdVfmadd132ss , "vfmadd132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(99,U) , U ),
+ INST(kX86InstIdVfmadd213pd , "vfmadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A8,U) , U ),
+ INST(kX86InstIdVfmadd213ps , "vfmadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A8,U) , U ),
+ INST(kX86InstIdVfmadd213sd , "vfmadd213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(A9,U) , U ),
+ INST(kX86InstIdVfmadd213ss , "vfmadd213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(A9,U) , U ),
+ INST(kX86InstIdVfmadd231pd , "vfmadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B8,U) , U ),
+ INST(kX86InstIdVfmadd231ps , "vfmadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B8,U) , U ),
+ INST(kX86InstIdVfmadd231sd , "vfmadd231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(B9,U) , U ),
+ INST(kX86InstIdVfmadd231ss , "vfmadd231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(B9,U) , U ),
+ INST(kX86InstIdVfmaddpd , "vfmaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(69,U) , U ),
+ INST(kX86InstIdVfmaddps , "vfmaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(68,U) , U ),
+ INST(kX86InstIdVfmaddsd , "vfmaddsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6B,U) , U ),
+ INST(kX86InstIdVfmaddss , "vfmaddss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6A,U) , U ),
+ INST(kX86InstIdVfmaddsub132pd , "vfmaddsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(96,U) , U ),
+ INST(kX86InstIdVfmaddsub132ps , "vfmaddsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(96,U) , U ),
+ INST(kX86InstIdVfmaddsub213pd , "vfmaddsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A6,U) , U ),
+ INST(kX86InstIdVfmaddsub213ps , "vfmaddsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A6,U) , U ),
+ INST(kX86InstIdVfmaddsub231pd , "vfmaddsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B6,U) , U ),
+ INST(kX86InstIdVfmaddsub231ps , "vfmaddsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B6,U) , U ),
+ INST(kX86InstIdVfmaddsubpd , "vfmaddsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5D,U) , U ),
+ INST(kX86InstIdVfmaddsubps , "vfmaddsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5C,U) , U ),
+ INST(kX86InstIdVfmsub132pd , "vfmsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9A,U) , U ),
+ INST(kX86InstIdVfmsub132ps , "vfmsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9A,U) , U ),
+ INST(kX86InstIdVfmsub132sd , "vfmsub132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9B,U) , U ),
+ INST(kX86InstIdVfmsub132ss , "vfmsub132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9B,U) , U ),
+ INST(kX86InstIdVfmsub213pd , "vfmsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AA,U) , U ),
+ INST(kX86InstIdVfmsub213ps , "vfmsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AA,U) , U ),
+ INST(kX86InstIdVfmsub213sd , "vfmsub213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AB,U) , U ),
+ INST(kX86InstIdVfmsub213ss , "vfmsub213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AB,U) , U ),
+ INST(kX86InstIdVfmsub231pd , "vfmsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BA,U) , U ),
+ INST(kX86InstIdVfmsub231ps , "vfmsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BA,U) , U ),
+ INST(kX86InstIdVfmsub231sd , "vfmsub231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BB,U) , U ),
+ INST(kX86InstIdVfmsub231ss , "vfmsub231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BB,U) , U ),
+ INST(kX86InstIdVfmsubadd132pd , "vfmsubadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(97,U) , U ),
+ INST(kX86InstIdVfmsubadd132ps , "vfmsubadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(97,U) , U ),
+ INST(kX86InstIdVfmsubadd213pd , "vfmsubadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A7,U) , U ),
+ INST(kX86InstIdVfmsubadd213ps , "vfmsubadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A7,U) , U ),
+ INST(kX86InstIdVfmsubadd231pd , "vfmsubadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B7,U) , U ),
+ INST(kX86InstIdVfmsubadd231ps , "vfmsubadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B7,U) , U ),
+ INST(kX86InstIdVfmsubaddpd , "vfmsubaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5F,U) , U ),
+ INST(kX86InstIdVfmsubaddps , "vfmsubaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5E,U) , U ),
+ INST(kX86InstIdVfmsubpd , "vfmsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(6D,U) , U ),
+ INST(kX86InstIdVfmsubps , "vfmsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(6C,U) , U ),
+ INST(kX86InstIdVfmsubsd , "vfmsubsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6F,U) , U ),
+ INST(kX86InstIdVfmsubss , "vfmsubss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6E,U) , U ),
+ INST(kX86InstIdVfnmadd132pd , "vfnmadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9C,U) , U ),
+ INST(kX86InstIdVfnmadd132ps , "vfnmadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9C,U) , U ),
+ INST(kX86InstIdVfnmadd132sd , "vfnmadd132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9D,U) , U ),
+ INST(kX86InstIdVfnmadd132ss , "vfnmadd132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9D,U) , U ),
+ INST(kX86InstIdVfnmadd213pd , "vfnmadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AC,U) , U ),
+ INST(kX86InstIdVfnmadd213ps , "vfnmadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AC,U) , U ),
+ INST(kX86InstIdVfnmadd213sd , "vfnmadd213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AD,U) , U ),
+ INST(kX86InstIdVfnmadd213ss , "vfnmadd213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AD,U) , U ),
+ INST(kX86InstIdVfnmadd231pd , "vfnmadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BC,U) , U ),
+ INST(kX86InstIdVfnmadd231ps , "vfnmadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BC,U) , U ),
+ INST(kX86InstIdVfnmadd231sd , "vfnmadd231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BC,U) , U ),
+ INST(kX86InstIdVfnmadd231ss , "vfnmadd231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BC,U) , U ),
+ INST(kX86InstIdVfnmaddpd , "vfnmaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(79,U) , U ),
+ INST(kX86InstIdVfnmaddps , "vfnmaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(78,U) , U ),
+ INST(kX86InstIdVfnmaddsd , "vfnmaddsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7B,U) , U ),
+ INST(kX86InstIdVfnmaddss , "vfnmaddss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7A,U) , U ),
+ INST(kX86InstIdVfnmsub132pd , "vfnmsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9E,U) , U ),
+ INST(kX86InstIdVfnmsub132ps , "vfnmsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9E,U) , U ),
+ INST(kX86InstIdVfnmsub132sd , "vfnmsub132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9F,U) , U ),
+ INST(kX86InstIdVfnmsub132ss , "vfnmsub132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9F,U) , U ),
+ INST(kX86InstIdVfnmsub213pd , "vfnmsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AE,U) , U ),
+ INST(kX86InstIdVfnmsub213ps , "vfnmsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AE,U) , U ),
+ INST(kX86InstIdVfnmsub213sd , "vfnmsub213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AF,U) , U ),
+ INST(kX86InstIdVfnmsub213ss , "vfnmsub213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AF,U) , U ),
+ INST(kX86InstIdVfnmsub231pd , "vfnmsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BE,U) , U ),
+ INST(kX86InstIdVfnmsub231ps , "vfnmsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BE,U) , U ),
+ INST(kX86InstIdVfnmsub231sd , "vfnmsub231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BF,U) , U ),
+ INST(kX86InstIdVfnmsub231ss , "vfnmsub231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BF,U) , U ),
+ INST(kX86InstIdVfnmsubpd , "vfnmsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(7D,U) , U ),
+ INST(kX86InstIdVfnmsubps , "vfnmsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(7C,U) , U ),
+ INST(kX86InstIdVfnmsubsd , "vfnmsubsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7F,U) , U ),
+ INST(kX86InstIdVfnmsubss , "vfnmsubss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7E,U) , U ),
+ INST(kX86InstIdVfrczpd , "vfrczpd" , G(XopRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_00_M09(81,U) , U ),
+ INST(kX86InstIdVfrczps , "vfrczps" , G(XopRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_00_M09(80,U) , U ),
+ INST(kX86InstIdVfrczsd , "vfrczsd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(83,U) , U ),
+ INST(kX86InstIdVfrczss , "vfrczss" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(82,U) , U ),
+ INST(kX86InstIdVgatherdpd , "vgatherdpd" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(92,U) , U ),
+ INST(kX86InstIdVgatherdps , "vgatherdps" , G(AvxGather) , F(None) , 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(92,U) , U ),
+ INST(kX86InstIdVgatherqpd , "vgatherqpd" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(93,U) , U ),
+ INST(kX86InstIdVgatherqps , "vgatherqps" , G(AvxGatherEx) , F(None) , 0 , O(Xmm) , O(Mem) , O(Xmm) , U , E(________) , O_660F38(93,U) , U ),
+ INST(kX86InstIdVhaddpd , "vhaddpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(7C,U) , U ),
+ INST(kX86InstIdVhaddps , "vhaddps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(7C,U) , U ),
+ INST(kX86InstIdVhsubpd , "vhsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(7D,U) , U ),
+ INST(kX86InstIdVhsubps , "vhsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(7D,U) , U ),
+ INST(kX86InstIdVinsertf128 , "vinsertf128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(18,U)|L, U ),
+ INST(kX86InstIdVinserti128 , "vinserti128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(38,U)|L, U ),
+ INST(kX86InstIdVinsertps , "vinsertps" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(21,U) , U ),
+ INST(kX86InstIdVlddqu , "vlddqu" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(Mem) , U , U , E(________) , O_F20F00(F0,U) , U ),
+ INST(kX86InstIdVldmxcsr , "vldmxcsr" , G(AvxM) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,2) , U ),
+ INST(kX86InstIdVmaskmovdqu , "vmaskmovdqu" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(Xmm) , U , U , E(________) , O_660F00(F7,U) , U ),
+ INST(kX86InstIdVmaskmovpd , "vmaskmovpd" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(2D,U) , O_660F38(2F,U) ),
+ INST(kX86InstIdVmaskmovps , "vmaskmovps" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(2C,U) , O_660F38(2E,U) ),
+ INST(kX86InstIdVmaxpd , "vmaxpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5F,U) , U ),
+ INST(kX86InstIdVmaxps , "vmaxps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5F,U) , U ),
+ INST(kX86InstIdVmaxsd , "vmaxsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(5F,U) , U ),
+ INST(kX86InstIdVmaxss , "vmaxss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(5F,U) , U ),
+ INST(kX86InstIdVminpd , "vminpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5D,U) , U ),
+ INST(kX86InstIdVminps , "vminps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5D,U) , U ),
+ INST(kX86InstIdVminsd , "vminsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(5D,U) , U ),
+ INST(kX86InstIdVminss , "vminss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(5D,U) , U ),
+ INST(kX86InstIdVmovapd , "vmovapd" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_660F00(28,U) , O_660F00(29,U) ),
+ INST(kX86InstIdVmovaps , "vmovaps" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_000F00(28,U) , O_000F00(29,U) ),
+ INST(kX86InstIdVmovd , "vmovd" , G(AvxRmMr) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(6E,U) , O_660F00(7E,U) ),
+ INST(kX86InstIdVmovddup , "vmovddup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F20F00(12,U) , U ),
+ INST(kX86InstIdVmovdqa , "vmovdqa" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_660F00(6F,U) , O_660F00(7F,U) ),
+ INST(kX86InstIdVmovdqu , "vmovdqu" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(6F,U) , O_F30F00(7F,U) ),
+ INST(kX86InstIdVmovhlps , "vmovhlps" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(Xmm) , U , E(________) , O_000F00(12,U) , U ),
+ INST(kX86InstIdVmovhpd , "vmovhpd" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_660F00(16,U) , O_660F00(17,U) ),
+ INST(kX86InstIdVmovhps , "vmovhps" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_000F00(16,U) , O_000F00(17,U) ),
+ INST(kX86InstIdVmovlhps , "vmovlhps" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(Xmm) , U , E(________) , O_000F00(16,U) , U ),
+ INST(kX86InstIdVmovlpd , "vmovlpd" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_660F00(12,U) , O_660F00(13,U) ),
+ INST(kX86InstIdVmovlps , "vmovlps" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_000F00(12,U) , O_000F00(13,U) ),
+ INST(kX86InstIdVmovmskpd , "vmovmskpd" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , E(________) , O_660F00(50,U) , U ),
+ INST(kX86InstIdVmovmskps , "vmovmskps" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , E(________) , O_000F00(50,U) , U ),
+ INST(kX86InstIdVmovntdq , "vmovntdq" , G(AvxMr) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , E(________) , O_660F00(E7,U) , U ),
+ INST(kX86InstIdVmovntdqa , "vmovntdqa" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(Mem) , U , U , E(________) , O_660F38(2A,U) , U ),
+ INST(kX86InstIdVmovntpd , "vmovntpd" , G(AvxMr_P) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , E(________) , O_660F00(2B,U) , U ),
+ INST(kX86InstIdVmovntps , "vmovntps" , G(AvxMr_P) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , E(________) , O_000F00(2B,U) , U ),
+ INST(kX86InstIdVmovq , "vmovq" , G(AvxRmMr) , F(None) |F(W), 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(6E,U) , O_660F00(7E,U) ),
+ INST(kX86InstIdVmovsd , "vmovsd" , G(AvxMovSsSd) , F(None) , 0 , O(XmmMem) , O(XmmMem) , O(Xmm) , U , E(________) , O_F20F00(10,U) , O_F20F00(11,U) ),
+ INST(kX86InstIdVmovshdup , "vmovshdup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(16,U) , U ),
+ INST(kX86InstIdVmovsldup , "vmovsldup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(12,U) , U ),
+ INST(kX86InstIdVmovss , "vmovss" , G(AvxMovSsSd) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Xmm) , U , E(________) , O_F30F00(10,U) , O_F30F00(11,U) ),
+ INST(kX86InstIdVmovupd , "vmovupd" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_660F00(10,U) , O_660F00(11,U) ),
+ INST(kX86InstIdVmovups , "vmovups" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_000F00(10,U) , O_000F00(11,U) ),
+ INST(kX86InstIdVmpsadbw , "vmpsadbw" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(42,U) , U ),
+ INST(kX86InstIdVmulpd , "vmulpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(59,U) , U ),
+ INST(kX86InstIdVmulps , "vmulps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(59,U) , U ),
+ INST(kX86InstIdVmulsd , "vmulsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(59,U) , U ),
+ INST(kX86InstIdVmulss , "vmulss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(59,U) , U ),
+ INST(kX86InstIdVorpd , "vorpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(56,U) , U ),
+ INST(kX86InstIdVorps , "vorps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(56,U) , U ),
+ INST(kX86InstIdVpabsb , "vpabsb" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(1C,U) , U ),
+ INST(kX86InstIdVpabsd , "vpabsd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(1E,U) , U ),
+ INST(kX86InstIdVpabsw , "vpabsw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(1D,U) , U ),
+ INST(kX86InstIdVpackssdw , "vpackssdw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6B,U) , U ),
+ INST(kX86InstIdVpacksswb , "vpacksswb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(63,U) , U ),
+ INST(kX86InstIdVpackusdw , "vpackusdw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(2B,U) , U ),
+ INST(kX86InstIdVpackuswb , "vpackuswb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(67,U) , U ),
+ INST(kX86InstIdVpaddb , "vpaddb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FC,U) , U ),
+ INST(kX86InstIdVpaddd , "vpaddd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FE,U) , U ),
+ INST(kX86InstIdVpaddq , "vpaddq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D4,U) , U ),
+ INST(kX86InstIdVpaddsb , "vpaddsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EC,U) , U ),
+ INST(kX86InstIdVpaddsw , "vpaddsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(ED,U) , U ),
+ INST(kX86InstIdVpaddusb , "vpaddusb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DC,U) , U ),
+ INST(kX86InstIdVpaddusw , "vpaddusw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DD,U) , U ),
+ INST(kX86InstIdVpaddw , "vpaddw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FD,U) , U ),
+ INST(kX86InstIdVpalignr , "vpalignr" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0F,U) , U ),
+ INST(kX86InstIdVpand , "vpand" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DB,U) , U ),
+ INST(kX86InstIdVpandn , "vpandn" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DF,U) , U ),
+ INST(kX86InstIdVpavgb , "vpavgb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E0,U) , U ),
+ INST(kX86InstIdVpavgw , "vpavgw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E3,U) , U ),
+ INST(kX86InstIdVpblendd , "vpblendd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(02,U) , U ),
+ INST(kX86InstIdVpblendvb , "vpblendvb" , G(AvxRvmr) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , E(________) , O_660F3A(4C,U) , U ),
+ INST(kX86InstIdVpblendw , "vpblendw" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0E,U) , U ),
+ INST(kX86InstIdVpbroadcastb , "vpbroadcastb" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(78,U) , U ),
+ INST(kX86InstIdVpbroadcastd , "vpbroadcastd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(58,U) , U ),
+ INST(kX86InstIdVpbroadcastq , "vpbroadcastq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(59,U) , U ),
+ INST(kX86InstIdVpbroadcastw , "vpbroadcastw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(79,U) , U ),
+ INST(kX86InstIdVpclmulqdq , "vpclmulqdq" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(44,U) , U ),
+ INST(kX86InstIdVpcmov , "vpcmov" , G(XopRvrmRvmr_P), F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_00_M08(A2,U) , U ),
+ INST(kX86InstIdVpcmpeqb , "vpcmpeqb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(74,U) , U ),
+ INST(kX86InstIdVpcmpeqd , "vpcmpeqd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(76,U) , U ),
+ INST(kX86InstIdVpcmpeqq , "vpcmpeqq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(29,U) , U ),
+ INST(kX86InstIdVpcmpeqw , "vpcmpeqw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(75,U) , U ),
+ INST(kX86InstIdVpcmpestri , "vpcmpestri" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(61,U) , U ),
+ INST(kX86InstIdVpcmpestrm , "vpcmpestrm" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(60,U) , U ),
+ INST(kX86InstIdVpcmpgtb , "vpcmpgtb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(64,U) , U ),
+ INST(kX86InstIdVpcmpgtd , "vpcmpgtd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(66,U) , U ),
+ INST(kX86InstIdVpcmpgtq , "vpcmpgtq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(37,U) , U ),
+ INST(kX86InstIdVpcmpgtw , "vpcmpgtw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(65,U) , U ),
+ INST(kX86InstIdVpcmpistri , "vpcmpistri" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(63,U) , U ),
+ INST(kX86InstIdVpcmpistrm , "vpcmpistrm" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(62,U) , U ),
+ INST(kX86InstIdVpcomb , "vpcomb" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CC,U) , U ),
+ INST(kX86InstIdVpcomd , "vpcomd" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CE,U) , U ),
+ INST(kX86InstIdVpcomq , "vpcomq" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CF,U) , U ),
+ INST(kX86InstIdVpcomub , "vpcomub" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(EC,U) , U ),
+ INST(kX86InstIdVpcomud , "vpcomud" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(EE,U) , U ),
+ INST(kX86InstIdVpcomuq , "vpcomuq" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(EF,U) , U ),
+ INST(kX86InstIdVpcomuw , "vpcomuw" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(ED,U) , U ),
+ INST(kX86InstIdVpcomw , "vpcomw" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CD,U) , U ),
+ INST(kX86InstIdVperm2f128 , "vperm2f128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , E(________) , O_660F3A(06,U)|L, U ),
+ INST(kX86InstIdVperm2i128 , "vperm2i128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , E(________) , O_660F3A(46,U)|L, U ),
+ INST(kX86InstIdVpermd , "vpermd" , G(AvxRvm) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , U , E(________) , O_660F38(36,U)|L, U ),
+ INST(kX86InstIdVpermil2pd , "vpermil2pd" , G(AvxRvrmRvmr_P), F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_66_M03(49,U) , U ),
+ INST(kX86InstIdVpermil2ps , "vpermil2ps" , G(AvxRvrmRvmr_P), F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_66_M03(48,U) , U ),
+ INST(kX86InstIdVpermilpd , "vpermilpd" , G(AvxRvmRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F38(0D,U) , O_660F3A(05,U) ),
+ INST(kX86InstIdVpermilps , "vpermilps" , G(AvxRvmRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F38(0C,U) , O_660F3A(04,U) ),
+ INST(kX86InstIdVpermpd , "vpermpd" , G(AvxRmi) , F(None) |F(W), 0 , O(Ymm) , O(YmmMem) , O(Imm) , U , E(________) , O_660F3A(01,U)|L, U ),
+ INST(kX86InstIdVpermps , "vpermps" , G(AvxRvm) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , U , E(________) , O_660F38(16,U)|L, U ),
+ INST(kX86InstIdVpermq , "vpermq" , G(AvxRmi) , F(None) |F(W), 0 , O(Ymm) , O(YmmMem) , O(Imm) , U , E(________) , O_660F3A(00,U)|L, U ),
+ INST(kX86InstIdVpextrb , "vpextrb" , G(AvxMri) , F(None) , 0 , O(GqdwbMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(14,U) , U ),
+ INST(kX86InstIdVpextrd , "vpextrd" , G(AvxMri) , F(None) , 0 , O(GqdMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(16,U) , U ),
+ INST(kX86InstIdVpextrq , "vpextrq" , G(AvxMri) , F(None) |F(W), 0 , O(GqMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(16,U) , U ),
+ INST(kX86InstIdVpextrw , "vpextrw" , G(AvxMri) , F(None) , 0 , O(GqdwMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(15,U) , U ),
+ INST(kX86InstIdVpgatherdd , "vpgatherdd" , G(AvxGather) , F(None) , 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(90,U) , U ),
+ INST(kX86InstIdVpgatherdq , "vpgatherdq" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(90,U) , U ),
+ INST(kX86InstIdVpgatherqd , "vpgatherqd" , G(AvxGatherEx) , F(None) , 0 , O(Xmm) , O(Mem) , O(Xmm) , U , E(________) , O_660F38(91,U) , U ),
+ INST(kX86InstIdVpgatherqq , "vpgatherqq" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(91,U) , U ),
+ INST(kX86InstIdVphaddbd , "vphaddbd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C2,U) , U ),
+ INST(kX86InstIdVphaddbq , "vphaddbq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C3,U) , U ),
+ INST(kX86InstIdVphaddbw , "vphaddbw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C1,U) , U ),
+ INST(kX86InstIdVphaddd , "vphaddd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(02,U) , U ),
+ INST(kX86InstIdVphadddq , "vphadddq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(CB,U) , U ),
+ INST(kX86InstIdVphaddsw , "vphaddsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(03,U) , U ),
+ INST(kX86InstIdVphaddubd , "vphaddubd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D2,U) , U ),
+ INST(kX86InstIdVphaddubq , "vphaddubq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D3,U) , U ),
+ INST(kX86InstIdVphaddubw , "vphaddubw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D1,U) , U ),
+ INST(kX86InstIdVphaddudq , "vphaddudq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(DB,U) , U ),
+ INST(kX86InstIdVphadduwd , "vphadduwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D6,U) , U ),
+ INST(kX86InstIdVphadduwq , "vphadduwq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D7,U) , U ),
+ INST(kX86InstIdVphaddw , "vphaddw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(01,U) , U ),
+ INST(kX86InstIdVphaddwd , "vphaddwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C6,U) , U ),
+ INST(kX86InstIdVphaddwq , "vphaddwq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C7,U) , U ),
+ INST(kX86InstIdVphminposuw , "vphminposuw" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(41,U) , U ),
+ INST(kX86InstIdVphsubbw , "vphsubbw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(E1,U) , U ),
+ INST(kX86InstIdVphsubd , "vphsubd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(06,U) , U ),
+ INST(kX86InstIdVphsubdq , "vphsubdq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(E3,U) , U ),
+ INST(kX86InstIdVphsubsw , "vphsubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(07,U) , U ),
+ INST(kX86InstIdVphsubw , "vphsubw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(05,U) , U ),
+ INST(kX86InstIdVphsubwd , "vphsubwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(E2,U) , U ),
+ INST(kX86InstIdVpinsrb , "vpinsrb" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdwbMem) , O(Imm) , E(________) , O_660F3A(20,U) , U ),
+ INST(kX86InstIdVpinsrd , "vpinsrd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , O(Imm) , E(________) , O_660F3A(22,U) , U ),
+ INST(kX86InstIdVpinsrq , "vpinsrq" , G(AvxRvmi) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(GqMem) , O(Imm) , E(________) , O_660F3A(22,U) , U ),
+ INST(kX86InstIdVpinsrw , "vpinsrw" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdwMem) , O(Imm) , E(________) , O_660F00(C4,U) , U ),
+ INST(kX86InstIdVpmacsdd , "vpmacsdd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(9E,U) , U ),
+ INST(kX86InstIdVpmacsdqh , "vpmacsdqh" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(9F,U) , U ),
+ INST(kX86InstIdVpmacsdql , "vpmacsdql" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(97,U) , U ),
+ INST(kX86InstIdVpmacssdd , "vpmacssdd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(8E,U) , U ),
+ INST(kX86InstIdVpmacssdqh , "vpmacssdqh" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(8F,U) , U ),
+ INST(kX86InstIdVpmacssdql , "vpmacssdql" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(87,U) , U ),
+ INST(kX86InstIdVpmacsswd , "vpmacsswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(86,U) , U ),
+ INST(kX86InstIdVpmacssww , "vpmacssww" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(85,U) , U ),
+ INST(kX86InstIdVpmacswd , "vpmacswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(96,U) , U ),
+ INST(kX86InstIdVpmacsww , "vpmacsww" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(95,U) , U ),
+ INST(kX86InstIdVpmadcsswd , "vpmadcsswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(A6,U) , U ),
+ INST(kX86InstIdVpmadcswd , "vpmadcswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(B6,U) , U ),
+ INST(kX86InstIdVpmaddubsw , "vpmaddubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(04,U) , U ),
+ INST(kX86InstIdVpmaddwd , "vpmaddwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F5,U) , U ),
+ INST(kX86InstIdVpmaskmovd , "vpmaskmovd" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(8C,U) , O_660F38(8E,U) ),
+ INST(kX86InstIdVpmaskmovq , "vpmaskmovq" , G(AvxRvmMvr_P) , F(None) |F(W), 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(8C,U) , O_660F38(8E,U) ),
+ INST(kX86InstIdVpmaxsb , "vpmaxsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3C,U) , U ),
+ INST(kX86InstIdVpmaxsd , "vpmaxsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3D,U) , U ),
+ INST(kX86InstIdVpmaxsw , "vpmaxsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EE,U) , U ),
+ INST(kX86InstIdVpmaxub , "vpmaxub" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DE,U) , U ),
+ INST(kX86InstIdVpmaxud , "vpmaxud" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3F,U) , U ),
+ INST(kX86InstIdVpmaxuw , "vpmaxuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3E,U) , U ),
+ INST(kX86InstIdVpminsb , "vpminsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(38,U) , U ),
+ INST(kX86InstIdVpminsd , "vpminsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(39,U) , U ),
+ INST(kX86InstIdVpminsw , "vpminsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EA,U) , U ),
+ INST(kX86InstIdVpminub , "vpminub" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DA,U) , U ),
+ INST(kX86InstIdVpminud , "vpminud" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3B,U) , U ),
+ INST(kX86InstIdVpminuw , "vpminuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3A,U) , U ),
+ INST(kX86InstIdVpmovmskb , "vpmovmskb" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , E(________) , O_660F00(D7,U) , U ),
+ INST(kX86InstIdVpmovsxbd , "vpmovsxbd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(21,U) , U ),
+ INST(kX86InstIdVpmovsxbq , "vpmovsxbq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(22,U) , U ),
+ INST(kX86InstIdVpmovsxbw , "vpmovsxbw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(20,U) , U ),
+ INST(kX86InstIdVpmovsxdq , "vpmovsxdq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(25,U) , U ),
+ INST(kX86InstIdVpmovsxwd , "vpmovsxwd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(23,U) , U ),
+ INST(kX86InstIdVpmovsxwq , "vpmovsxwq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(24,U) , U ),
+ INST(kX86InstIdVpmovzxbd , "vpmovzxbd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(31,U) , U ),
+ INST(kX86InstIdVpmovzxbq , "vpmovzxbq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(32,U) , U ),
+ INST(kX86InstIdVpmovzxbw , "vpmovzxbw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(30,U) , U ),
+ INST(kX86InstIdVpmovzxdq , "vpmovzxdq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(35,U) , U ),
+ INST(kX86InstIdVpmovzxwd , "vpmovzxwd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(33,U) , U ),
+ INST(kX86InstIdVpmovzxwq , "vpmovzxwq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(34,U) , U ),
+ INST(kX86InstIdVpmuldq , "vpmuldq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(28,U) , U ),
+ INST(kX86InstIdVpmulhrsw , "vpmulhrsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(0B,U) , U ),
+ INST(kX86InstIdVpmulhuw , "vpmulhuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E4,U) , U ),
+ INST(kX86InstIdVpmulhw , "vpmulhw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E5,U) , U ),
+ INST(kX86InstIdVpmulld , "vpmulld" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(40,U) , U ),
+ INST(kX86InstIdVpmullw , "vpmullw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D5,U) , U ),
+ INST(kX86InstIdVpmuludq , "vpmuludq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F4,U) , U ),
+ INST(kX86InstIdVpor , "vpor" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EB,U) , U ),
+ INST(kX86InstIdVpperm , "vpperm" , G(XopRvrmRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_00_M08(A3,U) , U ),
+ INST(kX86InstIdVprotb , "vprotb" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(90,U) , O_00_M08(C0,U) ),
+ INST(kX86InstIdVprotd , "vprotd" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(92,U) , O_00_M08(C2,U) ),
+ INST(kX86InstIdVprotq , "vprotq" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(93,U) , O_00_M08(C3,U) ),
+ INST(kX86InstIdVprotw , "vprotw" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(91,U) , O_00_M08(C1,U) ),
+ INST(kX86InstIdVpsadbw , "vpsadbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F6,U) , U ),
+ INST(kX86InstIdVpshab , "vpshab" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(98,U) , U ),
+ INST(kX86InstIdVpshad , "vpshad" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(9A,U) , U ),
+ INST(kX86InstIdVpshaq , "vpshaq" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(9B,U) , U ),
+ INST(kX86InstIdVpshaw , "vpshaw" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(99,U) , U ),
+ INST(kX86InstIdVpshlb , "vpshlb" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(94,U) , U ),
+ INST(kX86InstIdVpshld , "vpshld" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(96,U) , U ),
+ INST(kX86InstIdVpshlq , "vpshlq" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(97,U) , U ),
+ INST(kX86InstIdVpshlw , "vpshlw" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(95,U) , U ),
+ INST(kX86InstIdVpshufb , "vpshufb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(00,U) , U ),
+ INST(kX86InstIdVpshufd , "vpshufd" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F00(70,U) , U ),
+ INST(kX86InstIdVpshufhw , "vpshufhw" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_F30F00(70,U) , U ),
+ INST(kX86InstIdVpshuflw , "vpshuflw" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_F20F00(70,U) , U ),
+ INST(kX86InstIdVpsignb , "vpsignb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(08,U) , U ),
+ INST(kX86InstIdVpsignd , "vpsignd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(0A,U) , U ),
+ INST(kX86InstIdVpsignw , "vpsignw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(09,U) , U ),
+ INST(kX86InstIdVpslld , "vpslld" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(F2,U) , O_660F00(72,6) ),
+ INST(kX86InstIdVpslldq , "vpslldq" , G(AvxVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F00(73,7) , U ),
+ INST(kX86InstIdVpsllq , "vpsllq" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(F3,U) , O_660F00(73,6) ),
+ INST(kX86InstIdVpsllvd , "vpsllvd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(47,U) , U ),
+ INST(kX86InstIdVpsllvq , "vpsllvq" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(47,U) , U ),
+ INST(kX86InstIdVpsllw , "vpsllw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(F1,U) , O_660F00(71,6) ),
+ INST(kX86InstIdVpsrad , "vpsrad" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(E2,U) , O_660F00(72,4) ),
+ INST(kX86InstIdVpsravd , "vpsravd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(46,U) , U ),
+ INST(kX86InstIdVpsraw , "vpsraw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(E1,U) , O_660F00(71,4) ),
+ INST(kX86InstIdVpsrld , "vpsrld" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(D2,U) , O_660F00(72,2) ),
+ INST(kX86InstIdVpsrldq , "vpsrldq" , G(AvxVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F00(73,3) , U ),
+ INST(kX86InstIdVpsrlq , "vpsrlq" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(D3,U) , O_660F00(73,2) ),
+ INST(kX86InstIdVpsrlvd , "vpsrlvd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(45,U) , U ),
+ INST(kX86InstIdVpsrlvq , "vpsrlvq" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(45,U) , U ),
+ INST(kX86InstIdVpsrlw , "vpsrlw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(D1,U) , O_660F00(71,2) ),
+ INST(kX86InstIdVpsubb , "vpsubb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F8,U) , U ),
+ INST(kX86InstIdVpsubd , "vpsubd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FA,U) , U ),
+ INST(kX86InstIdVpsubq , "vpsubq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FB,U) , U ),
+ INST(kX86InstIdVpsubsb , "vpsubsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E8,U) , U ),
+ INST(kX86InstIdVpsubsw , "vpsubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E9,U) , U ),
+ INST(kX86InstIdVpsubusb , "vpsubusb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D8,U) , U ),
+ INST(kX86InstIdVpsubusw , "vpsubusw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D9,U) , U ),
+ INST(kX86InstIdVpsubw , "vpsubw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F9,U) , U ),
+ INST(kX86InstIdVptest , "vptest" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(WWWWWW__) , O_660F38(17,U) , U ),
+ INST(kX86InstIdVpunpckhbw , "vpunpckhbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(68,U) , U ),
+ INST(kX86InstIdVpunpckhdq , "vpunpckhdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6A,U) , U ),
+ INST(kX86InstIdVpunpckhqdq , "vpunpckhqdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6D,U) , U ),
+ INST(kX86InstIdVpunpckhwd , "vpunpckhwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(69,U) , U ),
+ INST(kX86InstIdVpunpcklbw , "vpunpcklbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(60,U) , U ),
+ INST(kX86InstIdVpunpckldq , "vpunpckldq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(62,U) , U ),
+ INST(kX86InstIdVpunpcklqdq , "vpunpcklqdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6C,U) , U ),
+ INST(kX86InstIdVpunpcklwd , "vpunpcklwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(61,U) , U ),
+ INST(kX86InstIdVpxor , "vpxor" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EF,U) , U ),
+ INST(kX86InstIdVrcpps , "vrcpps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(53,U) , U ),
+ INST(kX86InstIdVrcpss , "vrcpss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(53,U) , U ),
+ INST(kX86InstIdVroundpd , "vroundpd" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F3A(09,U) , U ),
+ INST(kX86InstIdVroundps , "vroundps" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F3A(08,U) , U ),
+ INST(kX86InstIdVroundsd , "vroundsd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(0B,U) , U ),
+ INST(kX86InstIdVroundss , "vroundss" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(0A,U) , U ),
+ INST(kX86InstIdVrsqrtps , "vrsqrtps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(52,U) , U ),
+ INST(kX86InstIdVrsqrtss , "vrsqrtss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(52,U) , U ),
+ INST(kX86InstIdVshufpd , "vshufpd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F00(C6,U) , U ),
+ INST(kX86InstIdVshufps , "vshufps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_000F00(C6,U) , U ),
+ INST(kX86InstIdVsqrtpd , "vsqrtpd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(51,U) , U ),
+ INST(kX86InstIdVsqrtps , "vsqrtps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(51,U) , U ),
+ INST(kX86InstIdVsqrtsd , "vsqrtsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(51,U) , U ),
+ INST(kX86InstIdVsqrtss , "vsqrtss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(51,U) , U ),
+ INST(kX86InstIdVstmxcsr , "vstmxcsr" , G(AvxM) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,3) , U ),
+ INST(kX86InstIdVsubpd , "vsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5C,U) , U ),
+ INST(kX86InstIdVsubps , "vsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5C,U) , U ),
+ INST(kX86InstIdVsubsd , "vsubsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(5C,U) , U ),
+ INST(kX86InstIdVsubss , "vsubss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(5C,U) , U ),
+ INST(kX86InstIdVtestpd , "vtestpd" , G(AvxRm_P) , F(Test) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(WWWWWW__) , O_660F38(0F,U) , U ),
+ INST(kX86InstIdVtestps , "vtestps" , G(AvxRm_P) , F(Test) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(WWWWWW__) , O_660F38(0E,U) , U ),
+ INST(kX86InstIdVucomisd , "vucomisd" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F00(2E,U) , U ),
+ INST(kX86InstIdVucomiss , "vucomiss" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_000F00(2E,U) , U ),
+ INST(kX86InstIdVunpckhpd , "vunpckhpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(15,U) , U ),
+ INST(kX86InstIdVunpckhps , "vunpckhps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(15,U) , U ),
+ INST(kX86InstIdVunpcklpd , "vunpcklpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(14,U) , U ),
+ INST(kX86InstIdVunpcklps , "vunpcklps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(14,U) , U ),
+ INST(kX86InstIdVxorpd , "vxorpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(57,U) , U ),
+ INST(kX86InstIdVxorps , "vxorps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(57,U) , U ),
+ INST(kX86InstIdVzeroall , "vzeroall" , G(AvxOp) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(77,U)|L, U ),
+ INST(kX86InstIdVzeroupper , "vzeroupper" , G(AvxOp) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(77,U) , U ),
+ INST(kX86InstIdWrfsbase , "wrfsbase" , G(X86Rm) , F(None) , 0 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,2) , U ),
+ INST(kX86InstIdWrgsbase , "wrgsbase" , G(X86Rm) , F(None) , 0 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,3) , U ),
+ INST(kX86InstIdXadd , "xadd" , G(X86Xadd) , F(Xchg)|F(Lock) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , E(WWWWWW__) , O_000F00(C0,U) , U ),
+ INST(kX86InstIdXchg , "xchg" , G(X86Xchg) , F(Xchg)|F(Lock) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , E(________) , O_000000(86,U) , U ),
+ INST(kX86InstIdXor , "xor" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWUWW__) , O_000000(30,6) , U ),
+ INST(kX86InstIdXorpd , "xorpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(57,U) , U ),
+ INST(kX86InstIdXorps , "xorps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(57,U) , U )
+};
+
+#undef INST
+
+#undef O_00_X
+#undef O_9B_X
+
+#undef O_66_M09
+#undef O_66_M08
+#undef O_66_M03
+
+#undef O_00_M09
+#undef O_00_M08
+#undef O_00_M03
+
+#undef O_F30F3A
+#undef O_F30F38
+#undef O_F30F00
+#undef O_F30000
+#undef O_F20F3A
+#undef O_F20F38
+#undef O_F20F00
+#undef O_F20000
+#undef O_9B0000
+#undef O_660F3A
+#undef O_660F38
+#undef O_660F00
+#undef O_660000
+#undef O_000F3A
+#undef O_000F38
+#undef O_000F0F
+#undef O_000F01
+#undef O_000F00
+#undef O_000000
+
+#undef L
+#undef U
+
+#undef E
+#undef O
+#undef F
+#undef G
+
+// ============================================================================
+// [asmjit::X86Cond]
+// ============================================================================
+
+#define CC_TO_INST(_Inst_) { \
+ _Inst_##o, \
+ _Inst_##no, \
+ _Inst_##b, \
+ _Inst_##ae, \
+ _Inst_##e, \
+ _Inst_##ne, \
+ _Inst_##be, \
+ _Inst_##a, \
+ _Inst_##s, \
+ _Inst_##ns, \
+ _Inst_##pe, \
+ _Inst_##po, \
+ _Inst_##l, \
+ _Inst_##ge, \
+ _Inst_##le, \
+ _Inst_##g, \
+ \
+ kInstIdNone, \
+ kInstIdNone, \
+ kInstIdNone, \
+ kInstIdNone \
+}
+
+const uint32_t _x86ReverseCond[20] = {
+ /* kX86CondO -> */ kX86CondO,
+ /* kX86CondNO -> */ kX86CondNO,
+ /* kX86CondB -> */ kX86CondA,
+ /* kX86CondAE -> */ kX86CondBE,
+ /* kX86CondE -> */ kX86CondE,
+ /* kX86CondNE -> */ kX86CondNE,
+ /* kX86CondBE -> */ kX86CondAE,
+ /* kX86CondA -> */ kX86CondB,
+ /* kX86CondS -> */ kX86CondS,
+ /* kX86CondNS -> */ kX86CondNS,
+ /* kX86CondPE -> */ kX86CondPE,
+ /* kX86CondPO -> */ kX86CondPO,
+ /* kX86CondL -> */ kX86CondG,
+ /* kX86CondGE -> */ kX86CondLE,
+ /* kX86CondLE -> */ kX86CondGE,
+ /* kX86CondG -> */ kX86CondL,
+
+ /* kX86CondFpuUnordered -> */ kX86CondFpuUnordered,
+ /* kX86CondFpuNotUnordered -> */ kX86CondFpuNotUnordered,
+
+ 0x12,
+ 0x13
+};
+
+const uint32_t _x86CondToCmovcc[20] = CC_TO_INST(kX86InstIdCmov);
+const uint32_t _x86CondToJcc [20] = CC_TO_INST(kX86InstIdJ );
+const uint32_t _x86CondToSetcc [20] = CC_TO_INST(kX86InstIdSet );
+
+#undef CC_TO_INST
+
+// ============================================================================
+// [asmjit::X86Util]
+// ============================================================================
+
+#ifndef ASMJIT_DISABLE_NAMES
+// Compare two instruction names.
+//
+// `a` is null terminated instruction name from `_x86InstName[]` table.
+// `b` is non-null terminated instruction name passed to `getInstIdByName()`.
+static ASMJIT_INLINE int X86Util_cmpInstName(const char* a, const char* b, size_t len) {
+ for (size_t i = 0; i < len; i++) {
+ int c = static_cast<int>(static_cast<uint8_t>(a[i])) -
+ static_cast<int>(static_cast<uint8_t>(b[i])) ;
+ if (c != 0)
+ return c;
+ }
+
+ return static_cast<int>(a[len]);
+}
+
+uint32_t X86Util::getInstIdByName(const char* name, size_t len) {
+ if (!name)
+ return kInstIdNone;
+
+ if (len == kInvalidIndex)
+ len = ::strlen(name);
+
+ if (len == 0)
+ return kInstIdNone;
+
+ uint32_t prefix = name[0] - kX86InstAlphaIndexFirst;
+ if (prefix > kX86InstAlphaIndexLast - kX86InstAlphaIndexFirst)
+ return kInstIdNone;
+
+ uint32_t index = _x86InstAlphaIndex[prefix];
+ if (index == kX86InstAlphaIndexInvalid)
+ return kInstIdNone;
+
+ const X86InstInfo* base = _x86InstInfo + index;
+ const X86InstInfo* end = _x86InstInfo + _kX86InstIdCount;
+
+ // Handle instructions starting with 'j' specially. `jcc` instruction breaks
+ // the sorting, because of the suffixes (it's considered as one instruction),
+ // so basically `jecxz` and `jmp` are stored after all `jcc` instructions.
+ bool linearSearch = prefix == ('j' - kX86InstAlphaIndexFirst);
+
+ while (++prefix <= kX86InstAlphaIndexLast - kX86InstAlphaIndexFirst) {
+ index = _x86InstAlphaIndex[prefix];
+ if (index == kX86InstAlphaIndexInvalid)
+ continue;
+ end = _x86InstInfo + index;
+ break;
+ }
+
+ if (linearSearch) {
+ while (base != end) {
+ if (X86Util_cmpInstName(base->getInstName(), name, len) == 0)
+ return static_cast<uint32_t>(static_cast<size_t>(base - _x86InstInfo));
+ base++;
+ }
+ }
+ else {
+ for (size_t lim = static_cast<size_t>(end - base); lim != 0; lim >>= 1) {
+ const X86InstInfo* cur = base + (lim >> 1);
+ int result = X86Util_cmpInstName(cur->getInstName(), name, len);
+
+ if (result < 0) {
+ base = cur + 1;
+ lim--;
+ continue;
+ }
+
+ if (result > 0)
+ continue;
+
+ return static_cast<uint32_t>(static_cast<size_t>(cur - _x86InstInfo));
+ }
+ }
+
+ return kInstIdNone;
+}
+#endif // ASMJIT_DISABLE_NAMES
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86inst.h
@@ -1,1 +1,2207 @@
-
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#pragma once
+
+// [Dependencies - AsmJit]
+#include "../base/assembler.h"
+#include "../base/compiler.h"
+#include "../base/globals.h"
+#include "../base/intutil.h"
+#include "../base/operand.h"
+#include "../base/vectypes.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [Forward Declarations]
+// ============================================================================
+
+struct X86InstInfo;
+struct X86InstExtendedInfo;
+
+//! \addtogroup asmjit_x86_inst
+//! \{
+
+// ============================================================================
+// [asmjit::X86Inst/X86Cond - Globals]
+// ============================================================================
+
+#ifndef ASMJIT_DISABLE_NAMES
+//! \internal
+//!
+//! X86/X64 instructions' names, accessible through `X86InstInfo`.
+ASMJIT_VAR const char _x86InstName[];
+#endif // !ASMJIT_DISABLE_NAMES
+
+//! \internal
+//!
+//! X86/X64 instructions' extended information, accessible through `X86InstInfo`.
+ASMJIT_VAR const X86InstExtendedInfo _x86InstExtendedInfo[];
+
+//! \internal
+//!
+//! X86/X64 instructions' information.
+ASMJIT_VAR const X86InstInfo _x86InstInfo[];
+
+//! \internal
+//!
+//! X86/X64 condition codes to reversed condition codes map.
+ASMJIT_VAR const uint32_t _x86ReverseCond[20];
+
+//! \internal
+//!
+//! X86/X64 condition codes to "cmovcc" group map.
+ASMJIT_VAR const uint32_t _x86CondToCmovcc[20];
+
+//! \internal
+//!
+//! X86/X64 condition codes to "jcc" group map.
+ASMJIT_VAR const uint32_t _x86CondToJcc[20];
+
+//! \internal
+//!
+//! X86/X64 condition codes to "setcc" group map.
+ASMJIT_VAR const uint32_t _x86CondToSetcc[20];
+
+// ============================================================================
+// [asmjit::kX86InstId]
+// ============================================================================
+
+//! X86/X64 instruction codes.
+//!
+//! Note that these instruction codes are AsmJit specific. Each instruction has
+//! a unique ID that is used as an index to AsmJit instruction table.
+ASMJIT_ENUM(kX86InstId) {
+ kX86InstIdAdc = 1, // X86/X64
+ kX86InstIdAdd, // X86/X64
+ kX86InstIdAddpd, // SSE2
+ kX86InstIdAddps, // SSE
+ kX86InstIdAddsd, // SSE2
+ kX86InstIdAddss, // SSE
+ kX86InstIdAddsubpd, // SSE3
+ kX86InstIdAddsubps, // SSE3
+ kX86InstIdAesdec, // AESNI
+ kX86InstIdAesdeclast, // AESNI
+ kX86InstIdAesenc, // AESNI
+ kX86InstIdAesenclast, // AESNI
+ kX86InstIdAesimc, // AESNI
+ kX86InstIdAeskeygenassist, // AESNI
+ kX86InstIdAnd, // X86/X64
+ kX86InstIdAndn, // BMI
+ kX86InstIdAndnpd, // SSE2
+ kX86InstIdAndnps, // SSE
+ kX86InstIdAndpd, // SSE2
+ kX86InstIdAndps, // SSE
+ kX86InstIdBextr, // BMI
+ kX86InstIdBlendpd, // SSE4.1
+ kX86InstIdBlendps, // SSE4.1
+ kX86InstIdBlendvpd, // SSE4.1
+ kX86InstIdBlendvps, // SSE4.1
+ kX86InstIdBlsi, // BMI
+ kX86InstIdBlsmsk, // BMI
+ kX86InstIdBlsr, // BMI
+ kX86InstIdBsf, // X86/X64
+ kX86InstIdBsr, // X86/X64
+ kX86InstIdBswap, // X86/X64 (i486)
+ kX86InstIdBt, // X86/X64
+ kX86InstIdBtc, // X86/X64
+ kX86InstIdBtr, // X86/X64
+ kX86InstIdBts, // X86/X64
+ kX86InstIdBzhi, // BMI2
+ kX86InstIdCall, // X86/X64
+ kX86InstIdCbw, // X86/X64
+ kX86InstIdCdq, // X86/X64
+ kX86InstIdCdqe, // X64 only
+ kX86InstIdClc, // X86/X64
+ kX86InstIdCld, // X86/X64
+ kX86InstIdClflush, // SSE2
+ kX86InstIdCmc, // X86/X64
+ kX86InstIdCmova, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovae, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovb, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovbe, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovc, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmove, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovg, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovge, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovl, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovle, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovna, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovnae, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovnb, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovnbe, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovnc, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovne, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovng, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovnge, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovnl, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovnle, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovno, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovnp, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovns, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovnz, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovo, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovp, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovpe, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovpo, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovs, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmovz, // X86/X64 (cmovcc) (i586)
+ kX86InstIdCmp, // X86/X64
+ kX86InstIdCmppd, // SSE2
+ kX86InstIdCmpps, // SSE
+ kX86InstIdCmpsB, // CMPS - X86/X64
+ kX86InstIdCmpsD, // CMPS - X86/X64
+ kX86InstIdCmpsQ, // CMPS - X64
+ kX86InstIdCmpsW, // CMPS - X86/X64
+ kX86InstIdCmpsd, // SSE2
+ kX86InstIdCmpss, // SSE
+ kX86InstIdCmpxchg, // X86/X64 (i486)
+ kX86InstIdCmpxchg16b, // X64 only
+ kX86InstIdCmpxchg8b, // X86/X64 (i586)
+ kX86InstIdComisd, // SSE2
+ kX86InstIdComiss, // SSE
+ kX86InstIdCpuid, // X86/X64 (i486)
+ kX86InstIdCqo, // X64 only
+ kX86InstIdCrc32, // SSE4.2
+ kX86InstIdCvtdq2pd, // SSE2
+ kX86InstIdCvtdq2ps, // SSE2
+ kX86InstIdCvtpd2dq, // SSE2
+ kX86InstIdCvtpd2pi, // SSE2
+ kX86InstIdCvtpd2ps, // SSE2
+ kX86InstIdCvtpi2pd, // SSE2
+ kX86InstIdCvtpi2ps, // SSE
+ kX86InstIdCvtps2dq, // SSE2
+ kX86InstIdCvtps2pd, // SSE2
+ kX86InstIdCvtps2pi, // SSE
+ kX86InstIdCvtsd2si, // SSE2
+ kX86InstIdCvtsd2ss, // SSE2
+ kX86InstIdCvtsi2sd, // SSE2
+ kX86InstIdCvtsi2ss, // SSE
+ kX86InstIdCvtss2sd, // SSE2
+ kX86InstIdCvtss2si, // SSE
+ kX86InstIdCvttpd2dq, // SSE2
+ kX86InstIdCvttpd2pi, // SSE2
+ kX86InstIdCvttps2dq, // SSE2
+ kX86InstIdCvttps2pi, // SSE
+ kX86InstIdCvttsd2si, // SSE2
+ kX86InstIdCvttss2si, // SSE
+ kX86InstIdCwd, // X86/X64
+ kX86InstIdCwde, // X86/X64
+ kX86InstIdDaa, // X86 only
+ kX86InstIdDas, // X86 only
+ kX86InstIdDec, // X86/X64
+ kX86InstIdDiv, // X86/X64
+ kX86InstIdDivpd, // SSE2
+ kX86InstIdDivps, // SSE
+ kX86InstIdDivsd, // SSE2
+ kX86InstIdDivss, // SSE
+ kX86InstIdDppd, // SSE4.1
+ kX86InstIdDpps, // SSE4.1
+ kX86InstIdEmms, // MMX
+ kX86InstIdEnter, // X86/X64
+ kX86InstIdExtractps, // SSE4.1
+ kX86InstIdF2xm1, // FPU
+ kX86InstIdFabs, // FPU
+ kX86InstIdFadd, // FPU
+ kX86InstIdFaddp, // FPU
+ kX86InstIdFbld, // FPU
+ kX86InstIdFbstp, // FPU
+ kX86InstIdFchs, // FPU
+ kX86InstIdFclex, // FPU
+ kX86InstIdFcmovb, // FPU
+ kX86InstIdFcmovbe, // FPU
+ kX86InstIdFcmove, // FPU
+ kX86InstIdFcmovnb, // FPU
+ kX86InstIdFcmovnbe, // FPU
+ kX86InstIdFcmovne, // FPU
+ kX86InstIdFcmovnu, // FPU
+ kX86InstIdFcmovu, // FPU
+ kX86InstIdFcom, // FPU
+ kX86InstIdFcomi, // FPU
+ kX86InstIdFcomip, // FPU
+ kX86InstIdFcomp, // FPU
+ kX86InstIdFcompp, // FPU
+ kX86InstIdFcos, // FPU
+ kX86InstIdFdecstp, // FPU
+ kX86InstIdFdiv, // FPU
+ kX86InstIdFdivp, // FPU
+ kX86InstIdFdivr, // FPU
+ kX86InstIdFdivrp, // FPU
+ kX86InstIdFemms, // 3dNow!
+ kX86InstIdFfree, // FPU
+ kX86InstIdFiadd, // FPU
+ kX86InstIdFicom, // FPU
+ kX86InstIdFicomp, // FPU
+ kX86InstIdFidiv, // FPU
+ kX86InstIdFidivr, // FPU
+ kX86InstIdFild, // FPU
+ kX86InstIdFimul, // FPU
+ kX86InstIdFincstp, // FPU
+ kX86InstIdFinit, // FPU
+ kX86InstIdFist, // FPU
+ kX86InstIdFistp, // FPU
+ kX86InstIdFisttp, // SSE3
+ kX86InstIdFisub, // FPU
+ kX86InstIdFisubr, // FPU
+ kX86InstIdFld, // FPU
+ kX86InstIdFld1, // FPU
+ kX86InstIdFldcw, // FPU
+ kX86InstIdFldenv, // FPU
+ kX86InstIdFldl2e, // FPU
+ kX86InstIdFldl2t, // FPU
+ kX86InstIdFldlg2, // FPU
+ kX86InstIdFldln2, // FPU
+ kX86InstIdFldpi, // FPU
+ kX86InstIdFldz, // FPU
+ kX86InstIdFmul, // FPU
+ kX86InstIdFmulp, // FPU
+ kX86InstIdFnclex, // FPU
+ kX86InstIdFninit, // FPU
+ kX86InstIdFnop, // FPU
+ kX86InstIdFnsave, // FPU
+ kX86InstIdFnstcw, // FPU
+ kX86InstIdFnstenv, // FPU
+ kX86InstIdFnstsw, // FPU
+ kX86InstIdFpatan, // FPU
+ kX86InstIdFprem, // FPU
+ kX86InstIdFprem1, // FPU
+ kX86InstIdFptan, // FPU
+ kX86InstIdFrndint, // FPU
+ kX86InstIdFrstor, // FPU
+ kX86InstIdFsave, // FPU
+ kX86InstIdFscale, // FPU
+ kX86InstIdFsin, // FPU
+ kX86InstIdFsincos, // FPU
+ kX86InstIdFsqrt, // FPU
+ kX86InstIdFst, // FPU
+ kX86InstIdFstcw, // FPU
+ kX86InstIdFstenv, // FPU
+ kX86InstIdFstp, // FPU
+ kX86InstIdFstsw, // FPU
+ kX86InstIdFsub, // FPU
+ kX86InstIdFsubp, // FPU
+ kX86InstIdFsubr, // FPU
+ kX86InstIdFsubrp, // FPU
+ kX86InstIdFtst, // FPU
+ kX86InstIdFucom, // FPU
+ kX86InstIdFucomi, // FPU
+ kX86InstIdFucomip, // FPU
+ kX86InstIdFucomp, // FPU
+ kX86InstIdFucompp, // FPU
+ kX86InstIdFwait, // FPU
+ kX86InstIdFxam, // FPU
+ kX86InstIdFxch, // FPU
+ kX86InstIdFxrstor, // FPU
+ kX86InstIdFxsave, // FPU
+ kX86InstIdFxtract, // FPU
+ kX86InstIdFyl2x, // FPU
+ kX86InstIdFyl2xp1, // FPU
+ kX86InstIdHaddpd, // SSE3
+ kX86InstIdHaddps, // SSE3
+ kX86InstIdHsubpd, // SSE3
+ kX86InstIdHsubps, // SSE3
+ kX86InstIdIdiv, // X86/X64
+ kX86InstIdImul, // X86/X64
+ kX86InstIdInc, // X86/X64
+ kX86InstIdInsertps, // SSE4.1
+ kX86InstIdInt, // X86/X64
+ kX86InstIdJa, // X86/X64 (jcc)
+ kX86InstIdJae, // X86/X64 (jcc)
+ kX86InstIdJb, // X86/X64 (jcc)
+ kX86InstIdJbe, // X86/X64 (jcc)
+ kX86InstIdJc, // X86/X64 (jcc)
+ kX86InstIdJe, // X86/X64 (jcc)
+ kX86InstIdJg, // X86/X64 (jcc)
+ kX86InstIdJge, // X86/X64 (jcc)
+ kX86InstIdJl, // X86/X64 (jcc)
+ kX86InstIdJle, // X86/X64 (jcc)
+ kX86InstIdJna, // X86/X64 (jcc)
+ kX86InstIdJnae, // X86/X64 (jcc)
+ kX86InstIdJnb, // X86/X64 (jcc)
+ kX86InstIdJnbe, // X86/X64 (jcc)
+ kX86InstIdJnc, // X86/X64 (jcc)
+ kX86InstIdJne, // X86/X64 (jcc)
+ kX86InstIdJng, // X86/X64 (jcc)
+ kX86InstIdJnge, // X86/X64 (jcc)
+ kX86InstIdJnl, // X86/X64 (jcc)
+ kX86InstIdJnle, // X86/X64 (jcc)
+ kX86InstIdJno, // X86/X64 (jcc)
+ kX86InstIdJnp, // X86/X64 (jcc)
+ kX86InstIdJns, // X86/X64 (jcc)
+ kX86InstIdJnz, // X86/X64 (jcc)
+ kX86InstIdJo, // X86/X64 (jcc)
+ kX86InstIdJp, // X86/X64 (jcc)
+ kX86InstIdJpe, // X86/X64 (jcc)
+ kX86InstIdJpo, // X86/X64 (jcc)
+ kX86InstIdJs, // X86/X64 (jcc)
+ kX86InstIdJz, // X86/X64 (jcc)
+ kX86InstIdJecxz, // X86/X64 (jcxz/jecxz/jrcxz)
+ kX86InstIdJmp, // X86/X64 (jmp)
+ kX86InstIdLahf, // X86/X64 (CPUID NEEDED)
+ kX86InstIdLddqu, // SSE3
+ kX86InstIdLdmxcsr, // SSE
+ kX86InstIdLea, // X86/X64
+ kX86InstIdLeave, // X86/X64
+ kX86InstIdLfence, // SSE2
+ kX86InstIdLodsB, // LODS - X86/X64
+ kX86InstIdLodsD, // LODS - X86/X64
+ kX86InstIdLodsQ, // LODS - X86/X64
+ kX86InstIdLodsW, // LODS - X86/X64
+ kX86InstIdLzcnt, // LZCNT
+ kX86InstIdMaskmovdqu, // SSE2
+ kX86InstIdMaskmovq, // MMX-Ext
+ kX86InstIdMaxpd, // SSE2
+ kX86InstIdMaxps, // SSE
+ kX86InstIdMaxsd, // SSE2
+ kX86InstIdMaxss, // SSE
+ kX86InstIdMfence, // SSE2
+ kX86InstIdMinpd, // SSE2
+ kX86InstIdMinps, // SSE
+ kX86InstIdMinsd, // SSE2
+ kX86InstIdMinss, // SSE
+ kX86InstIdMonitor, // SSE3
+ kX86InstIdMov, // X86/X64
+ kX86InstIdMovPtr, // X86/X64
+ kX86InstIdMovapd, // SSE2
+ kX86InstIdMovaps, // SSE
+ kX86InstIdMovbe, // SSE3 - Intel-Atom
+ kX86InstIdMovd, // MMX/SSE2
+ kX86InstIdMovddup, // SSE3
+ kX86InstIdMovdq2q, // SSE2
+ kX86InstIdMovdqa, // SSE2
+ kX86InstIdMovdqu, // SSE2
+ kX86InstIdMovhlps, // SSE
+ kX86InstIdMovhpd, // SSE2
+ kX86InstIdMovhps, // SSE
+ kX86InstIdMovlhps, // SSE
+ kX86InstIdMovlpd, // SSE2
+ kX86InstIdMovlps, // SSE
+ kX86InstIdMovmskpd, // SSE2
+ kX86InstIdMovmskps, // SSE2
+ kX86InstIdMovntdq, // SSE2
+ kX86InstIdMovntdqa, // SSE4.1
+ kX86InstIdMovnti, // SSE2
+ kX86InstIdMovntpd, // SSE2
+ kX86InstIdMovntps, // SSE
+ kX86InstIdMovntq, // MMX-Ext
+ kX86InstIdMovq, // MMX/SSE/SSE2
+ kX86InstIdMovq2dq, // SSE2
+ kX86InstIdMovsB, // MOVS - X86/X64
+ kX86InstIdMovsD, // MOVS - X86/X64
+ kX86InstIdMovsQ, // MOVS - X64
+ kX86InstIdMovsW, // MOVS - X86/X64
+ kX86InstIdMovsd, // SSE2
+ kX86InstIdMovshdup, // SSE3
+ kX86InstIdMovsldup, // SSE3
+ kX86InstIdMovss, // SSE
+ kX86InstIdMovsx, // X86/X64
+ kX86InstIdMovsxd, // X86/X64
+ kX86InstIdMovupd, // SSE2
+ kX86InstIdMovups, // SSE
+ kX86InstIdMovzx, // X86/X64
+ kX86InstIdMpsadbw, // SSE4.1
+ kX86InstIdMul, // X86/X64
+ kX86InstIdMulpd, // SSE2
+ kX86InstIdMulps, // SSE
+ kX86InstIdMulsd, // SSE2
+ kX86InstIdMulss, // SSE
+ kX86InstIdMulx, // BMI2
+ kX86InstIdMwait, // SSE3
+ kX86InstIdNeg, // X86/X64
+ kX86InstIdNop, // X86/X64
+ kX86InstIdNot, // X86/X64
+ kX86InstIdOr, // X86/X64
+ kX86InstIdOrpd, // SSE2
+ kX86InstIdOrps, // SSE
+ kX86InstIdPabsb, // SSSE3
+ kX86InstIdPabsd, // SSSE3
+ kX86InstIdPabsw, // SSSE3
+ kX86InstIdPackssdw, // MMX/SSE2
+ kX86InstIdPacksswb, // MMX/SSE2
+ kX86InstIdPackusdw, // SSE4.1
+ kX86InstIdPackuswb, // MMX/SSE2
+ kX86InstIdPaddb, // MMX/SSE2
+ kX86InstIdPaddd, // MMX/SSE2
+ kX86InstIdPaddq, // SSE2
+ kX86InstIdPaddsb, // MMX/SSE2
+ kX86InstIdPaddsw, // MMX/SSE2
+ kX86InstIdPaddusb, // MMX/SSE2
+ kX86InstIdPaddusw, // MMX/SSE2
+ kX86InstIdPaddw, // MMX/SSE2
+ kX86InstIdPalignr, // SSSE3
+ kX86InstIdPand, // MMX/SSE2
+ kX86InstIdPandn, // MMX/SSE2
+ kX86InstIdPause, // SSE2.
+ kX86InstIdPavgb, // MMX-Ext
+ kX86InstIdPavgw, // MMX-Ext
+ kX86InstIdPblendvb, // SSE4.1
+ kX86InstIdPblendw, // SSE4.1
+ kX86InstIdPclmulqdq, // PCLMULQDQ
+ kX86InstIdPcmpeqb, // MMX/SSE2
+ kX86InstIdPcmpeqd, // MMX/SSE2
+ kX86InstIdPcmpeqq, // SSE4.1
+ kX86InstIdPcmpeqw, // MMX/SSE2
+ kX86InstIdPcmpestri, // SSE4.2
+ kX86InstIdPcmpestrm, // SSE4.2
+ kX86InstIdPcmpgtb, // MMX/SSE2
+ kX86InstIdPcmpgtd, // MMX/SSE2
+ kX86InstIdPcmpgtq, // SSE4.2
+ kX86InstIdPcmpgtw, // MMX/SSE2
+ kX86InstIdPcmpistri, // SSE4.2
+ kX86InstIdPcmpistrm, // SSE4.2
+ kX86InstIdPdep, // BMI2
+ kX86InstIdPext, // BMI2
+ kX86InstIdPextrb, // SSE4.1
+ kX86InstIdPextrd, // SSE4.1
+ kX86InstIdPextrq, // SSE4.1
+ kX86InstIdPextrw, // MMX-Ext/SSE2
+ kX86InstIdPf2id, // 3dNow!
+ kX86InstIdPf2iw, // Enhanced 3dNow!
+ kX86InstIdPfacc, // 3dNow!
+ kX86InstIdPfadd, // 3dNow!
+ kX86InstIdPfcmpeq, // 3dNow!
+ kX86InstIdPfcmpge, // 3dNow!
+ kX86InstIdPfcmpgt, // 3dNow!
+ kX86InstIdPfmax, // 3dNow!
+ kX86InstIdPfmin, // 3dNow!
+ kX86InstIdPfmul, // 3dNow!
+ kX86InstIdPfnacc, // Enhanced 3dNow!
+ kX86InstIdPfpnacc, // Enhanced 3dNow!
+ kX86InstIdPfrcp, // 3dNow!
+ kX86InstIdPfrcpit1, // 3dNow!
+ kX86InstIdPfrcpit2, // 3dNow!
+ kX86InstIdPfrsqit1, // 3dNow!
+ kX86InstIdPfrsqrt, // 3dNow!
+ kX86InstIdPfsub, // 3dNow!
+ kX86InstIdPfsubr, // 3dNow!
+ kX86InstIdPhaddd, // SSSE3
+ kX86InstIdPhaddsw, // SSSE3
+ kX86InstIdPhaddw, // SSSE3
+ kX86InstIdPhminposuw, // SSE4.1
+ kX86InstIdPhsubd, // SSSE3
+ kX86InstIdPhsubsw, // SSSE3
+ kX86InstIdPhsubw, // SSSE3
+ kX86InstIdPi2fd, // 3dNow!
+ kX86InstIdPi2fw, // Enhanced 3dNow!
+ kX86InstIdPinsrb, // SSE4.1
+ kX86InstIdPinsrd, // SSE4.1
+ kX86InstIdPinsrq, // SSE4.1
+ kX86InstIdPinsrw, // MMX-Ext
+ kX86InstIdPmaddubsw, // SSSE3
+ kX86InstIdPmaddwd, // MMX/SSE2
+ kX86InstIdPmaxsb, // SSE4.1
+ kX86InstIdPmaxsd, // SSE4.1
+ kX86InstIdPmaxsw, // MMX-Ext
+ kX86InstIdPmaxub, // MMX-Ext
+ kX86InstIdPmaxud, // SSE4.1
+ kX86InstIdPmaxuw, // SSE4.1
+ kX86InstIdPminsb, // SSE4.1
+ kX86InstIdPminsd, // SSE4.1
+ kX86InstIdPminsw, // MMX-Ext
+ kX86InstIdPminub, // MMX-Ext
+ kX86InstIdPminud, // SSE4.1
+ kX86InstIdPminuw, // SSE4.1
+ kX86InstIdPmovmskb, // MMX-Ext
+ kX86InstIdPmovsxbd, // SSE4.1
+ kX86InstIdPmovsxbq, // SSE4.1
+ kX86InstIdPmovsxbw, // SSE4.1
+ kX86InstIdPmovsxdq, // SSE4.1
+ kX86InstIdPmovsxwd, // SSE4.1
+ kX86InstIdPmovsxwq, // SSE4.1
+ kX86InstIdPmovzxbd, // SSE4.1
+ kX86InstIdPmovzxbq, // SSE4.1
+ kX86InstIdPmovzxbw, // SSE4.1
+ kX86InstIdPmovzxdq, // SSE4.1
+ kX86InstIdPmovzxwd, // SSE4.1
+ kX86InstIdPmovzxwq, // SSE4.1
+ kX86InstIdPmuldq, // SSE4.1
+ kX86InstIdPmulhrsw, // SSSE3
+ kX86InstIdPmulhuw, // MMX-Ext
+ kX86InstIdPmulhw, // MMX/SSE2
+ kX86InstIdPmulld, // SSE4.1
+ kX86InstIdPmullw, // MMX/SSE2
+ kX86InstIdPmuludq, // SSE2
+ kX86InstIdPop, // X86/X64
+ kX86InstIdPopa, // X86 only
+ kX86InstIdPopcnt, // SSE4.2
+ kX86InstIdPopf, // X86/X64
+ kX86InstIdPor, // MMX/SSE2
+ kX86InstIdPrefetch, // MMX-Ext/SSE
+ kX86InstIdPrefetch3dNow, // 3dNow!
+ kX86InstIdPrefetchw3dNow, // 3dNow!
+ kX86InstIdPsadbw, // MMX-Ext
+ kX86InstIdPshufb, // SSSE3
+ kX86InstIdPshufd, // SSE2
+ kX86InstIdPshufhw, // SSE2
+ kX86InstIdPshuflw, // SSE2
+ kX86InstIdPshufw, // MMX-Ext
+ kX86InstIdPsignb, // SSSE3
+ kX86InstIdPsignd, // SSSE3
+ kX86InstIdPsignw, // SSSE3
+ kX86InstIdPslld, // MMX/SSE2
+ kX86InstIdPslldq, // SSE2
+ kX86InstIdPsllq, // MMX/SSE2
+ kX86InstIdPsllw, // MMX/SSE2
+ kX86InstIdPsrad, // MMX/SSE2
+ kX86InstIdPsraw, // MMX/SSE2
+ kX86InstIdPsrld, // MMX/SSE2
+ kX86InstIdPsrldq, // SSE2
+ kX86InstIdPsrlq, // MMX/SSE2
+ kX86InstIdPsrlw, // MMX/SSE2
+ kX86InstIdPsubb, // MMX/SSE2
+ kX86InstIdPsubd, // MMX/SSE2
+ kX86InstIdPsubq, // SSE2
+ kX86InstIdPsubsb, // MMX/SSE2
+ kX86InstIdPsubsw, // MMX/SSE2
+ kX86InstIdPsubusb, // MMX/SSE2
+ kX86InstIdPsubusw, // MMX/SSE2
+ kX86InstIdPsubw, // MMX/SSE2
+ kX86InstIdPswapd, // Enhanced 3dNow!
+ kX86InstIdPtest, // SSE4.1
+ kX86InstIdPunpckhbw, // MMX/SSE2
+ kX86InstIdPunpckhdq, // MMX/SSE2
+ kX86InstIdPunpckhqdq, // SSE2
+ kX86InstIdPunpckhwd, // MMX/SSE2
+ kX86InstIdPunpcklbw, // MMX/SSE2
+ kX86InstIdPunpckldq, // MMX/SSE2
+ kX86InstIdPunpcklqdq, // SSE2
+ kX86InstIdPunpcklwd, // MMX/SSE2
+ kX86InstIdPush, // X86/X64
+ kX86InstIdPusha, // X86 only
+ kX86InstIdPushf, // X86/X64
+ kX86InstIdPxor, // MMX/SSE2
+ kX86InstIdRcl, // X86/X64
+ kX86InstIdRcpps, // SSE
+ kX86InstIdRcpss, // SSE
+ kX86InstIdRcr, // X86/X64
+ kX86InstIdRdfsbase, // FSGSBASE (x64)
+ kX86InstIdRdgsbase, // FSGSBASE (x64)
+ kX86InstIdRdrand, // RDRAND
+ kX86InstIdRdtsc, // X86/X64
+ kX86InstIdRdtscp, // X86/X64
+ kX86InstIdRepLodsB, // X86/X64 (REP)
+ kX86InstIdRepLodsD, // X86/X64 (REP)
+ kX86InstIdRepLodsQ, // X64 only (REP)
+ kX86InstIdRepLodsW, // X86/X64 (REP)
+ kX86InstIdRepMovsB, // X86/X64 (REP)
+ kX86InstIdRepMovsD, // X86/X64 (REP)
+ kX86InstIdRepMovsQ, // X64 only (REP)
+ kX86InstIdRepMovsW, // X86/X64 (REP)
+ kX86InstIdRepStosB, // X86/X64 (REP)
+ kX86InstIdRepStosD, // X86/X64 (REP)
+ kX86InstIdRepStosQ, // X64 only (REP)
+ kX86InstIdRepStosW, // X86/X64 (REP)
+ kX86InstIdRepeCmpsB, // X86/X64 (REP)
+ kX86InstIdRepeCmpsD, // X86/X64 (REP)
+ kX86InstIdRepeCmpsQ, // X64 only (REP)
+ kX86InstIdRepeCmpsW, // X86/X64 (REP)
+ kX86InstIdRepeScasB, // X86/X64 (REP)
+ kX86InstIdRepeScasD, // X86/X64 (REP)
+ kX86InstIdRepeScasQ, // X64 only (REP)
+ kX86InstIdRepeScasW, // X86/X64 (REP)
+ kX86InstIdRepneCmpsB, // X86/X64 (REP)
+ kX86InstIdRepneCmpsD, // X86/X64 (REP)
+ kX86InstIdRepneCmpsQ, // X64 only (REP)
+ kX86InstIdRepneCmpsW, // X86/X64 (REP)
+ kX86InstIdRepneScasB, // X86/X64 (REP)
+ kX86InstIdRepneScasD, // X86/X64 (REP)
+ kX86InstIdRepneScasQ, // X64 only (REP)
+ kX86InstIdRepneScasW, // X86/X64 (REP)
+ kX86InstIdRet, // X86/X64
+ kX86InstIdRol, // X86/X64
+ kX86InstIdRor, // X86/X64
+ kX86InstIdRorx, // BMI2
+ kX86InstIdRoundpd, // SSE4.1
+ kX86InstIdRoundps, // SSE4.1
+ kX86InstIdRoundsd, // SSE4.1
+ kX86InstIdRoundss, // SSE4.1
+ kX86InstIdRsqrtps, // SSE
+ kX86InstIdRsqrtss, // SSE
+ kX86InstIdSahf, // X86/X64 (CPUID NEEDED)
+ kX86InstIdSal, // X86/X64
+ kX86InstIdSar, // X86/X64
+ kX86InstIdSarx, // BMI2
+ kX86InstIdSbb, // X86/X64
+ kX86InstIdScasB, // SCAS - X86/X64
+ kX86InstIdScasD, // SCAS - X86/X64
+ kX86InstIdScasQ, // SCAS - X64
+ kX86InstIdScasW, // SCAS - X86/X64
+ kX86InstIdSeta, // X86/X64 (setcc)
+ kX86InstIdSetae, // X86/X64 (setcc)
+ kX86InstIdSetb, // X86/X64 (setcc)
+ kX86InstIdSetbe, // X86/X64 (setcc)
+ kX86InstIdSetc, // X86/X64 (setcc)
+ kX86InstIdSete, // X86/X64 (setcc)
+ kX86InstIdSetg, // X86/X64 (setcc)
+ kX86InstIdSetge, // X86/X64 (setcc)
+ kX86InstIdSetl, // X86/X64 (setcc)
+ kX86InstIdSetle, // X86/X64 (setcc)
+ kX86InstIdSetna, // X86/X64 (setcc)
+ kX86InstIdSetnae, // X86/X64 (setcc)
+ kX86InstIdSetnb, // X86/X64 (setcc)
+ kX86InstIdSetnbe, // X86/X64 (setcc)
+ kX86InstIdSetnc, // X86/X64 (setcc)
+ kX86InstIdSetne, // X86/X64 (setcc)
+ kX86InstIdSetng, // X86/X64 (setcc)
+ kX86InstIdSetnge, // X86/X64 (setcc)
+ kX86InstIdSetnl, // X86/X64 (setcc)
+ kX86InstIdSetnle, // X86/X64 (setcc)
+ kX86InstIdSetno, // X86/X64 (setcc)
+ kX86InstIdSetnp, // X86/X64 (setcc)
+ kX86InstIdSetns, // X86/X64 (setcc)
+ kX86InstIdSetnz, // X86/X64 (setcc)
+ kX86InstIdSeto, // X86/X64 (setcc)
+ kX86InstIdSetp, // X86/X64 (setcc)
+ kX86InstIdSetpe, // X86/X64 (setcc)
+ kX86InstIdSetpo, // X86/X64 (setcc)
+ kX86InstIdSets, // X86/X64 (setcc)
+ kX86InstIdSetz, // X86/X64 (setcc)
+ kX86InstIdSfence, // MMX-Ext/SSE
+ kX86InstIdShl, // X86/X64
+ kX86InstIdShld, // X86/X64
+ kX86InstIdShlx, // BMI2
+ kX86InstIdShr, // X86/X64
+ kX86InstIdShrd, // X86/X64
+ kX86InstIdShrx, // BMI2
+ kX86InstIdShufpd, // SSE2
+ kX86InstIdShufps, // SSE
+ kX86InstIdSqrtpd, // SSE2
+ kX86InstIdSqrtps, // SSE
+ kX86InstIdSqrtsd, // SSE2
+ kX86InstIdSqrtss, // SSE
+ kX86InstIdStc, // X86/X64
+ kX86InstIdStd, // X86/X64
+ kX86InstIdStmxcsr, // SSE
+ kX86InstIdStosB, // STOS - X86/X64
+ kX86InstIdStosD, // STOS - X86/X64
+ kX86InstIdStosQ, // STOS - X64
+ kX86InstIdStosW, // STOS - X86/X64
+ kX86InstIdSub, // X86/X64
+ kX86InstIdSubpd, // SSE2
+ kX86InstIdSubps, // SSE
+ kX86InstIdSubsd, // SSE2
+ kX86InstIdSubss, // SSE
+ kX86InstIdTest, // X86/X64
+ kX86InstIdTzcnt, // TZCNT
+ kX86InstIdUcomisd, // SSE2
+ kX86InstIdUcomiss, // SSE
+ kX86InstIdUd2, // X86/X64
+ kX86InstIdUnpckhpd, // SSE2
+ kX86InstIdUnpckhps, // SSE
+ kX86InstIdUnpcklpd, // SSE2
+ kX86InstIdUnpcklps, // SSE
+ kX86InstIdVaddpd, // AVX
+ kX86InstIdVaddps, // AVX
+ kX86InstIdVaddsd, // AVX
+ kX86InstIdVaddss, // AVX
+ kX86InstIdVaddsubpd, // AVX
+ kX86InstIdVaddsubps, // AVX
+ kX86InstIdVaesdec, // AVX+AESNI
+ kX86InstIdVaesdeclast, // AVX+AESNI
+ kX86InstIdVaesenc, // AVX+AESNI
+ kX86InstIdVaesenclast, // AVX+AESNI
+ kX86InstIdVaesimc, // AVX+AESNI
+ kX86InstIdVaeskeygenassist,// AVX+AESNI
+ kX86InstIdVandnpd, // AVX
+ kX86InstIdVandnps, // AVX
+ kX86InstIdVandpd, // AVX
+ kX86InstIdVandps, // AVX
+ kX86InstIdVblendpd, // AVX
+ kX86InstIdVblendps, // AVX
+ kX86InstIdVblendvpd, // AVX
+ kX86InstIdVblendvps, // AVX
+ kX86InstIdVbroadcastf128, // AVX
+ kX86InstIdVbroadcasti128, // AVX2
+ kX86InstIdVbroadcastsd, // AVX/AVX2
+ kX86InstIdVbroadcastss, // AVX/AVX2
+ kX86InstIdVcmppd, // AVX
+ kX86InstIdVcmpps, // AVX
+ kX86InstIdVcmpsd, // AVX
+ kX86InstIdVcmpss, // AVX
+ kX86InstIdVcomisd, // AVX
+ kX86InstIdVcomiss, // AVX
+ kX86InstIdVcvtdq2pd, // AVX
+ kX86InstIdVcvtdq2ps, // AVX
+ kX86InstIdVcvtpd2dq, // AVX
+ kX86InstIdVcvtpd2ps, // AVX
+ kX86InstIdVcvtph2ps, // F16C
+ kX86InstIdVcvtps2dq, // AVX
+ kX86InstIdVcvtps2pd, // AVX
+ kX86InstIdVcvtps2ph, // F16C
+ kX86InstIdVcvtsd2si, // AVX
+ kX86InstIdVcvtsd2ss, // AVX
+ kX86InstIdVcvtsi2sd, // AVX
+ kX86InstIdVcvtsi2ss, // AVX
+ kX86InstIdVcvtss2sd, // AVX
+ kX86InstIdVcvtss2si, // AVX
+ kX86InstIdVcvttpd2dq, // AVX
+ kX86InstIdVcvttps2dq, // AVX
+ kX86InstIdVcvttsd2si, // AVX
+ kX86InstIdVcvttss2si, // AVX
+ kX86InstIdVdivpd, // AVX
+ kX86InstIdVdivps, // AVX
+ kX86InstIdVdivsd, // AVX
+ kX86InstIdVdivss, // AVX
+ kX86InstIdVdppd, // AVX
+ kX86InstIdVdpps, // AVX
+ kX86InstIdVextractf128, // AVX
+ kX86InstIdVextracti128, // AVX2
+ kX86InstIdVextractps, // AVX
+ kX86InstIdVfmadd132pd, // FMA3
+ kX86InstIdVfmadd132ps, // FMA3
+ kX86InstIdVfmadd132sd, // FMA3
+ kX86InstIdVfmadd132ss, // FMA3
+ kX86InstIdVfmadd213pd, // FMA3
+ kX86InstIdVfmadd213ps, // FMA3
+ kX86InstIdVfmadd213sd, // FMA3
+ kX86InstIdVfmadd213ss, // FMA3
+ kX86InstIdVfmadd231pd, // FMA3
+ kX86InstIdVfmadd231ps, // FMA3
+ kX86InstIdVfmadd231sd, // FMA3
+ kX86InstIdVfmadd231ss, // FMA3
+ kX86InstIdVfmaddpd, // FMA4
+ kX86InstIdVfmaddps, // FMA4
+ kX86InstIdVfmaddsd, // FMA4
+ kX86InstIdVfmaddss, // FMA4
+ kX86InstIdVfmaddsub132pd, // FMA3
+ kX86InstIdVfmaddsub132ps, // FMA3
+ kX86InstIdVfmaddsub213pd, // FMA3
+ kX86InstIdVfmaddsub213ps, // FMA3
+ kX86InstIdVfmaddsub231pd, // FMA3
+ kX86InstIdVfmaddsub231ps, // FMA3
+ kX86InstIdVfmaddsubpd, // FMA4
+ kX86InstIdVfmaddsubps, // FMA4
+ kX86InstIdVfmsub132pd, // FMA3
+ kX86InstIdVfmsub132ps, // FMA3
+ kX86InstIdVfmsub132sd, // FMA3
+ kX86InstIdVfmsub132ss, // FMA3
+ kX86InstIdVfmsub213pd, // FMA3
+ kX86InstIdVfmsub213ps, // FMA3
+ kX86InstIdVfmsub213sd, // FMA3
+ kX86InstIdVfmsub213ss, // FMA3
+ kX86InstIdVfmsub231pd, // FMA3
+ kX86InstIdVfmsub231ps, // FMA3
+ kX86InstIdVfmsub231sd, // FMA3
+ kX86InstIdVfmsub231ss, // FMA3
+ kX86InstIdVfmsubadd132pd, // FMA3
+ kX86InstIdVfmsubadd132ps, // FMA3
+ kX86InstIdVfmsubadd213pd, // FMA3
+ kX86InstIdVfmsubadd213ps, // FMA3
+ kX86InstIdVfmsubadd231pd, // FMA3
+ kX86InstIdVfmsubadd231ps, // FMA3
+ kX86InstIdVfmsubaddpd, // FMA4
+ kX86InstIdVfmsubaddps, // FMA4
+ kX86InstIdVfmsubpd, // FMA4
+ kX86InstIdVfmsubps, // FMA4
+ kX86InstIdVfmsubsd, // FMA4
+ kX86InstIdVfmsubss, // FMA4
+ kX86InstIdVfnmadd132pd, // FMA3
+ kX86InstIdVfnmadd132ps, // FMA3
+ kX86InstIdVfnmadd132sd, // FMA3
+ kX86InstIdVfnmadd132ss, // FMA3
+ kX86InstIdVfnmadd213pd, // FMA3
+ kX86InstIdVfnmadd213ps, // FMA3
+ kX86InstIdVfnmadd213sd, // FMA3
+ kX86InstIdVfnmadd213ss, // FMA3
+ kX86InstIdVfnmadd231pd, // FMA3
+ kX86InstIdVfnmadd231ps, // FMA3
+ kX86InstIdVfnmadd231sd, // FMA3
+ kX86InstIdVfnmadd231ss, // FMA3
+ kX86InstIdVfnmaddpd, // FMA4
+ kX86InstIdVfnmaddps, // FMA4
+ kX86InstIdVfnmaddsd, // FMA4
+ kX86InstIdVfnmaddss, // FMA4
+ kX86InstIdVfnmsub132pd, // FMA3
+ kX86InstIdVfnmsub132ps, // FMA3
+ kX86InstIdVfnmsub132sd, // FMA3
+ kX86InstIdVfnmsub132ss, // FMA3
+ kX86InstIdVfnmsub213pd, // FMA3
+ kX86InstIdVfnmsub213ps, // FMA3
+ kX86InstIdVfnmsub213sd, // FMA3
+ kX86InstIdVfnmsub213ss, // FMA3
+ kX86InstIdVfnmsub231pd, // FMA3
+ kX86InstIdVfnmsub231ps, // FMA3
+ kX86InstIdVfnmsub231sd, // FMA3
+ kX86InstIdVfnmsub231ss, // FMA3
+ kX86InstIdVfnmsubpd, // FMA4
+ kX86InstIdVfnmsubps, // FMA4
+ kX86InstIdVfnmsubsd, // FMA4
+ kX86InstIdVfnmsubss, // FMA4
+ kX86InstIdVfrczpd, // XOP
+ kX86InstIdVfrczps, // XOP
+ kX86InstIdVfrczsd, // XOP
+ kX86InstIdVfrczss, // XOP
+ kX86InstIdVgatherdpd, // AVX2
+ kX86InstIdVgatherdps, // AVX2
+ kX86InstIdVgatherqpd, // AVX2
+ kX86InstIdVgatherqps, // AVX2
+ kX86InstIdVhaddpd, // AVX
+ kX86InstIdVhaddps, // AVX
+ kX86InstIdVhsubpd, // AVX
+ kX86InstIdVhsubps, // AVX
+ kX86InstIdVinsertf128, // AVX
+ kX86InstIdVinserti128, // AVX2
+ kX86InstIdVinsertps, // AVX
+ kX86InstIdVlddqu, // AVX
+ kX86InstIdVldmxcsr, // AVX
+ kX86InstIdVmaskmovdqu, // AVX
+ kX86InstIdVmaskmovpd, // AVX
+ kX86InstIdVmaskmovps, // AVX
+ kX86InstIdVmaxpd, // AVX
+ kX86InstIdVmaxps, // AVX
+ kX86InstIdVmaxsd, // AVX
+ kX86InstIdVmaxss, // AVX
+ kX86InstIdVminpd, // AVX
+ kX86InstIdVminps, // AVX
+ kX86InstIdVminsd, // AVX
+ kX86InstIdVminss, // AVX
+ kX86InstIdVmovapd, // AVX
+ kX86InstIdVmovaps, // AVX
+ kX86InstIdVmovd, // AVX
+ kX86InstIdVmovddup, // AVX
+ kX86InstIdVmovdqa, // AVX
+ kX86InstIdVmovdqu, // AVX
+ kX86InstIdVmovhlps, // AVX
+ kX86InstIdVmovhpd, // AVX
+ kX86InstIdVmovhps, // AVX
+ kX86InstIdVmovlhps, // AVX
+ kX86InstIdVmovlpd, // AVX
+ kX86InstIdVmovlps, // AVX
+ kX86InstIdVmovmskpd, // AVX
+ kX86InstIdVmovmskps, // AVX
+ kX86InstIdVmovntdq, // AVX
+ kX86InstIdVmovntdqa, // AVX/AVX2
+ kX86InstIdVmovntpd, // AVX
+ kX86InstIdVmovntps, // AVX
+ kX86InstIdVmovq, // AVX
+ kX86InstIdVmovsd, // AVX
+ kX86InstIdVmovshdup, // AVX
+ kX86InstIdVmovsldup, // AVX
+ kX86InstIdVmovss, // AVX
+ kX86InstIdVmovupd, // AVX
+ kX86InstIdVmovups, // AVX
+ kX86InstIdVmpsadbw, // AVX/AVX2
+ kX86InstIdVmulpd, // AVX
+ kX86InstIdVmulps, // AVX
+ kX86InstIdVmulsd, // AVX
+ kX86InstIdVmulss, // AVX
+ kX86InstIdVorpd, // AVX
+ kX86InstIdVorps, // AVX
+ kX86InstIdVpabsb, // AVX2
+ kX86InstIdVpabsd, // AVX2
+ kX86InstIdVpabsw, // AVX2
+ kX86InstIdVpackssdw, // AVX2
+ kX86InstIdVpacksswb, // AVX2
+ kX86InstIdVpackusdw, // AVX2
+ kX86InstIdVpackuswb, // AVX2
+ kX86InstIdVpaddb, // AVX2
+ kX86InstIdVpaddd, // AVX2
+ kX86InstIdVpaddq, // AVX2
+ kX86InstIdVpaddsb, // AVX2
+ kX86InstIdVpaddsw, // AVX2
+ kX86InstIdVpaddusb, // AVX2
+ kX86InstIdVpaddusw, // AVX2
+ kX86InstIdVpaddw, // AVX2
+ kX86InstIdVpalignr, // AVX2
+ kX86InstIdVpand, // AVX2
+ kX86InstIdVpandn, // AVX2
+ kX86InstIdVpavgb, // AVX2
+ kX86InstIdVpavgw, // AVX2
+ kX86InstIdVpblendd, // AVX2
+ kX86InstIdVpblendvb, // AVX2
+ kX86InstIdVpblendw, // AVX2
+ kX86InstIdVpbroadcastb, // AVX2
+ kX86InstIdVpbroadcastd, // AVX2
+ kX86InstIdVpbroadcastq, // AVX2
+ kX86InstIdVpbroadcastw, // AVX2
+ kX86InstIdVpclmulqdq, // AVX+PCLMULQDQ
+ kX86InstIdVpcmov, // XOP
+ kX86InstIdVpcmpeqb, // AVX2
+ kX86InstIdVpcmpeqd, // AVX2
+ kX86InstIdVpcmpeqq, // AVX2
+ kX86InstIdVpcmpeqw, // AVX2
+ kX86InstIdVpcmpestri, // AVX
+ kX86InstIdVpcmpestrm, // AVX
+ kX86InstIdVpcmpgtb, // AVX2
+ kX86InstIdVpcmpgtd, // AVX2
+ kX86InstIdVpcmpgtq, // AVX2
+ kX86InstIdVpcmpgtw, // AVX2
+ kX86InstIdVpcmpistri, // AVX
+ kX86InstIdVpcmpistrm, // AVX
+ kX86InstIdVpcomb, // XOP
+ kX86InstIdVpcomd, // XOP
+ kX86InstIdVpcomq, // XOP
+ kX86InstIdVpcomub, // XOP
+ kX86InstIdVpcomud, // XOP
+ kX86InstIdVpcomuq, // XOP
+ kX86InstIdVpcomuw, // XOP
+ kX86InstIdVpcomw, // XOP
+ kX86InstIdVperm2f128, // AVX
+ kX86InstIdVperm2i128, // AVX2
+ kX86InstIdVpermd, // AVX2
+ kX86InstIdVpermil2pd, // XOP
+ kX86InstIdVpermil2ps, // XOP
+ kX86InstIdVpermilpd, // AVX
+ kX86InstIdVpermilps, // AVX
+ kX86InstIdVpermpd, // AVX2
+ kX86InstIdVpermps, // AVX2
+ kX86InstIdVpermq, // AVX2
+ kX86InstIdVpextrb, // AVX
+ kX86InstIdVpextrd, // AVX
+ kX86InstIdVpextrq, // AVX (x64 only)
+ kX86InstIdVpextrw, // AVX
+ kX86InstIdVpgatherdd, // AVX2
+ kX86InstIdVpgatherdq, // AVX2
+ kX86InstIdVpgatherqd, // AVX2
+ kX86InstIdVpgatherqq, // AVX2
+ kX86InstIdVphaddbd, // XOP
+ kX86InstIdVphaddbq, // XOP
+ kX86InstIdVphaddbw, // XOP
+ kX86InstIdVphaddd, // AVX2
+ kX86InstIdVphadddq, // XOP
+ kX86InstIdVphaddsw, // AVX2
+ kX86InstIdVphaddubd, // XOP
+ kX86InstIdVphaddubq, // XOP
+ kX86InstIdVphaddubw, // XOP
+ kX86InstIdVphaddudq, // XOP
+ kX86InstIdVphadduwd, // XOP
+ kX86InstIdVphadduwq, // XOP
+ kX86InstIdVphaddw, // AVX2
+ kX86InstIdVphaddwd, // XOP
+ kX86InstIdVphaddwq, // XOP
+ kX86InstIdVphminposuw, // AVX
+ kX86InstIdVphsubbw, // XOP
+ kX86InstIdVphsubd, // AVX2
+ kX86InstIdVphsubdq, // XOP
+ kX86InstIdVphsubsw, // AVX2
+ kX86InstIdVphsubw, // AVX2
+ kX86InstIdVphsubwd, // XOP
+ kX86InstIdVpinsrb, // AVX
+ kX86InstIdVpinsrd, // AVX
+ kX86InstIdVpinsrq, // AVX (x64 only)
+ kX86InstIdVpinsrw, // AVX
+ kX86InstIdVpmacsdd, // XOP
+ kX86InstIdVpmacsdqh, // XOP
+ kX86InstIdVpmacsdql, // XOP
+ kX86InstIdVpmacssdd, // XOP
+ kX86InstIdVpmacssdqh, // XOP
+ kX86InstIdVpmacssdql, // XOP
+ kX86InstIdVpmacsswd, // XOP
+ kX86InstIdVpmacssww, // XOP
+ kX86InstIdVpmacswd, // XOP
+ kX86InstIdVpmacsww, // XOP
+ kX86InstIdVpmadcsswd, // XOP
+ kX86InstIdVpmadcswd, // XOP
+ kX86InstIdVpmaddubsw, // AVX/AVX2
+ kX86InstIdVpmaddwd, // AVX/AVX2
+ kX86InstIdVpmaskmovd, // AVX2
+ kX86InstIdVpmaskmovq, // AVX2
+ kX86InstIdVpmaxsb, // AVX/AVX2
+ kX86InstIdVpmaxsd, // AVX/AVX2
+ kX86InstIdVpmaxsw, // AVX/AVX2
+ kX86InstIdVpmaxub, // AVX/AVX2
+ kX86InstIdVpmaxud, // AVX/AVX2
+ kX86InstIdVpmaxuw, // AVX/AVX2
+ kX86InstIdVpminsb, // AVX/AVX2
+ kX86InstIdVpminsd, // AVX/AVX2
+ kX86InstIdVpminsw, // AVX/AVX2
+ kX86InstIdVpminub, // AVX/AVX2
+ kX86InstIdVpminud, // AVX/AVX2
+ kX86InstIdVpminuw, // AVX/AVX2
+ kX86InstIdVpmovmskb, // AVX/AVX2
+ kX86InstIdVpmovsxbd, // AVX/AVX2
+ kX86InstIdVpmovsxbq, // AVX/AVX2
+ kX86InstIdVpmovsxbw, // AVX/AVX2
+ kX86InstIdVpmovsxdq, // AVX/AVX2
+ kX86InstIdVpmovsxwd, // AVX/AVX2
+ kX86InstIdVpmovsxwq, // AVX/AVX2
+ kX86InstIdVpmovzxbd, // AVX/AVX2
+ kX86InstIdVpmovzxbq, // AVX/AVX2
+ kX86InstIdVpmovzxbw, // AVX/AVX2
+ kX86InstIdVpmovzxdq, // AVX/AVX2
+ kX86InstIdVpmovzxwd, // AVX/AVX2
+ kX86InstIdVpmovzxwq, // AVX/AVX2
+ kX86InstIdVpmuldq, // AVX/AVX2
+ kX86InstIdVpmulhrsw, // AVX/AVX2
+ kX86InstIdVpmulhuw, // AVX/AVX2
+ kX86InstIdVpmulhw, // AVX/AVX2
+ kX86InstIdVpmulld, // AVX/AVX2
+ kX86InstIdVpmullw, // AVX/AVX2
+ kX86InstIdVpmuludq, // AVX/AVX2
+ kX86InstIdVpor, // AVX/AVX2
+ kX86InstIdVpperm, // XOP
+ kX86InstIdVprotb, // XOP
+ kX86InstIdVprotd, // XOP
+ kX86InstIdVprotq, // XOP
+ kX86InstIdVprotw, // XOP
+ kX86InstIdVpsadbw, // AVX/AVX2
+ kX86InstIdVpshab, // XOP
+ kX86InstIdVpshad, // XOP
+ kX86InstIdVpshaq, // XOP
+ kX86InstIdVpshaw, // XOP
+ kX86InstIdVpshlb, // XOP
+ kX86InstIdVpshld, // XOP
+ kX86InstIdVpshlq, // XOP
+ kX86InstIdVpshlw, // XOP
+ kX86InstIdVpshufb, // AVX/AVX2
+ kX86InstIdVpshufd, // AVX/AVX2
+ kX86InstIdVpshufhw, // AVX/AVX2
+ kX86InstIdVpshuflw, // AVX/AVX2
+ kX86InstIdVpsignb, // AVX/AVX2
+ kX86InstIdVpsignd, // AVX/AVX2
+ kX86InstIdVpsignw, // AVX/AVX2
+ kX86InstIdVpslld, // AVX/AVX2
+ kX86InstIdVpslldq, // AVX/AVX2
+ kX86InstIdVpsllq, // AVX/AVX2
+ kX86InstIdVpsllvd, // AVX2
+ kX86InstIdVpsllvq, // AVX2
+ kX86InstIdVpsllw, // AVX/AVX2
+ kX86InstIdVpsrad, // AVX/AVX2
+ kX86InstIdVpsravd, // AVX2
+ kX86InstIdVpsraw, // AVX/AVX2
+ kX86InstIdVpsrld, // AVX/AVX2
+ kX86InstIdVpsrldq, // AVX/AVX2
+ kX86InstIdVpsrlq, // AVX/AVX2
+ kX86InstIdVpsrlvd, // AVX2
+ kX86InstIdVpsrlvq, // AVX2
+ kX86InstIdVpsrlw, // AVX/AVX2
+ kX86InstIdVpsubb, // AVX/AVX2
+ kX86InstIdVpsubd, // AVX/AVX2
+ kX86InstIdVpsubq, // AVX/AVX2
+ kX86InstIdVpsubsb, // AVX/AVX2
+ kX86InstIdVpsubsw, // AVX/AVX2
+ kX86InstIdVpsubusb, // AVX/AVX2
+ kX86InstIdVpsubusw, // AVX/AVX2
+ kX86InstIdVpsubw, // AVX/AVX2
+ kX86InstIdVptest, // AVX
+ kX86InstIdVpunpckhbw, // AVX/AVX2
+ kX86InstIdVpunpckhdq, // AVX/AVX2
+ kX86InstIdVpunpckhqdq, // AVX/AVX2
+ kX86InstIdVpunpckhwd, // AVX/AVX2
+ kX86InstIdVpunpcklbw, // AVX/AVX2
+ kX86InstIdVpunpckldq, // AVX/AVX2
+ kX86InstIdVpunpcklqdq, // AVX/AVX2
+ kX86InstIdVpunpcklwd, // AVX/AVX2
+ kX86InstIdVpxor, // AVX/AVX2
+ kX86InstIdVrcpps, // AVX
+ kX86InstIdVrcpss, // AVX
+ kX86InstIdVroundpd, // AVX
+ kX86InstIdVroundps, // AVX
+ kX86InstIdVroundsd, // AVX
+ kX86InstIdVroundss, // AVX
+ kX86InstIdVrsqrtps, // AVX
+ kX86InstIdVrsqrtss, // AVX
+ kX86InstIdVshufpd, // AVX
+ kX86InstIdVshufps, // AVX
+ kX86InstIdVsqrtpd, // AVX
+ kX86InstIdVsqrtps, // AVX
+ kX86InstIdVsqrtsd, // AVX
+ kX86InstIdVsqrtss, // AVX
+ kX86InstIdVstmxcsr, // AVX
+ kX86InstIdVsubpd, // AVX
+ kX86InstIdVsubps, // AVX
+ kX86InstIdVsubsd, // AVX
+ kX86InstIdVsubss, // AVX
+ kX86InstIdVtestpd, // AVX
+ kX86InstIdVtestps, // AVX
+ kX86InstIdVucomisd, // AVX
+ kX86InstIdVucomiss, // AVX
+ kX86InstIdVunpckhpd, // AVX
+ kX86InstIdVunpckhps, // AVX
+ kX86InstIdVunpcklpd, // AVX
+ kX86InstIdVunpcklps, // AVX
+ kX86InstIdVxorpd, // AVX
+ kX86InstIdVxorps, // AVX
+ kX86InstIdVzeroall, // AVX
+ kX86InstIdVzeroupper, // AVX
+ kX86InstIdWrfsbase, // FSGSBASE (x64)
+ kX86InstIdWrgsbase, // FSGSBASE (x64)
+ kX86InstIdXadd, // X86/X64 (i486)
+ kX86InstIdXchg, // X86/X64 (i386)
+ kX86InstIdXor, // X86/X64
+ kX86InstIdXorpd, // SSE2
+ kX86InstIdXorps, // SSE
+
+ _kX86InstIdCount,
+
+ _kX86InstIdCmovcc = kX86InstIdCmova,
+ _kX86InstIdJcc = kX86InstIdJa,
+ _kX86InstIdSetcc = kX86InstIdSeta,
+
+ _kX86InstIdJbegin = kX86InstIdJa,
+ _kX86InstIdJend = kX86InstIdJmp
+};
+
+// ============================================================================
+// [asmjit::kX86InstOptions]
+// ============================================================================
+
+//! X86/X64 instruction emit options, mainly for internal purposes.
+ASMJIT_ENUM(kX86InstOptions) {
+ //! Emit instruction with LOCK prefix.
+ //!
+ //! If this option is used and instruction doesn't support LOCK prefix an
+ //! invalid instruction error is generated.
+ kX86InstOptionLock = 0x10,
+
+ //! Force REX prefix to be emitted.
+ //!
+ //! This option should be used carefully, because there are unencodable
+ //! combinations. If you want to access ah, bh, ch or dh registers the REX
+ //! prefix can't be emitted, otherwise illegal instruction error will be
+ //! returned.
+ kX86InstOptionRex = 0x40,
+
+ //! Force three-byte VEX prefix to be emitted (instead of more compact
+ //! two-byte VEX prefix).
+ //!
+ //! Ignored if the instruction doesn't use VEX prefix.
+ kX86InstOptionVex3 = 0x80
+};
+
+// ============================================================================
+// [asmjit::kX86InstGroup]
+// ============================================================================
+
+//! \internal
+//!
+//! X86/X64 instruction groups.
+//!
+//! This group is specific to AsmJit and only used by `X86Assembler`.
+ASMJIT_ENUM(kX86InstGroup) {
+ //! Never used.
+ kX86InstGroupNone,
+
+ kX86InstGroupX86Op,
+ kX86InstGroupX86Op_66H,
+ kX86InstGroupX86Rm,
+ kX86InstGroupX86Rm_B,
+ kX86InstGroupX86RmReg,
+ kX86InstGroupX86RegRm,
+ kX86InstGroupX86M,
+ //! Adc/Add/And/Cmp/Or/Sbb/Sub/Xor.
+ kX86InstGroupX86Arith,
+ //! Bswap.
+ kX86InstGroupX86BSwap,
+ //! Bt/Btc/Btr/Bts.
+ kX86InstGroupX86BTest,
+ //! Call.
+ kX86InstGroupX86Call,
+ //! Enter.
+ kX86InstGroupX86Enter,
+ //! Imul.
+ kX86InstGroupX86Imul,
+ //! Inc/Dec.
+ kX86InstGroupX86IncDec,
+ //! Int.
+ kX86InstGroupX86Int,
+ //! Jcc.
+ kX86InstGroupX86Jcc,
+ //! Jcxz/Jecxz/Jrcxz.
+ kX86InstGroupX86Jecxz,
+ //! Jmp.
+ kX86InstGroupX86Jmp,
+ //! Lea.
+ kX86InstGroupX86Lea,
+ //! Mov.
+ kX86InstGroupX86Mov,
+ //! Movsx/Movzx.
+ kX86InstGroupX86MovSxZx,
+ //! Movsxd.
+ kX86InstGroupX86MovSxd,
+ //! Mov having absolute memory operand (x86/x64).
+ kX86InstGroupX86MovPtr,
+ //! Push.
+ kX86InstGroupX86Push,
+ //! Pop.
+ kX86InstGroupX86Pop,
+ //! Rep/Repe/Repne LodsX/MovsX/StosX/CmpsX/ScasX.
+ kX86InstGroupX86Rep,
+ //! Ret.
+ kX86InstGroupX86Ret,
+ //! Rcl/Rcr/Rol/Ror/Sal/Sar/Shl/Shr.
+ kX86InstGroupX86Rot,
+ //! Setcc.
+ kX86InstGroupX86Set,
+ //! Shld/Rhrd.
+ kX86InstGroupX86Shlrd,
+ //! Test.
+ kX86InstGroupX86Test,
+ //! Xadd.
+ kX86InstGroupX86Xadd,
+ //! Xchg.
+ kX86InstGroupX86Xchg,
+
+ //! Fincstp/Finit/FldX/Fnclex/Fninit/Fnop/Fpatan/Fprem/Fprem1/Fptan/Frndint/Fscale/Fsin/Fsincos/Fsqrt/Ftst/Fucompp/Fxam/Fxtract/Fyl2x/Fyl2xp1.
+ kX86InstGroupFpuOp,
+ //! Fadd/Fdiv/Fdivr/Fmul/Fsub/Fsubr.
+ kX86InstGroupFpuArith,
+ //! Fcom/Fcomp.
+ kX86InstGroupFpuCom,
+ //! Fld/Fst/Fstp.
+ kX86InstGroupFpuFldFst,
+ //! Fiadd/Ficom/Ficomp/Fidiv/Fidivr/Fild/Fimul/Fist/Fistp/Fisttp/Fisub/Fisubr.
+ kX86InstGroupFpuM,
+ //! Fcmov/Fcomi/Fcomip/Ffree/Fucom/Fucomi/Fucomip/Fucomp/Fxch.
+ kX86InstGroupFpuR,
+ //! Faddp/Fdivp/Fdivrp/Fmulp/Fsubp/Fsubrp.
+ kX86InstGroupFpuRDef,
+ //! Fnstsw/Fstsw.
+ kX86InstGroupFpuStsw,
+
+ //! Mm/Xmm instruction.
+ kX86InstGroupExtRm,
+ //! Mm/Xmm instruction (propagates 66H if the instruction uses Xmm register).
+ kX86InstGroupExtRm_P,
+ //! Mm/Xmm instruction (propagates REX.W if GPQ is used).
+ kX86InstGroupExtRm_Q,
+ //! Mm/Xmm instruction (propagates 66H and REX.W).
+ kX86InstGroupExtRm_PQ,
+ //! Mm/Xmm instruction having Rm/Ri encodings.
+ kX86InstGroupExtRmRi,
+ //! Mm/Xmm instruction having Rm/Ri encodings (propagates 66H if the instruction uses Xmm register).
+ kX86InstGroupExtRmRi_P,
+ //! Mm/Xmm instruction having Rmi encoding.
+ kX86InstGroupExtRmi,
+ //! Mm/Xmm instruction having Rmi encoding (propagates 66H if the instruction uses Xmm register).
+ kX86InstGroupExtRmi_P,
+ //! Crc32.
+ kX86InstGroupExtCrc,
+ //! Pextrb/Pextrw/Pextrd/Pextrq/Extractps.
+ kX86InstGroupExtExtract,
+ //! Lfence/Mfence/Sfence.
+ kX86InstGroupExtFence,
+ //! Mov Mm/Xmm.
+ //!
+ //! 0x66 prefix must be set manually in opcodes.
+ //!
+ //! - Primary opcode is used for instructions in (X)Mm <- (X)Mm/X86Mem format,
+ //! - Secondary opcode is used for instructions in (X)Mm/X86Mem <- (X)Mm format.
+ kX86InstGroupExtMov,
+ //! Mov Mm/Xmm.
+ kX86InstGroupExtMovNoRexW,
+ //! Movbe.
+ kX86InstGroupExtMovBe,
+ //! Movd.
+ kX86InstGroupExtMovD,
+ //! Movq.
+ kX86InstGroupExtMovQ,
+ //! Prefetch.
+ kX86InstGroupExtPrefetch,
+
+ //! 3dNow instruction.
+ kX86InstGroup3dNow,
+
+ //! AVX instruction without operands.
+ kX86InstGroupAvxOp,
+ //! AVX instruction encoded as 'M'.
+ kX86InstGroupAvxM,
+ //! AVX instruction encoded as 'MR'.
+ kX86InstGroupAvxMr,
+ //! AVX instruction encoded as 'MR' (Propagates AVX.L if Ymm used).
+ kX86InstGroupAvxMr_P,
+ //! AVX instruction encoded as 'MRI'.
+ kX86InstGroupAvxMri,
+ //! AVX instruction encoded as 'MRI' (Propagates AVX.L if Ymm used).
+ kX86InstGroupAvxMri_P,
+ //! AVX instruction encoded as 'RM'.
+ kX86InstGroupAvxRm,
+ //! AVX instruction encoded as 'RM' (Propagates AVX.L if Ymm used).
+ kX86InstGroupAvxRm_P,
+ //! AVX instruction encoded as 'RMI'.
+ kX86InstGroupAvxRmi,
+ //! AVX instruction encoded as 'RMI' (Propagates AVX.L if Ymm used).
+ kX86InstGroupAvxRmi_P,
+ //! AVX instruction encoded as 'RVM'.
+ kX86InstGroupAvxRvm,
+ //! AVX instruction encoded as 'RVM' (Propagates AVX.L if Ymm used).
+ kX86InstGroupAvxRvm_P,
+ //! AVX instruction encoded as 'RVMR'.
+ kX86InstGroupAvxRvmr,
+ //! AVX instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used).
+ kX86InstGroupAvxRvmr_P,
+ //! AVX instruction encoded as 'RVMI'.
+ kX86InstGroupAvxRvmi,
+ //! AVX instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used).
+ kX86InstGroupAvxRvmi_P,
+ //! AVX instruction encoded as 'RMV'.
+ kX86InstGroupAvxRmv,
+ //! AVX instruction encoded as 'RMVI'.
+ kX86InstGroupAvxRmvi,
+ //! AVX instruction encoded as 'RM' or 'MR'.
+ kX86InstGroupAvxRmMr,
+ //! AVX instruction encoded as 'RM' or 'MR' (Propagates AVX.L if Ymm used).
+ kX86InstGroupAvxRmMr_P,
+ //! AVX instruction encoded as 'RVM' or 'RMI'.
+ kX86InstGroupAvxRvmRmi,
+ //! AVX instruction encoded as 'RVM' or 'RMI' (Propagates AVX.L if Ymm used).
+ kX86InstGroupAvxRvmRmi_P,
+ //! AVX instruction encoded as 'RVM' or 'MR'.
+ kX86InstGroupAvxRvmMr,
+ //! AVX instruction encoded as 'RVM' or 'MVR'.
+ kX86InstGroupAvxRvmMvr,
+ //! AVX instruction encoded as 'RVM' or 'MVR' (Propagates AVX.L if Ymm used).
+ kX86InstGroupAvxRvmMvr_P,
+ //! AVX instruction encoded as 'RVM' or 'VMI'.
+ kX86InstGroupAvxRvmVmi,
+ //! AVX instruction encoded as 'RVM' or 'VMI' (Propagates AVX.L if Ymm used).
+ kX86InstGroupAvxRvmVmi_P,
+ //! AVX instruction encoded as 'VM'.
+ kX86InstGroupAvxVm,
+ //! AVX instruction encoded as 'VMI'.
+ kX86InstGroupAvxVmi,
+ //! AVX instruction encoded as 'VMI' (Propagates AVX.L if Ymm used).
+ kX86InstGroupAvxVmi_P,
+ //! AVX instruction encoded as 'RVRM' or 'RVMR'.
+ kX86InstGroupAvxRvrmRvmr,
+ //! AVX instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used).
+ kX86InstGroupAvxRvrmRvmr_P,
+ //! Vmovss/Vmovsd.
+ kX86InstGroupAvxMovSsSd,
+ //! AVX2 gather family instructions (VSIB).
+ kX86InstGroupAvxGather,
+ //! AVX2 gather family instructions (VSIB), differs only in mem operand.
+ kX86InstGroupAvxGatherEx,
+
+ //! FMA4 instruction in form [R, R, R/M, R/M].
+ kX86InstGroupFma4,
+ //! FMA4 instruction in form [R, R, R/M, R/M] (Propagates AVX.L if Ymm used).
+ kX86InstGroupFma4_P,
+
+ //! XOP instruction encoded as 'RM'.
+ kX86InstGroupXopRm,
+ //! XOP instruction encoded as 'RM' (Propagates AVX.L if Ymm used).
+ kX86InstGroupXopRm_P,
+ //! XOP instruction encoded as 'RVM' or 'RMV'.
+ kX86InstGroupXopRvmRmv,
+ //! XOP instruction encoded as 'RVM' or 'RMI'.
+ kX86InstGroupXopRvmRmi,
+ //! XOP instruction encoded as 'RVMR'.
+ kX86InstGroupXopRvmr,
+ //! XOP instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used).
+ kX86InstGroupXopRvmr_P,
+ //! XOP instruction encoded as 'RVMI'.
+ kX86InstGroupXopRvmi,
+ //! XOP instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used).
+ kX86InstGroupXopRvmi_P,
+ //! XOP instruction encoded as 'RVRM' or 'RVMR'.
+ kX86InstGroupXopRvrmRvmr,
+ //! XOP instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used).
+ kX86InstGroupXopRvrmRvmr_P,
+
+ //! Count of X86 instruction groups.
+ _kX86InstGroupCount
+};
+
+// ============================================================================
+// [asmjit::kX86InstOpCode]
+// ============================================================================
+
+//! \internal
+//!
+//! Instruction OpCode encoding used by asmjit 'X86InstInfo' table.
+//!
+//! The schema was inspired by AVX/AVX2 features.
+ASMJIT_ENUM(kX86InstOpCode) {
+ // 'MMMMM' field in AVX/XOP instruction.
+ // 'OpCode' leading bytes in legacy encoding.
+ kX86InstOpCode_MM_Shift = 16,
+ kX86InstOpCode_MM_Mask = 0x0FU << kX86InstOpCode_MM_Shift,
+ kX86InstOpCode_MM_00 = 0x00U << kX86InstOpCode_MM_Shift,
+ kX86InstOpCode_MM_0F = 0x01U << kX86InstOpCode_MM_Shift,
+ kX86InstOpCode_MM_0F38 = 0x02U << kX86InstOpCode_MM_Shift,
+ kX86InstOpCode_MM_0F3A = 0x03U << kX86InstOpCode_MM_Shift,
+ kX86InstOpCode_MM_0F01 = 0x0FU << kX86InstOpCode_MM_Shift, // Ext/Not part of AVX.
+
+ kX86InstOpCode_MM_00011 = 0x03U << kX86InstOpCode_MM_Shift,
+ kX86InstOpCode_MM_01000 = 0x08U << kX86InstOpCode_MM_Shift,
+ kX86InstOpCode_MM_01001 = 0x09U << kX86InstOpCode_MM_Shift,
+
+ // 'PP' field in AVX/XOP instruction.
+ // 'Mandatory Prefix' in legacy encoding.
+ kX86InstOpCode_PP_Shift = 21,
+ kX86InstOpCode_PP_Mask = 0x07U << kX86InstOpCode_PP_Shift,
+ kX86InstOpCode_PP_00 = 0x00U << kX86InstOpCode_PP_Shift,
+ kX86InstOpCode_PP_66 = 0x01U << kX86InstOpCode_PP_Shift,
+ kX86InstOpCode_PP_F3 = 0x02U << kX86InstOpCode_PP_Shift,
+ kX86InstOpCode_PP_F2 = 0x03U << kX86InstOpCode_PP_Shift,
+ kX86InstOpCode_PP_9B = 0x07U << kX86InstOpCode_PP_Shift, // Ext/Not part of AVX.
+
+ // 'L' field in AVX/XOP instruction.
+ kX86InstOpCode_L_Shift = 24,
+ kX86InstOpCode_L_Mask = 0x01U << kX86InstOpCode_L_Shift,
+ kX86InstOpCode_L_False = 0x00U << kX86InstOpCode_L_Shift,
+ kX86InstOpCode_L_True = 0x01U << kX86InstOpCode_L_Shift,
+
+ // 'O' field.
+ kX86InstOpCode_O_Shift = 29,
+ kX86InstOpCode_O_Mask = 0x07U << kX86InstOpCode_O_Shift
+};
+
+// ============================================================================
+// [asmjit::kX86InstFlags]
+// ============================================================================
+
+//! \internal
+//!
+//! X86/X64 instruction type flags.
+ASMJIT_ENUM(kX86InstFlags) {
+ //! No flags.
+ kX86InstFlagNone = 0x0000,
+
+ //! Instruction is a control-flow instruction.
+ //!
+ //! Control flow instructions are jmp, jcc, call and ret.
+ kX86InstFlagFlow = 0x0001,
+
+ //! Instruction is a compare/test like instruction.
+ kX86InstFlagTest = 0x0002,
+
+ //! Instruction is a move like instruction.
+ //!
+ //! Move instructions typically overwrite the first operand by the second
+ //! operand. The first operand can be the exact copy of the second operand
+ //! or it can be any kind of conversion or shuffling.
+ //!
+ //! Mov instructions are 'mov', 'movd', 'movq', movdq', 'lea', multimedia
+ //! instructions like 'cvtdq2pd', shuffle instructions like 'pshufb' and
+ //! SSE/SSE2 mathematic instructions like 'rcp?', 'round?' and 'rsqrt?'.
+ //!
+ //! There are some MOV instructions that do only a partial move (for example
+ //! 'cvtsi2ss'), register allocator has to know the variable size and use
+ //! the flag accordingly to it.
+ kX86InstFlagMove = 0x0004,
+
+ //! Instruction is an exchange like instruction.
+ //!
+ //! Exchange instruction typically overwrite first and second operand. So
+ //! far only the instructions 'xchg' and 'xadd' are considered.
+ kX86InstFlagXchg = 0x0008,
+
+ //! Instruction accesses Fp register(s).
+ kX86InstFlagFp = 0x0010,
+
+ //! Instruction can be prefixed by using the LOCK prefix.
+ kX86InstFlagLock = 0x0020,
+
+ //! Instruction is special, this is for `Compiler`.
+ kX86InstFlagSpecial = 0x0040,
+
+ //! Instruction always performs memory access.
+ //!
+ //! This flag is always combined with `kX86InstFlagSpecial` and signalizes
+ //! that there is an implicit address which is accessed (usually EDI/RDI or
+ //! ESI/EDI).
+ kX86InstFlagSpecialMem = 0x0080,
+
+ //! Instruction memory operand can refer to 16-bit address (used by FPU).
+ kX86InstFlagMem2 = 0x0100,
+ //! Instruction memory operand can refer to 32-bit address (used by FPU).
+ kX86InstFlagMem4 = 0x0200,
+ //! Instruction memory operand can refer to 64-bit address (used by FPU).
+ kX86InstFlagMem8 = 0x0400,
+ //! Instruction memory operand can refer to 80-bit address (used by FPU).
+ kX86InstFlagMem10 = 0x0800,
+
+ //! \internal
+ //!
+ //! Combination of `kX86InstFlagMem2` and `kX86InstFlagMem4`.
+ kX86InstFlagMem2_4 = kX86InstFlagMem2 | kX86InstFlagMem4,
+
+ //! \internal
+ //!
+ //! Combination of `kX86InstFlagMem2`, `kX86InstFlagMem4` and `kX86InstFlagMem8`.
+ kX86InstFlagMem2_4_8 = kX86InstFlagMem2_4 | kX86InstFlagMem8,
+
+ //! \internal
+ //!
+ //! Combination of `kX86InstFlagMem4` and `kX86InstFlagMem8`.
+ kX86InstFlagMem4_8 = kX86InstFlagMem4 | kX86InstFlagMem8,
+
+ //! \internal
+ //!
+ //! Combination of `kX86InstFlagMem4`, `kX86InstFlagMem8` and `kX86InstFlagMem10`.
+ kX86InstFlagMem4_8_10 = kX86InstFlagMem4_8 | kX86InstFlagMem10,
+
+ //! Zeroes the rest of the register if the source operand is memory.
+ //!
+ //! Special behavior related to some SIMD load instructions.
+ kX86InstFlagZ = 0x1000,
+
+ //! REX.W/VEX.W by default.
+ kX86InstFlagW = 0x8000
+};
+
+// ============================================================================
+// [asmjit::kX86InstOp]
+// ============================================================================
+
+//! \internal
+//!
+//! X86/X64 instruction operand flags.
+ASMJIT_ENUM(kX86InstOp) {
+ //! Instruction operand can be 8-bit Gpb register.
+ kX86InstOpGb = 0x0001,
+ //! Instruction operand can be 16-bit Gpw register.
+ kX86InstOpGw = 0x0002,
+ //! Instruction operand can be 32-bit Gpd register.
+ kX86InstOpGd = 0x0004,
+ //! Instruction operand can be 64-bit Gpq register.
+ kX86InstOpGq = 0x0008,
+ //! Instruction operand can be Fp register.
+ kX86InstOpFp = 0x0010,
+ //! Instruction operand can be 64-bit Mmx register.
+ kX86InstOpMm = 0x0020,
+ //! Instruction operand can be 128-bit Xmm register.
+ kX86InstOpXmm = 0x0100,
+ //! Instruction operand can be 256-bit Ymm register.
+ kX86InstOpYmm = 0x0200,
+ //! Instruction operand can be 512-bit Zmm register.
+ kX86InstOpZmm = 0x0400,
+
+ //! Instruction operand can be memory.
+ kX86InstOpMem = 0x2000,
+ //! Instruction operand can be immediate.
+ kX86InstOpImm = 0x4000,
+ //! Instruction operand can be label.
+ kX86InstOpLabel = 0x8000,
+
+ //! \internal
+ //!
+ //! Combined flags.
+ //!
+ //! \{
+
+ kX86InstOpGwb = kX86InstOpGw | kX86InstOpGb,
+ kX86InstOpGqd = kX86InstOpGq | kX86InstOpGd,
+ kX86InstOpGqdw = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw,
+ kX86InstOpGqdwb = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw | kX86InstOpGb,
+
+ kX86InstOpGbMem = kX86InstOpGb | kX86InstOpMem,
+ kX86InstOpGwMem = kX86InstOpGw | kX86InstOpMem,
+ kX86InstOpGdMem = kX86InstOpGd | kX86InstOpMem,
+ kX86InstOpGqMem = kX86InstOpGq | kX86InstOpMem,
+ kX86InstOpGwbMem = kX86InstOpGwb | kX86InstOpMem,
+ kX86InstOpGqdMem = kX86InstOpGqd | kX86InstOpMem,
+ kX86InstOpGqdwMem = kX86InstOpGqdw | kX86InstOpMem,
+ kX86InstOpGqdwbMem = kX86InstOpGqdwb | kX86InstOpMem,
+
+ kX86InstOpFpMem = kX86InstOpFp | kX86InstOpMem,
+ kX86InstOpMmMem = kX86InstOpMm | kX86InstOpMem,
+ kX86InstOpXmmMem = kX86InstOpXmm | kX86InstOpMem,
+ kX86InstOpYmmMem = kX86InstOpYmm | kX86InstOpMem,
+
+ kX86InstOpMmXmm = kX86InstOpMm | kX86InstOpXmm,
+ kX86InstOpMmXmmMem = kX86InstOpMmXmm | kX86InstOpMem,
+
+ kX86InstOpXmmYmm = kX86InstOpXmm | kX86InstOpYmm,
+ kX86InstOpXmmYmmMem = kX86InstOpXmmYmm | kX86InstOpMem
+
+ //! \}
+};
+
+// ============================================================================
+// [asmjit::kX86Cond]
+// ============================================================================
+
+//! X86/X64 Condition codes.
+ASMJIT_ENUM(kX86Cond) {
+ kX86CondA = 0x07, // CF==0 & ZF==0 (unsigned)
+ kX86CondAE = 0x03, // CF==0 (unsigned)
+ kX86CondB = 0x02, // CF==1 (unsigned)
+ kX86CondBE = 0x06, // CF==1 | ZF==1 (unsigned)
+ kX86CondC = 0x02, // CF==1
+ kX86CondE = 0x04, // ZF==1 (signed/unsigned)
+ kX86CondG = 0x0F, // ZF==0 & SF==OF (signed)
+ kX86CondGE = 0x0D, // SF==OF (signed)
+ kX86CondL = 0x0C, // SF!=OF (signed)
+ kX86CondLE = 0x0E, // ZF==1 | SF!=OF (signed)
+ kX86CondNA = 0x06, // CF==1 | ZF==1 (unsigned)
+ kX86CondNAE = 0x02, // CF==1 (unsigned)
+ kX86CondNB = 0x03, // CF==0 (unsigned)
+ kX86CondNBE = 0x07, // CF==0 & ZF==0 (unsigned)
+ kX86CondNC = 0x03, // CF==0
+ kX86CondNE = 0x05, // ZF==0 (signed/unsigned)
+ kX86CondNG = 0x0E, // ZF==1 | SF!=OF (signed)
+ kX86CondNGE = 0x0C, // SF!=OF (signed)
+ kX86CondNL = 0x0D, // SF==OF (signed)
+ kX86CondNLE = 0x0F, // ZF==0 & SF==OF (signed)
+ kX86CondNO = 0x01, // OF==0
+ kX86CondNP = 0x0B, // PF==0
+ kX86CondNS = 0x09, // SF==0
+ kX86CondNZ = 0x05, // ZF==0
+ kX86CondO = 0x00, // OF==1
+ kX86CondP = 0x0A, // PF==1
+ kX86CondPE = 0x0A, // PF==1
+ kX86CondPO = 0x0B, // PF==0
+ kX86CondS = 0x08, // SF==1
+ kX86CondZ = 0x04, // ZF==1
+
+ // Simplified condition codes.
+ kX86CondOverflow = 0x00,
+ kX86CondNotOverflow = 0x01,
+ kX86CondBelow = 0x02, //!< Unsigned comparison.
+ kX86CondAboveEqual = 0x03, //!< Unsigned comparison.
+ kX86CondEqual = 0x04,
+ kX86CondNotEqual = 0x05,
+ kX86CondBelowEqual = 0x06, //!< Unsigned comparison.
+ kX86CondAbove = 0x07, //!< Unsigned comparison.
+ kX86CondSign = 0x08,
+ kX86CondNotSign = 0x09,
+ kX86CondParityEven = 0x0A,
+ kX86CondParityOdd = 0x0B,
+ kX86CondLess = 0x0C, //!< Signed comparison.
+ kX86CondGreaterEqual = 0x0D, //!< Signed comparison.
+ kX86CondLessEqual = 0x0E, //!< Signed comparison.
+ kX86CondGreater = 0x0F, //!< Signed comparison.
+
+ // Aliases.
+ kX86CondZero = 0x04,
+ kX86CondNotZero = 0x05,
+ kX86CondNegative = 0x08,
+ kX86CondPositive = 0x09,
+
+ // Fpu-only.
+ kX86CondFpuUnordered = 0x10,
+ kX86CondFpuNotUnordered = 0x11,
+
+ //! No condition code.
+ kX86CondNone = 0x12
+};
+
+// ============================================================================
+// [asmjit::kX86EFlags]
+// ============================================================================
+
+//! X86/X64 EFLAGs bits (AsmJit specific).
+//!
+//! Each instruction stored in AsmJit database contains flags that instruction
+//! uses (reads) and flags that instruction modifies (writes). This is used by
+//! instruction reordering, but can be used by third parties as the API and
+//! definitions are public.
+//!
+//! \note Flags defined here doesn't correspond to real flags used by X86/X64
+//! architecture defined in Intel's Manual Section `3.4.3 - EFLAGS Register`.
+//!
+//! \note Flags are designed to fit in 8-bit integer.
+ASMJIT_ENUM(kX86EFlags) {
+ // --------------------------------------------------------------------------
+ // src-gendefs.js relies on the values of these masks, to modify them the
+ // tool has to be changed as well.
+ // --------------------------------------------------------------------------
+
+ //! Overflow flag (OF).
+ //!
+ //! Set if the integer result is too large a positive number or too small a
+ //! negative number (excluding the sign-bit) to fit in the destination
+ //! operand; cleared otherwise. This flag indicates an overflow condition for
+ //! signed-integer arithmetic.
+ kX86EFlagO = 0x01,
+
+ //! Sign flag (SF).
+ //!
+ //! Set equal to the most-significant bit of the result, which is the sign
+ //! bit of a signed integer (0 == positive value, 1 == negative value).
+ kX86EFlagS = 0x02,
+
+ //! Zero flag (ZF).
+ //!
+ //! Set if the result is zero; cleared otherwise.
+ kX86EFlagZ = 0x04,
+
+ //! Adjust flag (AF).
+ //!
+ //! Set if an arithmetic operation generates a carry or a borrow out of bit
+ //! 3 of the result; cleared otherwise. This flag is used in binary-coded
+ //! decimal (BCD) arithmetic.
+ kX86EFlagA = 0x08,
+
+ //! Parity flag (PF).
+ //!
+ //! Set if the least-significant byte of the result contains an even number
+ //! of 1 bits; cleared otherwise.
+ kX86EFlagP = 0x10,
+
+ //! Carry flag (CF).
+ //!
+ //! Set if an arithmetic operation generates a carry or a borrow out of the
+ //! mostsignificant bit of the result; cleared otherwise.
+ kX86EFlagC = 0x20,
+
+ //! Direction flag (DF).
+ //!
+ //! The direction flag controls string instructions `movs`, `cmps`, `scas,
+ //! `lods` and `stos`.
+ kX86EFlagD = 0x40,
+
+ //! Any other flag that AsmJit doesn't use to keep track of it.
+ kX86EFlagX = 0x80
+};
+
+// ============================================================================
+// [asmjit::kX86FpSw]
+// ============================================================================
+
+//! X86/X64 FPU status Word.
+ASMJIT_ENUM(kX86FpSw) {
+ kX86FpSw_Invalid = 0x0001,
+ kX86FpSw_Denormalized = 0x0002,
+ kX86FpSw_DivByZero = 0x0004,
+ kX86FpSw_Overflow = 0x0008,
+ kX86FpSw_Underflow = 0x0010,
+ kX86FpSw_Precision = 0x0020,
+ kX86FpSw_StackFault = 0x0040,
+ kX86FpSw_Interrupt = 0x0080,
+ kX86FpSw_C0 = 0x0100,
+ kX86FpSw_C1 = 0x0200,
+ kX86FpSw_C2 = 0x0400,
+ kX86FpSw_Top = 0x3800,
+ kX86FpSw_C3 = 0x4000,
+ kX86FpSw_Busy = 0x8000
+};
+
+// ============================================================================
+// [asmjit::kX86FpCw]
+// ============================================================================
+
+//! X86/X64 FPU control Word.
+ASMJIT_ENUM(kX86FpCw) {
+ kX86FpCw_EM_Mask = 0x003F, // Bits 0-5.
+ kX86FpCw_EM_Invalid = 0x0001,
+ kX86FpCw_EM_Denormal = 0x0002,
+ kX86FpCw_EM_DivByZero = 0x0004,
+ kX86FpCw_EM_Overflow = 0x0008,
+ kX86FpCw_EM_Underflow = 0x0010,
+ kX86FpCw_EM_Inexact = 0x0020,
+
+ kX86FpCw_PC_Mask = 0x0300, // Bits 8-9.
+ kX86FpCw_PC_Float = 0x0000,
+ kX86FpCw_PC_Reserved = 0x0100,
+ kX86FpCw_PC_Double = 0x0200,
+ kX86FpCw_PC_Extended = 0x0300,
+
+ kX86FpCw_RC_Mask = 0x0C00, // Bits 10-11.
+ kX86FpCw_RC_Nearest = 0x0000,
+ kX86FpCw_RC_Down = 0x0400,
+ kX86FpCw_RC_Up = 0x0800,
+ kX86FpCw_RC_Truncate = 0x0C00,
+
+ kX86FpCw_IC_Mask = 0x1000, // Bit 12.
+ kX86FpCw_IC_Projective = 0x0000,
+ kX86FpCw_IC_Affine = 0x1000
+};
+
+// ============================================================================
+// [asmjit::kX86Prefetch]
+// ============================================================================
+
+//! X86/X64 Prefetch hints.
+ASMJIT_ENUM(kX86Prefetch) {
+ //! Prefetch using NT hint.
+ kX86PrefetchNta = 0,
+ //! Prefetch to L0 cache.
+ kX86PrefetchT0 = 1,
+ //! Prefetch to L1 cache.
+ kX86PrefetchT1 = 2,
+ //! Prefetch to L2 cache.
+ kX86PrefetchT2 = 3
+};
+
+// ============================================================================
+// [asmjit::X86InstExtendedInfo]
+// ============================================================================
+
+//! X86/X64 instruction extended information.
+//!
+//! Extended information has been introduced to minimize data needed for a
+//! single instruction, because two or more instructions can share the common
+//! data, for example operands definition or secondary opcode, which is only
+//! used by few instructions.
+struct X86InstExtendedInfo {
+ // --------------------------------------------------------------------------
+ // [Accessors - InstGroup]
+ // --------------------------------------------------------------------------
+
+ //! Get instruction group, see \ref kX86InstGroup.
+ ASMJIT_INLINE uint32_t getInstGroup() const {
+ return _instGroup;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - InstFlags]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the instruction has flag `flag`, see `kX86InstFlags`.
+ ASMJIT_INLINE bool hasInstFlag(uint32_t flag) const {
+ return (_instFlags & flag) != 0;
+ }
+
+ //! Get instruction flags, see `kX86InstFlags`.
+ ASMJIT_INLINE uint32_t getInstFlags() const {
+ return _instFlags;
+ }
+
+ //! Get whether the instruction is a control-flow intruction.
+ //!
+ //! Control flow instruction is instruction that modifies instruction pointer,
+ //! typically jmp, jcc, call, or ret.
+ ASMJIT_INLINE bool isFlow() const {
+ return (getInstFlags() & kX86InstFlagFlow) != 0;
+ }
+
+ //! Get whether the instruction is a compare/test like intruction.
+ ASMJIT_INLINE bool isTest() const {
+ return (getInstFlags() & kX86InstFlagTest) != 0;
+ }
+
+ //! Get whether the instruction is a typical move instruction.
+ //!
+ //! Move instructions overwrite the first operand or at least part of it,
+ //! This is a very useful hint that is used by variable liveness analysis
+ //! and `Compiler` in general to know which variable is completely
+ //! overwritten.
+ //!
+ //! All AVX/XOP instructions that have 3 or more operands are considered to
+ //! have move semantics move by default.
+ ASMJIT_INLINE bool isMove() const {
+ return (getInstFlags() & kX86InstFlagMove) != 0;
+ }
+
+ //! Get whether the instruction is a typical Exchange instruction.
+ //!
+ //! Exchange instructios are 'xchg' and 'xadd'.
+ ASMJIT_INLINE bool isXchg() const {
+ return (getInstFlags() & kX86InstFlagXchg) != 0;
+ }
+
+ //! Get whether the instruction accesses Fp register(s).
+ ASMJIT_INLINE bool isFp() const {
+ return (getInstFlags() & kX86InstFlagFp) != 0;
+ }
+
+ //! Get whether the instruction can be prefixed by LOCK prefix.
+ ASMJIT_INLINE bool isLockable() const {
+ return (getInstFlags() & kX86InstFlagLock) != 0;
+ }
+
+ //! Get whether the instruction is special type (this is used by
+ //! `Compiler` to manage additional variables or functionality).
+ ASMJIT_INLINE bool isSpecial() const {
+ return (getInstFlags() & kX86InstFlagSpecial) != 0;
+ }
+
+ //! Get whether the instruction is special type and it performs
+ //! memory access.
+ ASMJIT_INLINE bool isSpecialMem() const {
+ return (getInstFlags() & kX86InstFlagSpecialMem) != 0;
+ }
+
+ //! Get whether the move instruction zeroes the rest of the register
+ //! if the source is memory operand.
+ //!
+ //! Basically flag needed only to support `movsd` and `movss` instructions.
+ ASMJIT_INLINE bool isZeroIfMem() const {
+ return (getInstFlags() & kX86InstFlagZ) != 0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - EFlags]
+ // --------------------------------------------------------------------------
+
+ //! Get EFLAGS that the instruction reads.
+ ASMJIT_INLINE uint32_t getEFlagsIn() const {
+ return _eflagsIn;
+ }
+
+ //! Get EFLAGS that the instruction writes.
+ ASMJIT_INLINE uint32_t getEFlagsOut() const {
+ return _eflagsOut;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Move-Size]
+ // --------------------------------------------------------------------------
+
+ //! Get size of move instruction in bytes.
+ //!
+ //! See \ref X86InstInfo::getMoveSize() for more details.
+ ASMJIT_INLINE uint32_t getMoveSize() const {
+ return _moveSize;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Operand-Flags]
+ // --------------------------------------------------------------------------
+
+ //! Get flags of operand at index `index`.
+ //!
+ //! See \ref X86InstInfo::getOperandFlags() for more details.
+ ASMJIT_INLINE uint16_t getOperandFlags(uint32_t index) const {
+ ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_opFlags));
+ return _opFlags[index];
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - OpCode]
+ // --------------------------------------------------------------------------
+
+ //! Get the secondary instruction opcode, see \ref kX86InstOpCode.
+ //!
+ //! See \ref X86InstInfo::getSecondaryOpCode() for more details.
+ ASMJIT_INLINE uint32_t getSecondaryOpCode() const {
+ return _secondaryOpCode;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Instruction group.
+ uint8_t _instGroup;
+
+ //! Count of bytes overwritten by a move instruction.
+ //!
+ //! Only used with `kX86InstFlagMove` flag. If this value is zero move depends
+ //! on size of the destination register.
+ uint8_t _moveSize;
+
+ //! EFlags read by the instruction.
+ uint8_t _eflagsIn;
+ //! EFlags modified by the instruction.
+ uint8_t _eflagsOut;
+
+ //! Instruction flags.
+ uint16_t _instFlags;
+
+ //! Operands' flags.
+ uint16_t _opFlags[5];
+
+ //! Secondary opcode.
+ uint32_t _secondaryOpCode;
+};
+
+// ============================================================================
+// [asmjit::X86InstInfo]
+// ============================================================================
+
+//! X86/X64 instruction information.
+struct X86InstInfo {
+ // --------------------------------------------------------------------------
+ // [Accessors - Instruction Name]
+ // --------------------------------------------------------------------------
+
+#ifndef ASMJIT_DISABLE_NAMES
+ //! Get instruction name string (null terminated).
+ ASMJIT_INLINE const char* getInstName() const {
+ return _x86InstName + static_cast<uint32_t>(_nameIndex);
+ }
+
+ //! Get instruction name index to `_x86InstName` array.
+ ASMJIT_INLINE uint32_t _getNameIndex() const {
+ return _nameIndex;
+ }
+#endif // !ASMJIT_DISABLE_NAMES
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Extended-Info]
+ // --------------------------------------------------------------------------
+
+ //! Get `X86InstExtendedInfo` for this instruction.
+ ASMJIT_INLINE const X86InstExtendedInfo& getExtendedInfo() const {
+ return _x86InstExtendedInfo[_extendedIndex];
+ }
+
+ //! Get index to the `_x86InstExtendedInfo` table.
+ ASMJIT_INLINE uint32_t _getExtendedIndex() const {
+ return _extendedIndex;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Group]
+ // --------------------------------------------------------------------------
+
+ //! Get instruction group, see \ref kX86InstGroup.
+ ASMJIT_INLINE uint32_t getInstGroup() const {
+ return getExtendedInfo().getInstGroup();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Flags]
+ // --------------------------------------------------------------------------
+
+ //! Get instruction flags, see `kX86InstFlags`.
+ ASMJIT_INLINE uint32_t getInstFlags() const {
+ return getExtendedInfo().getInstFlags();
+ }
+
+ //! Get whether the instruction has flag `flag`, see `kX86InstFlags`.
+ ASMJIT_INLINE bool hasInstFlag(uint32_t flag) const {
+ return (getInstFlags() & flag) != 0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Move-Size]
+ // --------------------------------------------------------------------------
+
+ //! Get size of move instruction in bytes.
+ //!
+ //! If zero, the size of MOV instruction is determined by the size of the
+ //! destination register (applies mostly for x86 arithmetic). This value is
+ //! useful for register allocator when determining if a variable is going to
+ //! be overwritten or not. Basically if the move size is equal or greater
+ //! than a variable itself it is considered overwritten.
+ ASMJIT_INLINE uint32_t getMoveSize() const {
+ return getExtendedInfo().getMoveSize();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Operand-Flags]
+ // --------------------------------------------------------------------------
+
+ //! Get flags of operand at index `index`.
+ ASMJIT_INLINE uint32_t getOperandFlags(uint32_t index) const {
+ return getExtendedInfo().getOperandFlags(index);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - OpCode]
+ // --------------------------------------------------------------------------
+
+ //! Get the primary instruction opcode, see \ref kX86InstOpCode.
+ ASMJIT_INLINE uint32_t getPrimaryOpCode() const {
+ return _primaryOpCode;
+ }
+
+ //! Get the secondary instruction opcode, see \ref kX86InstOpCode.
+ ASMJIT_INLINE uint32_t getSecondaryOpCode() const {
+ return getExtendedInfo().getSecondaryOpCode();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Instruction name index in `_x86InstName[]` array.
+ uint16_t _nameIndex;
+ //! Extended information name index in `_x86InstExtendedInfo[]` array.
+ uint16_t _extendedIndex;
+
+ //! Primary opcode, secondary opcode is stored in `X86InstExtendedInfo` table.
+ uint32_t _primaryOpCode;
+};
+
+// ============================================================================
+// [asmjit::X86Util]
+// ============================================================================
+
+struct X86Util {
+ // --------------------------------------------------------------------------
+ // [Instruction Info]
+ // --------------------------------------------------------------------------
+
+ //! Get instruction information based on `instId`.
+ //!
+ //! \note `instId` has to be valid instruction ID, it can't be greater than
+ //! or equal to `_kX86InstIdCount`. It asserts in debug mode.
+ static ASMJIT_INLINE const X86InstInfo& getInstInfo(uint32_t instId) {
+ ASMJIT_ASSERT(instId < _kX86InstIdCount);
+ return _x86InstInfo[instId];
+ }
+
+#ifndef ASMJIT_DISABLE_NAMES
+ //! Get an instruction ID from a given instruction `name`.
+ //!
+ //! If there is an exact match the instruction id is returned, otherwise
+ //! `kInstIdNone` (zero) is returned.
+ //!
+ //! The given `name` doesn't have to be null-terminated if `len` is provided.
+ ASMJIT_API static uint32_t getInstIdByName(
+ const char* name, size_t len = kInvalidIndex);
+#endif // !ASMJIT_DISABLE_NAMES
+
+ // --------------------------------------------------------------------------
+ // [Condition Codes]
+ // --------------------------------------------------------------------------
+
+ //! Corresponds to transposing the operands of a comparison.
+ static ASMJIT_INLINE uint32_t reverseCond(uint32_t cond) {
+ ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_x86ReverseCond));
+ return _x86ReverseCond[cond];
+ }
+
+ //! Get the equivalent of negated condition code.
+ static ASMJIT_INLINE uint32_t negateCond(uint32_t cond) {
+ ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_x86ReverseCond));
+ return static_cast<kX86Cond>(cond ^ static_cast<uint32_t>(cond < kX86CondNone));
+ }
+
+ //! Translate condition code `cc` to `cmovcc` instruction code.
+ //! \sa \ref kX86InstId, \ref _kX86InstIdCmovcc.
+ static ASMJIT_INLINE uint32_t condToCmovcc(uint32_t cond) {
+ ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86CondToCmovcc));
+ return _x86CondToCmovcc[cond];
+ }
+
+ //! Translate condition code `cc` to `jcc` instruction code.
+ //! \sa \ref kX86InstId, \ref _kX86InstIdJcc.
+ static ASMJIT_INLINE uint32_t condToJcc(uint32_t cond) {
+ ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86CondToJcc));
+ return _x86CondToJcc[cond];
+ }
+
+ //! Translate condition code `cc` to `setcc` instruction code.
+ //! \sa \ref kX86InstId, \ref _kX86InstIdSetcc.
+ static ASMJIT_INLINE uint32_t condToSetcc(uint32_t cond) {
+ ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86CondToSetcc));
+ return _x86CondToSetcc[cond];
+ }
+
+ // --------------------------------------------------------------------------
+ // [MmShuffle]
+ // --------------------------------------------------------------------------
+
+ //! Pack a shuffle constant to be used with multimedia instrutions (2 values).
+ //!
+ //! \param x First component position, number at interval [0, 1] inclusive.
+ //! \param y Second component position, number at interval [0, 1] inclusive.
+ //!
+ //! Shuffle constants can be used to make immediate value for these intrinsics:
+ //! - `X86Assembler::shufpd()` and `X86Compiler::shufpd()`
+ static ASMJIT_INLINE int mmShuffle(uint32_t x, uint32_t y) {
+ return static_cast<int>((x << 1) | y);
+ }
+
+ //! Pack a shuffle constant to be used with multimedia instrutions (4 values).
+ //!
+ //! \param z First component position, number at interval [0, 3] inclusive.
+ //! \param x Second component position, number at interval [0, 3] inclusive.
+ //! \param y Third component position, number at interval [0, 3] inclusive.
+ //! \param w Fourth component position, number at interval [0, 3] inclusive.
+ //!
+ //! Shuffle constants can be used to make immediate value for these intrinsics:
+ //! - `X86Assembler::pshufw()` and `X86Compiler::pshufw()`
+ //! - `X86Assembler::pshufd()` and `X86Compiler::pshufd()`
+ //! - `X86Assembler::pshufhw()` and `X86Compiler::pshufhw()`
+ //! - `X86Assembler::pshuflw()` and `X86Compiler::pshuflw()`
+ //! - `X86Assembler::shufps()` and `X86Compiler::shufps()`
+ static ASMJIT_INLINE int mmShuffle(uint32_t z, uint32_t y, uint32_t x, uint32_t w) {
+ return static_cast<int>((z << 6) | (y << 4) | (x << 2) | w);
+ }
+};
+
+//! \}
+
+} // asmjit namespace
+
+#undef _OP_ID
+
+// [Api-End]
+#include "../apiend.h"
+
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86operand.cpp
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86operand.cpp
@@ -1,365 +1,86 @@
// [AsmJit]
-// Complete JIT Assembler for C++ Language.
+// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
-// Zlib - See COPYING file in this package.
+// Zlib - See LICENSE.md file in the package.
+// [Export]
#define ASMJIT_EXPORTS
+// [Guard]
+#include "../build.h"
+#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
+
// [Dependencies - AsmJit]
-#include "../x86/x86defs.h"
#include "../x86/x86operand.h"
// [Api-Begin]
-#include "../core/apibegin.h"
+#include "../apibegin.h"
-namespace AsmJit
-{
+namespace asmjit {
+namespace x86 {
// ============================================================================
-// [AsmJit::Registers - no_reg]
+// [asmjit::X86Mem - abs[]]
// ============================================================================
-const GpReg no_reg(_Initialize(), kInvalidValue);
+X86Mem ptr_abs(Ptr pAbs, int32_t disp, uint32_t size) {
+ X86Mem m(NoInit);
-// ============================================================================
-// [AsmJit::Registers - 8-bit]
-// ============================================================================
+ m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, 0, kInvalidValue);
+ m._vmem.index = kInvalidValue;
+ m._vmem.displacement = static_cast<int32_t>(static_cast<intptr_t>(pAbs + disp));
-const GpReg al(_Initialize(), kX86RegAl);
-const GpReg cl(_Initialize(), kX86RegCl);
-const GpReg dl(_Initialize(), kX86RegDl);
-const GpReg bl(_Initialize(), kX86RegBl);
-
-#ifdef ASMJIT_X64
-const GpReg spl(_Initialize(), kX86RegSpl);
-const GpReg bpl(_Initialize(), kX86RegBpl);
-const GpReg sil(_Initialize(), kX86RegSil);
-const GpReg dil(_Initialize(), kX86RegDil);
-
-const GpReg r8b(_Initialize(), kX86RegR8b);
-const GpReg r9b(_Initialize(), kX86RegR9b);
-const GpReg r10b(_Initialize(), kX86RegR10b);
-const GpReg r11b(_Initialize(), kX86RegR11b);
-const GpReg r12b(_Initialize(), kX86RegR12b);
-const GpReg r13b(_Initialize(), kX86RegR13b);
-const GpReg r14b(_Initialize(), kX86RegR14b);
-const GpReg r15b(_Initialize(), kX86RegR15b);
-#endif // ASMJIT_X64
-
-const GpReg ah(_Initialize(), kX86RegAh);
-const GpReg ch(_Initialize(), kX86RegCh);
-const GpReg dh(_Initialize(), kX86RegDh);
-const GpReg bh(_Initialize(), kX86RegBh);
-
-// ============================================================================
-// [AsmJit::Registers - 16-bit]
-// ============================================================================
-
-const GpReg ax(_Initialize(), kX86RegAx);
-const GpReg cx(_Initialize(), kX86RegCx);
-const GpReg dx(_Initialize(), kX86RegDx);
-const GpReg bx(_Initialize(), kX86RegBx);
-const GpReg sp(_Initialize(), kX86RegSp);
-const GpReg bp(_Initialize(), kX86RegBp);
-const GpReg si(_Initialize(), kX86RegSi);
-const GpReg di(_Initialize(), kX86RegDi);
-
-#ifdef ASMJIT_X64
-const GpReg r8w(_Initialize(), kX86RegR8w);
-const GpReg r9w(_Initialize(), kX86RegR9w);
-const GpReg r10w(_Initialize(), kX86RegR10w);
-const GpReg r11w(_Initialize(), kX86RegR11w);
-const GpReg r12w(_Initialize(), kX86RegR12w);
-const GpReg r13w(_Initialize(), kX86RegR13w);
-const GpReg r14w(_Initialize(), kX86RegR14w);
-const GpReg r15w(_Initialize(), kX86RegR15w);
-#endif // ASMJIT_X64
-
-// ============================================================================
-// [AsmJit::Registers - 32-bit]
-// ============================================================================
-
-const GpReg eax(_Initialize(), kX86RegEax);
-const GpReg ecx(_Initialize(), kX86RegEcx);
-const GpReg edx(_Initialize(), kX86RegEdx);
-const GpReg ebx(_Initialize(), kX86RegEbx);
-const GpReg esp(_Initialize(), kX86RegEsp);
-const GpReg ebp(_Initialize(), kX86RegEbp);
-const GpReg esi(_Initialize(), kX86RegEsi);
-const GpReg edi(_Initialize(), kX86RegEdi);
-
-#ifdef ASMJIT_X64
-const GpReg r8d(_Initialize(), kX86RegR8d);
-const GpReg r9d(_Initialize(), kX86RegR9d);
-const GpReg r10d(_Initialize(), kX86RegR10d);
-const GpReg r11d(_Initialize(), kX86RegR11d);
-const GpReg r12d(_Initialize(), kX86RegR12d);
-const GpReg r13d(_Initialize(), kX86RegR13d);
-const GpReg r14d(_Initialize(), kX86RegR14d);
-const GpReg r15d(_Initialize(), kX86RegR15d);
-#endif // ASMJIT_X64
-
-// ============================================================================
-// [AsmJit::Registers - 64-bit]
-// ============================================================================
-
-#ifdef ASMJIT_X64
-const GpReg rax(_Initialize(), kX86RegRax);
-const GpReg rcx(_Initialize(), kX86RegRcx);
-const GpReg rdx(_Initialize(), kX86RegRdx);
-const GpReg rbx(_Initialize(), kX86RegRbx);
-const GpReg rsp(_Initialize(), kX86RegRsp);
-const GpReg rbp(_Initialize(), kX86RegRbp);
-const GpReg rsi(_Initialize(), kX86RegRsi);
-const GpReg rdi(_Initialize(), kX86RegRdi);
-
-const GpReg r8(_Initialize(), kX86RegR8);
-const GpReg r9(_Initialize(), kX86RegR9);
-const GpReg r10(_Initialize(), kX86RegR10);
-const GpReg r11(_Initialize(), kX86RegR11);
-const GpReg r12(_Initialize(), kX86RegR12);
-const GpReg r13(_Initialize(), kX86RegR13);
-const GpReg r14(_Initialize(), kX86RegR14);
-const GpReg r15(_Initialize(), kX86RegR15);
-#endif // ASMJIT_X64
-
-// ============================================================================
-// [AsmJit::Registers - Native (AsmJit extension)]
-// ============================================================================
-
-const GpReg zax(_Initialize(), kX86RegZax);
-const GpReg zcx(_Initialize(), kX86RegZcx);
-const GpReg zdx(_Initialize(), kX86RegZdx);
-const GpReg zbx(_Initialize(), kX86RegZbx);
-const GpReg zsp(_Initialize(), kX86RegZsp);
-const GpReg zbp(_Initialize(), kX86RegZbp);
-const GpReg zsi(_Initialize(), kX86RegZsi);
-const GpReg zdi(_Initialize(), kX86RegZdi);
-
-// ============================================================================
-// [AsmJit::Registers - MM]
-// ============================================================================
-
-const MmReg mm0(_Initialize(), kX86RegMm0);
-const MmReg mm1(_Initialize(), kX86RegMm1);
-const MmReg mm2(_Initialize(), kX86RegMm2);
-const MmReg mm3(_Initialize(), kX86RegMm3);
-const MmReg mm4(_Initialize(), kX86RegMm4);
-const MmReg mm5(_Initialize(), kX86RegMm5);
-const MmReg mm6(_Initialize(), kX86RegMm6);
-const MmReg mm7(_Initialize(), kX86RegMm7);
-
-// ============================================================================
-// [AsmJit::Registers - XMM]
-// ============================================================================
-
-const XmmReg xmm0(_Initialize(), kX86RegXmm0);
-const XmmReg xmm1(_Initialize(), kX86RegXmm1);
-const XmmReg xmm2(_Initialize(), kX86RegXmm2);
-const XmmReg xmm3(_Initialize(), kX86RegXmm3);
-const XmmReg xmm4(_Initialize(), kX86RegXmm4);
-const XmmReg xmm5(_Initialize(), kX86RegXmm5);
-const XmmReg xmm6(_Initialize(), kX86RegXmm6);
-const XmmReg xmm7(_Initialize(), kX86RegXmm7);
-
-#ifdef ASMJIT_X64
-const XmmReg xmm8(_Initialize(), kX86RegXmm8);
-const XmmReg xmm9(_Initialize(), kX86RegXmm9);
-const XmmReg xmm10(_Initialize(), kX86RegXmm10);
-const XmmReg xmm11(_Initialize(), kX86RegXmm11);
-const XmmReg xmm12(_Initialize(), kX86RegXmm12);
-const XmmReg xmm13(_Initialize(), kX86RegXmm13);
-const XmmReg xmm14(_Initialize(), kX86RegXmm14);
-const XmmReg xmm15(_Initialize(), kX86RegXmm15);
-#endif // ASMJIT_X64
-
-// ============================================================================
-// [AsmJit::Registers - Segment]
-// ============================================================================
-
-const SegmentReg cs(_Initialize(), kX86RegCs);
-const SegmentReg ss(_Initialize(), kX86RegSs);
-const SegmentReg ds(_Initialize(), kX86RegDs);
-const SegmentReg es(_Initialize(), kX86RegEs);
-const SegmentReg fs(_Initialize(), kX86RegFs);
-const SegmentReg gs(_Initialize(), kX86RegGs);
-
-// ============================================================================
-// [AsmJit::Var]
-// ============================================================================
-
-Mem _BaseVarMem(const Var &var, uint32_t size, sysint_t disp)
-{
- Mem m; //(_DontInitialize());
-
- m._mem.op = kOperandMem;
- m._mem.size = static_cast<uint8_t>(size == kInvalidValue ? var.getSize() : size);
- m._mem.type = kOperandMemNative;
- m._mem.segment = kX86SegNone;
- m._mem.sizePrefix = 0;
- m._mem.shift = 0;
-
- m._mem.id = var.getId();
-
- m._mem.base = kInvalidValue;
- m._mem.index = kInvalidValue;
-
- m._mem.target = nullptr;
- m._mem.displacement = disp;
-
- return m;
+ return m;
}
-Mem _BaseVarMem(const Var &var, uint32_t size, const GpVar &index, uint32_t shift, sysint_t disp)
-{
- Mem m; //(_DontInitialize());
+X86Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift, int32_t disp, uint32_t size) {
+ X86Mem m(NoInit);
+ uint32_t flags = shift << kX86MemShiftIndex;
- m._mem.op = kOperandMem;
- m._mem.size = static_cast<uint8_t>(size == kInvalidValue ? var.getSize() : size);
- m._mem.type = kOperandMemNative;
- m._mem.segment = kX86SegNone;
- m._mem.sizePrefix = 0;
- m._mem.shift = shift;
+ if (index.isGp())
+ flags |= X86Mem::_getGpdFlags(index);
+ else if (index.isXmm())
+ flags |= kX86MemVSibXmm << kX86MemVSibIndex;
+ else if (index.isYmm())
+ flags |= kX86MemVSibYmm << kX86MemVSibIndex;
- m._mem.id = var.getId();
+ m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, flags, kInvalidValue);
+ m._vmem.index = index.getRegIndex();
+ m._vmem.displacement = static_cast<int32_t>(static_cast<intptr_t>(pAbs + disp));
- m._mem.base = kInvalidValue;
- m._mem.index = index.getId();
-
- m._mem.target = nullptr;
- m._mem.displacement = disp;
-
- return m;
+ return m;
}
-// ============================================================================
-// [AsmJit::Mem - ptr[]]
-// ============================================================================
+#ifndef ASMJIT_DISABLE_COMPILER
+X86Mem ptr_abs(Ptr pAbs, const X86Var& index, uint32_t shift, int32_t disp, uint32_t size) {
+ X86Mem m(NoInit);
+ uint32_t flags = shift << kX86MemShiftIndex;
-Mem ptr(const Label &label, sysint_t disp, uint32_t size)
-{
- return Mem(label, disp, size);
+ const Var& index_ = reinterpret_cast<const Var&>(index);
+ uint32_t indexRegType = index_.getRegType();
+
+ if (indexRegType <= kX86RegTypeGpq)
+ flags |= X86Mem::_getGpdFlags(reinterpret_cast<const Var&>(index));
+ else if (indexRegType == kX86RegTypeXmm)
+ flags |= kX86MemVSibXmm << kX86MemVSibIndex;
+ else if (indexRegType == kX86RegTypeYmm)
+ flags |= kX86MemVSibYmm << kX86MemVSibIndex;
+
+ m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, flags, kInvalidValue);
+ m._vmem.index = index_.getId();
+ m._vmem.displacement = static_cast<int32_t>(static_cast<intptr_t>(pAbs + disp));
+
+ return m;
}
+#endif // !ASMJIT_DISABLE_COMPILER
-Mem ptr(const Label &label, const GpReg &index, uint32_t shift, sysint_t disp, uint32_t size)
-{
- Mem m(label, disp, size);
-
- m._mem.index = index.getRegIndex();
- m._mem.shift = shift;
-
- return m;
-}
-
-Mem ptr(const Label &label, const GpVar &index, uint32_t shift, sysint_t disp, uint32_t size)
-{
- Mem m(label, disp, size);
-
- m._mem.index = index.getId();
- m._mem.shift = shift;
-
- return m;
-}
-
-// ============================================================================
-// [AsmJit::Mem - ptr[] - Absolute Addressing]
-// ============================================================================
-
-ASMJIT_API Mem ptr_abs(void *target, sysint_t disp, uint32_t size)
-{
- Mem m;
-
- m._mem.size = size;
- m._mem.type = kOperandMemAbsolute;
- m._mem.segment = kX86SegNone;
-
- m._mem.target = target;
- m._mem.displacement = disp;
-
- return m;
-}
-
-ASMJIT_API Mem ptr_abs(void *target, const GpReg &index, uint32_t shift, sysint_t disp, uint32_t size)
-{
- Mem m;// (_DontInitialize());
-
- m._mem.op = kOperandMem;
- m._mem.size = size;
- m._mem.type = kOperandMemAbsolute;
- m._mem.segment = kX86SegNone;
-
-#ifdef ASMJIT_X86
- m._mem.sizePrefix = index.getSize() != 4;
-#else
- m._mem.sizePrefix = index.getSize() != 8;
-#endif
-
- m._mem.shift = shift;
-
- m._mem.id = kInvalidValue;
- m._mem.base = kInvalidValue;
- m._mem.index = index.getRegIndex();
-
- m._mem.target = target;
- m._mem.displacement = disp;
-
- return m;
-}
-
-ASMJIT_API Mem ptr_abs(void *target, const GpVar &index, uint32_t shift, sysint_t disp, uint32_t size)
-{
- Mem m;// (_DontInitialize());
-
- m._mem.op = kOperandMem;
- m._mem.size = size;
- m._mem.type = kOperandMemAbsolute;
- m._mem.segment = kX86SegNone;
-
-#ifdef ASMJIT_X86
- m._mem.sizePrefix = index.getSize() != 4;
-#else
- m._mem.sizePrefix = index.getSize() != 8;
-#endif
-
- m._mem.shift = shift;
-
- m._mem.id = kInvalidValue;
- m._mem.base = kInvalidValue;
- m._mem.index = index.getId();
-
- m._mem.target = target;
- m._mem.displacement = disp;
-
- return m;
-}
-
-// ============================================================================
-// [AsmJit::Mem - ptr[base + displacement]]
-// ============================================================================
-
-Mem ptr(const GpReg &base, sysint_t disp, uint32_t size)
-{
- return Mem(base, disp, size);
-}
-
-Mem ptr(const GpReg &base, const GpReg &index, uint32_t shift, sysint_t disp, uint32_t size)
-{
- return Mem(base, index, shift, disp, size);
-}
-
-Mem ptr(const GpVar &base, sysint_t disp, uint32_t size)
-{
- return Mem(base, disp, size);
-}
-
-Mem ptr(const GpVar &base, const GpVar &index, uint32_t shift, sysint_t disp, uint32_t size)
-{
- return Mem(base, index, shift, disp, size);
-}
-
-} // AsmJit namespace
+} // x86 namespace
+} // asmjit namespace
// [Api-End]
-#include "../core/apiend.h"
+#include "../apiend.h"
+// [Guard]
+#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64
+
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86operand.h
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86operand.h
@@ -1,1775 +1,1527 @@
// [AsmJit]
-// Complete JIT Assembler for C++ Language.
+// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
-// Zlib - See COPYING file in this package.
+// Zlib - See LICENSE.md file in the package.
#pragma once
// [Dependencies - AsmJit]
-#include "../core/defs.h"
-#include "../core/operand.h"
-
-#include "../x86/x86defs.h"
-
-namespace AsmJit
-{
+#include "../base/assembler.h"
+#include "../base/compiler.h"
+#include "../base/globals.h"
+#include "../base/intutil.h"
+#include "../base/operand.h"
+#include "../base/vectypes.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+//! \internal
+//!
+//! Internal macro to get an operand ID casting it to `Operand`. Basically
+//! allows to get an id of operand that has been just 'typedef'ed.
+#define _OP_ID(_Op_) reinterpret_cast<const Operand&>(_Op_).getId()
+
+namespace asmjit {
// ============================================================================
// [Forward Declarations]
// ============================================================================
-struct GpReg;
-struct GpVar;
-struct Mem;
-struct MmReg;
-struct MmVar;
-struct Var;
-struct X87Reg;
-struct X87Var;
-struct XmmReg;
-struct XmmVar;
-
-struct SegmentReg;
-
-//! @addtogroup AsmJit_X86
-//! @{
-
-// ============================================================================
-// [AsmJit::MmData]
-// ============================================================================
-
-//! @brief Structure used for MMX specific data (64-bit).
+struct X86Reg;
+struct X86GpReg;
+struct X86FpReg;
+struct X86MmReg;
+struct X86XmmReg;
+struct X86YmmReg;
+struct X86SegReg;
+
+#ifndef ASMJIT_DISABLE_COMPILER
+struct X86Var;
+struct X86GpVar;
+struct X86MmVar;
+struct X86XmmVar;
+struct X86YmmVar;
+#endif // !ASMJIT_DISABLE_COMPILER
+
+//! \addtogroup asmjit_x86_general
+//! \{
+
+// ============================================================================
+// [asmjit::kX86RegClass]
+// ============================================================================
+
+//! X86/X64 variable class.
+ASMJIT_ENUM(kX86RegClass) {
+ //! X86/X64 Gp register class (compatible with universal \ref kRegClassGp).
+ kX86RegClassGp = kRegClassGp,
+ //! X86/X64 Fp register class.
+ kX86RegClassFp = 1,
+ //! X86/X64 Mm register class.
+ kX86RegClassMm = 2,
+ //! X86/X64 Xmm/Ymm/Zmm register class.
+ kX86RegClassXyz = 3,
+
+ //! Count of X86/X64 register classes.
+ kX86RegClassCount = 4
+};
+
+// ============================================================================
+// [asmjit::kX86RegType]
+// ============================================================================
+
+//! X86/X64 register type.
+ASMJIT_ENUM(kX86RegType) {
+ //! Gpb-lo register (AL, BL, CL, DL, ...).
+ kX86RegTypeGpbLo = 0x01,
+ //! Gpb-hi register (AH, BH, CH, DH only).
+ kX86RegTypeGpbHi = 0x02,
+
+ //! \internal
+ //!
+ //! Gpb-hi register patched to native index (4-7).
+ _kX86RegTypePatchedGpbHi = kX86RegTypeGpbLo | kX86RegTypeGpbHi,
+
+ //! Gpw register.
+ kX86RegTypeGpw = 0x10,
+ //! Gpd register.
+ kX86RegTypeGpd = 0x20,
+ //! Gpq register.
+ kX86RegTypeGpq = 0x30,
+
+ //! Fp register.
+ kX86RegTypeFp = 0x50,
+ //! Mm register.
+ kX86RegTypeMm = 0x60,
+
+ //! Xmm register.
+ kX86RegTypeXmm = 0x70,
+ //! Ymm register.
+ kX86RegTypeYmm = 0x80,
+ //! Zmm register.
+ kX86RegTypeZmm = 0x90,
+
+ //! Segment register.
+ kX86RegTypeSeg = 0xF0
+};
+
+// ============================================================================
+// [asmjit::kX86RegIndex]
+// ============================================================================
+
+//! X86/X64 register indexes.
//!
-//! This structure can be used to load / store data from / to MMX register.
-union MmData
-{
- // --------------------------------------------------------------------------
- // [Methods]
- // --------------------------------------------------------------------------
-
- //! @brief Set all eight signed 8-bit integers.
- void setSB(int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7)
- {
- this->sb[0] = x0;
- this->sb[1] = x1;
- this->sb[2] = x2;
- this->sb[3] = x3;
- this->sb[4] = x4;
- this->sb[5] = x5;
- this->sb[6] = x6;
- this->sb[7] = x7;
- }
-
- //! @brief Set all eight unsigned 8-bit integers.
- void setUB(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7)
- {
- this->ub[0] = x0;
- this->ub[1] = x1;
- this->ub[2] = x2;
- this->ub[3] = x3;
- this->ub[4] = x4;
- this->ub[5] = x5;
- this->ub[6] = x6;
- this->ub[7] = x7;
- }
-
- //! @brief Set all four signed 16-bit integers.
- void setSW(int16_t x0, int16_t x1, int16_t x2, int16_t x3)
- {
- this->sw[0] = x0;
- this->sw[1] = x1;
- this->sw[2] = x2;
- this->sw[3] = x3;
- }
-
- //! @brief Set all four unsigned 16-bit integers.
- void setUW(uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3)
- {
- this->uw[0] = x0;
- this->uw[1] = x1;
- this->uw[2] = x2;
- this->uw[3] = x3;
- }
-
- //! @brief Set all two signed 32-bit integers.
- void setSD(int32_t x0, int32_t x1)
- {
- this->sd[0] = x0;
- this->sd[1] = x1;
- }
-
- //! @brief Set all two unsigned 32-bit integers.
- void setUD(uint32_t x0, uint32_t x1)
- {
- this->ud[0] = x0;
- this->ud[1] = x1;
- }
-
- //! @brief Set signed 64-bit integer.
- void setSQ(int64_t x0)
- {
- this->sq[0] = x0;
- }
-
- //! @brief Set unsigned 64-bit integer.
- void setUQ(uint64_t x0)
- {
- this->uq[0] = x0;
- }
-
- //! @brief Set all two SP-FP values.
- void setSF(float x0, float x1)
- {
- this->sf[0] = x0;
- this->sf[1] = x1;
- }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Array of eight signed 8-bit integers.
- int8_t sb[8];
- //! @brief Array of eight unsigned 8-bit integers.
- uint8_t ub[8];
- //! @brief Array of four signed 16-bit integers.
- int16_t sw[4];
- //! @brief Array of four unsigned 16-bit integers.
- uint16_t uw[4];
- //! @brief Array of two signed 32-bit integers.
- int32_t sd[2];
- //! @brief Array of two unsigned 32-bit integers.
- uint32_t ud[2];
- //! @brief Array of one signed 64-bit integer.
- int64_t sq[1];
- //! @brief Array of one unsigned 64-bit integer.
- uint64_t uq[1];
-
- //! @brief Array of two SP-FP values.
- float sf[2];
+//! \note Register indexes have been reduced to only support general purpose
+//! registers. There is no need to have enumerations with number suffix that
+//! expands to the exactly same value as the suffix value itself.
+ASMJIT_ENUM(kX86RegIndex) {
+ //! Index of Al/Ah/Ax/Eax/Rax registers.
+ kX86RegIndexAx = 0,
+ //! Index of Cl/Ch/Cx/Ecx/Rcx registers.
+ kX86RegIndexCx = 1,
+ //! Index of Dl/Dh/Dx/Edx/Rdx registers.
+ kX86RegIndexDx = 2,
+ //! Index of Bl/Bh/Bx/Ebx/Rbx registers.
+ kX86RegIndexBx = 3,
+ //! Index of Spl/Sp/Esp/Rsp registers.
+ kX86RegIndexSp = 4,
+ //! Index of Bpl/Bp/Ebp/Rbp registers.
+ kX86RegIndexBp = 5,
+ //! Index of Sil/Si/Esi/Rsi registers.
+ kX86RegIndexSi = 6,
+ //! Index of Dil/Di/Edi/Rdi registers.
+ kX86RegIndexDi = 7,
+ //! Index of R8b/R8w/R8d/R8 registers (64-bit only).
+ kX86RegIndexR8 = 8,
+ //! Index of R9B/R9w/R9d/R9 registers (64-bit only).
+ kX86RegIndexR9 = 9,
+ //! Index of R10B/R10w/R10D/R10 registers (64-bit only).
+ kX86RegIndexR10 = 10,
+ //! Index of R11B/R11w/R11d/R11 registers (64-bit only).
+ kX86RegIndexR11 = 11,
+ //! Index of R12B/R12w/R12d/R12 registers (64-bit only).
+ kX86RegIndexR12 = 12,
+ //! Index of R13B/R13w/R13d/R13 registers (64-bit only).
+ kX86RegIndexR13 = 13,
+ //! Index of R14B/R14w/R14d/R14 registers (64-bit only).
+ kX86RegIndexR14 = 14,
+ //! Index of R15B/R15w/R15d/R15 registers (64-bit only).
+ kX86RegIndexR15 = 15
};
// ============================================================================
-// [AsmJit::XmmData]
-// ============================================================================
-
-//! @brief Structure used for SSE specific data (128-bit).
+// [asmjit::kX86Seg]
+// ============================================================================
+
+//! X86/X64 segment codes.
+ASMJIT_ENUM(kX86Seg) {
+ //! No/Default segment.
+ kX86SegDefault = 0,
+ //! Es segment.
+ kX86SegEs = 1,
+ //! Cs segment.
+ kX86SegCs = 2,
+ //! Ss segment.
+ kX86SegSs = 3,
+ //! Ds segment.
+ kX86SegDs = 4,
+ //! Fs segment.
+ kX86SegFs = 5,
+ //! Gs segment.
+ kX86SegGs = 6,
+
+ //! Count of X86 segment registers supported by AsmJit.
+ //!
+ //! \note X86 architecture has 6 segment registers - ES, CS, SS, DS, FS, GS.
+ //! X64 architecture lowers them down to just FS and GS. AsmJit supports 7
+ //! segment registers - all addressable in both X86 and X64 modes and one
+ //! extra called `kX86SegDefault`, which is AsmJit specific and means that there
+ //! is no segment register specified so the segment prefix will not be emitted.
+ kX86SegCount = 7
+};
+
+// ============================================================================
+// [asmjit::kX86MemVSib]
+// ============================================================================
+
+//! X86/X64 index register legacy and AVX2 (VSIB) support.
+ASMJIT_ENUM(kX86MemVSib) {
+ //! Memory operand uses Gp or no index register.
+ kX86MemVSibGpz = 0,
+ //! Memory operand uses Xmm or no index register.
+ kX86MemVSibXmm = 1,
+ //! Memory operand uses Ymm or no index register.
+ kX86MemVSibYmm = 2
+};
+
+// ============================================================================
+// [asmjit::kX86MemFlags]
+// ============================================================================
+
+//! \internal
//!
-//! This structure can be used to load / store data from / to SSE register.
+//! X86/X64 specific memory flags.
+ASMJIT_ENUM(kX86MemFlags) {
+ kX86MemSegBits = 0x7,
+ kX86MemSegIndex = 0,
+ kX86MemSegMask = kX86MemSegBits << kX86MemSegIndex,
+
+ kX86MemGpdBits = 0x1,
+ kX86MemGpdIndex = 3,
+ kX86MemGpdMask = kX86MemGpdBits << kX86MemGpdIndex,
+
+ kX86MemVSibBits = 0x3,
+ kX86MemVSibIndex = 4,
+ kX86MemVSibMask = kX86MemVSibBits << kX86MemVSibIndex,
+
+ kX86MemShiftBits = 0x3,
+ kX86MemShiftIndex = 6,
+ kX86MemShiftMask = kX86MemShiftBits << kX86MemShiftIndex
+};
+
+// This is only defined by `x86operand_regs.cpp` when exporting registers.
+#ifndef ASMJIT_EXPORTS_X86OPERAND_REGS
+
+// ============================================================================
+// [asmjit::X86RegCount]
+// ============================================================================
+
+//! \internal
//!
-//! @note Always align SSE data to 16-bytes.
-union XmmData
-{
- // --------------------------------------------------------------------------
- // [Methods]
- // --------------------------------------------------------------------------
-
- //! @brief Set all sixteen signed 8-bit integers.
- void setSB(int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7, int8_t x8, int8_t x9, int8_t x10, int8_t x11, int8_t x12, int8_t x13, int8_t x14, int8_t x15)
- {
- this->sb[0] = x0;
- this->sb[1] = x1;
- this->sb[2] = x2;
- this->sb[3] = x3;
- this->sb[4] = x4;
- this->sb[5] = x5;
- this->sb[6] = x6;
- this->sb[7] = x7;
- this->sb[8] = x8;
- this->sb[9] = x9;
- this->sb[10] = x10;
- this->sb[11] = x11;
- this->sb[12] = x12;
- this->sb[13] = x13;
- this->sb[14] = x14;
- this->sb[15] = x15;
- }
-
- //! @brief Set all sixteen unsigned 8-bit integers.
- void setUB(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7, uint8_t x8, uint8_t x9, uint8_t x10, uint8_t x11, uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15)
- {
- this->ub[0] = x0;
- this->ub[1] = x1;
- this->ub[2] = x2;
- this->ub[3] = x3;
- this->ub[4] = x4;
- this->ub[5] = x5;
- this->ub[6] = x6;
- this->ub[7] = x7;
- this->ub[8] = x8;
- this->ub[9] = x9;
- this->ub[10] = x10;
- this->ub[11] = x11;
- this->ub[12] = x12;
- this->ub[13] = x13;
- this->ub[14] = x14;
- this->ub[15] = x15;
- }
-
- //! @brief Set all eight signed 16-bit integers.
- void setSW(int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7)
- {
- this->sw[0] = x0;
- this->sw[1] = x1;
- this->sw[2] = x2;
- this->sw[3] = x3;
- this->sw[4] = x4;
- this->sw[5] = x5;
- this->sw[6] = x6;
- this->sw[7] = x7;
- }
-
- //! @brief Set all eight unsigned 16-bit integers.
- void setUW(uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7)
- {
- this->uw[0] = x0;
- this->uw[1] = x1;
- this->uw[2] = x2;
- this->uw[3] = x3;
- this->uw[4] = x4;
- this->uw[5] = x5;
- this->uw[6] = x6;
- this->uw[7] = x7;
- }
-
- //! @brief Set all four signed 32-bit integers.
- void setSD(int32_t x0, int32_t x1, int32_t x2, int32_t x3)
- {
- this->sd[0] = x0;
- this->sd[1] = x1;
- this->sd[2] = x2;
- this->sd[3] = x3;
- }
-
- //! @brief Set all four unsigned 32-bit integers.
- void setUD(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3)
- {
- this->ud[0] = x0;
- this->ud[1] = x1;
- this->ud[2] = x2;
- ud[3] = x3;
- }
-
- //! @brief Set all two signed 64-bit integers.
- void setSQ(int64_t x0, int64_t x1)
- {
- this->sq[0] = x0;
- this->sq[1] = x1;
- }
-
- //! @brief Set all two unsigned 64-bit integers.
- void setUQ(uint64_t x0, uint64_t x1)
- {
- this->uq[0] = x0;
- this->uq[1] = x1;
- }
-
- //! @brief Set all four SP-FP floats.
- void setSF(float x0, float x1, float x2, float x3)
- {
- this->sf[0] = x0;
- this->sf[1] = x1;
- this->sf[2] = x2;
- this->sf[3] = x3;
- }
-
- //! @brief Set all two DP-FP floats.
- void setDF(double x0, double x1)
- {
- this->df[0] = x0;
- this->df[1] = x1;
- }
-
- // --------------------------------------------------------------------------
- // [Members]
- // --------------------------------------------------------------------------
-
- //! @brief Array of sixteen signed 8-bit integers.
- int8_t sb[16];
- //! @brief Array of sixteen unsigned 8-bit integers.
- uint8_t ub[16];
- //! @brief Array of eight signed 16-bit integers.
- int16_t sw[8];
- //! @brief Array of eight unsigned 16-bit integers.
- uint16_t uw[8];
- //! @brief Array of four signed 32-bit integers.
- int32_t sd[4];
- //! @brief Array of four unsigned 32-bit integers.
- uint32_t ud[4];
- //! @brief Array of two signed 64-bit integers.
- int64_t sq[2];
- //! @brief Array of two unsigned 64-bit integers.
- uint64_t uq[2];
-
- //! @brief Array of four 32-bit single precision floating points.
- float sf[4];
- //! @brief Array of two 64-bit double precision floating points.
- double df[2];
+//! X86/X64 registers count (Gp, Fp, Mm, Xmm).
+struct X86RegCount {
+ // --------------------------------------------------------------------------
+ // [Zero]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void reset() {
+ _packed = 0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Get]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE uint32_t get(uint32_t c) const {
+ ASMJIT_ASSERT(c < kX86RegClassCount);
+ return _regs[c];
+ }
+
+ ASMJIT_INLINE uint32_t getGp() const { return _regs[kX86RegClassGp]; }
+ ASMJIT_INLINE uint32_t getFp() const { return _regs[kX86RegClassFp]; }
+ ASMJIT_INLINE uint32_t getMm() const { return _regs[kX86RegClassMm]; }
+ ASMJIT_INLINE uint32_t getXyz() const { return _regs[kX86RegClassXyz]; }
+
+ // --------------------------------------------------------------------------
+ // [Set]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void set(uint32_t c, uint32_t n) {
+ ASMJIT_ASSERT(c < kX86RegClassCount);
+ ASMJIT_ASSERT(n < 0x100);
+
+ _regs[c] = static_cast<uint8_t>(n);
+ }
+
+ ASMJIT_INLINE void setGp(uint32_t n) { set(kX86RegClassGp, n); }
+ ASMJIT_INLINE void setFp(uint32_t n) { set(kX86RegClassFp, n); }
+ ASMJIT_INLINE void setMm(uint32_t n) { set(kX86RegClassMm, n); }
+ ASMJIT_INLINE void setXyz(uint32_t n) { set(kX86RegClassXyz, n); }
+
+ // --------------------------------------------------------------------------
+ // [Add]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void add(uint32_t c, uint32_t n = 1) {
+ ASMJIT_ASSERT(c < kX86RegClassCount);
+ ASMJIT_ASSERT(n < 0x100);
+
+ _regs[c] += static_cast<uint8_t>(n);
+ }
+
+ ASMJIT_INLINE void addGp(uint32_t n) { add(kX86RegClassGp, n); }
+ ASMJIT_INLINE void addFp(uint32_t n) { add(kX86RegClassFp, n); }
+ ASMJIT_INLINE void addMm(uint32_t n) { add(kX86RegClassMm, n); }
+ ASMJIT_INLINE void addXyz(uint32_t n) { add(kX86RegClassXyz, n); }
+
+ // --------------------------------------------------------------------------
+ // [Misc]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void makeIndex(const X86RegCount& count) {
+ uint8_t a = count._regs[0];
+ uint8_t b = count._regs[1];
+ uint8_t c = count._regs[2];
+
+ _regs[0] = 0;
+ _regs[1] = a;
+ _regs[2] = a + b;
+ _regs[3] = a + b + c;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ union {
+ struct {
+ uint8_t _gp;
+ uint8_t _fp;
+ uint8_t _mm;
+ uint8_t _xy;
+ };
+
+ uint8_t _regs[4];
+ uint32_t _packed;
+ };
};
// ============================================================================
-// [AsmJit::GpReg]
-// ============================================================================
-
-//! @brief General purpose register.
+// [asmjit::X86RegMask]
+// ============================================================================
+
+//! \internal
//!
-//! This class is for all general purpose registers (64, 32, 16 and 8-bit).
-struct GpReg : public Reg
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create non-initialized general purpose register.
- GpReg() : Reg(kInvalidValue, 0) { }
- //! @brief Create a reference to @a other general purpose register.
- GpReg(const GpReg &other) : Reg(other) { }
-
-#ifndef ASMJIT_NODOC
- GpReg(const _DontInitialize &dontInitialize) : Reg(dontInitialize) { }
- GpReg(const _Initialize &, uint32_t code) : Reg(code, static_cast<uint32_t>(1U << ((code & kRegTypeMask) >> 12))) { }
-#endif // ASMJIT_NODOC
-
- // --------------------------------------------------------------------------
- // [Reg Specific]
- // --------------------------------------------------------------------------
-
- //! @brief Set register code to @a code.
- GpReg &setCode(uint32_t code)
- {
- this->_reg.code = code;
- return *this;
- }
-
- //! @brief Set register size to @a size.
- GpReg &setSize(uint32_t size)
- {
- this->_reg.size = static_cast<uint8_t>(size);
- return *this;
- }
-
- // --------------------------------------------------------------------------
- // [GpReg Specific]
- // --------------------------------------------------------------------------
-
- //! @brief Get whether the general purpose register is BYTE (8-bit) type.
- bool isGpb() const { return (this->_reg.code & kRegTypeMask) <= kX86RegTypeGpbHi; }
- //! @brief Get whether the general purpose register is LO-BYTE (8-bit) type.
- bool isGpbLo() const { return (this->_reg.code & kRegTypeMask) == kX86RegTypeGpbLo; }
- //! @brief Get whether the general purpose register is HI-BYTE (8-bit) type.
- bool isGpbHi() const { return (this->_reg.code & kRegTypeMask) == kX86RegTypeGpbHi; }
-
- //! @brief Get whether the general purpose register is WORD (16-bit) type.
- bool isGpw() const { return (this->_reg.code & kRegTypeMask) == kX86RegTypeGpw; }
- //! @brief Get whether the general purpose register is DWORD (32-bit) type.
- //!
- //! This is default type for 32-bit platforms.
- bool isGpd() const { return (this->_reg.code & kRegTypeMask) == kX86RegTypeGpd; }
- //! @brief Get whether the general purpose register is QWORD (64-bit) type.
- //!
- //! This is default type for 64-bit platforms.
- bool isGpq() const { return (this->_reg.code & kRegTypeMask) == kX86RegTypeGpq; }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_NODOC
- GpReg &operator=(const GpReg &other) { this->_copy(other); return *this; }
- bool operator==(const GpReg &other) const { return this->getRegCode() == other.getRegCode(); }
- bool operator!=(const GpReg &other) const { return this->getRegCode() != other.getRegCode(); }
-#endif // ASMJIT_NODOC
+//! X86/X64 registers mask (Gp, Fp, Mm, Xmm/Ymm/Zmm).
+struct X86RegMask {
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void reset() {
+ _packed.reset();
+ }
+
+ // --------------------------------------------------------------------------
+ // [IsEmpty / Has]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE bool isEmpty() const {
+ return _packed.isZero();
+ }
+
+ ASMJIT_INLINE bool has(uint32_t c, uint32_t mask = 0xFFFFFFFF) const {
+ switch (c) {
+ case kX86RegClassGp : return (static_cast<uint32_t>(_gp ) & mask) != 0;
+ case kX86RegClassFp : return (static_cast<uint32_t>(_fp ) & mask) != 0;
+ case kX86RegClassMm : return (static_cast<uint32_t>(_mm ) & mask) != 0;
+ case kX86RegClassXyz: return (static_cast<uint32_t>(_xyz) & mask) != 0;
+ }
+
+ ASMJIT_ASSERT(!"Reached");
+ return false;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Zero]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void zero(uint32_t c) {
+ switch (c) {
+ case kX86RegClassGp : _gp = 0; break;
+ case kX86RegClassFp : _fp = 0; break;
+ case kX86RegClassMm : _mm = 0; break;
+ case kX86RegClassXyz: _xyz = 0; break;
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // [Get]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE uint32_t get(uint32_t c) const {
+ switch (c) {
+ case kX86RegClassGp : return _gp;
+ case kX86RegClassFp : return _fp;
+ case kX86RegClassMm : return _mm;
+ case kX86RegClassXyz: return _xyz;
+ }
+
+ ASMJIT_ASSERT(!"Reached");
+ return 0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Set]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void set(uint32_t c, uint32_t mask) {
+ switch (c) {
+ case kX86RegClassGp : _gp = static_cast<uint16_t>(mask); break;
+ case kX86RegClassFp : _fp = static_cast<uint8_t >(mask); break;
+ case kX86RegClassMm : _mm = static_cast<uint8_t >(mask); break;
+ case kX86RegClassXyz: _xyz = static_cast<uint32_t>(mask); break;
+ }
+ }
+
+ ASMJIT_INLINE void set(const X86RegMask& other) {
+ _packed.setUInt64(other._packed);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Add]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void add(uint32_t c, uint32_t mask) {
+ switch (c) {
+ case kX86RegClassGp : _gp |= static_cast<uint16_t>(mask); break;
+ case kX86RegClassFp : _fp |= static_cast<uint8_t >(mask); break;
+ case kX86RegClassMm : _mm |= static_cast<uint8_t >(mask); break;
+ case kX86RegClassXyz: _xyz |= static_cast<uint32_t>(mask); break;
+ }
+ }
+
+ ASMJIT_INLINE void add(const X86RegMask& other) {
+ _packed.or_(other._packed);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Del]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void del(uint32_t c, uint32_t mask) {
+ switch (c) {
+ case kX86RegClassGp : _gp &= ~static_cast<uint16_t>(mask); break;
+ case kX86RegClassFp : _fp &= ~static_cast<uint8_t >(mask); break;
+ case kX86RegClassMm : _mm &= ~static_cast<uint8_t >(mask); break;
+ case kX86RegClassXyz: _xyz &= ~static_cast<uint32_t>(mask); break;
+ }
+ }
+
+ ASMJIT_INLINE void del(const X86RegMask& other) {
+ _packed.del(other._packed);
+ }
+
+ // --------------------------------------------------------------------------
+ // [And]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void and_(uint32_t c, uint32_t mask) {
+ switch (c) {
+ case kX86RegClassGp : _gp &= static_cast<uint16_t>(mask); break;
+ case kX86RegClassFp : _fp &= static_cast<uint8_t >(mask); break;
+ case kX86RegClassMm : _mm &= static_cast<uint8_t >(mask); break;
+ case kX86RegClassXyz: _xyz &= static_cast<uint32_t>(mask); break;
+ }
+ }
+
+ ASMJIT_INLINE void and_(const X86RegMask& other) {
+ _packed.and_(other._packed);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Xor]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void xor_(uint32_t c, uint32_t mask) {
+ switch (c) {
+ case kX86RegClassGp : _gp ^= static_cast<uint16_t>(mask); break;
+ case kX86RegClassFp : _fp ^= static_cast<uint8_t >(mask); break;
+ case kX86RegClassMm : _mm ^= static_cast<uint8_t >(mask); break;
+ case kX86RegClassXyz: _xyz ^= static_cast<uint32_t>(mask); break;
+ }
+ }
+
+ ASMJIT_INLINE void xor_(const X86RegMask& other) {
+ _packed.xor_(other._packed);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ union {
+ struct {
+ //! Gp mask (16-bit).
+ uint16_t _gp;
+ //! Fp mask (8-bit).
+ uint8_t _fp;
+ //! Mm mask (8-bit).
+ uint8_t _mm;
+ //! Xmm/Ymm/Zmm mask (32-bit).
+ uint32_t _xyz;
+ };
+
+ //! All masks as 64-bit integer.
+ UInt64 _packed;
+ };
};
// ============================================================================
-// [AsmJit::X87Reg]
-// ============================================================================
-
-//! @brief 80-bit x87 floating point register.
-//!
-//! To create instance of x87 register, use @c st() function.
-struct X87Reg : public Reg
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create non-initialized x87 register.
- X87Reg() : Reg(kInvalidValue, 10) { }
- //! @brief Create a reference to @a other x87 register.
- X87Reg(const X87Reg &other) : Reg(other) { }
-
-#ifndef ASMJIT_NODOC
- X87Reg(const _DontInitialize &dontInitialize) : Reg(dontInitialize) { }
- X87Reg(const _Initialize &, uint32_t code) : Reg(code | kX86RegTypeX87, 10) { }
-#endif // ASMJIT_NODOC
-
- // --------------------------------------------------------------------------
- // [Reg Specific]
- // --------------------------------------------------------------------------
-
- //! @brief Set register code to @a code.
- X87Reg &setCode(uint32_t code)
- {
- this->_reg.code = code;
- return *this;
- }
-
- //! @brief Set register size to @a size.
- X87Reg &setSize(uint32_t size)
- {
- this->_reg.size = static_cast<uint8_t>(size);
- return *this;
- }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_NODOC
- X87Reg &operator=(const X87Reg &other) { this->_copy(other); return *this; }
- bool operator==(const X87Reg &other) const { return this->getRegCode() == other.getRegCode(); }
- bool operator!=(const X87Reg &other) const { return this->getRegCode() != other.getRegCode(); }
-#endif // ASMJIT_NODOC
+// [asmjit::X86Reg]
+// ============================================================================
+
+//! Base class for all X86 registers.
+struct X86Reg : public Reg {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a dummy X86 register.
+ ASMJIT_INLINE X86Reg() : Reg() {}
+ //! Create a reference to `other` X86 register.
+ ASMJIT_INLINE X86Reg(const X86Reg& other) : Reg(other) {}
+ //! Create a reference to `other` X86 register and change the index to `index`.
+ ASMJIT_INLINE X86Reg(const X86Reg& other, uint32_t index) : Reg(other, index) {}
+ //! Create a custom X86 register.
+ ASMJIT_INLINE X86Reg(uint32_t type, uint32_t index, uint32_t size) : Reg(type, index, size) {}
+ //! Create non-initialized X86 register.
+ explicit ASMJIT_INLINE X86Reg(const _NoInit&) : Reg(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [X86Reg Specific]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_REG_OP(X86Reg)
+
+ //! Get whether the register is Gp register.
+ ASMJIT_INLINE bool isGp() const { return _vreg.type <= kX86RegTypeGpq; }
+ //! Get whether the register is Gp byte (8-bit) register.
+ ASMJIT_INLINE bool isGpb() const { return _vreg.type <= kX86RegTypeGpbHi; }
+ //! Get whether the register is Gp lo-byte (8-bit) register.
+ ASMJIT_INLINE bool isGpbLo() const { return _vreg.type == kX86RegTypeGpbLo; }
+ //! Get whether the register is Gp hi-byte (8-bit) register.
+ ASMJIT_INLINE bool isGpbHi() const { return _vreg.type == kX86RegTypeGpbHi; }
+ //! Get whether the register is Gp word (16-bit) register.
+ ASMJIT_INLINE bool isGpw() const { return _vreg.type == kX86RegTypeGpw; }
+ //! Get whether the register is Gp dword (32-bit) register.
+ ASMJIT_INLINE bool isGpd() const { return _vreg.type == kX86RegTypeGpd; }
+ //! Get whether the register is Gp qword (64-bit) register.
+ ASMJIT_INLINE bool isGpq() const { return _vreg.type == kX86RegTypeGpq; }
+
+ //! Get whether the register is Fp register.
+ ASMJIT_INLINE bool isFp() const { return _vreg.type == kX86RegTypeFp; }
+ //! Get whether the register is Mm (64-bit) register.
+ ASMJIT_INLINE bool isMm() const { return _vreg.type == kX86RegTypeMm; }
+ //! Get whether the register is Xmm (128-bit) register.
+ ASMJIT_INLINE bool isXmm() const { return _vreg.type == kX86RegTypeXmm; }
+ //! Get whether the register is Ymm (256-bit) register.
+ ASMJIT_INLINE bool isYmm() const { return _vreg.type == kX86RegTypeYmm; }
+ //! Get whether the register is Zmm (512-bit) register.
+ ASMJIT_INLINE bool isZmm() const { return _vreg.type == kX86RegTypeZmm; }
+
+ //! Get whether the register is a segment.
+ ASMJIT_INLINE bool isSeg() const { return _vreg.type == kX86RegTypeSeg; }
+
+ // --------------------------------------------------------------------------
+ // [Statics]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the `op` operand is Gpb-Lo or Gpb-Hi register.
+ static ASMJIT_INLINE bool isGpbReg(const Operand& op) {
+ const uint32_t mask = IntUtil::pack32_2x8_1x16(
+ 0xFF, 0xFF, ~(_kX86RegTypePatchedGpbHi << 8) & 0xFF00);
+
+ return (op._packed[0].u32[0] & mask) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 1, 0x0000);
+ }
};
// ============================================================================
-// [AsmJit::MmReg]
-// ============================================================================
-
-//! @brief 64-bit MMX register.
-struct MmReg : public Reg
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create non-initialized MM register.
- MmReg() : Reg(kInvalidValue, 8) { }
- //! @brief Create a reference to @a other MM register.
- MmReg(const MmReg &other) : Reg(other) { }
-
-#ifndef ASMJIT_NODOC
- MmReg(const _DontInitialize &dontInitialize) : Reg(dontInitialize) { }
- MmReg(const _Initialize &, uint32_t code) : Reg(code, 8) { }
-#endif // ASMJIT_NODOC
-
- // --------------------------------------------------------------------------
- // [Reg Specific]
- // --------------------------------------------------------------------------
-
- //! @brief Set register code to @a code.
- MmReg &setCode(uint32_t code)
- {
- this->_reg.code = code;
- return *this;
- }
-
- //! @brief Set register size to @a size.
- MmReg &setSize(uint32_t size)
- {
- this->_reg.size = static_cast<uint8_t>(size);
- return *this;
- }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_NODOC
- MmReg &operator=(const MmReg &other) { this->_copy(other); return *this; }
- bool operator==(const MmReg &other) const { return this->getRegCode() == other.getRegCode(); }
- bool operator!=(const MmReg &other) const { return this->getRegCode() != other.getRegCode(); }
-#endif // ASMJIT_NODOC
+// [asmjit::X86GpReg]
+// ============================================================================
+
+//! X86/X64 Gpb/Gpw/Gpd/Gpq register.
+struct X86GpReg : public X86Reg {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a dummy Gp register.
+ ASMJIT_INLINE X86GpReg() : X86Reg() {}
+ //! Create a reference to `other` Gp register.
+ ASMJIT_INLINE X86GpReg(const X86GpReg& other) : X86Reg(other) {}
+ //! Create a reference to `other` Gp register and change the index to `index`.
+ ASMJIT_INLINE X86GpReg(const X86GpReg& other, uint32_t index) : X86Reg(other, index) {}
+ //! Create a custom Gp register.
+ ASMJIT_INLINE X86GpReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
+ //! Create non-initialized Gp register.
+ explicit ASMJIT_INLINE X86GpReg(const _NoInit&) : X86Reg(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [X86GpReg Specific]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_REG_OP(X86GpReg)
};
// ============================================================================
-// [AsmJit::XmmReg]
-// ============================================================================
-
-//! @brief 128-bit SSE register.
-struct XmmReg : public Reg
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create non-initialized XMM register.
- XmmReg() : Reg(kInvalidValue, 16) { }
- //! @brief Create a reference to @a other XMM register.
- XmmReg(const _Initialize &, uint32_t code) : Reg(code, 16) { }
-
-#ifndef ASMJIT_NODOC
- XmmReg(const _DontInitialize &dontInitialize) : Reg(dontInitialize) { }
- XmmReg(const XmmReg &other) : Reg(other) { }
-#endif // ASMJIT_NODOC
-
- // --------------------------------------------------------------------------
- // [Reg Specific]
- // --------------------------------------------------------------------------
-
- //! @brief Set register code to @a code.
- XmmReg &setCode(uint32_t code)
- {
- this->_reg.code = code;
- return *this;
- }
-
- //! @brief Set register size to @a size.
- XmmReg &setSize(uint32_t size)
- {
- this->_reg.size = static_cast<uint8_t>(size);
- return *this;
- }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_NODOC
- XmmReg &operator=(const XmmReg &other) { this->_copy(other); return *this; }
- bool operator==(const XmmReg &other) const { return this->getRegCode() == other.getRegCode(); }
- bool operator!=(const XmmReg &other) const { return this->getRegCode() != other.getRegCode(); }
-#endif // ASMJIT_NODOC
+// [asmjit::X86FpReg]
+// ============================================================================
+
+//! X86/X64 80-bit Fp register.
+struct X86FpReg : public X86Reg {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a dummy Fp register.
+ ASMJIT_INLINE X86FpReg() : X86Reg() {}
+ //! Create a reference to `other` Fp register.
+ ASMJIT_INLINE X86FpReg(const X86FpReg& other) : X86Reg(other) {}
+ //! Create a reference to `other` Fp register and change the index to `index`.
+ ASMJIT_INLINE X86FpReg(const X86FpReg& other, uint32_t index) : X86Reg(other, index) {}
+ //! Create a custom Fp register.
+ ASMJIT_INLINE X86FpReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
+ //! Create non-initialized Fp register.
+ explicit ASMJIT_INLINE X86FpReg(const _NoInit&) : X86Reg(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [X86FpReg Specific]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_REG_OP(X86FpReg)
};
// ============================================================================
-// [AsmJit::SegmentReg]
-// ============================================================================
-
-//! @brief Segment register.
-struct SegmentReg : public Reg
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create non-initialized segment register.
- SegmentReg() : Reg(kInvalidValue, 2) { }
- //! @brief Create a reference to @a other segment register.
- SegmentReg(const _Initialize &, uint32_t code) : Reg(code, 2) { }
-
-#ifndef ASMJIT_NODOC
- SegmentReg(const _DontInitialize &dontInitialize) : Reg(dontInitialize) { }
- SegmentReg(const SegmentReg &other) : Reg(other) { }
-#endif // ASMJIT_NODOC
-
- // --------------------------------------------------------------------------
- // [Reg Specific]
- // --------------------------------------------------------------------------
-
- //! @brief Set register code to @a code.
- SegmentReg &setCode(uint32_t code)
- {
- this->_reg.code = code;
- return *this;
- }
-
- //! @brief Set register size to @a size.
- SegmentReg &setSize(uint32_t size)
- {
- this->_reg.size = static_cast<uint8_t>(size);
- return *this;
- }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_NODOC
- SegmentReg &operator=(const SegmentReg &other) { this->_copy(other); return *this; }
- bool operator==(const SegmentReg &other) const { return this->getRegCode() == other.getRegCode(); }
- bool operator!=(const SegmentReg &other) const { return this->getRegCode() != other.getRegCode(); }
-#endif // ASMJIT_NODOC
+// [asmjit::X86MmReg]
+// ============================================================================
+
+//! X86/X64 64-bit Mm register.
+struct X86MmReg : public X86Reg {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a dummy Mm register.
+ ASMJIT_INLINE X86MmReg() : X86Reg() {}
+ //! Create a reference to `other` Mm register.
+ ASMJIT_INLINE X86MmReg(const X86MmReg& other) : X86Reg(other) {}
+ //! Create a reference to `other` Mm register and change the index to `index`.
+ ASMJIT_INLINE X86MmReg(const X86MmReg& other, uint32_t index) : X86Reg(other, index) {}
+ //! Create a custom Mm register.
+ ASMJIT_INLINE X86MmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
+ //! Create non-initialized Mm register.
+ explicit ASMJIT_INLINE X86MmReg(const _NoInit&) : X86Reg(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [X86MmReg Specific]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_REG_OP(X86MmReg)
};
// ============================================================================
-// [AsmJit::Registers - no_reg]
-// ============================================================================
-
-//! @brief No register, can be used only in @c Mem operand.
-ASMJIT_VAR const GpReg no_reg;
-
-// ============================================================================
-// [AsmJit::Registers - 8-bit]
-// ============================================================================
-
-//! @brief 8-bit General purpose register.
-ASMJIT_VAR const GpReg al;
-//! @brief 8-bit General purpose register.
-ASMJIT_VAR const GpReg cl;
-//! @brief 8-bit General purpose register.
-ASMJIT_VAR const GpReg dl;
-//! @brief 8-bit General purpose register.
-ASMJIT_VAR const GpReg bl;
-
-#ifdef ASMJIT_X64
-//! @brief 8-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg spl;
-//! @brief 8-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg bpl;
-//! @brief 8-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg sil;
-//! @brief 8-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg dil;
-
-//! @brief 8-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r8b;
-//! @brief 8-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r9b;
-//! @brief 8-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r10b;
-//! @brief 8-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r11b;
-//! @brief 8-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r12b;
-//! @brief 8-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r13b;
-//! @brief 8-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r14b;
-//! @brief 8-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r15b;
-#endif // ASMJIT_X64
-
-//! @brief 8-bit General purpose register.
-ASMJIT_VAR const GpReg ah;
-//! @brief 8-bit General purpose register.
-ASMJIT_VAR const GpReg ch;
-//! @brief 8-bit General purpose register.
-ASMJIT_VAR const GpReg dh;
-//! @brief 8-bit General purpose register.
-ASMJIT_VAR const GpReg bh;
-
-// ============================================================================
-// [AsmJit::Registers - 16-bit]
-// ============================================================================
-
-//! @brief 16-bit General purpose register.
-ASMJIT_VAR const GpReg ax;
-//! @brief 16-bit General purpose register.
-ASMJIT_VAR const GpReg cx;
-//! @brief 16-bit General purpose register.
-ASMJIT_VAR const GpReg dx;
-//! @brief 16-bit General purpose register.
-ASMJIT_VAR const GpReg bx;
-//! @brief 16-bit General purpose register.
-ASMJIT_VAR const GpReg sp;
-//! @brief 16-bit General purpose register.
-ASMJIT_VAR const GpReg bp;
-//! @brief 16-bit General purpose register.
-ASMJIT_VAR const GpReg si;
-//! @brief 16-bit General purpose register.
-ASMJIT_VAR const GpReg di;
-
-#ifdef ASMJIT_X64
-//! @brief 16-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r8w;
-//! @brief 16-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r9w;
-//! @brief 16-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r10w;
-//! @brief 16-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r11w;
-//! @brief 16-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r12w;
-//! @brief 16-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r13w;
-//! @brief 16-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r14w;
-//! @brief 16-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r15w;
-#endif // ASMJIT_X64
-
-// ============================================================================
-// [AsmJit::Registers - 32-bit]
-// ============================================================================
-
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg eax;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg ecx;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg edx;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg ebx;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg esp;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg ebp;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg esi;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg edi;
-
-#ifdef ASMJIT_X64
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg r8d;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg r9d;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg r10d;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg r11d;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg r12d;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg r13d;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg r14d;
-//! @brief 32-bit General purpose register.
-ASMJIT_VAR const GpReg r15d;
-#endif // ASMJIT_X64
-
-// ============================================================================
-// [AsmJit::Registers - 64-bit]
-// ============================================================================
-
-#ifdef ASMJIT_X64
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg rax;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg rcx;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg rdx;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg rbx;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg rsp;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg rbp;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg rsi;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg rdi;
-
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r8;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r9;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r10;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r11;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r12;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r13;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r14;
-//! @brief 64-bit General purpose register (64-bit mode only).
-ASMJIT_VAR const GpReg r15;
-#endif // ASMJIT_X64
-
-// ============================================================================
-// [AsmJit::Registers - Native (AsmJit extension)]
-// ============================================================================
-
-//! @brief 32-bit or 64-bit General purpose register.
-ASMJIT_VAR const GpReg zax;
-//! @brief 32-bit or 64-bit General purpose register.
-ASMJIT_VAR const GpReg zcx;
-//! @brief 32-bit or 64-bit General purpose register.
-ASMJIT_VAR const GpReg zdx;
-//! @brief 32-bit or 64-bit General purpose register.
-ASMJIT_VAR const GpReg zbx;
-//! @brief 32-bit or 64-bit General purpose register.
-ASMJIT_VAR const GpReg zsp;
-//! @brief 32-bit or 64-bit General purpose register.
-ASMJIT_VAR const GpReg zbp;
-//! @brief 32-bit or 64-bit General purpose register.
-ASMJIT_VAR const GpReg zsi;
-//! @brief 32-bit or 64-bit General purpose register.
-ASMJIT_VAR const GpReg zdi;
-
-// ============================================================================
-// [AsmJit::Registers - MM]
-// ============================================================================
-
-//! @brief 64-bit MM register.
-ASMJIT_VAR const MmReg mm0;
-//! @brief 64-bit MM register.
-ASMJIT_VAR const MmReg mm1;
-//! @brief 64-bit MM register.
-ASMJIT_VAR const MmReg mm2;
-//! @brief 64-bit MM register.
-ASMJIT_VAR const MmReg mm3;
-//! @brief 64-bit MM register.
-ASMJIT_VAR const MmReg mm4;
-//! @brief 64-bit MM register.
-ASMJIT_VAR const MmReg mm5;
-//! @brief 64-bit MM register.
-ASMJIT_VAR const MmReg mm6;
-//! @brief 64-bit MM register.
-ASMJIT_VAR const MmReg mm7;
-
-// ============================================================================
-// [AsmJit::Registers - XMM]
-// ============================================================================
-
-//! @brief 128-bit XMM register.
-ASMJIT_VAR const XmmReg xmm0;
-//! @brief 128-bit XMM register.
-ASMJIT_VAR const XmmReg xmm1;
-//! @brief 128-bit XMM register.
-ASMJIT_VAR const XmmReg xmm2;
-//! @brief 128-bit XMM register.
-ASMJIT_VAR const XmmReg xmm3;
-//! @brief 128-bit XMM register.
-ASMJIT_VAR const XmmReg xmm4;
-//! @brief 128-bit XMM register.
-ASMJIT_VAR const XmmReg xmm5;
-//! @brief 128-bit XMM register.
-ASMJIT_VAR const XmmReg xmm6;
-//! @brief 128-bit XMM register.
-ASMJIT_VAR const XmmReg xmm7;
-
-#ifdef ASMJIT_X64
-//! @brief 128-bit XMM register (64-bit mode only).
-ASMJIT_VAR const XmmReg xmm8;
-//! @brief 128-bit XMM register (64-bit mode only).
-ASMJIT_VAR const XmmReg xmm9;
-//! @brief 128-bit XMM register (64-bit mode only).
-ASMJIT_VAR const XmmReg xmm10;
-//! @brief 128-bit XMM register (64-bit mode only).
-ASMJIT_VAR const XmmReg xmm11;
-//! @brief 128-bit XMM register (64-bit mode only).
-ASMJIT_VAR const XmmReg xmm12;
-//! @brief 128-bit XMM register (64-bit mode only).
-ASMJIT_VAR const XmmReg xmm13;
-//! @brief 128-bit XMM register (64-bit mode only).
-ASMJIT_VAR const XmmReg xmm14;
-//! @brief 128-bit XMM register (64-bit mode only).
-ASMJIT_VAR const XmmReg xmm15;
-#endif // ASMJIT_X64
-
-// ============================================================================
-// [AsmJit::Registers - Segment]
-// ============================================================================
-
-//! @brief CS segment register.
-ASMJIT_VAR const SegmentReg cs;
-//! @brief SS segment register.
-ASMJIT_VAR const SegmentReg ss;
-//! @brief DS segment register.
-ASMJIT_VAR const SegmentReg ds;
-//! @brief ES segment register.
-ASMJIT_VAR const SegmentReg es;
-//! @brief FS segment register.
-ASMJIT_VAR const SegmentReg fs;
-//! @brief GS segment register.
-ASMJIT_VAR const SegmentReg gs;
-
-// ============================================================================
-// [AsmJit::Registers - Register From Index]
-// ============================================================================
-
-//! @brief Get general purpose register of byte size.
-inline GpReg gpb_lo(uint32_t index) { return GpReg(_Initialize(), index | kX86RegTypeGpbLo); }
-
-//! @brief Get general purpose register of byte size.
-inline GpReg gpb_hi(uint32_t index) { return GpReg(_Initialize(), index | kX86RegTypeGpbHi); }
-
-//! @brief Get general purpose register of word size.
-inline GpReg gpw(uint32_t index) { return GpReg(_Initialize(), index | kX86RegTypeGpw); }
-
-//! @brief Get general purpose register of dword size.
-inline GpReg gpd(uint32_t index) { return GpReg(_Initialize(), index | kX86RegTypeGpd); }
-
-#ifdef ASMJIT_X64
-//! @brief Get general purpose register of qword size (64-bit only).
-inline GpReg gpq(uint32_t index) { return GpReg(_Initialize(), index | kX86RegTypeGpq); }
-#endif
-
-//! @brief Get general purpose dword/qword register (depending to architecture).
-inline GpReg gpz(uint32_t index) { return GpReg(_Initialize(), index | kX86RegTypeGpz); }
-
-//! @brief Get MMX (MM) register .
-inline MmReg mm(uint32_t index) { return MmReg(_Initialize(), index | kX86RegTypeMm); }
-
-//! @brief Get SSE (XMM) register.
-inline XmmReg xmm(uint32_t index) { return XmmReg(_Initialize(), index | kX86RegTypeXmm); }
-
-//! @brief Get x87 register with index @a i.
-inline X87Reg st(uint32_t i)
-{
- ASMJIT_ASSERT(i < 8);
- return X87Reg(_Initialize(), i);
+// [asmjit::X86XmmReg]
+// ============================================================================
+
+//! X86/X64 128-bit Xmm register.
+struct X86XmmReg : public X86Reg {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a dummy Xmm register.
+ ASMJIT_INLINE X86XmmReg() : X86Reg() {}
+ //! Create a reference to `other` Xmm register.
+ ASMJIT_INLINE X86XmmReg(const X86XmmReg& other) : X86Reg(other) {}
+ //! Create a reference to `other` Xmm register and change the index to `index`.
+ ASMJIT_INLINE X86XmmReg(const X86XmmReg& other, uint32_t index) : X86Reg(other, index) {}
+ //! Create a custom Xmm register.
+ ASMJIT_INLINE X86XmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
+ //! Create non-initialized Xmm register.
+ explicit ASMJIT_INLINE X86XmmReg(const _NoInit&) : X86Reg(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [X86XmmReg Specific]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_REG_OP(X86XmmReg)
+};
+
+// ============================================================================
+// [asmjit::X86YmmReg]
+// ============================================================================
+
+//! X86/X64 256-bit Ymm register.
+struct X86YmmReg : public X86Reg {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a dummy Ymm register.
+ ASMJIT_INLINE X86YmmReg() : X86Reg() {}
+ //! Create a reference to `other` Xmm register.
+ ASMJIT_INLINE X86YmmReg(const X86YmmReg& other) : X86Reg(other) {}
+ //! Create a reference to `other` Ymm register and change the index to `index`.
+ ASMJIT_INLINE X86YmmReg(const X86YmmReg& other, uint32_t index) : X86Reg(other, index) {}
+ //! Create a custom Ymm register.
+ ASMJIT_INLINE X86YmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
+ //! Create non-initialized Ymm register.
+ explicit ASMJIT_INLINE X86YmmReg(const _NoInit&) : X86Reg(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [X86YmmReg Specific]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_REG_OP(X86YmmReg)
+};
+
+// ============================================================================
+// [asmjit::X86SegReg]
+// ============================================================================
+
+//! X86/X64 segment register.
+struct X86SegReg : public X86Reg {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a dummy segment register.
+ ASMJIT_INLINE X86SegReg() : X86Reg() {}
+ //! Create a reference to `other` segment register.
+ ASMJIT_INLINE X86SegReg(const X86SegReg& other) : X86Reg(other) {}
+ //! Create a reference to `other` segment register and change the index to `index`.
+ ASMJIT_INLINE X86SegReg(const X86SegReg& other, uint32_t index) : X86Reg(other, index) {}
+ //! Create a custom segment register.
+ ASMJIT_INLINE X86SegReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
+ //! Create non-initialized segment register.
+ explicit ASMJIT_INLINE X86SegReg(const _NoInit&) : X86Reg(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [X86SegReg Specific]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_REG_OP(X86SegReg)
+};
+
+// ============================================================================
+// [asmjit::X86Mem]
+// ============================================================================
+
+//! X86 memory operand.
+struct X86Mem : public BaseMem {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE X86Mem() : BaseMem(NoInit) {
+ reset();
+ }
+
+ ASMJIT_INLINE X86Mem(const Label& label, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeLabel, 0, label._base.id);
+ _init_packed_d2_d3(kInvalidValue, disp);
+ }
+
+ ASMJIT_INLINE X86Mem(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
+ ASMJIT_ASSERT(shift <= 3);
+
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeLabel,
+ (kX86MemVSibGpz << kX86MemVSibIndex)
+ + (shift << kX86MemShiftIndex),
+ label.getId());
+ _vmem.index = index.getRegIndex();
+ _vmem.displacement = disp;
+ }
+
+ ASMJIT_INLINE X86Mem(const X86GpReg& base, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
+ _getGpdFlags(base)
+ + (kX86MemVSibGpz << kX86MemVSibIndex),
+ base.getRegIndex());
+ _init_packed_d2_d3(kInvalidValue, disp);
+ }
+
+ ASMJIT_INLINE X86Mem(const X86GpReg& base, const X86GpReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
+ ASMJIT_ASSERT(shift <= 3);
+
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
+ _getGpdFlags(base) + (shift << kX86MemShiftIndex),
+ base.getRegIndex());
+ _vmem.index = index.getRegIndex();
+ _vmem.displacement = disp;
+ }
+
+ ASMJIT_INLINE X86Mem(const X86GpReg& base, const X86XmmReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
+ ASMJIT_ASSERT(shift <= 3);
+
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
+ _getGpdFlags(base)
+ + (kX86MemVSibXmm << kX86MemVSibIndex)
+ + (shift << kX86MemShiftIndex),
+ base.getRegIndex());
+ _vmem.index = index.getRegIndex();
+ _vmem.displacement = disp;
+ }
+
+ ASMJIT_INLINE X86Mem(const X86GpReg& base, const X86YmmReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
+ ASMJIT_ASSERT(shift <= 3);
+
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
+ _getGpdFlags(base)
+ + (kX86MemVSibYmm << kX86MemVSibIndex)
+ + (shift << kX86MemShiftIndex),
+ base.getRegIndex());
+ _vmem.index = index.getRegIndex();
+ _vmem.displacement = disp;
+ }
+
+# ifndef ASMJIT_DISABLE_COMPILER
+ ASMJIT_INLINE X86Mem(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
+ ASMJIT_ASSERT(shift <= 3);
+
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeLabel,
+ (kX86MemVSibGpz << kX86MemVSibIndex)
+ + (shift << kX86MemShiftIndex),
+ label.getId());
+ _vmem.index = _OP_ID(index);
+ _vmem.displacement = disp;
+ }
+
+ ASMJIT_INLINE X86Mem(const X86GpVar& base, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
+ _getGpdFlags(reinterpret_cast<const Var&>(base))
+ + (kX86MemVSibGpz << kX86MemVSibIndex),
+ _OP_ID(base));
+ _init_packed_d2_d3(kInvalidValue, disp);
+ }
+
+ ASMJIT_INLINE X86Mem(const X86GpVar& base, const X86GpVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
+ ASMJIT_ASSERT(shift <= 3);
+
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
+ _getGpdFlags(reinterpret_cast<const Var&>(base))
+ + (shift << kX86MemShiftIndex),
+ _OP_ID(base));
+ _vmem.index = _OP_ID(index);
+ _vmem.displacement = disp;
+ }
+
+ ASMJIT_INLINE X86Mem(const X86GpVar& base, const X86XmmVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
+ ASMJIT_ASSERT(shift <= 3);
+
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
+ _getGpdFlags(reinterpret_cast<const Var&>(base))
+ + (kX86MemVSibXmm << kX86MemVSibIndex)
+ + (shift << kX86MemShiftIndex),
+ _OP_ID(base));
+ _vmem.index = _OP_ID(index);
+ _vmem.displacement = disp;
+ }
+
+ ASMJIT_INLINE X86Mem(const X86GpVar& base, const X86YmmVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
+ ASMJIT_ASSERT(shift <= 3);
+
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
+ _getGpdFlags(reinterpret_cast<const Var&>(base))
+ + (kX86MemVSibYmm << kX86MemVSibIndex)
+ + (shift << kX86MemShiftIndex),
+ _OP_ID(base));
+ _vmem.index = _OP_ID(index);
+ _vmem.displacement = disp;
+ }
+
+ ASMJIT_INLINE X86Mem(const _Init&, uint32_t memType, const X86Var& base, int32_t disp, uint32_t size) : BaseMem(NoInit) {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, 0, _OP_ID(base));
+ _vmem.index = kInvalidValue;
+ _vmem.displacement = disp;
+ }
+
+ ASMJIT_INLINE X86Mem(const _Init&, uint32_t memType, const X86Var& base, const X86GpVar& index, uint32_t shift, int32_t disp, uint32_t size) : BaseMem(NoInit) {
+ ASMJIT_ASSERT(shift <= 3);
+
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, shift << kX86MemShiftIndex, _OP_ID(base));
+ _vmem.index = _OP_ID(index);
+ _vmem.displacement = disp;
+ }
+# endif // !ASMJIT_DISABLE_COMPILER
+
+ ASMJIT_INLINE X86Mem(const X86Mem& other) : BaseMem(other) {}
+ explicit ASMJIT_INLINE X86Mem(const _NoInit&) : BaseMem(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [X86Mem Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone X86Mem operand.
+ ASMJIT_INLINE X86Mem clone() const {
+ return X86Mem(*this);
+ }
+
+ //! Reset X86Mem operand.
+ ASMJIT_INLINE void reset() {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, 0, kMemTypeBaseIndex, 0, kInvalidValue);
+ _init_packed_d2_d3(kInvalidValue, 0);
+ }
+
+ //! \internal
+ ASMJIT_INLINE void _init(uint32_t memType, uint32_t base, int32_t disp, uint32_t size) {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, 0, base);
+ _vmem.index = kInvalidValue;
+ _vmem.displacement = disp;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Segment]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the memory operand has segment override prefix.
+ ASMJIT_INLINE bool hasSegment() const {
+ return (_vmem.flags & kX86MemSegMask) != (kX86SegDefault << kX86MemSegIndex);
+ }
+
+ //! Get memory operand segment, see `kX86Seg`.
+ ASMJIT_INLINE uint32_t getSegment() const {
+ return (static_cast<uint32_t>(_vmem.flags) >> kX86MemSegIndex) & kX86MemSegBits;
+ }
+
+ //! Set memory operand segment, see `kX86Seg`.
+ ASMJIT_INLINE X86Mem& setSegment(uint32_t segIndex) {
+ _vmem.flags = static_cast<uint8_t>(
+ (static_cast<uint32_t>(_vmem.flags) & kX86MemSegMask) + (segIndex << kX86MemSegIndex));
+ return *this;
+ }
+
+ //! Set memory operand segment, see `kX86Seg`.
+ ASMJIT_INLINE X86Mem& setSegment(const X86SegReg& seg) {
+ return setSegment(seg.getRegIndex());
+ }
+
+ // --------------------------------------------------------------------------
+ // [Gpd]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the memory operand has 32-bit GP base.
+ ASMJIT_INLINE bool hasGpdBase() const {
+ return (_packed[0].u32[0] & IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemGpdMask)) != 0;
+ }
+
+ //! Set whether the memory operand has 32-bit GP base.
+ ASMJIT_INLINE X86Mem& setGpdBase() {
+ _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemGpdMask);
+ return *this;
+ }
+
+ //! Set whether the memory operand has 32-bit GP base to `b`.
+ ASMJIT_INLINE X86Mem& setGpdBase(uint32_t b) {
+ _packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemGpdMask);
+ _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, b << kX86MemGpdIndex);
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [VSib]
+ // --------------------------------------------------------------------------
+
+ //! Get SIB type.
+ ASMJIT_INLINE uint32_t getVSib() const {
+ return (static_cast<uint32_t>(_vmem.flags) >> kX86MemVSibIndex) & kX86MemVSibBits;
+ }
+
+ //! Set SIB type.
+ ASMJIT_INLINE X86Mem& _setVSib(uint32_t vsib) {
+ _packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemVSibMask);
+ _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, vsib << kX86MemVSibIndex);
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Size]
+ // --------------------------------------------------------------------------
+
+ //! Set memory operand size.
+ ASMJIT_INLINE X86Mem& setSize(uint32_t size) {
+ _vmem.size = static_cast<uint8_t>(size);
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Base]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the memory operand has base register.
+ ASMJIT_INLINE bool hasBase() const {
+ return _vmem.base != kInvalidValue;
+ }
+
+ //! Get memory operand base register code, variable id, or `kInvalidValue`.
+ ASMJIT_INLINE uint32_t getBase() const {
+ return _vmem.base;
+ }
+
+ //! Set memory operand base register code, variable id, or `kInvalidValue`.
+ ASMJIT_INLINE X86Mem& setBase(uint32_t base) {
+ _vmem.base = base;
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Index]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the memory operand has index.
+ ASMJIT_INLINE bool hasIndex() const {
+ return _vmem.index != kInvalidValue;
+ }
+
+ //! Get memory operand index register code, variable id, or `kInvalidValue`.
+ ASMJIT_INLINE uint32_t getIndex() const {
+ return _vmem.index;
+ }
+
+ //! Set memory operand index register code, variable id, or `kInvalidValue`.
+ ASMJIT_INLINE X86Mem& setIndex(uint32_t index) {
+ _vmem.index = index;
+ return *this;
+ }
+
+ //! Set memory index.
+ ASMJIT_INLINE X86Mem& setIndex(const X86GpReg& index) {
+ _vmem.index = index.getRegIndex();
+ return _setVSib(kX86MemVSibGpz);
+ }
+
+ //! Set memory index.
+ ASMJIT_INLINE X86Mem& setIndex(const X86GpReg& index, uint32_t shift) {
+ _vmem.index = index.getRegIndex();
+ return _setVSib(kX86MemVSibGpz).setShift(shift);
+ }
+
+ //! Set memory index.
+ ASMJIT_INLINE X86Mem& setIndex(const X86XmmReg& index) {
+ _vmem.index = index.getRegIndex();
+ return _setVSib(kX86MemVSibXmm);
+ }
+
+ //! Set memory index.
+ ASMJIT_INLINE X86Mem& setIndex(const X86XmmReg& index, uint32_t shift) {
+ _vmem.index = index.getRegIndex();
+ return _setVSib(kX86MemVSibXmm).setShift(shift);
+ }
+
+ //! Set memory index.
+ ASMJIT_INLINE X86Mem& setIndex(const X86YmmReg& index) {
+ _vmem.index = index.getRegIndex();
+ return _setVSib(kX86MemVSibYmm);
+ }
+
+ //! Set memory index.
+ ASMJIT_INLINE X86Mem& setIndex(const X86YmmReg& index, uint32_t shift) {
+ _vmem.index = index.getRegIndex();
+ return _setVSib(kX86MemVSibYmm).setShift(shift);
+ }
+
+# ifndef ASMJIT_DISABLE_COMPILER
+ //! Set memory index.
+ ASMJIT_INLINE X86Mem& setIndex(const X86GpVar& index) {
+ _vmem.index = _OP_ID(index);
+ return _setVSib(kX86MemVSibGpz);
+ }
+
+ //! Set memory index.
+ ASMJIT_INLINE X86Mem& setIndex(const X86GpVar& index, uint32_t shift) {
+ _vmem.index = _OP_ID(index);
+ return _setVSib(kX86MemVSibGpz).setShift(shift);
+ }
+
+
+ //! Set memory index.
+ ASMJIT_INLINE X86Mem& setIndex(const X86XmmVar& index) {
+ _vmem.index = _OP_ID(index);
+ return _setVSib(kX86MemVSibXmm);
+ }
+
+ //! Set memory index.
+ ASMJIT_INLINE X86Mem& setIndex(const X86XmmVar& index, uint32_t shift) {
+ _vmem.index = _OP_ID(index);
+ return _setVSib(kX86MemVSibXmm).setShift(shift);
+ }
+
+ //! Set memory index.
+ ASMJIT_INLINE X86Mem& setIndex(const X86YmmVar& index) {
+ _vmem.index = _OP_ID(index);
+ return _setVSib(kX86MemVSibYmm);
+ }
+
+ //! Set memory index.
+ ASMJIT_INLINE X86Mem& setIndex(const X86YmmVar& index, uint32_t shift) {
+ _vmem.index = _OP_ID(index);
+ return _setVSib(kX86MemVSibYmm).setShift(shift);
+ }
+# endif // !ASMJIT_DISABLE_COMPILER
+
+ //! Reset memory index.
+ ASMJIT_INLINE X86Mem& resetIndex() {
+ _vmem.index = kInvalidValue;
+ return _setVSib(kX86MemVSibGpz);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Misc]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the memory operand has base and index register.
+ ASMJIT_INLINE bool hasBaseOrIndex() const {
+ return _vmem.base != kInvalidValue || _vmem.index != kInvalidValue;
+ }
+
+ //! Get whether the memory operand has base and index register.
+ ASMJIT_INLINE bool hasBaseAndIndex() const {
+ return _vmem.base != kInvalidValue && _vmem.index != kInvalidValue;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Shift]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the memory operand has shift used.
+ ASMJIT_INLINE bool hasShift() const {
+ return (_vmem.flags & kX86MemShiftMask) != 0;
+ }
+
+ //! Get memory operand index scale (0, 1, 2 or 3).
+ ASMJIT_INLINE uint32_t getShift() const {
+ return _vmem.flags >> kX86MemShiftIndex;
+ }
+
+ //! Set memory operand index scale (0, 1, 2 or 3).
+ ASMJIT_INLINE X86Mem& setShift(uint32_t shift) {
+ _packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemShiftMask);
+ _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, shift << kX86MemShiftIndex);
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Displacement]
+ // --------------------------------------------------------------------------
+
+ //! Get memory operand relative displacement.
+ ASMJIT_INLINE int32_t getDisplacement() const {
+ return _vmem.displacement;
+ }
+
+ //! Set memory operand relative displacement.
+ ASMJIT_INLINE X86Mem& setDisplacement(int32_t disp) {
+ _vmem.displacement = disp;
+ return *this;
+ }
+
+ //! Reset memory operand relative displacement.
+ ASMJIT_INLINE X86Mem& resetDisplacement(int32_t) {
+ _vmem.displacement = 0;
+ return *this;
+ }
+
+ //! Adjust memory operand relative displacement by `disp`.
+ ASMJIT_INLINE X86Mem& adjust(int32_t disp) {
+ _vmem.displacement += disp;
+ return *this;
+ }
+
+ //! Get new memory operand adjusted by `disp`.
+ ASMJIT_INLINE X86Mem adjusted(int32_t disp) const {
+ X86Mem result(*this);
+ result.adjust(disp);
+ return result;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE X86Mem& operator=(const X86Mem& other) {
+ _copy(other);
+ return *this;
+ }
+
+ ASMJIT_INLINE bool operator==(const X86Mem& other) const {
+ return (_packed[0] == other._packed[0]) & (_packed[1] == other._packed[1]) ;
+ }
+
+ ASMJIT_INLINE bool operator!=(const X86Mem& other) const {
+ return !(*this == other);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Static]
+ // --------------------------------------------------------------------------
+
+ static ASMJIT_INLINE uint32_t _getGpdFlags(const Operand& base) {
+ return (base._vreg.size & 0x4) << (kX86MemGpdIndex - 2);
+ }
+};
+#endif // !ASMJIT_EXPORTS_X86OPERAND_REGS
+
+// ============================================================================
+// [asmjit::x86]
+// ============================================================================
+
+namespace x86 {
+
+// ============================================================================
+// [asmjit::x86 - Reg]
+// ============================================================================
+
+//! No Gp register, can be used only within `X86Mem` operand.
+ASMJIT_VAR const X86GpReg noGpReg;
+
+ASMJIT_VAR const X86GpReg al; //!< 8-bit Gpb-lo register.
+ASMJIT_VAR const X86GpReg cl; //!< 8-bit Gpb-lo register.
+ASMJIT_VAR const X86GpReg dl; //!< 8-bit Gpb-lo register.
+ASMJIT_VAR const X86GpReg bl; //!< 8-bit Gpb-lo register.
+ASMJIT_VAR const X86GpReg spl; //!< 8-bit Gpb-lo register (X64).
+ASMJIT_VAR const X86GpReg bpl; //!< 8-bit Gpb-lo register (X64).
+ASMJIT_VAR const X86GpReg sil; //!< 8-bit Gpb-lo register (X64).
+ASMJIT_VAR const X86GpReg dil; //!< 8-bit Gpb-lo register (X64).
+ASMJIT_VAR const X86GpReg r8b; //!< 8-bit Gpb-lo register (X64).
+ASMJIT_VAR const X86GpReg r9b; //!< 8-bit Gpb-lo register (X64).
+ASMJIT_VAR const X86GpReg r10b; //!< 8-bit Gpb-lo register (X64).
+ASMJIT_VAR const X86GpReg r11b; //!< 8-bit Gpb-lo register (X64).
+ASMJIT_VAR const X86GpReg r12b; //!< 8-bit Gpb-lo register (X64).
+ASMJIT_VAR const X86GpReg r13b; //!< 8-bit Gpb-lo register (X64).
+ASMJIT_VAR const X86GpReg r14b; //!< 8-bit Gpb-lo register (X64).
+ASMJIT_VAR const X86GpReg r15b; //!< 8-bit Gpb-lo register (X64).
+
+ASMJIT_VAR const X86GpReg ah; //!< 8-bit Gpb-hi register.
+ASMJIT_VAR const X86GpReg ch; //!< 8-bit Gpb-hi register.
+ASMJIT_VAR const X86GpReg dh; //!< 8-bit Gpb-hi register.
+ASMJIT_VAR const X86GpReg bh; //!< 8-bit Gpb-hi register.
+
+ASMJIT_VAR const X86GpReg ax; //!< 16-bit Gpw register.
+ASMJIT_VAR const X86GpReg cx; //!< 16-bit Gpw register.
+ASMJIT_VAR const X86GpReg dx; //!< 16-bit Gpw register.
+ASMJIT_VAR const X86GpReg bx; //!< 16-bit Gpw register.
+ASMJIT_VAR const X86GpReg sp; //!< 16-bit Gpw register.
+ASMJIT_VAR const X86GpReg bp; //!< 16-bit Gpw register.
+ASMJIT_VAR const X86GpReg si; //!< 16-bit Gpw register.
+ASMJIT_VAR const X86GpReg di; //!< 16-bit Gpw register.
+ASMJIT_VAR const X86GpReg r8w; //!< 16-bit Gpw register (X64).
+ASMJIT_VAR const X86GpReg r9w; //!< 16-bit Gpw register (X64).
+ASMJIT_VAR const X86GpReg r10w; //!< 16-bit Gpw register (X64).
+ASMJIT_VAR const X86GpReg r11w; //!< 16-bit Gpw register (X64).
+ASMJIT_VAR const X86GpReg r12w; //!< 16-bit Gpw register (X64).
+ASMJIT_VAR const X86GpReg r13w; //!< 16-bit Gpw register (X64).
+ASMJIT_VAR const X86GpReg r14w; //!< 16-bit Gpw register (X64).
+ASMJIT_VAR const X86GpReg r15w; //!< 16-bit Gpw register (X64).
+
+ASMJIT_VAR const X86GpReg eax; //!< 32-bit Gpd register.
+ASMJIT_VAR const X86GpReg ecx; //!< 32-bit Gpd register.
+ASMJIT_VAR const X86GpReg edx; //!< 32-bit Gpd register.
+ASMJIT_VAR const X86GpReg ebx; //!< 32-bit Gpd register.
+ASMJIT_VAR const X86GpReg esp; //!< 32-bit Gpd register.
+ASMJIT_VAR const X86GpReg ebp; //!< 32-bit Gpd register.
+ASMJIT_VAR const X86GpReg esi; //!< 32-bit Gpd register.
+ASMJIT_VAR const X86GpReg edi; //!< 32-bit Gpd register.
+ASMJIT_VAR const X86GpReg r8d; //!< 32-bit Gpd register (X64).
+ASMJIT_VAR const X86GpReg r9d; //!< 32-bit Gpd register (X64).
+ASMJIT_VAR const X86GpReg r10d; //!< 32-bit Gpd register (X64).
+ASMJIT_VAR const X86GpReg r11d; //!< 32-bit Gpd register (X64).
+ASMJIT_VAR const X86GpReg r12d; //!< 32-bit Gpd register (X64).
+ASMJIT_VAR const X86GpReg r13d; //!< 32-bit Gpd register (X64).
+ASMJIT_VAR const X86GpReg r14d; //!< 32-bit Gpd register (X64).
+ASMJIT_VAR const X86GpReg r15d; //!< 32-bit Gpd register (X64).
+
+ASMJIT_VAR const X86GpReg rax; //!< 64-bit Gpq register (X64).
+ASMJIT_VAR const X86GpReg rcx; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg rdx; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg rbx; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg rsp; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg rbp; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg rsi; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg rdi; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg r8; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg r9; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg r10; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg r11; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg r12; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg r13; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg r14; //!< 64-bit Gpq register (X64)
+ASMJIT_VAR const X86GpReg r15; //!< 64-bit Gpq register (X64)
+
+ASMJIT_VAR const X86FpReg fp0; //!< 80-bit Fp register.
+ASMJIT_VAR const X86FpReg fp1; //!< 80-bit Fp register.
+ASMJIT_VAR const X86FpReg fp2; //!< 80-bit Fp register.
+ASMJIT_VAR const X86FpReg fp3; //!< 80-bit Fp register.
+ASMJIT_VAR const X86FpReg fp4; //!< 80-bit Fp register.
+ASMJIT_VAR const X86FpReg fp5; //!< 80-bit Fp register.
+ASMJIT_VAR const X86FpReg fp6; //!< 80-bit Fp register.
+ASMJIT_VAR const X86FpReg fp7; //!< 80-bit Fp register.
+
+ASMJIT_VAR const X86MmReg mm0; //!< 64-bit Mm register.
+ASMJIT_VAR const X86MmReg mm1; //!< 64-bit Mm register.
+ASMJIT_VAR const X86MmReg mm2; //!< 64-bit Mm register.
+ASMJIT_VAR const X86MmReg mm3; //!< 64-bit Mm register.
+ASMJIT_VAR const X86MmReg mm4; //!< 64-bit Mm register.
+ASMJIT_VAR const X86MmReg mm5; //!< 64-bit Mm register.
+ASMJIT_VAR const X86MmReg mm6; //!< 64-bit Mm register.
+ASMJIT_VAR const X86MmReg mm7; //!< 64-bit Mm register.
+
+ASMJIT_VAR const X86XmmReg xmm0; //!< 128-bit Xmm register.
+ASMJIT_VAR const X86XmmReg xmm1; //!< 128-bit Xmm register.
+ASMJIT_VAR const X86XmmReg xmm2; //!< 128-bit Xmm register.
+ASMJIT_VAR const X86XmmReg xmm3; //!< 128-bit Xmm register.
+ASMJIT_VAR const X86XmmReg xmm4; //!< 128-bit Xmm register.
+ASMJIT_VAR const X86XmmReg xmm5; //!< 128-bit Xmm register.
+ASMJIT_VAR const X86XmmReg xmm6; //!< 128-bit Xmm register.
+ASMJIT_VAR const X86XmmReg xmm7; //!< 128-bit Xmm register.
+ASMJIT_VAR const X86XmmReg xmm8; //!< 128-bit Xmm register (X64).
+ASMJIT_VAR const X86XmmReg xmm9; //!< 128-bit Xmm register (X64).
+ASMJIT_VAR const X86XmmReg xmm10; //!< 128-bit Xmm register (X64).
+ASMJIT_VAR const X86XmmReg xmm11; //!< 128-bit Xmm register (X64).
+ASMJIT_VAR const X86XmmReg xmm12; //!< 128-bit Xmm register (X64).
+ASMJIT_VAR const X86XmmReg xmm13; //!< 128-bit Xmm register (X64).
+ASMJIT_VAR const X86XmmReg xmm14; //!< 128-bit Xmm register (X64).
+ASMJIT_VAR const X86XmmReg xmm15; //!< 128-bit Xmm register (X64).
+
+ASMJIT_VAR const X86YmmReg ymm0; //!< 256-bit Ymm register.
+ASMJIT_VAR const X86YmmReg ymm1; //!< 256-bit Ymm register.
+ASMJIT_VAR const X86YmmReg ymm2; //!< 256-bit Ymm register.
+ASMJIT_VAR const X86YmmReg ymm3; //!< 256-bit Ymm register.
+ASMJIT_VAR const X86YmmReg ymm4; //!< 256-bit Ymm register.
+ASMJIT_VAR const X86YmmReg ymm5; //!< 256-bit Ymm register.
+ASMJIT_VAR const X86YmmReg ymm6; //!< 256-bit Ymm register.
+ASMJIT_VAR const X86YmmReg ymm7; //!< 256-bit Ymm register.
+ASMJIT_VAR const X86YmmReg ymm8; //!< 256-bit Ymm register (X64).
+ASMJIT_VAR const X86YmmReg ymm9; //!< 256-bit Ymm register (X64).
+ASMJIT_VAR const X86YmmReg ymm10; //!< 256-bit Ymm register (X64).
+ASMJIT_VAR const X86YmmReg ymm11; //!< 256-bit Ymm register (X64).
+ASMJIT_VAR const X86YmmReg ymm12; //!< 256-bit Ymm register (X64).
+ASMJIT_VAR const X86YmmReg ymm13; //!< 256-bit Ymm register (X64).
+ASMJIT_VAR const X86YmmReg ymm14; //!< 256-bit Ymm register (X64).
+ASMJIT_VAR const X86YmmReg ymm15; //!< 256-bit Ymm register (X64).
+
+ASMJIT_VAR const X86SegReg cs; //!< Cs segment register.
+ASMJIT_VAR const X86SegReg ss; //!< Ss segment register.
+ASMJIT_VAR const X86SegReg ds; //!< Ds segment register.
+ASMJIT_VAR const X86SegReg es; //!< Es segment register.
+ASMJIT_VAR const X86SegReg fs; //!< Fs segment register.
+ASMJIT_VAR const X86SegReg gs; //!< Gs segment register.
+
+// This is only defined by `x86operand_regs.cpp` when exporting registers.
+#ifndef ASMJIT_EXPORTS_X86OPERAND_REGS
+
+//! Create 8-bit Gpb-lo register operand.
+static ASMJIT_INLINE X86GpReg gpb_lo(uint32_t index) { return X86GpReg(kX86RegTypeGpbLo, index, 1); }
+//! Create 8-bit Gpb-hi register operand.
+static ASMJIT_INLINE X86GpReg gpb_hi(uint32_t index) { return X86GpReg(kX86RegTypeGpbHi, index, 1); }
+//! Create 16-bit Gpw register operand.
+static ASMJIT_INLINE X86GpReg gpw(uint32_t index) { return X86GpReg(kX86RegTypeGpw, index, 2); }
+//! Create 32-bit Gpd register operand.
+static ASMJIT_INLINE X86GpReg gpd(uint32_t index) { return X86GpReg(kX86RegTypeGpd, index, 4); }
+//! Create 64-bit Gpq register operand (X64).
+static ASMJIT_INLINE X86GpReg gpq(uint32_t index) { return X86GpReg(kX86RegTypeGpq, index, 8); }
+//! Create 80-bit Fp register operand.
+static ASMJIT_INLINE X86FpReg fp(uint32_t index) { return X86FpReg(kX86RegTypeFp, index, 10); }
+//! Create 64-bit Mm register operand.
+static ASMJIT_INLINE X86MmReg mm(uint32_t index) { return X86MmReg(kX86RegTypeMm, index, 8); }
+//! Create 128-bit Xmm register operand.
+static ASMJIT_INLINE X86XmmReg xmm(uint32_t index) { return X86XmmReg(kX86RegTypeXmm, index, 16); }
+//! Create 256-bit Ymm register operand.
+static ASMJIT_INLINE X86YmmReg ymm(uint32_t index) { return X86YmmReg(kX86RegTypeYmm, index, 32); }
+
+// ============================================================================
+// [asmjit::x86 - Ptr (Reg)]
+// ============================================================================
+
+//! Create `[base.reg + disp]` memory operand with no/custom size information.
+static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, int32_t disp = 0, uint32_t size = 0) {
+ return X86Mem(base, disp, size);
}
-
-// ============================================================================
-// [AsmJit::Mem]
-// ============================================================================
-
-//! @brief Memory operand.
-struct Mem : public Operand
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- Mem() : Operand(_DontInitialize())
- {
- this->_mem.op = kOperandMem;
- this->_mem.size = 0;
- this->_mem.type = kOperandMemNative;
- this->_mem.segment = kX86SegNone;
- this->_mem.sizePrefix = 0;
- this->_mem.shift = 0;
-
- this->_mem.id = kInvalidValue;
- this->_mem.base = kInvalidValue;
- this->_mem.index = kInvalidValue;
-
- this->_mem.target = nullptr;
- this->_mem.displacement = 0;
- }
-
- Mem(const Label &label, sysint_t displacement, uint32_t size = 0) : Operand(_DontInitialize())
- {
- this->_mem.op = kOperandMem;
- this->_mem.size = static_cast<uint8_t>(size);
- this->_mem.type = kOperandMemLabel;
- this->_mem.segment = kX86SegNone;
- this->_mem.sizePrefix = 0;
- this->_mem.shift = 0;
-
- this->_mem.id = kInvalidValue;
- this->_mem.base = reinterpret_cast<const Operand &>(label)._base.id;
- _mem.index = kInvalidValue;
-
- _mem.target = nullptr;
- _mem.displacement = displacement;
- }
-
- Mem(const GpReg &base, sysint_t displacement, uint32_t size = 0) : Operand(_DontInitialize())
- {
- this->_mem.op = kOperandMem;
- this->_mem.size = static_cast<uint8_t>(size);
- this->_mem.type = kOperandMemNative;
- this->_mem.segment = kX86SegNone;
-
-#ifdef ASMJIT_X86
- this->_mem.sizePrefix = base.getSize() != 4;
-#else
- this->_mem.sizePrefix = base.getSize() != 8;
-#endif
-
- this->_mem.shift = 0;
-
- this->_mem.id = kInvalidValue;
- this->_mem.base = base.getRegCode() & kRegIndexMask;
- this->_mem.index = kInvalidValue;
-
- this->_mem.target = nullptr;
- this->_mem.displacement = displacement;
- }
-
- Mem(const GpVar &base, sysint_t displacement, uint32_t size = 0) : Operand(_DontInitialize())
- {
- this->_mem.op = kOperandMem;
- this->_mem.size = static_cast<uint8_t>(size);
- this->_mem.type = kOperandMemNative;
- this->_mem.segment = kX86SegNone;
-
-#ifdef ASMJIT_X86
- this->_mem.sizePrefix = (reinterpret_cast<const Operand &>(base)._var.size) != 4;
-#else
- this->_mem.sizePrefix = (reinterpret_cast<const Operand &>(base)._var.size) != 8;
-#endif
-
- this->_mem.shift = 0;
-
- this->_mem.id = kInvalidValue;
- this->_mem.base = reinterpret_cast<const Operand &>(base).getId();
- this->_mem.index = kInvalidValue;
-
- this->_mem.target = nullptr;
- this->_mem.displacement = displacement;
- }
-
- Mem(const GpReg &base, const GpReg &index, uint32_t shift, sysint_t displacement, uint32_t size = 0) : Operand(_DontInitialize())
- {
- ASMJIT_ASSERT(shift <= 3);
-
- this->_mem.op = kOperandMem;
- this->_mem.size = static_cast<uint8_t>(size);
- this->_mem.type = kOperandMemNative;
- this->_mem.segment = kX86SegNone;
-
-#ifdef ASMJIT_X86
- this->_mem.sizePrefix = (base.getSize() | index.getSize()) != 4;
-#else
- this->_mem.sizePrefix = (base.getSize() | index.getSize()) != 8;
-#endif
-
- this->_mem.shift = static_cast<uint8_t>(shift);
-
- this->_mem.id = kInvalidValue;
- this->_mem.base = base.getRegIndex();
- this->_mem.index = index.getRegIndex();
-
- this->_mem.target = nullptr;
- this->_mem.displacement = displacement;
- }
-
- Mem(const GpVar &base, const GpVar &index, uint32_t shift, sysint_t displacement, uint32_t size = 0) : Operand(_DontInitialize())
- {
- ASMJIT_ASSERT(shift <= 3);
-
- this->_mem.op = kOperandMem;
- this->_mem.size = static_cast<uint8_t>(size);
- this->_mem.type = kOperandMemNative;
- this->_mem.segment = kX86SegNone;
-
-#ifdef ASMJIT_X86
- this->_mem.sizePrefix = (reinterpret_cast<const Operand &>(base)._var.size | reinterpret_cast<const Operand &>(index)._var.size) != 4;
-#else
- this->_mem.sizePrefix = (reinterpret_cast<const Operand &>(base)._var.size | reinterpret_cast<const Operand &>(index)._var.size) != 8;
-#endif
-
- this->_mem.shift = static_cast<uint8_t>(shift);
-
- this->_mem.id = kInvalidValue;
- this->_mem.base = reinterpret_cast<const Operand &>(base).getId();
- this->_mem.index = reinterpret_cast<const Operand &>(index).getId();
-
- this->_mem.target = nullptr;
- this->_mem.displacement = displacement;
- }
-
- Mem(const Mem &other) : Operand(other) { }
-
- Mem(const _DontInitialize &dontInitialize) : Operand(dontInitialize) { }
-
- // --------------------------------------------------------------------------
- // [Mem Specific]
- // --------------------------------------------------------------------------
-
- //! @brief Get type of memory operand, see @c kOperandMemType.
- uint32_t getMemType() const { return this->_mem.type; }
-
- //! @brief Get memory operand segment, see @c kX86Seg.
- uint32_t getSegment() const { return this->_mem.segment; }
-
- //! @brief Set memory operand segment, see @c kX86Seg.
- Mem &setSegment(uint32_t seg)
- {
- this->_mem.segment = static_cast<uint8_t>(seg);
- return *this;
- }
-
- //! @brief Set memory operand segment, see @c kX86Seg.
- Mem &setSegment(const SegmentReg &seg)
- {
- this->_mem.segment = static_cast<uint8_t>(seg.getRegIndex());
- return *this;
- }
-
- //! @brief Get whether the memory operand has segment override prefix.
- bool hasSegment() const { return this->_mem.segment >= kX86SegCount; }
-
- //! @brief Get whether the memory operand has base register.
- bool hasBase() const { return this->_mem.base != kInvalidValue; }
-
- //! @brief Get whether the memory operand has index.
- bool hasIndex() const { return this->_mem.index != kInvalidValue; }
-
- //! @brief Get whether the memory operand has shift used.
- bool hasShift() const { return !!this->_mem.shift; }
-
- //! @brief Get memory operand base register or @c kInvalidValue.
- uint32_t getBase() const { return this->_mem.base; }
-
- //! @brief Get memory operand index register or @c kInvalidValue.
- uint32_t getIndex() const { return this->_mem.index; }
-
- //! @brief Get memory operand index scale (0, 1, 2 or 3).
- uint32_t getShift() const { return this->_mem.shift; }
-
- //! @brief Get whether to use size-override prefix.
- //!
- //! @note This is useful only for MOV and LEA type of instructions.
- bool getSizePrefix() const { return !!this->_mem.sizePrefix; }
-
- //! @brief Set whether to use size-override prefix.
- Mem &setSizePrefix(bool b)
- {
- this->_mem.sizePrefix = b;
- return *this;
- }
-
- //! @brief Get absolute target address.
- //!
- //! @note You should always check if operand contains address by @c getMemType().
- void *getTarget() const { return this->_mem.target; }
-
- //! @brief Set absolute target address.
- Mem &setTarget(void *target)
- {
- this->_mem.target = target;
- return *this;
- }
-
- //! @brief Set memory operand size.
- Mem &setSize(uint32_t size)
- {
- this->_mem.size = size;
- return *this;
- }
-
- //! @brief Get memory operand relative displacement.
- sysint_t getDisplacement() const { return this->_mem.displacement; }
-
- //! @brief Set memory operand relative displacement.
- Mem &setDisplacement(sysint_t displacement)
- {
- this->_mem.displacement = displacement;
- return *this;
- }
-
- //! @brief Adjust memory operand relative displacement by @a displacement.
- Mem &adjust(sysint_t displacement)
- {
- this->_mem.displacement += displacement;
- return *this;
- }
-
- //! @brief Get new memory operand adjusted by @a displacement.
- Mem adjusted(sysint_t displacement) const
- {
- Mem result(*this);
- result.adjust(displacement);
- return result;
- }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_NODOC
- Mem &operator=(const Mem &other) { this->_copy(other); return *this; }
-
- bool operator==(const Mem &other) const
- {
- return this->_bin.u32[0] == other._bin.u32[0] && this->_bin.u32[1] == other._bin.u32[1] && this->_bin.u32[2] == other._bin.u32[2] && this->_bin.u32[3] == other._bin.u32[3] &&
- this->_bin.uptr[0] == other._bin.uptr[0] && this->_bin.uptr[1] == other._bin.uptr[1];
- }
-
- bool operator!=(const Mem &other) const
- {
- return !(*this == other);
- }
-#endif // ASMJIT_NODOC
-};
-
-// ============================================================================
-// [AsmJit::Var]
-// ============================================================================
-
-ASMJIT_API Mem _BaseVarMem(const Var &var, uint32_t size, sysint_t disp = 0);
-ASMJIT_API Mem _BaseVarMem(const Var &var, uint32_t size, const GpVar &index, uint32_t shift, sysint_t disp);
-
-//! @brief Base class for all variables.
-struct Var : public Operand
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_NODOC
- Var(const _DontInitialize &dontInitialize) : Operand(dontInitialize) { }
-#endif // ASMJIT_NODOC
-
- Var() : Operand(_DontInitialize())
- {
- this->_var.op = kOperandVar;
- this->_var.size = 0;
- this->_var.regCode = kInvalidValue;
- this->_var.varType = kInvalidValue;
- this->_var.id = kInvalidValue;
- }
-
- Var(const Var &other) : Operand(other) { }
-
- // --------------------------------------------------------------------------
- // [Type]
- // --------------------------------------------------------------------------
-
- uint32_t getVarType() const { return this->_var.varType; }
-
- bool isGpVar() const { return this->_var.varType <= kX86VarTypeGpq; }
-
- bool isX87Var() const { return this->_var.varType >= kX86VarTypeX87 && this->_var.varType <= kX86VarTypeX87SD; }
-
- bool isMmVar() const { return this->_var.varType == kX86VarTypeMm; }
-
- bool isXmmVar() const { return this->_var.varType >= kX86VarTypeXmm && this->_var.varType <= kX86VarTypeXmmPD; }
-
- // --------------------------------------------------------------------------
- // [Memory Cast]
- // --------------------------------------------------------------------------
-
- //! @brief Cast this variable to memory operand.
- //!
- //! @note Size of operand depends on native variable type, you can use other
- //! variants if you want specific one.
- Mem m() const { return _BaseVarMem(*this, kInvalidValue); }
-
- //! @overload.
- Mem m(sysint_t disp) const { return _BaseVarMem(*this, kInvalidValue, disp); }
-
- //! @overload.
- Mem m(const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) const { return _BaseVarMem(*this, kInvalidValue, index, shift, disp); }
-
- //! @brief Cast this variable to 8-bit memory operand.
- Mem m8() const { return _BaseVarMem(*this, 1); }
-
- //! @overload.
- Mem m8(sysint_t disp) const { return _BaseVarMem(*this, 1, disp); }
-
- //! @overload.
- Mem m8(const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) const { return _BaseVarMem(*this, 1, index, shift, disp); }
-
- //! @brief Cast this variable to 16-bit memory operand.
- Mem m16() const { return _BaseVarMem(*this, 2); }
-
- //! @overload.
- Mem m16(sysint_t disp) const { return _BaseVarMem(*this, 2, disp); }
-
- //! @overload.
- Mem m16(const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) const { return _BaseVarMem(*this, 2, index, shift, disp); }
-
- //! @brief Cast this variable to 32-bit memory operand.
- Mem m32() const { return _BaseVarMem(*this, 4); }
-
- //! @overload.
- Mem m32(sysint_t disp) const { return _BaseVarMem(*this, 4, disp); }
-
- //! @overload.
- Mem m32(const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) const { return _BaseVarMem(*this, 4, index, shift, disp); }
-
- //! @brief Cast this variable to 64-bit memory operand.
- Mem m64() const { return _BaseVarMem(*this, 8); }
-
- //! @overload.
- Mem m64(sysint_t disp) const { return _BaseVarMem(*this, 8, disp); }
-
- //! @overload.
- Mem m64(const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) const { return _BaseVarMem(*this, 8, index, shift, disp); }
-
- //! @brief Cast this variable to 80-bit memory operand (long double).
- Mem m80() const { return _BaseVarMem(*this, 10); }
-
- //! @overload.
- Mem m80(sysint_t disp) const { return _BaseVarMem(*this, 10, disp); }
-
- //! @overload.
- Mem m80(const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) const { return _BaseVarMem(*this, 10, index, shift, disp); }
-
- //! @brief Cast this variable to 128-bit memory operand.
- Mem m128() const { return _BaseVarMem(*this, 16); }
-
- //! @overload.
- Mem m128(sysint_t disp) const { return _BaseVarMem(*this, 16, disp); }
-
- //! @overload.
- Mem m128(const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) const { return _BaseVarMem(*this, 16, index, shift, disp); }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_NODOC
- Var &operator=(const Var &other) { this->_copy(other); return *this; }
-
- bool operator==(const Var &other) const { return this->_base.id == other._base.id && this->_var.regCode == other._var.regCode; }
- bool operator!=(const Var &other) const { return this->_base.id != other._base.id || this->_var.regCode != other._var.regCode; }
-#endif // ASMJIT_NODOC
-
- // --------------------------------------------------------------------------
- // [Private]
- // --------------------------------------------------------------------------
-
-protected:
- Var(const Var &other, uint32_t regCode, uint32_t size) : Operand(_DontInitialize())
- {
- this->_var.op = kOperandVar;
- this->_var.size = static_cast<uint8_t>(size);
- this->_var.id = other._base.id;
- this->_var.regCode = regCode;
- this->_var.varType = other._var.varType;
- }
-};
-
-// ============================================================================
-// [AsmJit::X87Var]
-// ============================================================================
-
-//! @brief X87 Variable operand.
-struct X87Var : public Var
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- X87Var(const _DontInitialize &dontInitialize) : Var(dontInitialize) { }
-
- X87Var() : Var(_DontInitialize())
- {
- this->_var.op = kOperandVar;
- this->_var.size = 12;
- this->_var.id = kInvalidValue;
-
- this->_var.regCode = kX86RegTypeX87;
- this->_var.varType = kX86VarTypeX87;
- }
-
- X87Var(const X87Var &other) : Var(other) { }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_NODOC
- X87Var &operator=(const X87Var &other) { this->_copy(other); return *this; }
-
- bool operator==(const X87Var &other) const { return this->_base.id == other._base.id; }
- bool operator!=(const X87Var &other) const { return this->_base.id != other._base.id; }
-#endif // ASMJIT_NODOC
-};
-
-// ============================================================================
-// [AsmJit::GpVar]
-// ============================================================================
-
-//! @brief GP variable operand.
-struct GpVar : public Var
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create new uninitialized @c GpVar instance (internal constructor).
- GpVar(const _DontInitialize &dontInitialize) : Var(dontInitialize) { }
-
- //! @brief Create new uninitialized @c GpVar instance.
- GpVar() : Var(_DontInitialize())
- {
- this->_var.op = kOperandVar;
- this->_var.size = sizeof(sysint_t);
- this->_var.id = kInvalidValue;
-
- this->_var.regCode = kX86RegTypeGpz;
- this->_var.varType = kX86VarTypeGpz;
- }
-
- //! @brief Create new @c GpVar instance using @a other.
- //!
- //! Note this will not create a different variable, use @c Compiler::newGpVar()
- //! if you want to do so. This is only copy-constructor that allows to store
- //! the same variable in different places.
- GpVar(const GpVar &other) : Var(other) { }
-
- // --------------------------------------------------------------------------
- // [GpVar Specific]
- // --------------------------------------------------------------------------
-
- //! @brief Get whether this variable is general purpose BYTE register.
- bool isGpb() const { return (this->_var.regCode & kRegTypeMask) <= kX86RegTypeGpbHi; }
- //! @brief Get whether this variable is general purpose BYTE.LO register.
- bool isGpbLo() const { return (this->_var.regCode & kRegTypeMask) == kX86RegTypeGpbLo; }
- //! @brief Get whether this variable is general purpose BYTE.HI register.
- bool isGpbHi() const { return (this->_var.regCode & kRegTypeMask) == kX86RegTypeGpbHi; }
-
- //! @brief Get whether this variable is general purpose WORD register.
- bool isGpw() const { return (this->_var.regCode & kRegTypeMask) == kX86RegTypeGpw; }
- //! @brief Get whether this variable is general purpose DWORD register.
- bool isGpd() const { return (this->_var.regCode & kRegTypeMask) == kX86RegTypeGpd; }
- //! @brief Get whether this variable is general purpose QWORD (only 64-bit) register.
- bool isGpq() const { return (this->_var.regCode & kRegTypeMask) == kX86RegTypeGpq; }
-
- // --------------------------------------------------------------------------
- // [GpVar Cast]
- // --------------------------------------------------------------------------
-
- //! @brief Cast this variable to 8-bit (LO) part of variable
- GpVar r8() const { return GpVar(*this, kX86RegTypeGpbLo, 1); }
- //! @brief Cast this variable to 8-bit (LO) part of variable
- GpVar r8Lo() const { return GpVar(*this, kX86RegTypeGpbLo, 1); }
- //! @brief Cast this variable to 8-bit (HI) part of variable
- GpVar r8Hi() const { return GpVar(*this, kX86RegTypeGpbHi, 1); }
-
- //! @brief Cast this variable to 16-bit part of variable
- GpVar r16() const { return GpVar(*this, kX86RegTypeGpw, 2); }
- //! @brief Cast this variable to 32-bit part of variable
- GpVar r32() const { return GpVar(*this, kX86RegTypeGpd, 4); }
-#ifdef ASMJIT_X64
- //! @brief Cast this variable to 64-bit part of variable
- GpVar r64() const { return GpVar(*this, kX86RegTypeGpq, 8); }
-#endif // ASMJIT_X64
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_NODOC
- GpVar &operator=(const GpVar &other) { this->_copy(other); return *this; }
-
- bool operator==(const GpVar &other) const { return this->_base.id == other._base.id && this->_var.regCode == other._var.regCode; }
- bool operator!=(const GpVar &other) const { return this->_base.id != other._base.id || this->_var.regCode != other._var.regCode; }
-#endif // ASMJIT_NODOC
-
- // --------------------------------------------------------------------------
- // [Private]
- // --------------------------------------------------------------------------
-
-protected:
- GpVar(const GpVar &other, uint32_t regCode, uint32_t size) : Var(other, regCode, size) { }
-};
-
-// ============================================================================
-// [AsmJit::MmVar]
-// ============================================================================
-
-//! @brief MM variable operand.
-struct MmVar : public Var
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- //! @brief Create new uninitialized @c MmVar instance (internal constructor).
- MmVar(const _DontInitialize &dontInitialize) : Var(dontInitialize) { }
-
- //! @brief Create new uninitialized @c MmVar instance.
- MmVar() : Var(_DontInitialize())
- {
- this->_var.op = kOperandVar;
- this->_var.size = 8;
- this->_var.id = kInvalidValue;
-
- this->_var.regCode = kX86RegTypeMm;
- this->_var.varType = kX86VarTypeMm;
- }
-
- //! @brief Create new @c MmVar instance using @a other.
- //!
- //! Note this will not create a different variable, use @c Compiler::newMmVar()
- //! if you want to do so. This is only copy-constructor that allows to store
- //! the same variable in different places.
- MmVar(const MmVar &other) : Var(other) { }
-
- // --------------------------------------------------------------------------
- // [MmVar Cast]
- // --------------------------------------------------------------------------
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_NODOC
- MmVar &operator=(const MmVar &other) { this->_copy(other); return *this; }
-
- bool operator==(const MmVar &other) const { return this->_base.id == other._base.id; }
- bool operator!=(const MmVar &other) const { return this->_base.id != other._base.id; }
-#endif // ASMJIT_NODOC
-};
-
-// ============================================================================
-// [AsmJit::XmmVar]
-// ============================================================================
-
-//! @brief XMM Variable operand.
-struct XmmVar : public Var
-{
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
-
- XmmVar(const _DontInitialize &dontInitialize) : Var(dontInitialize) { }
-
- XmmVar() : Var(_DontInitialize())
- {
- this->_var.op = kOperandVar;
- this->_var.size = 16;
- this->_var.id = kInvalidValue;
-
- this->_var.regCode = kX86RegTypeXmm;
- this->_var.varType = kX86VarTypeXmm;
- }
-
- XmmVar(const XmmVar &other) : Var(other) { }
-
- // --------------------------------------------------------------------------
- // [XmmVar Access]
- // --------------------------------------------------------------------------
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
-#ifndef ASMJIT_NODOC
- XmmVar &operator=(const XmmVar &other) { this->_copy(other); return *this; }
-
- bool operator==(const XmmVar &other) const { return this->_base.id == other._base.id; }
- bool operator!=(const XmmVar &other) const { return this->_base.id != other._base.id; }
-#endif // ASMJIT_NODOC
-};
-
-// ============================================================================
-// [AsmJit::Mem - [label + displacement]]
-// ============================================================================
-
-//! @brief Create a custom pointer operand.
-ASMJIT_API Mem ptr(const Label &label, sysint_t disp = 0, uint32_t size = 0);
-//! @brief Create a byte pointer operand.
-inline Mem byte_ptr(const Label &label, sysint_t disp = 0) { return ptr(label, disp, kSizeByte); }
-//! @brief Create a word pointer operand.
-inline Mem word_ptr(const Label &label, sysint_t disp = 0) { return ptr(label, disp, kSizeWord); }
-//! @brief Create a dword pointer operand.
-inline Mem dword_ptr(const Label &label, sysint_t disp = 0) { return ptr(label, disp, kSizeDWord); }
-//! @brief Create a qword pointer operand.
-inline Mem qword_ptr(const Label &label, sysint_t disp = 0) { return ptr(label, disp, kSizeQWord); }
-//! @brief Create a tword pointer operand.
-inline Mem tword_ptr(const Label &label, sysint_t disp = 0) { return ptr(label, disp, kSizeTWord); }
-//! @brief Create a dqword pointer operand.
-inline Mem dqword_ptr(const Label &label, sysint_t disp = 0) { return ptr(label, disp, kSizeDQWord); }
-//! @brief Create a mmword pointer operand.
-inline Mem mmword_ptr(const Label &label, sysint_t disp = 0) { return ptr(label, disp, kSizeQWord); }
-//! @brief Create a xmmword pointer operand.
-inline Mem xmmword_ptr(const Label &label, sysint_t disp = 0) { return ptr(label, disp, kSizeDQWord); }
-//! @brief Create an intptr_t pointer operand.
-inline Mem sysint_ptr(const Label &label, sysint_t disp = 0) { return ptr(label, disp, sizeof(sysint_t)); }
-
-// ============================================================================
-// [AsmJit::Mem - [label + index << shift + displacement]]
-// ============================================================================
-
-//! @brief Create a custom pointer operand.
-ASMJIT_API Mem ptr(const Label &label, const GpReg &index, uint32_t shift, sysint_t disp = 0, uint32_t size = 0);
-//! @brief Create a byte pointer operand.
-inline Mem byte_ptr(const Label &label, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeByte); }
-//! @brief Create a word pointer operand.
-inline Mem word_ptr(const Label &label, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeWord); }
-//! @brief Create a dword pointer operand.
-inline Mem dword_ptr(const Label &label, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeDWord); }
-//! @brief Create a qword pointer operand.
-inline Mem qword_ptr(const Label &label, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeQWord); }
-//! @brief Create a tword pointer operand.
-inline Mem tword_ptr(const Label &label, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeTWord); }
-//! @brief Create a dqword pointer operand.
-inline Mem dqword_ptr(const Label &label, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeDQWord); }
-//! @brief Create a mmword pointer operand.
-inline Mem mmword_ptr(const Label &label, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeQWord); }
-//! @brief Create a xmmword pointer operand.
-inline Mem xmmword_ptr(const Label &label, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeDQWord); }
-//! @brief Create an intptr_t pointer operand.
-inline Mem sysint_ptr(const Label &label, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, sizeof(sysint_t)); }
-
-//! @brief Create a custom pointer operand.
-ASMJIT_API Mem ptr(const Label &label, const GpVar &index, uint32_t shift, sysint_t disp = 0, uint32_t size = 0);
-//! @brief Create a byte pointer operand.
-inline Mem byte_ptr(const Label &label, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeByte); }
-//! @brief Create a word pointer operand.
-inline Mem word_ptr(const Label &label, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeWord); }
-//! @brief Create a dword pointer operand.
-inline Mem dword_ptr(const Label &label, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeDWord); }
-//! @brief Create a qword pointer operand.
-inline Mem qword_ptr(const Label &label, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeQWord); }
-//! @brief Create a tword pointer operand.
-inline Mem tword_ptr(const Label &label, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeTWord); }
-//! @brief Create a dqword pointer operand.
-inline Mem dqword_ptr(const Label &label, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeDQWord); }
-//! @brief Create a mmword pointer operand.
-inline Mem mmword_ptr(const Label &label, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeQWord); }
-//! @brief Create a xmmword pointer operand.
-inline Mem xmmword_ptr(const Label &label, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, kSizeDQWord); }
-//! @brief Create an intptr_t pointer operand.
-inline Mem sysint_ptr(const Label &label, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr(label, index, shift, disp, sizeof(sysint_t)); }
-
-// ============================================================================
-// [AsmJit::Mem - segment[target + displacement]
-// ============================================================================
-
-//! @brief Create a custom pointer operand.
-ASMJIT_API Mem ptr_abs(void *target, sysint_t disp = 0, uint32_t size = 0);
-//! @brief Create a byte pointer operand.
-inline Mem byte_ptr_abs(void *target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeByte); }
-//! @brief Create a word pointer operand.
-inline Mem word_ptr_abs(void *target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeWord); }
-//! @brief Create a dword pointer operand.
-inline Mem dword_ptr_abs(void *target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeDWord); }
-//! @brief Create a qword pointer operand.
-inline Mem qword_ptr_abs(void *target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeQWord); }
-//! @brief Create a tword pointer operand (used for 80-bit floating points).
-inline Mem tword_ptr_abs(void *target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeTWord); }
-//! @brief Create a dqword pointer operand.
-inline Mem dqword_ptr_abs(void *target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeDQWord); }
-//! @brief Create a mmword pointer operand.
-inline Mem mmword_ptr_abs(void *target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeQWord); }
-//! @brief Create a xmmword pointer operand.
-inline Mem xmmword_ptr_abs(void *target, sysint_t disp = 0) { return ptr_abs(target, disp, kSizeDQWord); }
-//! @brief Create an intptr_t pointer operand.
-inline Mem sysint_ptr_abs(void *target, sysint_t disp = 0) { return ptr_abs(target, disp, sizeof(sysint_t)); }
-
-// ============================================================================
-// [AsmJit::Mem - segment[target + index << shift + displacement]
-// ============================================================================
-
-//! @brief Create a custom pointer operand.
-ASMJIT_API Mem ptr_abs(void *target, const GpReg &index, uint32_t shift, sysint_t disp = 0, uint32_t size = 0);
-//! @brief Create a byte pointer operand.
-inline Mem byte_ptr_abs(void *target, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeByte); }
-//! @brief Create a word pointer operand.
-inline Mem word_ptr_abs(void *target, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeWord); }
-//! @brief Create a dword pointer operand.
-inline Mem dword_ptr_abs(void *target, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeDWord); }
-//! @brief Create a qword pointer operand.
-inline Mem qword_ptr_abs(void *target, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeQWord); }
-//! @brief Create a tword pointer operand.
-inline Mem tword_ptr_abs(void *target, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeTWord); }
-//! @brief Create a dqword pointer operand.
-inline Mem dqword_ptr_abs(void *target, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeDQWord); }
-//! @brief Create a mmword pointer operand.
-inline Mem mmword_ptr_abs(void *target, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeQWord); }
-//! @brief Create a xmmword pointer operand.
-inline Mem xmmword_ptr_abs(void *target, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeDQWord); }
-//! @brief Create an intptr_t pointer operand.
-inline Mem sysint_ptr_abs(void *target, const GpReg &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, sizeof(sysint_t)); }
-
-//! @brief Create a custom pointer operand.
-ASMJIT_API Mem ptr_abs(void *target, const GpVar &index, uint32_t shift, sysint_t disp = 0, uint32_t size = 0);
-//! @brief Create a byte pointer operand.
-inline Mem byte_ptr_abs(void *target, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeByte); }
-//! @brief Create a word pointer operand.
-inline Mem word_ptr_abs(void *target, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeWord); }
-//! @brief Create a dword pointer operand.
-inline Mem dword_ptr_abs(void *target, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeDWord); }
-//! @brief Create a qword pointer operand.
-inline Mem qword_ptr_abs(void *target, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeQWord); }
-//! @brief Create a tword pointer operand.
-inline Mem tword_ptr_abs(void *target, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeTWord); }
-//! @brief Create a dqword pointer operand.
-inline Mem dqword_ptr_abs(void *target, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeDQWord); }
-//! @brief Create a mmword pointer operand.
-inline Mem mmword_ptr_abs(void *target, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeQWord); }
-//! @brief Create a xmmword pointer operand.
-inline Mem xmmword_ptr_abs(void *target, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, kSizeDQWord); }
-//! @brief Create an intptr_t pointer operand.
-inline Mem sysint_ptr_abs(void *target, const GpVar &index, uint32_t shift, sysint_t disp = 0) { return ptr_abs(target, index, shift, disp, sizeof(sysint_t)); }
-
-// ============================================================================
-// [AsmJit::Mem - ptr[base + displacement]]
-// ============================================================================
-
-//! @brief Create a custom pointer operand.
-ASMJIT_API Mem ptr(const GpReg &base, sysint_t disp = 0, uint32_t size = 0);
-//! @brief Create a byte pointer operand.
-inline Mem byte_ptr(const GpReg &base, sysint_t disp = 0) { return ptr(base, disp, kSizeByte); }
-//! @brief Create a word pointer operand.
-inline Mem word_ptr(const GpReg &base, sysint_t disp = 0) { return ptr(base, disp, kSizeWord); }
-//! @brief Create a dword pointer operand.
-inline Mem dword_ptr(const GpReg &base, sysint_t disp = 0) { return ptr(base, disp, kSizeDWord); }
-//! @brief Create a qword pointer operand.
-inline Mem qword_ptr(const GpReg &base, sysint_t disp = 0) { return ptr(base, disp, kSizeQWord); }
-//! @brief Create a tword pointer operand.
-inline Mem tword_ptr(const GpReg &base, sysint_t disp = 0) { return ptr(base, disp, kSizeTWord); }
-//! @brief Create a dqword pointer operand.
-inline Mem dqword_ptr(const GpReg &base, sysint_t disp = 0) { return ptr(base, disp, kSizeDQWord); }
-//! @brief Create a mmword pointer operand.
-inline Mem mmword_ptr(const GpReg &base, sysint_t disp = 0) { return ptr(base, disp, kSizeQWord); }
-//! @brief Create a xmmword pointer operand.
-inline Mem xmmword_ptr(const GpReg &base, sysint_t disp = 0) { return ptr(base, disp, kSizeDQWord); }
-//! @brief Create an intptr_t pointer operand.
-inline Mem sysint_ptr(const GpReg &base, sysint_t disp = 0) { return ptr(base, disp, sizeof(sysint_t)); }
-
-//! @brief Create a custom pointer operand.
-ASMJIT_API Mem ptr(const GpVar &base, sysint_t disp = 0, uint32_t size = 0);
-//! @brief Create a byte pointer operand.
-inline Mem byte_ptr(const GpVar &base, sysint_t disp = 0) { return ptr(base, disp, kSizeByte); }
-//! @brief Create a word pointer operand.
-inline Mem word_ptr(const GpVar &base, sysint_t disp = 0) { return ptr(base, disp, kSizeWord); }
-//! @brief Create a dword pointer operand.
-inline Mem dword_ptr(const GpVar &base, sysint_t disp = 0) { return ptr(base, disp, kSizeDWord); }
-//! @brief Create a qword pointer operand.
-inline Mem qword_ptr(const GpVar &base, sysint_t disp = 0) { return ptr(base, disp, kSizeQWord); }
-//! @brief Create a tword pointer operand.
-inline Mem tword_ptr(const GpVar &base, sysint_t disp = 0) { return ptr(base, disp, kSizeTWord); }
-//! @brief Create a dqword pointer operand.
-inline Mem dqword_ptr(const GpVar &base, sysint_t disp = 0) { return ptr(base, disp, kSizeDQWord); }
-//! @brief Create a mmword pointer operand.
-inline Mem mmword_ptr(const GpVar &base, sysint_t disp = 0) { return ptr(base, disp, kSizeQWord); }
-//! @brief Create a xmmword pointer operand.
-inline Mem xmmword_ptr(const GpVar &base, sysint_t disp = 0) { return ptr(base, disp, kSizeDQWord); }
-//! @brief Create an intptr_t pointer operand.
-inline Mem sysint_ptr(const GpVar &base, sysint_t disp = 0) { return ptr(base, disp, sizeof(sysint_t)); }
-
-// ============================================================================
-// [AsmJit::Mem - ptr[base + (index << shift) + displacement]]
-// ============================================================================
-
-//! @brief Create a custom pointer operand.
-ASMJIT_API Mem ptr(const GpReg &base, const GpReg &index, uint32_t shift = 0, sysint_t disp = 0, uint32_t size = 0);
-//! @brief Create a byte pointer operand.
-inline Mem byte_ptr(const GpReg &base, const GpReg &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeByte); }
-//! @brief Create a word pointer operand.
-inline Mem word_ptr(const GpReg &base, const GpReg &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeWord); }
-//! @brief Create a dword pointer operand.
-inline Mem dword_ptr(const GpReg &base, const GpReg &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeDWord); }
-//! @brief Create a qword pointer operand.
-inline Mem qword_ptr(const GpReg &base, const GpReg &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeQWord); }
-//! @brief Create a tword pointer operand.
-inline Mem tword_ptr(const GpReg &base, const GpReg &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeTWord); }
-//! @brief Create a dqword pointer operand.
-inline Mem dqword_ptr(const GpReg &base, const GpReg &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeDQWord); }
-//! @brief Create a mmword pointer operand.
-inline Mem mmword_ptr(const GpReg &base, const GpReg &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeQWord); }
-//! @brief Create a xmmword pointer operand.
-inline Mem xmmword_ptr(const GpReg &base, const GpReg &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeDQWord); }
-//! @brief Create an intptr_t pointer operand.
-inline Mem sysint_ptr(const GpReg &base, const GpReg &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, sizeof(sysint_t)); }
-
-//! @brief Create a custom pointer operand.
-ASMJIT_API Mem ptr(const GpVar &base, const GpVar &index, uint32_t shift = 0, sysint_t disp = 0, uint32_t size = 0);
-//! @brief Create a byte pointer operand.
-inline Mem byte_ptr(const GpVar &base, const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeByte); }
-//! @brief Create a word pointer operand.
-inline Mem word_ptr(const GpVar &base, const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeWord); }
-//! @brief Create a dword pointer operand.
-inline Mem dword_ptr(const GpVar &base, const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeDWord); }
-//! @brief Create a qword pointer operand.
-inline Mem qword_ptr(const GpVar &base, const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeQWord); }
-//! @brief Create a tword pointer operand.
-inline Mem tword_ptr(const GpVar &base, const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeTWord); }
-//! @brief Create a dqword pointer operand.
-inline Mem dqword_ptr(const GpVar &base, const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeDQWord); }
-//! @brief Create a mmword pointer operand.
-inline Mem mmword_ptr(const GpVar &base, const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeQWord); }
-//! @brief Create a xmmword pointer operand.
-inline Mem xmmword_ptr(const GpVar &base, const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, kSizeDQWord); }
-//! @brief Create an intptr_t pointer operand.
-inline Mem sysint_ptr(const GpVar &base, const GpVar &index, uint32_t shift = 0, sysint_t disp = 0) { return ptr(base, index, shift, disp, sizeof(sysint_t)); }
-
-// ============================================================================
-// [AsmJit::Macros]
-// ============================================================================
-
-//! @brief Create Shuffle Constant for MMX/SSE shuffle instrutions.
-//! @param z First component position, number at interval [0, 3] inclusive.
-//! @param x Second component position, number at interval [0, 3] inclusive.
-//! @param y Third component position, number at interval [0, 3] inclusive.
-//! @param w Fourth component position, number at interval [0, 3] inclusive.
-//!
-//! Shuffle constants can be used to make immediate value for these intrinsics:
-//! - @ref X86Assembler::pshufw()
-//! - @ref X86Assembler::pshufd()
-//! - @ref X86Assembler::pshufhw()
-//! - @ref X86Assembler::pshuflw()
-//! - @ref X86Assembler::shufps()
-inline uint8_t mm_shuffle(uint8_t z, uint8_t y, uint8_t x, uint8_t w) { return (z << 6) | (y << 4) | (x << 2) | w; }
-
-//! @}
-
-} // AsmJit namespace
-
+//! Create `[base.reg + (index.reg << shift) + disp]` memory operand with no/custom size information.
+static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
+ return X86Mem(base, index, shift, disp, size);
+}
+//! Create `[base.reg + (xmm.reg << shift) + disp]` memory operand with no/custom size information.
+static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86XmmReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
+ return X86Mem(base, index, shift, disp, size);
+}
+//! Create `[base.reg + (ymm.reg << shift) + disp]` memory operand with no/custom size information.
+static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
+ return X86Mem(base, index, shift, disp, size);
+}
+//! Create `[label + disp]` memory operand with no/custom size information.
+static ASMJIT_INLINE X86Mem ptr(const Label& label, int32_t disp = 0, uint32_t size = 0) {
+ return X86Mem(label, disp, size);
+}
+//! Create `[label + (index.reg << shift) + disp]` memory operand with no/custom size information.
+static ASMJIT_INLINE X86Mem ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0, uint32_t size = 0) { \
+ return X86Mem(label, index, shift, disp, size); \
+}
+
+//! Create `[pAbs + disp]` absolute memory operand with no/custom size information.
+ASMJIT_API X86Mem ptr_abs(Ptr pAbs, int32_t disp = 0, uint32_t size = 0);
+//! Create `[pAbs + (index.reg << shift) + disp]` absolute memory operand with no/custom size information.
+ASMJIT_API X86Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0);
+
+//! \internal
+#define ASMJIT_EXPAND_PTR_REG(_Prefix_, _Size_) \
+ /*! Create `[base.reg + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, int32_t disp = 0) { \
+ return X86Mem(base, disp, _Size_); \
+ } \
+ /*! Create `[base.reg + (index.reg << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) { \
+ return ptr(base, index, shift, disp, _Size_); \
+ } \
+ /*! Create `[base.reg + (xmm.reg << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, const X86XmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \
+ return ptr(base, index, shift, disp, _Size_); \
+ } \
+ /*! Create `[base.reg + (ymm.reg << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \
+ return ptr(base, index, shift, disp, _Size_); \
+ } \
+ /*! Create `[label + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, int32_t disp = 0) { \
+ return ptr(label, disp, _Size_); \
+ } \
+ /*! Create `[label + (index.reg << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0) { \
+ return ptr(label, index, shift, disp, _Size_); \
+ } \
+ /*! Create `[pAbs + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, int32_t disp = 0) { \
+ return ptr_abs(pAbs, disp, _Size_); \
+ } \
+ /*! Create `[pAbs + (index.reg << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) { \
+ return ptr_abs(pAbs, index, shift, disp, _Size_); \
+ } \
+ /*! Create `[pAbs + (xmm.reg << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86XmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \
+ return ptr_abs(pAbs, index, shift, disp, _Size_); \
+ } \
+ /*! Create `[pAbs + (ymm.reg << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \
+ return ptr_abs(pAbs, index, shift, disp, _Size_); \
+ }
+
+ASMJIT_EXPAND_PTR_REG(byte, 1)
+ASMJIT_EXPAND_PTR_REG(word, 2)
+ASMJIT_EXPAND_PTR_REG(dword, 4)
+ASMJIT_EXPAND_PTR_REG(qword, 8)
+ASMJIT_EXPAND_PTR_REG(tword, 10)
+ASMJIT_EXPAND_PTR_REG(oword, 16)
+ASMJIT_EXPAND_PTR_REG(yword, 32)
+ASMJIT_EXPAND_PTR_REG(zword, 64)
+#undef ASMJIT_EXPAND_PTR_REG
+
+// ============================================================================
+// [asmjit::x86 - Ptr (Var)]
+// ============================================================================
+
+# ifndef ASMJIT_DISABLE_COMPILER
+//! Create `[base.var + disp]` memory operand with no/custom size information.
+static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, int32_t disp = 0, uint32_t size = 0) {
+ return X86Mem(base, disp, size);
+}
+//! Create `[base.var + (index.var << shift) + disp]` memory operand with no/custom size information.
+static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
+ return X86Mem(base, index, shift, disp, size);
+}
+//! Create `[base.var + (xmm.var << shift) + disp]` memory operand with no/custom size information.
+static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, const X86XmmVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
+ return X86Mem(base, index, shift, disp, size);
+}
+//! Create `[base.var + (ymm.var << shift) + disp]` memory operand with no/custom size information.
+static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, const X86YmmVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
+ return X86Mem(base, index, shift, disp, size);
+}
+//! Create `[label + (index.var << shift) + disp]` memory operand with no/custom size information.
+static ASMJIT_INLINE X86Mem ptr(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp = 0, uint32_t size = 0) { \
+ return X86Mem(label, index, shift, disp, size); \
+}
+
+//! Create `[pAbs + (index.var << shift) + disp]` absolute memory operand with no/custom size information.
+ASMJIT_API X86Mem ptr_abs(Ptr pAbs, const X86Var& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0);
+
+//! \internal
+#define ASMJIT_EXPAND_PTR_VAR(_Prefix_, _Size_) \
+ /*! Create `[base.var + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, int32_t disp = 0) { \
+ return X86Mem(base, disp, _Size_); \
+ } \
+ /*! Create `[base.var + (index.var << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) { \
+ return ptr(base, index, shift, disp, _Size_); \
+ } \
+ /*! Create `[base.var + (xmm.var << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, const X86XmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \
+ return ptr(base, index, shift, disp, _Size_); \
+ } \
+ /*! Create `[base.var + (ymm.var << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, const X86YmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \
+ return ptr(base, index, shift, disp, _Size_); \
+ } \
+ /*! Create `[label + (index.var << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp = 0) { \
+ return ptr(label, index, shift, disp, _Size_); \
+ } \
+ /*! Create `[pAbs + (index.var << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) { \
+ return ptr_abs(pAbs, reinterpret_cast<const X86Var&>(index), shift, disp, _Size_); \
+ } \
+ /*! Create `[pAbs + (xmm.var << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86XmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \
+ return ptr_abs(pAbs, reinterpret_cast<const X86Var&>(index), shift, disp, _Size_); \
+ } \
+ /*! Create `[pAbs + (ymm.var << shift) + disp]` memory operand. */ \
+ static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86YmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \
+ return ptr_abs(pAbs, reinterpret_cast<const X86Var&>(index), shift, disp, _Size_); \
+ }
+
+ASMJIT_EXPAND_PTR_VAR(byte, 1)
+ASMJIT_EXPAND_PTR_VAR(word, 2)
+ASMJIT_EXPAND_PTR_VAR(dword, 4)
+ASMJIT_EXPAND_PTR_VAR(qword, 8)
+ASMJIT_EXPAND_PTR_VAR(tword, 10)
+ASMJIT_EXPAND_PTR_VAR(oword, 16)
+ASMJIT_EXPAND_PTR_VAR(yword, 32)
+ASMJIT_EXPAND_PTR_VAR(zword, 64)
+#undef ASMJIT_EXPAND_PTR_VAR
+# endif // !ASMJIT_DISABLE_COMPILER
+
+#endif // !ASMJIT_EXPORTS_X86OPERAND_REGS
+
+} // x86 namespace
+
+//! \}
+
+} // asmjit namespace
+
+#undef _OP_ID
+
+// [Api-End]
+#include "../apiend.h"
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86operand_regs.cpp
@@ -1,1 +1,189 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+// [Export]
+#define ASMJIT_EXPORTS
+#define ASMJIT_EXPORTS_X86OPERAND_REGS
+
+// [Guard]
+#include "../build.h"
+#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
+
+// [Dependencies - AsmJit]
+#include "../x86/x86operand.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// Prevent static initialization.
+//
+// Remap all classes to POD structs so they can be statically initialized
+// without calling a constructor. Compiler will store these in data section.
+struct X86GpReg { Operand::VRegOp data; };
+struct X86FpReg { Operand::VRegOp data; };
+struct X86MmReg { Operand::VRegOp data; };
+struct X86XmmReg { Operand::VRegOp data; };
+struct X86YmmReg { Operand::VRegOp data; };
+struct X86SegReg { Operand::VRegOp data; };
+
+namespace x86 {
+
+// ============================================================================
+// [asmjit::x86::Registers]
+// ============================================================================
+
+#define REG(_Class_, _Name_, _Type_, _Index_, _Size_) \
+ const _Class_ _Name_ = {{ \
+ kOperandTypeReg, _Size_, { ((_Type_) << 8) + _Index_ }, kInvalidValue, {{ kInvalidVar, 0 }} \
+ }}
+
+REG(X86GpReg, noGpReg, kInvalidReg, kInvalidReg, 0);
+
+REG(X86GpReg, al, kX86RegTypeGpbLo, kX86RegIndexAx, 1);
+REG(X86GpReg, cl, kX86RegTypeGpbLo, kX86RegIndexCx, 1);
+REG(X86GpReg, dl, kX86RegTypeGpbLo, kX86RegIndexDx, 1);
+REG(X86GpReg, bl, kX86RegTypeGpbLo, kX86RegIndexBx, 1);
+REG(X86GpReg, spl, kX86RegTypeGpbLo, kX86RegIndexSp, 1);
+REG(X86GpReg, bpl, kX86RegTypeGpbLo, kX86RegIndexBp, 1);
+REG(X86GpReg, sil, kX86RegTypeGpbLo, kX86RegIndexSi, 1);
+REG(X86GpReg, dil, kX86RegTypeGpbLo, kX86RegIndexDi, 1);
+REG(X86GpReg, r8b, kX86RegTypeGpbLo, 8, 1);
+REG(X86GpReg, r9b, kX86RegTypeGpbLo, 9, 1);
+REG(X86GpReg, r10b, kX86RegTypeGpbLo, 10, 1);
+REG(X86GpReg, r11b, kX86RegTypeGpbLo, 11, 1);
+REG(X86GpReg, r12b, kX86RegTypeGpbLo, 12, 1);
+REG(X86GpReg, r13b, kX86RegTypeGpbLo, 13, 1);
+REG(X86GpReg, r14b, kX86RegTypeGpbLo, 14, 1);
+REG(X86GpReg, r15b, kX86RegTypeGpbLo, 15, 1);
+
+REG(X86GpReg, ah, kX86RegTypeGpbHi, kX86RegIndexAx, 1);
+REG(X86GpReg, ch, kX86RegTypeGpbHi, kX86RegIndexCx, 1);
+REG(X86GpReg, dh, kX86RegTypeGpbHi, kX86RegIndexDx, 1);
+REG(X86GpReg, bh, kX86RegTypeGpbHi, kX86RegIndexBx, 1);
+
+REG(X86GpReg, ax, kX86RegTypeGpw, kX86RegIndexAx, 2);
+REG(X86GpReg, cx, kX86RegTypeGpw, kX86RegIndexCx, 2);
+REG(X86GpReg, dx, kX86RegTypeGpw, kX86RegIndexDx, 2);
+REG(X86GpReg, bx, kX86RegTypeGpw, kX86RegIndexBx, 2);
+REG(X86GpReg, sp, kX86RegTypeGpw, kX86RegIndexSp, 2);
+REG(X86GpReg, bp, kX86RegTypeGpw, kX86RegIndexBp, 2);
+REG(X86GpReg, si, kX86RegTypeGpw, kX86RegIndexSi, 2);
+REG(X86GpReg, di, kX86RegTypeGpw, kX86RegIndexDi, 2);
+REG(X86GpReg, r8w, kX86RegTypeGpw, 8, 2);
+REG(X86GpReg, r9w, kX86RegTypeGpw, 9, 2);
+REG(X86GpReg, r10w, kX86RegTypeGpw, 10, 2);
+REG(X86GpReg, r11w, kX86RegTypeGpw, 11, 2);
+REG(X86GpReg, r12w, kX86RegTypeGpw, 12, 2);
+REG(X86GpReg, r13w, kX86RegTypeGpw, 13, 2);
+REG(X86GpReg, r14w, kX86RegTypeGpw, 14, 2);
+REG(X86GpReg, r15w, kX86RegTypeGpw, 15, 2);
+
+REG(X86GpReg, eax, kX86RegTypeGpd, kX86RegIndexAx, 4);
+REG(X86GpReg, ecx, kX86RegTypeGpd, kX86RegIndexCx, 4);
+REG(X86GpReg, edx, kX86RegTypeGpd, kX86RegIndexDx, 4);
+REG(X86GpReg, ebx, kX86RegTypeGpd, kX86RegIndexBx, 4);
+REG(X86GpReg, esp, kX86RegTypeGpd, kX86RegIndexSp, 4);
+REG(X86GpReg, ebp, kX86RegTypeGpd, kX86RegIndexBp, 4);
+REG(X86GpReg, esi, kX86RegTypeGpd, kX86RegIndexSi, 4);
+REG(X86GpReg, edi, kX86RegTypeGpd, kX86RegIndexDi, 4);
+REG(X86GpReg, r8d, kX86RegTypeGpd, 8, 4);
+REG(X86GpReg, r9d, kX86RegTypeGpd, 9, 4);
+REG(X86GpReg, r10d, kX86RegTypeGpd, 10, 4);
+REG(X86GpReg, r11d, kX86RegTypeGpd, 11, 4);
+REG(X86GpReg, r12d, kX86RegTypeGpd, 12, 4);
+REG(X86GpReg, r13d, kX86RegTypeGpd, 13, 4);
+REG(X86GpReg, r14d, kX86RegTypeGpd, 14, 4);
+REG(X86GpReg, r15d, kX86RegTypeGpd, 15, 4);
+
+REG(X86GpReg, rax, kX86RegTypeGpq, kX86RegIndexAx, 8);
+REG(X86GpReg, rcx, kX86RegTypeGpq, kX86RegIndexCx, 8);
+REG(X86GpReg, rdx, kX86RegTypeGpq, kX86RegIndexDx, 8);
+REG(X86GpReg, rbx, kX86RegTypeGpq, kX86RegIndexBx, 8);
+REG(X86GpReg, rsp, kX86RegTypeGpq, kX86RegIndexSp, 8);
+REG(X86GpReg, rbp, kX86RegTypeGpq, kX86RegIndexBp, 8);
+REG(X86GpReg, rsi, kX86RegTypeGpq, kX86RegIndexSi, 8);
+REG(X86GpReg, rdi, kX86RegTypeGpq, kX86RegIndexDi, 8);
+REG(X86GpReg, r8, kX86RegTypeGpq, 8, 8);
+REG(X86GpReg, r9, kX86RegTypeGpq, 9, 8);
+REG(X86GpReg, r10, kX86RegTypeGpq, 10, 8);
+REG(X86GpReg, r11, kX86RegTypeGpq, 11, 8);
+REG(X86GpReg, r12, kX86RegTypeGpq, 12, 8);
+REG(X86GpReg, r13, kX86RegTypeGpq, 13, 8);
+REG(X86GpReg, r14, kX86RegTypeGpq, 14, 8);
+REG(X86GpReg, r15, kX86RegTypeGpq, 15, 8);
+
+REG(X86FpReg, fp0, kX86RegTypeFp, 0, 10);
+REG(X86FpReg, fp1, kX86RegTypeFp, 1, 10);
+REG(X86FpReg, fp2, kX86RegTypeFp, 2, 10);
+REG(X86FpReg, fp3, kX86RegTypeFp, 3, 10);
+REG(X86FpReg, fp4, kX86RegTypeFp, 4, 10);
+REG(X86FpReg, fp5, kX86RegTypeFp, 5, 10);
+REG(X86FpReg, fp6, kX86RegTypeFp, 6, 10);
+REG(X86FpReg, fp7, kX86RegTypeFp, 7, 10);
+
+REG(X86MmReg, mm0, kX86RegTypeMm, 0, 8);
+REG(X86MmReg, mm1, kX86RegTypeMm, 1, 8);
+REG(X86MmReg, mm2, kX86RegTypeMm, 2, 8);
+REG(X86MmReg, mm3, kX86RegTypeMm, 3, 8);
+REG(X86MmReg, mm4, kX86RegTypeMm, 4, 8);
+REG(X86MmReg, mm5, kX86RegTypeMm, 5, 8);
+REG(X86MmReg, mm6, kX86RegTypeMm, 6, 8);
+REG(X86MmReg, mm7, kX86RegTypeMm, 7, 8);
+
+REG(X86XmmReg, xmm0, kX86RegTypeXmm, 0, 16);
+REG(X86XmmReg, xmm1, kX86RegTypeXmm, 1, 16);
+REG(X86XmmReg, xmm2, kX86RegTypeXmm, 2, 16);
+REG(X86XmmReg, xmm3, kX86RegTypeXmm, 3, 16);
+REG(X86XmmReg, xmm4, kX86RegTypeXmm, 4, 16);
+REG(X86XmmReg, xmm5, kX86RegTypeXmm, 5, 16);
+REG(X86XmmReg, xmm6, kX86RegTypeXmm, 6, 16);
+REG(X86XmmReg, xmm7, kX86RegTypeXmm, 7, 16);
+REG(X86XmmReg, xmm8, kX86RegTypeXmm, 8, 16);
+REG(X86XmmReg, xmm9, kX86RegTypeXmm, 9, 16);
+REG(X86XmmReg, xmm10, kX86RegTypeXmm, 10, 16);
+REG(X86XmmReg, xmm11, kX86RegTypeXmm, 11, 16);
+REG(X86XmmReg, xmm12, kX86RegTypeXmm, 12, 16);
+REG(X86XmmReg, xmm13, kX86RegTypeXmm, 13, 16);
+REG(X86XmmReg, xmm14, kX86RegTypeXmm, 14, 16);
+REG(X86XmmReg, xmm15, kX86RegTypeXmm, 15, 16);
+
+REG(X86YmmReg, ymm0, kX86RegTypeYmm, 0, 32);
+REG(X86YmmReg, ymm1, kX86RegTypeYmm, 1, 32);
+REG(X86YmmReg, ymm2, kX86RegTypeYmm, 2, 32);
+REG(X86YmmReg, ymm3, kX86RegTypeYmm, 3, 32);
+REG(X86YmmReg, ymm4, kX86RegTypeYmm, 4, 32);
+REG(X86YmmReg, ymm5, kX86RegTypeYmm, 5, 32);
+REG(X86YmmReg, ymm6, kX86RegTypeYmm, 6, 32);
+REG(X86YmmReg, ymm7, kX86RegTypeYmm, 7, 32);
+REG(X86YmmReg, ymm8, kX86RegTypeYmm, 8, 32);
+REG(X86YmmReg, ymm9, kX86RegTypeYmm, 9, 32);
+REG(X86YmmReg, ymm10, kX86RegTypeYmm, 10, 32);
+REG(X86YmmReg, ymm11, kX86RegTypeYmm, 11, 32);
+REG(X86YmmReg, ymm12, kX86RegTypeYmm, 12, 32);
+REG(X86YmmReg, ymm13, kX86RegTypeYmm, 13, 32);
+REG(X86YmmReg, ymm14, kX86RegTypeYmm, 14, 32);
+REG(X86YmmReg, ymm15, kX86RegTypeYmm, 15, 32);
+
+REG(X86SegReg, cs, kX86RegTypeSeg, kX86SegCs, 2);
+REG(X86SegReg, ss, kX86RegTypeSeg, kX86SegSs, 2);
+REG(X86SegReg, ds, kX86RegTypeSeg, kX86SegDs, 2);
+REG(X86SegReg, es, kX86RegTypeSeg, kX86SegEs, 2);
+REG(X86SegReg, fs, kX86RegTypeSeg, kX86SegFs, 2);
+REG(X86SegReg, gs, kX86RegTypeSeg, kX86SegGs, 2);
+
+#undef REG
+
+} // x86 namespace
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86scheduler.cpp
@@ -1,1 +1,95 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+// [Export]
+#define ASMJIT_EXPORTS
+
+// [Guard]
+#include "../build.h"
+#if !defined(ASMJIT_DISABLE_COMPILER) && (defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64))
+
+// [Dependencies - AsmJit]
+#include "../base/containers.h"
+#include "../x86/x86scheduler_p.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [Internals]
+// ============================================================================
+
+//! \internal
+struct X86ScheduleData {
+ //! Registers read by the instruction.
+ X86RegMask regsIn;
+ //! Registers written by the instruction.
+ X86RegMask regsOut;
+
+ //! Flags read by the instruction.
+ uint8_t flagsIn;
+ //! Flags written by the instruction.
+ uint8_t flagsOut;
+
+ //! How many `uops` or `cycles` the instruction takes.
+ uint8_t ops;
+ //! Instruction latency.
+ uint8_t latency;
+
+ //! Which ports the instruction can run at.
+ uint16_t ports;
+ //! \internal
+ uint16_t reserved;
+
+ //! All instructions that this instruction depends on.
+ PodList<InstNode*>::Link* dependsOn;
+ //! All instructions that use the result of this instruction.
+ PodList<InstNode*>::Link* usedBy;
+};
+
+// ============================================================================
+// [asmjit::X86Scheduler - Construction / Destruction]
+// ============================================================================
+
+X86Scheduler::X86Scheduler(X86Compiler* compiler, const X86CpuInfo* cpuInfo) :
+ _compiler(compiler),
+ _cpuInfo(cpuInfo) {}
+X86Scheduler::~X86Scheduler() {}
+
+// ============================================================================
+// [asmjit::X86Scheduler - Run]
+// ============================================================================
+
+Error X86Scheduler::run(Node* /*start*/, Node* /*stop*/) {
+ /*
+ ASMJIT_TLOG("[Schedule] === Begin ===");
+
+ Zone zone(8096 - kZoneOverhead);
+ Node* node_ = start;
+
+ while (node_ != stop) {
+ Node* next = node_->getNext();
+ ASMJIT_ASSERT(node_->getType() == kNodeTypeInst);
+
+ printf(" %s\n", X86Util::getInstInfo(static_cast<InstNode*>(node_)->getCode()).getInstName());
+ node_ = next;
+ }
+
+ ASMJIT_TLOG("[Schedule] === End ===");
+ */
+ return kErrorOk;
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // !ASMJIT_DISABLE_COMPILER && (ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64)
+
--- /dev/null
+++ b/src/in_2sf/desmume/utils/AsmJit/x86/x86scheduler_p.h
@@ -1,1 +1,60 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+#pragma once
+
+#include "../build.h"
+#ifndef ASMJIT_DISABLE_COMPILER
+
+// [Dependencies - AsmJit]
+#include "../x86/x86compiler.h"
+#include "../x86/x86context_p.h"
+#include "../x86/x86cpuinfo.h"
+#include "../x86/x86inst.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [asmjit::X86Scheduler]
+// ============================================================================
+
+//! \internal
+//!
+//! X86 scheduler.
+struct X86Scheduler {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ X86Scheduler(X86Compiler* compiler, const X86CpuInfo* cpuInfo);
+ ~X86Scheduler();
+
+ // --------------------------------------------------------------------------
+ // [Run]
+ // --------------------------------------------------------------------------
+
+ Error run(Node* start, Node* stop);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Attached compiler.
+ X86Compiler* _compiler;
+ //! CPU information used for scheduling.
+ const X86CpuInfo* _cpuInfo;
+};
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+#endif // !ASMJIT_DISABLE_COMPILER
+
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86util.cpp
+++ /dev/null
@@ -1,140 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#define ASMJIT_EXPORTS
-
-// [Dependencies - AsmJit]
-#include "../x86/x86defs.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-// ============================================================================
-// [AsmJit::_x86UtilJccFromCond]
-// ============================================================================
-
-const uint32_t _x86UtilJccFromCond[] =
-{
- kX86InstJO,
- kX86InstJNO,
- kX86InstJB,
- kX86InstJAE,
- kX86InstJE,
- kX86InstJNE,
- kX86InstJBE,
- kX86InstJA,
- kX86InstJS,
- kX86InstJNS,
- kX86InstJPE,
- kX86InstJPO,
- kX86InstJL,
- kX86InstJGE,
- kX86InstJLE,
- kX86InstJG,
-
- kInstNone,
- kInstNone,
- kInstNone,
- kInstNone
-};
-
-// ============================================================================
-// [AsmJit::_x86UtilMovccFromCond]
-// ============================================================================
-
-const uint32_t _x86UtilMovccFromCond[] =
-{
- kX86InstCMovO,
- kX86InstCMovNO,
- kX86InstCMovB,
- kX86InstCMovAE,
- kX86InstCMovE,
- kX86InstCMovNE,
- kX86InstCMovBE,
- kX86InstCMovA,
- kX86InstCMovS,
- kX86InstCMovNS,
- kX86InstCMovPE,
- kX86InstCMovPO,
- kX86InstCMovL,
- kX86InstCMovGE,
- kX86InstCMovLE,
- kX86InstCMovG,
-
- kInstNone,
- kInstNone,
- kInstNone,
- kInstNone
-};
-
-// ============================================================================
-// [AsmJit::_x86UtilSetccFromCond]
-// ============================================================================
-
-const uint32_t _x86UtilSetccFromCond[] =
-{
- kX86InstSetO,
- kX86InstSetNO,
- kX86InstSetB,
- kX86InstSetAE,
- kX86InstSetE,
- kX86InstSetNE,
- kX86InstSetBE,
- kX86InstSetA,
- kX86InstSetS,
- kX86InstSetNS,
- kX86InstSetPE,
- kX86InstSetPO,
- kX86InstSetL,
- kX86InstSetGE,
- kX86InstSetLE,
- kX86InstSetG,
-
- kInstNone,
- kInstNone,
- kInstNone,
- kInstNone
-};
-
-// ============================================================================
-// [AsmJit::_x86UtilReversedCond]
-// ============================================================================
-
-const uint32_t _x86UtilReversedCond[] =
-{
- /* x86CondO -> */ kX86CondO,
- /* x86CondNO -> */ kX86CondNO,
- /* x86CondB -> */ kX86CondA,
- /* x86CondAE -> */ kX86CondBE,
- /* x86CondE -> */ kX86CondE,
- /* x86CondNE -> */ kX86CondNE,
- /* x86CondBE -> */ kX86CondAE,
- /* x86CondA -> */ kX86CondB,
- /* x86CondS -> */ kX86CondS,
- /* x86CondNS -> */ kX86CondNS,
- /* x86CondPE -> */ kX86CondPE,
- /* x86CondPO -> */ kX86CondPO,
-
- /* x86CondL -> */ kX86CondG,
- /* x86CondGE -> */ kX86CondLE,
-
- /* x86CondLE -> */ kX86CondGE,
- /* x86CondG -> */ kX86CondL,
-
- /* kX86CondFpuUnordered -> */ kX86CondFpuUnordered,
- /* kX86CondFpuNotUnordered -> */ kX86CondFpuNotUnordered,
-
- 0x12,
- 0x13
-};
-
-} // AsmJit namespace
-
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/utils/AsmJit/x86/x86util.h
+++ /dev/null
@@ -1,119 +1,1 @@
-// [AsmJit]
-// Complete JIT Assembler for C++ Language.
-//
-// [License]
-// Zlib - See COPYING file in this package.
-#pragma once
-
-// [Dependencies - AsmJit]
-#include "../x86/x86defs.h"
-#include "../x86/x86operand.h"
-
-// [Api-Begin]
-#include "../core/apibegin.h"
-
-namespace AsmJit
-{
-
-//! @addtogroup AsmJit_X86
-//! @{
-
-// ============================================================================
-// [AsmJit::X86Util]
-// ============================================================================
-
-//! @brief Map condition code to "jcc" group of instructions.
-ASMJIT_VAR const uint32_t _x86UtilJccFromCond[20];
-//! @brief Map condition code to "cmovcc" group of instructions.
-ASMJIT_VAR const uint32_t _x86UtilMovccFromCond[20];
-//! @brief Map condition code to "setcc" group of instructions.
-ASMJIT_VAR const uint32_t _x86UtilSetccFromCond[20];
-//! @brief Map condition code to reversed condition code.
-ASMJIT_VAR const uint32_t _x86UtilReversedCond[20];
-
-struct X86Util
-{
- // --------------------------------------------------------------------------
- // [Condition Codes]
- // --------------------------------------------------------------------------
-
- //! @brief Get the equivalent of negated condition code.
- static uint32_t getNegatedCond(uint32_t cond)
- {
- return static_cast<kX86Cond>(cond ^ static_cast<uint32_t>(cond < kX86CondNone));
- }
-
- //! @brief Corresponds to transposing the operands of a comparison.
- static uint32_t getReversedCond(uint32_t cond)
- {
- ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86UtilReversedCond));
- return _x86UtilReversedCond[cond];
- }
-
- //! @brief Translate condition code @a cc to jcc instruction code.
- //! @sa @c kX86InstCode, @c kX86InstJ.
- static uint32_t getJccInstFromCond(uint32_t cond)
- {
- ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86UtilJccFromCond));
- return _x86UtilJccFromCond[cond];
- }
-
- //! @brief Translate condition code @a cc to cmovcc instruction code.
- //! @sa @c kX86InstCode, @c kX86InstCMov.
- static uint32_t getCMovccInstFromCond(uint32_t cond)
- {
- ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86UtilMovccFromCond));
- return _x86UtilMovccFromCond[cond];
- }
-
- //! @brief Translate condition code @a cc to setcc instruction code.
- //! @sa @c kX86InstCode, @c kX86InstSet.
- static uint32_t getSetccInstFromCond(uint32_t cond)
- {
- ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86UtilSetccFromCond));
- return _x86UtilSetccFromCond[cond];
- }
-
- // --------------------------------------------------------------------------
- // [Variables]
- // --------------------------------------------------------------------------
-
- static uint32_t getVarClassFromVarType(uint32_t varType)
- {
- ASMJIT_ASSERT(varType < kX86VarTypeCount);
- return x86VarInfo[varType].getClass();
- }
-
- static uint32_t getVarSizeFromVarType(uint32_t varType)
- {
- ASMJIT_ASSERT(varType < kX86VarTypeCount);
- return x86VarInfo[varType].getSize();
- }
-
- static uint32_t getRegCodeFromVarType(uint32_t varType, uint32_t regIndex)
- {
- ASMJIT_ASSERT(varType < kX86VarTypeCount);
- return x86VarInfo[varType].getCode() | regIndex;
- }
-
- static bool isVarTypeInt(uint32_t varType)
- {
- ASMJIT_ASSERT(varType < kX86VarTypeCount);
- return !!(x86VarInfo[varType].getClass() & kX86VarClassGp);
- }
-
- static bool isVarTypeFloat(uint32_t varType)
- {
- ASMJIT_ASSERT(varType < kX86VarTypeCount);
- return !!(x86VarInfo[varType].getFlags() & (kX86VarFlagSP | kX86VarFlagDP));
- }
-};
-
-//! @}
-
-} // AsmJit namespace
-
-// [Api-End]
-#include "../core/apiend.h"
-
--- a/src/in_2sf/desmume/version.cpp
+++ b/src/in_2sf/desmume/version.cpp
@@ -16,6 +16,7 @@
*/
#include "version.h"
+#include "types.h"
// Helper macros to convert numerics to strings
#if defined(_MSC_VER)
@@ -91,9 +92,7 @@
# define DESMUME_JIT ""
#endif
-#define DESMUME_VERSION_STRING " " "0.9.9" DESMUME_SUBVERSION_STRING DESMUME_PLATFORM_STRING DESMUME_JIT DESMUME_CPUEXT_STRING
-#define DESMUME_NAME_AND_VERSION DESMUME_NAME DESMUME_VERSION_STRING
+#define DESMUME_NAME_AND_VERSION DESMUME_NAME " 0.9.9" DESMUME_SUBVERSION_STRING DESMUME_PLATFORM_STRING DESMUME_JIT DESMUME_CPUEXT_STRING
-const char *EMU_DESMUME_VERSION_STRING() { return DESMUME_VERSION_STRING; }
const char *EMU_DESMUME_NAME_AND_VERSION() { return DESMUME_NAME_AND_VERSION; }
--- a/src/in_2sf/desmume/version.h
+++ b/src/in_2sf/desmume/version.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2009-2011 DeSmuME team
+ Copyright (C) 2009-2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,6 +17,5 @@
#pragma once
-const char *EMU_DESMUME_VERSION_STRING();
const char *EMU_DESMUME_NAME_AND_VERSION();
--- a/src/in_2sf/in_2sf.vcxproj
+++ b/src/in_2sf/in_2sf.vcxproj
@@ -82,33 +82,22 @@
<ItemGroup>
<ClCompile Include="desmume\arm_jit.cpp" />
<ClCompile Include="desmume\metaspu\SoundTouch\mmx_optimized.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\assembler.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\assert.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\buffer.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\compiler.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\compilercontext.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\compilerfunc.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\compileritem.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\context.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\cpuinfo.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\defs.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\logger.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\memorymanager.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\operand.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\stringbuilder.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\stringutil.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\virtualmemory.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\core\zonememory.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\x86\x86assembler.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\x86\x86compiler.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\x86\x86compilercontext.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\x86\x86compilerfunc.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\x86\x86compileritem.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\x86\x86cpuinfo.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\x86\x86defs.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\x86\x86func.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\x86\x86operand.cpp" />
- <ClCompile Include="desmume\utils\AsmJit\x86\x86util.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\assembler.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\codegen.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\compiler.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\constpool.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\containers.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\context.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\cpuinfo.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\cputicks.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\error.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\globals.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\logger.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\operand.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\runtime.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\string.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\vmem.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\base\zone.cpp" />
<ClCompile Include="desmume\addons\slot1_retail.cpp" />
<ClCompile Include="desmume\armcpu.cpp" />
<ClCompile Include="desmume\arm_instructions.cpp" />
@@ -135,6 +124,14 @@
<ClCompile Include="desmume\slot1.cpp" />
<ClCompile Include="desmume\SPU.cpp" />
<ClCompile Include="desmume\thumb_instructions.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\x86\x86assembler.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\x86\x86compiler.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\x86\x86context.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\x86\x86cpuinfo.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\x86\x86inst.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\x86\x86operand.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\x86\x86operand_regs.cpp" />
+ <ClCompile Include="desmume\utils\AsmJit\x86\x86scheduler.cpp" />
<ClCompile Include="desmume\utils\dlditool.cpp" />
<ClCompile Include="desmume\utils\xstring.cpp" />
<ClCompile Include="desmume\version.cpp" />
@@ -145,45 +142,33 @@
<ClInclude Include="desmume\arm_jit.h" />
<ClInclude Include="desmume\instructions.h" />
<ClInclude Include="desmume\instruction_attributes.h" />
- <ClInclude Include="desmume\utils\AsmJit\AsmJit.h" />
- <ClInclude Include="desmume\utils\AsmJit\Config.h" />
- <ClInclude Include="desmume\utils\AsmJit\core.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\apibegin.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\apiend.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\assembler.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\assert.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\buffer.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\build.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\compiler.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\compilercontext.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\compilerfunc.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\compileritem.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\context.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\cpuinfo.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\defs.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\func.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\intutil.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\lock.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\logger.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\memorymanager.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\memorymarker.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\operand.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\podvector.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\stringbuilder.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\stringutil.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\virtualmemory.h" />
- <ClInclude Include="desmume\utils\AsmJit\core\zonememory.h" />
+ <ClInclude Include="desmume\utils\AsmJit\apibegin.h" />
+ <ClInclude Include="desmume\utils\AsmJit\apiend.h" />
+ <ClInclude Include="desmume\utils\AsmJit\asmjit.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\assembler.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\codegen.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\compiler.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\constpool.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\containers.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\context_p.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\cpuinfo.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\cputicks.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\error.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\globals.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\intutil.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\lock.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\logger.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\operand.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\runtime.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\string.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\vectypes.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\vmem.h" />
+ <ClInclude Include="desmume\utils\AsmJit\base\zone.h" />
+ <ClInclude Include="desmume\utils\AsmJit\build.h" />
+ <ClInclude Include="desmume\utils\AsmJit\config.h" />
+ <ClInclude Include="desmume\utils\AsmJit\host.h" />
<ClInclude Include="desmume\utils\AsmJit\x86.h" />
- <ClInclude Include="desmume\utils\AsmJit\x86\x86assembler.h" />
- <ClInclude Include="desmume\utils\AsmJit\x86\x86compiler.h" />
- <ClInclude Include="desmume\utils\AsmJit\x86\x86compilercontext.h" />
- <ClInclude Include="desmume\utils\AsmJit\x86\x86compilerfunc.h" />
- <ClInclude Include="desmume\utils\AsmJit\x86\x86compileritem.h" />
- <ClInclude Include="desmume\utils\AsmJit\x86\x86cpuinfo.h" />
- <ClInclude Include="desmume\utils\AsmJit\x86\x86defs.h" />
- <ClInclude Include="desmume\utils\AsmJit\x86\x86func.h" />
- <ClInclude Include="desmume\utils\AsmJit\x86\x86operand.h" />
- <ClInclude Include="desmume\utils\AsmJit\x86\x86util.h" />
<ClInclude Include="desmume\armcpu.h" />
<ClInclude Include="desmume\bios.h" />
<ClInclude Include="desmume\bits.h" />
@@ -215,6 +200,13 @@
<ClInclude Include="desmume\slot1.h" />
<ClInclude Include="desmume\SPU.h" />
<ClInclude Include="desmume\types.h" />
+ <ClInclude Include="desmume\utils\AsmJit\x86\x86assembler.h" />
+ <ClInclude Include="desmume\utils\AsmJit\x86\x86compiler.h" />
+ <ClInclude Include="desmume\utils\AsmJit\x86\x86context_p.h" />
+ <ClInclude Include="desmume\utils\AsmJit\x86\x86cpuinfo.h" />
+ <ClInclude Include="desmume\utils\AsmJit\x86\x86inst.h" />
+ <ClInclude Include="desmume\utils\AsmJit\x86\x86operand.h" />
+ <ClInclude Include="desmume\utils\AsmJit\x86\x86scheduler_p.h" />
<ClInclude Include="desmume\utils\xstring.h" />
<ClInclude Include="desmume\version.h" />
</ItemGroup>
--- a/src/in_2sf/in_2sf.vcxproj.filters
+++ b/src/in_2sf/in_2sf.vcxproj.filters
@@ -43,20 +43,20 @@
<Filter Include="Header Files\desmume\utils\AsmJit">
<UniqueIdentifier>{d5d55f5d-549c-4b4a-b2d6-bffdc147e106}</UniqueIdentifier>
</Filter>
- <Filter Include="Header Files\desmume\utils\AsmJit\core">
- <UniqueIdentifier>{57296fc0-a795-4e7e-adbd-c6b574717b02}</UniqueIdentifier>
- </Filter>
<Filter Include="Header Files\desmume\utils\AsmJit\x86">
<UniqueIdentifier>{1468db50-bcab-4c3c-82d1-657d4398655f}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\desmume\utils\AsmJit">
<UniqueIdentifier>{72c389f1-eb07-4364-b4b6-5410b9afd4f7}</UniqueIdentifier>
</Filter>
- <Filter Include="Source Files\desmume\utils\AsmJit\core">
- <UniqueIdentifier>{f956626e-6723-44cc-b636-c1a97df9bd63}</UniqueIdentifier>
- </Filter>
<Filter Include="Source Files\desmume\utils\AsmJit\x86">
<UniqueIdentifier>{3e71aea6-b686-4c96-b397-85ada17e6a4b}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\desmume\utils\AsmJit\base">
+ <UniqueIdentifier>{2245a91d-b729-4c29-9eb2-3d7807cf454a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\desmume\utils\AsmJit\base">
+ <UniqueIdentifier>{3ca7e13f-394b-4d27-bdbf-135feb26480f}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
@@ -156,56 +156,56 @@
<ClCompile Include="desmume\arm_jit.cpp">
<Filter>Source Files\desmume</Filter>
</ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\logger.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\memorymanager.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\operand.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\stringbuilder.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\stringutil.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\virtualmemory.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\zonememory.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\assembler.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\assert.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\buffer.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\compiler.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\compilercontext.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\compilerfunc.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\compileritem.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\context.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\cpuinfo.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\core\defs.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\core</Filter>
+ <ClCompile Include="desmume\metaspu\SoundTouch\mmx_optimized.cpp">
+ <Filter>Source Files\desmume\metaspu\SoundTouch</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\assembler.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\codegen.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\compiler.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\constpool.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\containers.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\context.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\cpuinfo.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\cputicks.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\error.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\globals.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\logger.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\operand.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\runtime.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\string.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\vmem.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\base\zone.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\base</Filter>
</ClCompile>
<ClCompile Include="desmume\utils\AsmJit\x86\x86assembler.cpp">
<Filter>Source Files\desmume\utils\AsmJit\x86</Filter>
@@ -213,32 +213,23 @@
<ClCompile Include="desmume\utils\AsmJit\x86\x86compiler.cpp">
<Filter>Source Files\desmume\utils\AsmJit\x86</Filter>
</ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\x86\x86compilercontext.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\x86</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\x86\x86compilerfunc.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\x86</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\x86\x86compileritem.cpp">
+ <ClCompile Include="desmume\utils\AsmJit\x86\x86context.cpp">
<Filter>Source Files\desmume\utils\AsmJit\x86</Filter>
</ClCompile>
<ClCompile Include="desmume\utils\AsmJit\x86\x86cpuinfo.cpp">
<Filter>Source Files\desmume\utils\AsmJit\x86</Filter>
</ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\x86\x86defs.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\x86</Filter>
- </ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\x86\x86func.cpp">
+ <ClCompile Include="desmume\utils\AsmJit\x86\x86inst.cpp">
<Filter>Source Files\desmume\utils\AsmJit\x86</Filter>
</ClCompile>
<ClCompile Include="desmume\utils\AsmJit\x86\x86operand.cpp">
<Filter>Source Files\desmume\utils\AsmJit\x86</Filter>
</ClCompile>
- <ClCompile Include="desmume\utils\AsmJit\x86\x86util.cpp">
- <Filter>Source Files\desmume\utils\AsmJit\x86</Filter>
- </ClCompile>
- <ClCompile Include="desmume\metaspu\SoundTouch\mmx_optimized.cpp">
- <Filter>Source Files\desmume\metaspu\SoundTouch</Filter>
+ <ClCompile Include="desmume\utils\AsmJit\x86\x86operand_regs.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\x86</Filter>
+ </ClCompile>
+ <ClCompile Include="desmume\utils\AsmJit\x86\x86scheduler.cpp">
+ <Filter>Source Files\desmume\utils\AsmJit\x86</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
@@ -350,121 +341,106 @@
<ClInclude Include="desmume\instruction_attributes.h">
<Filter>Header Files\desmume</Filter>
</ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\AsmJit.h">
- <Filter>Header Files\desmume\utils\AsmJit</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core.h">
- <Filter>Header Files\desmume\utils\AsmJit</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\assembler.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\assert.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\buffer.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\compiler.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\compilercontext.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\compilerfunc.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\compileritem.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\cpuinfo.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\defs.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\func.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\intutil.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\lock.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\logger.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\memorymanager.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\memorymarker.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\operand.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\podvector.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\stringbuilder.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\stringutil.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\virtualmemory.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\zonememory.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\context.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\apibegin.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\apiend.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\core\build.h">
- <Filter>Header Files\desmume\utils\AsmJit\core</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\Config.h">
+ <ClInclude Include="desmume\utils\AsmJit\apibegin.h">
+ <Filter>Header Files\desmume\utils\AsmJit</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\apiend.h">
+ <Filter>Header Files\desmume\utils\AsmJit</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\asmjit.h">
+ <Filter>Header Files\desmume\utils\AsmJit</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base.h">
+ <Filter>Header Files\desmume\utils\AsmJit</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\build.h">
+ <Filter>Header Files\desmume\utils\AsmJit</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\config.h">
+ <Filter>Header Files\desmume\utils\AsmJit</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\host.h">
<Filter>Header Files\desmume\utils\AsmJit</Filter>
</ClInclude>
<ClInclude Include="desmume\utils\AsmJit\x86.h">
<Filter>Header Files\desmume\utils\AsmJit</Filter>
</ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\assembler.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\codegen.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\compiler.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\constpool.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\containers.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\context_p.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\cpuinfo.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\cputicks.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\error.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\globals.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\intutil.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\lock.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\logger.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\operand.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\runtime.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\string.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\vectypes.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\vmem.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
+ <ClInclude Include="desmume\utils\AsmJit\base\zone.h">
+ <Filter>Header Files\desmume\utils\AsmJit\base</Filter>
+ </ClInclude>
<ClInclude Include="desmume\utils\AsmJit\x86\x86assembler.h">
<Filter>Header Files\desmume\utils\AsmJit\x86</Filter>
</ClInclude>
<ClInclude Include="desmume\utils\AsmJit\x86\x86compiler.h">
<Filter>Header Files\desmume\utils\AsmJit\x86</Filter>
</ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\x86\x86compilercontext.h">
- <Filter>Header Files\desmume\utils\AsmJit\x86</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\x86\x86compilerfunc.h">
- <Filter>Header Files\desmume\utils\AsmJit\x86</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\x86\x86compileritem.h">
+ <ClInclude Include="desmume\utils\AsmJit\x86\x86context_p.h">
<Filter>Header Files\desmume\utils\AsmJit\x86</Filter>
</ClInclude>
<ClInclude Include="desmume\utils\AsmJit\x86\x86cpuinfo.h">
<Filter>Header Files\desmume\utils\AsmJit\x86</Filter>
</ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\x86\x86defs.h">
- <Filter>Header Files\desmume\utils\AsmJit\x86</Filter>
- </ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\x86\x86func.h">
+ <ClInclude Include="desmume\utils\AsmJit\x86\x86inst.h">
<Filter>Header Files\desmume\utils\AsmJit\x86</Filter>
</ClInclude>
<ClInclude Include="desmume\utils\AsmJit\x86\x86operand.h">
<Filter>Header Files\desmume\utils\AsmJit\x86</Filter>
</ClInclude>
- <ClInclude Include="desmume\utils\AsmJit\x86\x86util.h">
+ <ClInclude Include="desmume\utils\AsmJit\x86\x86scheduler_p.h">
<Filter>Header Files\desmume\utils\AsmJit\x86</Filter>
</ClInclude>
</ItemGroup>
--- a/src/in_gsf/XSFConfig_GSF.cpp
+++ b/src/in_gsf/XSFConfig_GSF.cpp
@@ -1,7 +1,7 @@
/*
* xSF - GSF configuration
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-03-30
+ * Last modification on 2014-09-17
*
* Partially based on the vio*sf framework
*/
@@ -141,7 +141,7 @@
void XSFConfig_GSF::About(HWND parent)
{
- MessageBox(parent, (XSFConfig::commonName + L" v" + XSFConfig::versionNumber + L", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
- L"Utilizes modified VBA-M, SVN revision 1102, for audio playback.").c_str(), (XSFConfig::commonName + L" v" + XSFConfig::versionNumber).c_str(), MB_OK);
+ MessageBoxW(parent, (XSFConfig::commonName + L" v" + XSFConfig::versionNumber + L", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
+ L"Utilizes modified VBA-M, SVN revision 1231, for audio playback.").c_str(), (XSFConfig::commonName + L" v" + XSFConfig::versionNumber).c_str(), MB_OK);
}
--- a/src/in_gsf/XSFPlayer_GSF.cpp
+++ b/src/in_gsf/XSFPlayer_GSF.cpp
@@ -1,7 +1,7 @@
/*
* xSF - GSF Player
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-04-23
+ * Last modification on 2014-09-17
*
* Based on a modified viogsf v0.08
*
@@ -24,7 +24,9 @@
{
public:
XSFPlayer_GSF(const std::string &filename);
+#ifdef _MSC_VER
XSFPlayer_GSF(const std::wstring &filename);
+#endif
~XSFPlayer_GSF() { this->Terminate(); }
bool Load();
void GenerateSamples(std::vector<uint8_t> &buf, unsigned offset, unsigned samples);
@@ -39,10 +41,12 @@
return new XSFPlayer_GSF(fn);
}
+#ifdef _MSC_VER
XSFPlayer *XSFPlayer::Create(const std::wstring &fn)
{
return new XSFPlayer_GSF(fn);
}
+#endif
static struct
{
@@ -148,7 +152,7 @@
{
if (level <= 10 && xSF->GetTagExists("_lib"))
{
-#ifdef _WIN32
+#ifdef _MSC_VER
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetWStr()) + xSF->GetTagValue("_lib").GetWStr(), 8, 12));
#else
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetAnsi()) + xSF->GetTagValue("_lib").GetAnsi(), 8, 12));
@@ -169,7 +173,7 @@
if (xSF->GetTagExists(libTag))
{
found = true;
-#ifdef _WIN32
+#ifdef _MSC_VER
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetWStr()) + xSF->GetTagValue(libTag).GetWStr(), 8, 12));
#else
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetAnsi()) + xSF->GetTagValue(libTag).GetAnsi(), 8, 12));
@@ -195,10 +199,12 @@
this->xSF.reset(new XSFFile(filename, 8, 12));
}
+#ifdef _MSC_VER
XSFPlayer_GSF::XSFPlayer_GSF(const std::wstring &filename) : XSFPlayer()
{
this->xSF.reset(new XSFFile(filename, 8, 12));
}
+#endif
bool XSFPlayer_GSF::Load()
{
--- a/src/in_gsf/vbam/apu/Blip_Buffer.cpp
+++ b/src/in_gsf/vbam/apu/Blip_Buffer.cpp
@@ -5,6 +5,7 @@
#include <cmath>
#include <cstring>
#include "Blip_Buffer.h"
+#include "XSFCommon.h"
/* Copyright (C) 2003-2007 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@@ -63,7 +64,7 @@
void Blip_Buffer::set_sample_rate(long new_rate, long msec)
{
// start with maximum length that resampled time can represent
- long new_size = (ULONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
+ long new_size = (std::numeric_limits<unsigned long>::max() >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
if (msec != blip_max_length)
{
long s = (new_rate * (msec + 1) + 999) / 1000;
@@ -289,7 +290,7 @@
// volume might require rescaling
double vol = this->volume_unit_;
- if (vol)
+ if (!fEqual(vol, 0.0))
{
this->volume_unit_ = 0.0;
this->volume_unit(vol);
@@ -298,7 +299,7 @@
void Blip_Synth_::volume_unit(double new_unit)
{
- if (new_unit != this->volume_unit_)
+ if (!fEqual(new_unit, this->volume_unit_))
{
// use default eq if it hasn't been set yet
if (!this->kernel_unit)
--- a/src/in_gsf/vbam/apu/Gb_Apu.cpp
+++ b/src/in_gsf/vbam/apu/Gb_Apu.cpp
@@ -2,6 +2,7 @@
#include <algorithm>
#include "Gb_Apu.h"
+#include "XSFCommon.h"
/* Copyright (C) 2003-2007 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@@ -76,7 +77,7 @@
void Gb_Apu::volume(double v)
{
- if (this->volume_ != v)
+ if (!fEqual(this->volume_, v))
{
this->volume_ = v;
this->apply_volume();
@@ -157,7 +158,7 @@
void Gb_Apu::set_tempo(double t)
{
this->frame_period = 4194304 / 512; // 512 Hz
- if (t != 1.0)
+ if (!fEqual(t, 1.0))
this->frame_period = static_cast<blip_time_t>(this->frame_period / t);
}
--- a/src/in_gsf/vbam/apu/Gb_Oscs.cpp
+++ b/src/in_gsf/vbam/apu/Gb_Oscs.cpp
@@ -533,7 +533,7 @@
else if (!vol)
{
// Maintain phase when not playing
- int32_t count = (end_time - time + per - 1) / per;
+ count = (end_time - time + per - 1) / per;
time += static_cast<blip_time_t>(count) * per;
bits = run_lfsr(bits, ~mask, count);
}
--- a/src/in_gsf/vbam/apu/Gb_Oscs.h
+++ b/src/in_gsf/vbam/apu/Gb_Oscs.h
@@ -49,7 +49,7 @@
class Gb_Env : public Gb_Osc
{
public:
- Gb_Env() : env_enabled(false), env_delay(0) { }
+ Gb_Env() : env_delay(0), env_enabled(false) { }
int env_delay;
int volume;
bool env_enabled;
--- a/src/in_gsf/vbam/apu/Multi_Buffer.h
+++ b/src/in_gsf/vbam/apu/Multi_Buffer.h
@@ -131,7 +131,6 @@
buf_t bufs[bufs_size];
Stereo_Mixer mixer;
channel_t chan;
- long samples_avail_;
};
inline void Multi_Buffer::set_sample_rate(long rate, long msec)
--- a/src/in_gsf/vbam/common/SoundDriver.h
+++ b/src/in_gsf/vbam/common/SoundDriver.h
@@ -57,6 +57,6 @@
*/
virtual void write(uint16_t *finalWave, int length) = 0;
- virtual void setThrottle(unsigned short throttle) { }
+ virtual void setThrottle(unsigned short) { }
};
--- a/src/in_gsf/vbam/gba/GBA-arm.cpp
+++ b/src/in_gsf/vbam/gba/GBA-arm.cpp
@@ -17,7 +17,7 @@
static int clockTicks;
-static INSN_REGPARM void armUnknownInsn(uint32_t opcode)
+static INSN_REGPARM void armUnknownInsn(uint32_t)
{
CPUUndefinedException();
}
--- a/src/in_gsf/vbam/gba/GBA-thumb.cpp
+++ b/src/in_gsf/vbam/gba/GBA-thumb.cpp
@@ -9,7 +9,7 @@
static int clockTicks;
-static INSN_REGPARM void thumbUnknownInsn(uint32_t opcode)
+static INSN_REGPARM void thumbUnknownInsn(uint32_t)
{
CPUUndefinedException();
}
@@ -1364,7 +1364,7 @@
// SWI #comment
static INSN_REGPARM void thumbDF(uint32_t opcode)
{
- uint32_t address = 0;
+ //uint32_t address = 0;
//clockTicks = codeTicksAccessSeq16(address) * 2 + codeTicksAccess16(address) + 3;
clockTicks = 3;
busPrefetchCount = 0;
--- a/src/in_gsf/vbam/gba/Sound.cpp
+++ b/src/in_gsf/vbam/gba/Sound.cpp
@@ -6,6 +6,7 @@
#include "../apu/Gb_Apu.h"
#include "../apu/Multi_Buffer.h"
#include "../common/SoundDriver.h"
+#include "XSFCommon.h"
extern SoundDriver *systemSoundInit();
@@ -117,7 +118,7 @@
// base filtering on how long since last sample was output
int32_t period = time - this->last_time;
- int idx = period / 512;
+ idx = period / 512;
if (idx >= 3)
idx = 3;
@@ -189,11 +190,11 @@
if (!this->count)
{
// Not filled by DMA, so fill with 16 bytes of silence
- int reg = this->which ? FIFOB_L : FIFOA_L;
+ int regi = this->which ? FIFOB_L : FIFOA_L;
for (int n = 8; n--; )
{
- soundEvent(reg, static_cast<uint16_t>(0));
- soundEvent(reg + 2, static_cast<uint16_t>(0));
+ soundEvent(regi, static_cast<uint16_t>(0));
+ soundEvent(regi + 2, static_cast<uint16_t>(0));
}
}
}
@@ -393,10 +394,10 @@
flush_samples(stereo_buffer.get());
- if (soundFiltering_ != soundFiltering)
+ if (!fEqual(soundFiltering_, soundFiltering))
apply_filtering();
- if (soundVolume_ != soundVolume)
+ if (!fEqual(soundVolume_, soundVolume))
apply_volume();
}
}
@@ -412,10 +413,12 @@
if (gb_apu)
// APU
for (int i = 0; i < 4; ++i)
+ {
if (soundEnableFlag >> i & 1)
gb_apu->set_output(stereo_buffer->center(), stereo_buffer->left(), stereo_buffer->right(), i);
else
gb_apu->set_output(nullptr, nullptr, nullptr, i);
+ }
}
static void reset_apu()
--- a/src/in_gsf/vbam/gba/bios.cpp
+++ b/src/in_gsf/vbam/gba/bios.cpp
@@ -4,6 +4,7 @@
#include "bios.h"
#include "GBAinline.h"
#include "Globals.h"
+#include "XSFCommon.h"
int32_t sineTable[] =
{
@@ -64,7 +65,7 @@
res = (x >> 16) & 0x8000;
else if (!x)
res = ((y >> 16) & 0x8000) + 0x4000;
- else if (std::abs(x) > std::abs(y) || (std::abs(x) == std::abs(y) && !(x < 0 && y < 0)))
+ else if (std::abs(x) > std::abs(y) || (fEqual(std::abs(x), std::abs(y)) && !(x < 0 && y < 0)))
{
reg[1].I = x;
reg[0].I = y << 14;
--- a/src/in_ncsf/SSEQPlayer/Channel.h
+++ b/src/in_ncsf/SSEQPlayer/Channel.h
@@ -1,7 +1,7 @@
/*
* SSEQ Player - Channel structures
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-09-08
+ * Last modification on 2014-09-17
*
* Adapted from source code of FeOS Sound System
* By fincs
@@ -13,6 +13,7 @@
#pragma once
+#include <algorithm>
#include <bitset>
#include <cstdint>
#include "SWAV.h"
@@ -153,7 +154,7 @@
if (this->bufferPos >= N * 3 / 2)
this->bufferPos -= N;
}
- const int16_t *const GetBuffer() const
+ const int16_t *GetBuffer() const
{
return &this->buffer[this->getPos];
}
--- a/src/in_ncsf/SSEQPlayer/FATSection.cpp
+++ b/src/in_ncsf/SSEQPlayer/FATSection.cpp
@@ -1,12 +1,13 @@
/*
* SSEQ Player - SDAT FAT (File Allocation Table) Section structures
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-03-21
+ * Last modification on 2014-09-17
*
* Nintendo DS Nitro Composer (SDAT) Specification document found at
* http://www.feshrine.net/hacking/doc/nds-sdat.html
*/
+#include <stdexcept>
#include "FATSection.h"
FATRecord::FATRecord() : offset(0)
--- a/src/in_ncsf/SSEQPlayer/NDSStdHeader.cpp
+++ b/src/in_ncsf/SSEQPlayer/NDSStdHeader.cpp
@@ -1,12 +1,13 @@
/*
* SSEQ Player - Nintendo DS Standard Header structure
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-03-21
+ * Last modification on 2014-09-17
*
* Nintendo DS Nitro Composer (SDAT) Specification document found at
* http://www.feshrine.net/hacking/doc/nds-sdat.html
*/
+#include <stdexcept>
#include "NDSStdHeader.h"
NDSStdHeader::NDSStdHeader() : magic(0)
--- a/src/in_ncsf/XSFConfig_NCSF.cpp
+++ b/src/in_ncsf/XSFConfig_NCSF.cpp
@@ -1,7 +1,7 @@
/*
* xSF - NCSF configuration
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-06-17
+ * Last modification on 2014-09-17
*
* Partially based on the vio*sf framework
*/
@@ -69,7 +69,7 @@
void XSFConfig_NCSF::LoadSpecificConfig()
{
this->interpolation = this->configIO->GetValue(L"Interpolation", XSFConfig_NCSF::initInterpolation);
- std::wstringstream mutesSS = std::wstringstream(this->configIO->GetValue(L"Mutes", XSFConfig_NCSF::initMutes));
+ std::wstringstream mutesSS(this->configIO->GetValue(L"Mutes", XSFConfig_NCSF::initMutes));
mutesSS >> this->mutes;
}
@@ -141,7 +141,7 @@
void XSFConfig_NCSF::About(HWND parent)
{
- MessageBox(parent, (XSFConfig::commonName + L" v" + XSFConfig::versionNumber + L", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
+ MessageBoxW(parent, (XSFConfig::commonName + L" v" + XSFConfig::versionNumber + L", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
L"Utilizes code adapted from the FeOS Sound System library by fincs, git revision 5204c55 on GitHub, for audio playback.").c_str(), (XSFConfig::commonName + L" v" + XSFConfig::versionNumber).c_str(), MB_OK);
}
--- a/src/in_ncsf/XSFPlayer_NCSF.cpp
+++ b/src/in_ncsf/XSFPlayer_NCSF.cpp
@@ -1,7 +1,7 @@
/*
* xSF - NCSF Player
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-04-26
+ * Last modification on 2014-09-17
*
* Partially based on the vio*sf framework
*
@@ -25,10 +25,12 @@
return new XSFPlayer_NCSF(fn);
}
+#ifdef _MSC_VER
XSFPlayer *XSFPlayer::Create(const std::wstring &fn)
{
return new XSFPlayer_NCSF(fn);
}
+#endif
void XSFPlayer_NCSF::MapNCSFSection(const std::vector<uint8_t> §ion)
{
@@ -60,7 +62,7 @@
{
if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
{
-#ifdef _WIN32
+#ifdef _MSC_VER
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue("_lib").GetWStr(), 8, 12));
#else
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue("_lib").GetAnsi(), 8, 12));
@@ -81,7 +83,7 @@
if (xSFToLoad->GetTagExists(libTag))
{
found = true;
-#ifdef _WIN32
+#ifdef _MSC_VER
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue(libTag).GetWStr(), 8, 12));
#else
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue(libTag).GetAnsi(), 8, 12));
@@ -105,11 +107,13 @@
this->xSF.reset(new XSFFile(filename, 8, 12));
}
+#ifdef _MSC_VER
XSFPlayer_NCSF::XSFPlayer_NCSF(const std::wstring &filename) : XSFPlayer()
{
this->uses32BitSamplesClampedTo16Bit = true;
this->xSF.reset(new XSFFile(filename, 8, 12));
}
+#endif
bool XSFPlayer_NCSF::Load()
{
--- a/src/in_ncsf/XSFPlayer_NCSF.h
+++ b/src/in_ncsf/XSFPlayer_NCSF.h
@@ -1,7 +1,7 @@
/*
* xSF - NCSF Player
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-09-08
+ * Last modification on 2014-09-17
*
* Partially based on the vio*sf framework
*
@@ -33,7 +33,9 @@
bool LoadNCSF();
public:
XSFPlayer_NCSF(const std::string &filename);
+#ifdef _MSC_VER
XSFPlayer_NCSF(const std::wstring &filename);
+#endif
bool Load();
void GenerateSamples(std::vector<uint8_t> &buf, unsigned offset, unsigned samples);
void Terminate();
--- a/src/in_snsf/XSFConfig_SNSF.cpp
+++ b/src/in_snsf/XSFConfig_SNSF.cpp
@@ -1,7 +1,7 @@
/*
* xSF - SNSF configuration
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-05-08
+ * Last modification on 2014-09-17
*
* Partially based on the vio*sf framework
*
@@ -133,7 +133,7 @@
this->mutes[x] = !!SendMessageW(GetDlgItem(hwndDlg, idMutes), LB_GETSEL, x, 0);
}
-void XSFConfig_SNSF::CopySpecificConfigToMemory(XSFPlayer *xSFPlayer, bool preLoad)
+void XSFConfig_SNSF::CopySpecificConfigToMemory(XSFPlayer *, bool preLoad)
{
if (preLoad)
{
@@ -147,7 +147,7 @@
void XSFConfig_SNSF::About(HWND parent)
{
- MessageBox(parent, (XSFConfig::commonName + L" v" + XSFConfig::versionNumber + L", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
+ MessageBoxW(parent, (XSFConfig::commonName + L" v" + XSFConfig::versionNumber + L", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
L"Utilizes modified snes9x v1.53 for audio playback.").c_str(), (XSFConfig::commonName + L" v" + XSFConfig::versionNumber).c_str(), MB_OK);
}
--- a/src/in_snsf/XSFPlayer_SNSF.cpp
+++ b/src/in_snsf/XSFPlayer_SNSF.cpp
@@ -1,7 +1,7 @@
/*
* xSF - SNSF Player
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-05-08
+ * Last modification on 2014-09-17
*
* Based on a modified in_snsf by Caitsith2
* http://snsf.caitsith2.net/
@@ -33,7 +33,9 @@
{
public:
XSFPlayer_SNSF(const std::string &filename);
+#ifdef _MSC_VER
XSFPlayer_SNSF(const std::wstring &filename);
+#endif
~XSFPlayer_SNSF() { this->Terminate(); }
bool Load();
void GenerateSamples(std::vector<uint8_t> &buf, unsigned offset, unsigned samples);
@@ -50,10 +52,12 @@
return new XSFPlayer_SNSF(fn);
}
+#ifdef _MSC_VER
XSFPlayer *XSFPlayer::Create(const std::wstring &fn)
{
return new XSFPlayer_SNSF(fn);
}
+#endif
volatile bool execute = false;
@@ -105,7 +109,7 @@
return true;
}
-static void Map2SFSection(const std::vector<uint8_t> §ion, int level)
+static void Map2SFSection(const std::vector<uint8_t> §ion)
{
auto &data = loaderwork.rom;
@@ -125,7 +129,7 @@
std::copy_n(§ion[8], size, &data[offset]);
}
-static bool Map2SF(XSFFile *xSF, int level)
+static bool Map2SF(XSFFile *xSF)
{
if (!xSF->IsValidType(0x23))
return false;
@@ -156,7 +160,7 @@
}
if (!programSection.empty())
- Map2SFSection(programSection, level);
+ Map2SFSection(programSection);
return true;
}
@@ -165,7 +169,7 @@
{
if (level <= 10 && xSF->GetTagExists("_lib"))
{
-#ifdef _WIN32
+#ifdef _MSC_VER
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetWStr()) + xSF->GetTagValue("_lib").GetWStr(), 4, 8));
#else
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetAnsi()) + xSF->GetTagValue("_lib").GetAnsi(), 4, 8));
@@ -174,7 +178,7 @@
return false;
}
- if (!Map2SF(xSF, level))
+ if (!Map2SF(xSF))
return false;
unsigned n = 2;
@@ -186,7 +190,7 @@
if (xSF->GetTagExists(libTag))
{
found = true;
-#ifdef _WIN32
+#ifdef _MSC_VER
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetWStr()) + xSF->GetTagValue(libTag).GetWStr(), 4, 8));
#else
auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetAnsi()) + xSF->GetTagValue(libTag).GetAnsi(), 4, 8));
@@ -214,10 +218,12 @@
this->xSF.reset(new XSFFile(filename, 4, 8));
}
+#ifdef _MSC_VER
XSFPlayer_SNSF::XSFPlayer_SNSF(const std::wstring &filename) : XSFPlayer()
{
this->xSF.reset(new XSFFile(filename, 4, 8));
}
+#endif
bool XSFPlayer_SNSF::Load()
{
--- a/src/in_snsf/snes9x/apu/SNES_SPC.h
+++ b/src/in_snsf/snes9x/apu/SNES_SPC.h
@@ -230,7 +230,7 @@
}
inline void SNES_SPC::mute_voices(int mask) { this->dsp.mute_voices(mask); }
-
+
inline void SNES_SPC::disable_surround(bool disable) { this->dsp.disable_surround(disable); }
inline void SNES_SPC::spc_allow_time_overflow(bool allow) { this->allow_time_overflow = allow; }
--- a/src/in_snsf/snes9x/apu/SPC_CPU.h
+++ b/src/in_snsf/snes9x/apu/SPC_CPU.h
@@ -172,7 +172,7 @@
goto stop;
if ((rel_time += this->m.cycle_table[opcode]) > 0 && !this->allow_time_overflow)
goto out_of_time;
-
+
#ifdef SPC_CPU_OPCODE_HOOK
SPC_CPU_OPCODE_HOOK(GET_PC(), opcode);
#endif
--- a/src/in_snsf/snes9x/apu/SPC_DSP.cpp
+++ b/src/in_snsf/snes9x/apu/SPC_DSP.cpp
@@ -238,7 +238,7 @@
if (v->env_mode == env_attack)
v->env_mode = env_decay;
}
-
+
if (!this->read_counter(rate))
v->env = env; // nothing else is controlled by the counter
}
@@ -326,7 +326,7 @@
if (this->m.every_other_sample)
{
this->m.kon = this->m.new_kon;
- this->m.t_koff = this->m.regs[r_koff] | this->m.mute_mask;
+ this->m.t_koff = this->m.regs[r_koff] | this->m.mute_mask;
}
this->run_counters();
@@ -606,7 +606,7 @@
// Left output volumes
// (save sample for next clock so we can output both together)
this->m.t_main_out[0] = echo_output(0);
-
+
// Echo feedback
int l = this->m.t_echo_out[0] + static_cast<int16_t>((this->m.t_echo_in[0] * static_cast<int8_t>(this->m.regs[r_efb])) >> 7);
int r = this->m.t_echo_out[1] + static_cast<int16_t>((this->m.t_echo_in[1] * static_cast<int8_t>(this->m.regs[r_efb])) >> 7);
@@ -744,7 +744,7 @@
#define PHASE(n) if (n && !--clocks_remain) break; case n:
GEN_DSP_TIMING
#undef PHASE
-
+
if (--clocks_remain)
goto loop;
}
--- a/src/in_snsf/snes9x/apu/SPC_DSP.h
+++ b/src/in_snsf/snes9x/apu/SPC_DSP.h
@@ -243,7 +243,7 @@
void echo_28();
void echo_29();
void echo_30();
-
+
void soft_reset_common();
};
--- a/src/in_snsf/snes9x/apu/apu.cpp
+++ b/src/in_snsf/snes9x/apu/apu.cpp
@@ -404,7 +404,7 @@
return false;
/* The resampler and spc unit use samples (16-bit short) as
- /* arguments. Use 2x in the resampler for buffer leveling with SoundSync */
+ * arguments. Use 2x in the resampler for buffer leveling with SoundSync */
spc::resampler.reset(new ResamplerClass(spc::buffer_size >> (Settings.SoundSync ? 0 : 1)));
if (!spc::resampler)
{
--- a/src/in_snsf/snes9x/apu/bspline_resampler.h
+++ b/src/in_snsf/snes9x/apu/bspline_resampler.h
@@ -52,7 +52,7 @@
void read(short *data, int num_samples)
{
int i_position = this->start >> 1;
- short *internal_buffer = reinterpret_cast<short *>(this->buffer);
+ short *internal_buffer = reinterpret_cast<short *>(&this->buffer[0]);
int o_position = 0;
int consumed = 0;
--- a/src/in_snsf/snes9x/apu/hermite_resampler.h
+++ b/src/in_snsf/snes9x/apu/hermite_resampler.h
@@ -61,7 +61,7 @@
void read(short *data, int num_samples)
{
int i_position = this->start >> 1;
- short *internal_buffer = reinterpret_cast<short *>(this->buffer);
+ short *internal_buffer = reinterpret_cast<short *>(&this->buffer[0]);
int o_position = 0;
int consumed = 0;
--- a/src/in_snsf/snes9x/apu/license.txt
+++ b/src/in_snsf/snes9x/apu/license.txt
@@ -146,7 +146,7 @@
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
-
+
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
--- a/src/in_snsf/snes9x/apu/linear_resampler.h
+++ b/src/in_snsf/snes9x/apu/linear_resampler.h
@@ -3,12 +3,13 @@
#pragma once
#include "resampler.h"
-
-const int f_prec = 15;
-const uint32_t f__one = 1 << f_prec;
+#include "XSFCommon.h"
class LinearResampler : public Resampler
{
+ static const int f_prec = 15;
+ static const uint32_t f__one = 1 << f_prec;
+
protected:
uint32_t f__r_step;
uint32_t f__inv_r_step;
@@ -25,7 +26,7 @@
void time_ratio(double ratio)
{
- if (!ratio)
+ if (fEqual(ratio, 0.0))
ratio = 1.0;
this->f__r_step = static_cast<uint32_t>(ratio * f__one);
this->f__inv_r_step = static_cast<uint32_t>(f__one / ratio);
@@ -43,7 +44,7 @@
void read(short *data, int num_samples)
{
int i_position = this->start >> 1;
- short *internal_buffer = reinterpret_cast<short *>(this->buffer);
+ short *internal_buffer = reinterpret_cast<short *>(&this->buffer[0]);
int o_position = 0;
int consumed = 0;
int max_samples = this->buffer_size >> 1;
--- a/src/in_snsf/snes9x/apu/osculating_resampler.h
+++ b/src/in_snsf/snes9x/apu/osculating_resampler.h
@@ -53,7 +53,7 @@
void read(short *data, int num_samples)
{
int i_position = this->start >> 1;
- short *internal_buffer = reinterpret_cast<short *>(this->buffer);
+ short *internal_buffer = reinterpret_cast<short *>(&this->buffer[0]);
int o_position = 0;
int consumed = 0;
--- a/src/in_snsf/snes9x/apu/ring_buffer.h
+++ b/src/in_snsf/snes9x/apu/ring_buffer.h
@@ -2,6 +2,7 @@
#pragma once
+#include <memory>
#include <algorithm>
#include <cstring>
@@ -11,19 +12,14 @@
int size;
int buffer_size;
int start;
- unsigned char *buffer;
+ std::unique_ptr<unsigned char[]> buffer;
public:
- ring_buffer(int buffer_size)
+ ring_buffer(int buf_size)
{
- this->buffer_size = buffer_size;
- this->buffer = new unsigned char[this->buffer_size];
+ this->buffer_size = buf_size;
+ this->buffer.reset(new unsigned char[this->buffer_size]);
this->clear();
- }
-
- ~ring_buffer()
- {
- delete[] buffer;
}
bool push(unsigned char *src, int bytes)
@@ -60,11 +56,10 @@
std::fill_n(&this->buffer[0], this->buffer_size, 0);
}
- void resize(int size)
+ void resize(int new_size)
{
- delete[] this->buffer;
- this->buffer_size = size;
- this->buffer = new unsigned char[this->buffer_size];
+ this->buffer_size = new_size;
+ this->buffer.reset(new unsigned char[this->buffer_size]);
this->clear();
}
};
--- a/src/in_snsf/snes9x/apu/sinc_resampler.h
+++ b/src/in_snsf/snes9x/apu/sinc_resampler.h
@@ -6,6 +6,7 @@
#define _USE_MATH_DEFINES
#include <cmath>
#include "resampler.h"
+#include "XSFCommon.h"
#ifndef M_PI
const double M_PI = 3.14159265358979323846;
@@ -26,14 +27,6 @@
template<typename T1, typename T2> static T1 CLAMP(T1 x, T2 low, T2 high) { return x > high ? high : (x < low ? low : x); }
template<typename T> static short SHORT_CLAMP(T n) { return static_cast<short>(CLAMP(n, -32768, 32767)); }
-
- // Code from http://learningcppisfun.blogspot.com/2010/04/comparing-floating-point-numbers.html
- template<typename T> static bool fEqual(T x, T y, int N = 1)
- {
- T diff = std::abs(x - y);
- T tolerance = N * std::numeric_limits<T>::epsilon();
- return diff <= tolerance * std::abs(x) && diff <= tolerance * std::abs(y);
- }
static inline double sinc(double x)
{
@@ -87,7 +80,7 @@
void read(short *data, int num_samples)
{
int i_position = this->start >> 1;
- short *internal_buffer = reinterpret_cast<short *>(this->buffer);
+ short *internal_buffer = reinterpret_cast<short *>(&this->buffer[0]);
int o_position = 0;
int consumed = 0;
--- a/src/in_snsf/snes9x/cpuaddr.h
+++ b/src/in_snsf/snes9x/cpuaddr.h
@@ -283,7 +283,7 @@
return addr2;
}
-inline uint32_t AbsoluteIndexedIndirect(AccessMode a) // (a,X)
+inline uint32_t AbsoluteIndexedIndirect(AccessMode) // (a,X)
{
uint16_t addr = Immediate16Slow(READ);
addr += Registers.X.W;
@@ -295,7 +295,7 @@
return addr2;
}
-template<typename F> inline uint32_t AbsoluteIndirectLongWrapper(F f, AccessMode a)
+template<typename F> inline uint32_t AbsoluteIndirectLongWrapper(F f, AccessMode)
{
uint16_t addr = f(READ);
@@ -317,7 +317,7 @@
return AbsoluteIndirectLongWrapper(Immediate16, a);
}
-template<typename F> inline uint32_t AbsoluteIndirectWrapper(F f, AccessMode a)
+template<typename F> inline uint32_t AbsoluteIndirectWrapper(F f, AccessMode)
{
// No info on wrapping, but it doesn't matter anyway due to mirroring
uint16_t addr2 = S9xGetWord(f(READ));
@@ -460,7 +460,7 @@
return addr + Registers.Y.W;
}
-template<typename F> inline uint32_t DirectIndirectLongWrapper(F f, AccessMode a)
+template<typename F> inline uint32_t DirectIndirectLongWrapper(F f, AccessMode)
{
uint16_t addr = f(READ);
uint32_t addr2 = S9xGetWord(addr);
--- a/src/in_snsf/snes9x/cpuexec.cpp
+++ b/src/in_snsf/snes9x/cpuexec.cpp
@@ -259,8 +259,8 @@
if (CPU.Flags & SCAN_KEYS_FLAG)
break;
- register uint8_t Op;
- register SOpcodes *Opcodes;
+ uint8_t Op;
+ SOpcodes *Opcodes;
if (CPU.PCBase)
{
--- a/src/in_snsf/snes9x/cpuops.cpp
+++ b/src/in_snsf/snes9x/cpuops.cpp
@@ -187,16 +187,16 @@
/* ADC ********************************************************************* */
-template<typename T> static inline void ADC(T Work)
-{
-}
-
-template<> static inline void ADC<uint16_t>(uint16_t Work16)
+template<typename T> static inline void ADC(T)
+{
+}
+
+template<> inline void ADC<uint16_t>(uint16_t Work16)
{
ADC16(Work16);
}
-template<> static inline void ADC<uint8_t>(uint8_t Work8)
+template<> inline void ADC<uint8_t>(uint8_t Work8)
{
ADC8(Work8);
}
@@ -1199,16 +1199,16 @@
/* SBC ********************************************************************* */
-template<typename T> static inline void SBC(T Work)
-{
-}
-
-template<> static inline void SBC<uint16_t>(uint16_t Work16)
+template<typename T> static inline void SBC(T)
+{
+}
+
+template<> inline void SBC<uint16_t>(uint16_t Work16)
{
SBC16(Work16);
}
-template<> static inline void SBC<uint8_t>(uint8_t Work8)
+template<> inline void SBC<uint8_t>(uint8_t Work8)
{
SBC8(Work8);
}
--- a/src/in_snsf/snes9x/getset.h
+++ b/src/in_snsf/snes9x/getset.h
@@ -363,7 +363,7 @@
}
}
-inline void S9xSetByte(uint8_t Byte, uint32_t Address)
+inline void S9xSetByte(uint8_t Byt, uint32_t Address)
{
int block = (Address & 0xffffff) >> MEMMAP_SHIFT;
uint8_t *SetAddress = Memory.WriteMap[block];
@@ -371,7 +371,7 @@
if (SetAddress >= reinterpret_cast<uint8_t *>(CMemory::MAP_LAST))
{
- SetAddress[Address & 0xffff] = Byte;
+ SetAddress[Address & 0xffff] = Byt;
addCyclesInMemoryAccess(speed);
return;
}
@@ -379,7 +379,7 @@
switch (reinterpret_cast<intptr_t>(SetAddress))
{
case CMemory::MAP_CPU:
- S9xSetCPU(Byte, Address & 0xffff);
+ S9xSetCPU(Byt, Address & 0xffff);
addCyclesInMemoryAccess(speed);
break;
@@ -387,26 +387,26 @@
if (CPU.InDMAorHDMA && (Address & 0xff00) == 0x2100)
return;
- S9xSetPPU(Byte, Address & 0xffff);
+ S9xSetPPU(Byt, Address & 0xffff);
addCyclesInMemoryAccess(speed);
break;
case CMemory::MAP_LOROM_SRAM:
if (Memory.SRAMMask)
- Memory.SRAM[(((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask] = Byte;
+ Memory.SRAM[(((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask] = Byt;
addCyclesInMemoryAccess(speed);
break;
case CMemory::MAP_HIROM_SRAM:
if (Memory.SRAMMask)
- Memory.SRAM[((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask] = Byte;
+ Memory.SRAM[((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask] = Byt;
addCyclesInMemoryAccess(speed);
break;
case CMemory::MAP_SA1RAM:
- Memory.SRAM[Address & 0xffff] = Byte;
+ Memory.SRAM[Address & 0xffff] = Byt;
addCyclesInMemoryAccess(speed);
break;
--- a/src/in_snsf/snes9x/memmap.cpp
+++ b/src/in_snsf/snes9x/memmap.cpp
@@ -184,53 +184,6 @@
#include "memmap.h"
#include "apu/apu.h"
#include "sdd1.h"
-
-static const uint32_t crc32Table[] =
-{
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
- 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
- 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
- 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
- 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
- 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
- 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
- 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
- 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
- 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
- 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
- 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
- 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
- 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
- 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
- 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
- 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
- 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
- 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
- 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
- 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
- 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
-};
// deinterleave
--- a/src/in_snsf/snes9x/port.h
+++ b/src/in_snsf/snes9x/port.h
@@ -204,7 +204,7 @@
# endif
#endif
-#ifdef _WIN32
+#ifdef _MSC_VER
# define strcasecmp stricmp
#endif
--- a/src/in_snsf/snes9x/ppu.h
+++ b/src/in_snsf/snes9x/ppu.h
@@ -281,13 +281,13 @@
extern SnesModel *Model;
extern SnesModel M1SNES;
-inline void REGISTER_2104(uint8_t Byte)
+inline void REGISTER_2104(uint8_t Byt)
{
if (PPU.OAMAddr & 0x100)
{
int addr = ((PPU.OAMAddr & 0x10f) << 1) + (PPU.OAMFlip & 1);
- if (Byte != PPU.OAMData[addr])
- PPU.OAMData[addr] = Byte;
+ if (Byt != PPU.OAMData[addr])
+ PPU.OAMData[addr] = Byt;
PPU.OAMFlip ^= 1;
if (!(PPU.OAMFlip & 1))
@@ -301,15 +301,15 @@
else if (!(PPU.OAMFlip & 1))
{
PPU.OAMWriteRegister &= 0xff00;
- PPU.OAMWriteRegister |= Byte;
+ PPU.OAMWriteRegister |= Byt;
PPU.OAMFlip |= 1;
}
else
{
PPU.OAMWriteRegister &= 0x00ff;
uint8_t lowbyte = static_cast<uint8_t>(PPU.OAMWriteRegister);
- uint8_t highbyte = Byte;
- PPU.OAMWriteRegister |= Byte << 8;
+ uint8_t highbyte = Byt;
+ PPU.OAMWriteRegister |= Byt << 8;
int addr = PPU.OAMAddr << 1;
if (lowbyte != PPU.OAMData[addr] || highbyte != PPU.OAMData[addr + 1])
@@ -328,7 +328,7 @@
// This code is correct, however due to Snes9x's inaccurate timings, some games might be broken by this chage. :(
inline bool CHECK_INBLANK() { return Settings.BlockInvalidVRAMAccess && !PPU.ForcedBlanking && CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE; }
-inline void REGISTER_2118(uint8_t Byte)
+inline void REGISTER_2118(uint8_t Byt)
{
if (CHECK_INBLANK())
return;
@@ -339,16 +339,16 @@
{
uint32_t rem = PPU.VMA.Address & PPU.VMA.Mask1;
address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff;
- Memory.VRAM[address] = Byte;
+ Memory.VRAM[address] = Byt;
}
else
- Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xffff] = Byte;
+ Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xffff] = Byt;
if (!PPU.VMA.High)
PPU.VMA.Address += PPU.VMA.Increment;
}
-inline void REGISTER_2119(uint8_t Byte)
+inline void REGISTER_2119(uint8_t Byt)
{
if (CHECK_INBLANK())
return;
@@ -359,16 +359,16 @@
{
uint32_t rem = PPU.VMA.Address & PPU.VMA.Mask1;
address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xffff;
- Memory.VRAM[address] = Byte;
+ Memory.VRAM[address] = Byt;
}
else
- Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xffff] = Byte;
+ Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xffff] = Byt;
if (PPU.VMA.High)
PPU.VMA.Address += PPU.VMA.Increment;
}
-inline void REGISTER_2118_tile(uint8_t Byte)
+inline void REGISTER_2118_tile(uint8_t Byt)
{
if (CHECK_INBLANK())
return;
@@ -376,13 +376,13 @@
uint32_t rem = PPU.VMA.Address & PPU.VMA.Mask1;
uint32_t address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff;
- Memory.VRAM[address] = Byte;
+ Memory.VRAM[address] = Byt;
if (!PPU.VMA.High)
PPU.VMA.Address += PPU.VMA.Increment;
}
-inline void REGISTER_2119_tile(uint8_t Byte)
+inline void REGISTER_2119_tile(uint8_t Byt)
{
if (CHECK_INBLANK())
return;
@@ -390,41 +390,41 @@
uint32_t rem = PPU.VMA.Address & PPU.VMA.Mask1;
uint32_t address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xffff;
- Memory.VRAM[address] = Byte;
+ Memory.VRAM[address] = Byt;
if (PPU.VMA.High)
PPU.VMA.Address += PPU.VMA.Increment;
}
-inline void REGISTER_2118_linear(uint8_t Byte)
+inline void REGISTER_2118_linear(uint8_t Byt)
{
if (CHECK_INBLANK())
return;
uint32_t address;
- Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xffff] = Byte;
+ Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xffff] = Byt;
if (!PPU.VMA.High)
PPU.VMA.Address += PPU.VMA.Increment;
}
-inline void REGISTER_2119_linear(uint8_t Byte)
+inline void REGISTER_2119_linear(uint8_t Byt)
{
if (CHECK_INBLANK())
return;
uint32_t address;
- Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xffff] = Byte;
+ Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xffff] = Byt;
if (PPU.VMA.High)
PPU.VMA.Address += PPU.VMA.Increment;
}
-inline void REGISTER_2180(uint8_t Byte)
-{
- Memory.RAM[PPU.WRAM++] = Byte;
+inline void REGISTER_2180(uint8_t Byt)
+{
+ Memory.RAM[PPU.WRAM++] = Byt;
PPU.WRAM &= 0x1ffff;
}
--- a/src/in_xsf_framework/DialogBuilder.h
+++ b/src/in_xsf_framework/DialogBuilder.h
@@ -1,7 +1,7 @@
/*
* Windows Dynamic Dialog Builder framework
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-09-08
+ * Last modification on 2014-09-17
*/
#pragma once
@@ -429,14 +429,14 @@
DialogGroup() : DialogControl(), controls(), groupName(L"") { }
DialogGroup(const DialogGroup &control) : DialogControl(control), controls(), groupName(control.groupName)
{
- std::for_each(control.controls.begin(), control.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
+ std::for_each(control.controls.begin(), control.controls.end(), [&](const std::unique_ptr<DialogControl> &ctl) { this->controls.push_back(std::unique_ptr<DialogControl>(ctl->Clone())); });
}
DialogGroup &operator=(const DialogGroup &control)
{
DialogControl::operator=(control);
this->controls.clear();
- std::for_each(control.controls.begin(), control.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
+ std::for_each(control.controls.begin(), control.controls.end(), [&](const std::unique_ptr<DialogControl> &ctl) { this->controls.push_back(std::unique_ptr<DialogControl>(ctl->Clone())); });
this->groupName = control.groupName;
--- a/src/in_xsf_framework/XSFCommon.h
+++ b/src/in_xsf_framework/XSFCommon.h
@@ -1,7 +1,7 @@
/*
* xSF - Common functions
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-09-08
+ * Last modification on 2014-09-17
*
* Partially based on the vio*sf framework
*/
@@ -60,7 +60,7 @@
if (value < 1)
return 1;
--value;
- for (size_t i = 1; i < sizeof(T) * CHAR_BIT; i <<= 1)
+ for (size_t i = 1; i < sizeof(T) * std::numeric_limits<unsigned char>::digits; i <<= 1)
value |= value >> i;
return value + 1;
}
@@ -80,7 +80,7 @@
return !!file;
}
-#ifdef _WIN32
+#ifdef _MSC_VER
inline bool FileExists(const std::wstring &filename)
{
std::ifstream file(filename.c_str());
--- a/src/in_xsf_framework/XSFFile.cpp
+++ b/src/in_xsf_framework/XSFFile.cpp
@@ -1,7 +1,7 @@
/*
* xSF - File structure
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-03-30
+ * Last modification on 2014-09-17
*
* Partially based on the vio*sf framework
*/
@@ -64,7 +64,7 @@
this->ReadXSF(filename, programSizeOffset, programHeaderSize);
}
-#ifdef _WIN32
+#ifdef _MSC_VER
XSFFile::XSFFile(const std::wstring &filename) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
{
this->ReadXSF(filename, 0, 0, true);
@@ -88,7 +88,7 @@
this->ReadXSF(xSF, programSizeOffset, programHeaderSize, readTagsOnly);
}
-#ifdef _WIN32
+#ifdef _MSC_VER
void XSFFile::ReadXSF(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
{
if (!FileExists(filename))
@@ -454,7 +454,7 @@
{
std::ofstream xSF;
xSF.exceptions(std::ofstream::failbit);
-#ifdef _WIN32
+#ifdef _MSC_VER
xSF.open(this->fileName.GetWStrC(), std::ofstream::out | std::ofstream::binary);
#else
xSF.open(this->fileName.GetStrC(), std::ofstream::out | std::ofstream::binary);
--- a/src/in_xsf_framework/XSFFile.h
+++ b/src/in_xsf_framework/XSFFile.h
@@ -1,7 +1,7 @@
/*
* xSF - File structure
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-09-08
+ * Last modification on 2014-09-17
*
* Partially based on the vio*sf framework
*/
@@ -9,6 +9,7 @@
#pragma once
#include <cstdint>
+#include "convert.h"
#include "TagList.h"
#include "BigSString.h"
@@ -36,7 +37,7 @@
TagList tags;
String fileName;
void ReadXSF(const std::string &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly = false);
-#ifdef _WIN32
+#ifdef _MSC_VER
void ReadXSF(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly = false);
#endif
void ReadXSF(std::ifstream &xSF, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly = false);
@@ -45,7 +46,7 @@
XSFFile();
XSFFile(const std::string &filename);
XSFFile(const std::string &filename, uint32_t programSizeOffset, uint32_t programHeaderSize);
-#ifdef _WIN32
+#ifdef _MSC_VER
XSFFile(const std::wstring &filename);
XSFFile(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize);
#endif
--- a/src/in_xsf_framework/XSFPlayer.h
+++ b/src/in_xsf_framework/XSFPlayer.h
@@ -1,13 +1,14 @@
/*
* xSF - Core Player
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-09-08
+ * Last modification on 2014-09-17
*
* Partially based on the vio*sf framework
*/
#pragma once
+#include <memory>
#include "XSFFile.h"
#ifdef WINAMP_PLUGIN
@@ -36,7 +37,9 @@
static const char *WinampDescription;
static const char *WinampExts;
static XSFPlayer *Create(const std::string &fn);
+#ifdef _MSC_VER
static XSFPlayer *Create(const std::wstring &fn);
+#endif
virtual ~XSFPlayer() { }
XSFPlayer &operator=(const XSFPlayer &xSFPlayer);
--- a/src/in_xsf_framework/common.props
+++ b/src/in_xsf_framework/common.props
@@ -1,9 +1,9 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
- <zlibRootDir>ZLIBFIXME</zlibRootDir>
- <WinampSDKDir>WINAMPSDKFIXME</WinampSDKDir>
+ <zlibRootDir>G:\Code\zlib128-dll</zlibRootDir>
+ <WinampSDKDir>G:\Code\Winamp SDK</WinampSDKDir>
</PropertyGroup>
<PropertyGroup />
<ItemDefinitionGroup />
@@ -16,3 +16,4 @@
</BuildMacro>
</ItemGroup>
</Project>
+
--- a/src/in_xsf_framework/convert.h
+++ b/src/in_xsf_framework/convert.h
@@ -1,7 +1,7 @@
/*
* Common conversion functions
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-09-08
+ * Last modification on 2014-09-17
*/
#pragma once
@@ -12,6 +12,7 @@
#include <typeinfo>
#include <locale>
#include <vector>
+#include <memory>
#include <cmath>
#include "BigSString.h"
@@ -48,7 +49,7 @@
template<typename T, typename S> inline void convert(const std::basic_string<S> &s, T &x, bool failIfLeftoverChars = true)
{
- auto i = std::basic_istringstream<S>(s);
+ std::basic_istringstream<S> i(s);
S c;
if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
throw BadConversion(std::string("convert(") + typeid(S).name() + ")");
@@ -69,7 +70,7 @@
{
auto inputChars = std::vector<T>(input.begin(), input.end());
size_t length = inputChars.size();
- auto masks = std::vector<std::ctype<T>::mask>(length);
+ auto masks = std::vector<typename std::ctype<T>::mask>(length);
std::use_facet<std::ctype<T>>(loc).is(&inputChars[0], &inputChars[length], &masks[0]);
for (size_t x = 0; x < length; ++x)
if (inputChars[x] != '.' && !(masks[x] & std::ctype<T>::digit))
--- a/src/in_xsf_framework/ialogBuilder.h
+++ /dev/null
@@ -1,678 +1,1 @@
-/*
- * Windows Dynamic Dialog Builder framework
- * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-04-23
- */
-#ifndef DIALOG_BUILDER_H
-#define DIALOG_BUILDER_H
-
-#include <string>
-#include <memory>
-#include <vector>
-#include <algorithm>
-#include <stdexcept>
-#include <cstdint>
-#include "windowsh_wrapper.h"
-#include "UtfConverter.h"
-
-template<typename T> struct Point
-{
- T x, y;
-
- Point() : x(), y() { }
- Point(T X, T Y) : x(X), y(Y) { }
-};
-
-template<typename T> struct Size
-{
- T width, height;
-
- Size() : width(), height() { }
- Size(T Width, T Height) : width(Width), height(Height) { }
-};
-
-template<typename T> struct Rect
-{
- Point<T> position;
- Size<T> size;
-
- Rect() : position(), size() { }
- Rect(const Point<T> &Position, const Size<T> &Sz) : position(Position), size(Sz) { }
- Rect(T X, T Y, T Width, T Height) : position(X, Y), size(Width, Height) { }
-};
-
-class RelativePosition
-{
-public:
- Point<short> relativePosition;
- enum BaseType
- {
- TO_PARENT,
- TO_SIBLING
- } type;
- enum PositionType
- {
- FROM_TOP,
- FROM_BOTTOM,
- FROM_LEFT,
- FROM_RIGHT,
- FROM_TOPLEFT,
- FROM_BOTTOMLEFT,
- FROM_TOPRIGHT,
- FROM_BOTTOMRIGHT
- } positionType;
-
- RelativePosition(const Point<short> &RelPosition, BaseType Type, PositionType PosType) : relativePosition(RelPosition), type(Type), positionType(PosType) { }
- virtual ~RelativePosition() { }
- virtual RelativePosition *Clone() const = 0;
- Point<short> CalculatePosition(const Rect<short> &child, const Rect<short> &other);
-};
-
-class RelativePositionToParent : public RelativePosition
-{
-public:
- RelativePositionToParent(const Point<short> &RelPosition, PositionType PosType) : RelativePosition(RelPosition, TO_PARENT, PosType) { }
- RelativePositionToParent *Clone() const { return new RelativePositionToParent(this->relativePosition, this->positionType); }
-};
-
-class RelativePositionToSibling : public RelativePosition
-{
-public:
- short siblingsBack;
-
- RelativePositionToSibling(const Point<short> &RelPosition, PositionType PosType, short SiblingsBack = 1) : RelativePosition(RelPosition, TO_SIBLING, PosType), siblingsBack(SiblingsBack) { }
- RelativePositionToSibling *Clone() const { return new RelativePositionToSibling(this->relativePosition, this->positionType, this->siblingsBack); }
-};
-
-enum DialogControlType
-{
- NO_CONTROL,
- GROUP_CONTROL,
- EDITBOX_CONTROL,
- LABEL_CONTROL,
- CHECKBOX_CONTROL,
- BUTTON_CONTROL,
- LISTBOX_CONTROL,
- COMBOBOX_CONTROL
-};
-
-class DialogTemplate;
-
-class DialogBuilder
-{
-protected:
- friend class DialogTemplate;
- std::wstring title, fontName;
- uint32_t style, exstyle;
- uint16_t fontSizeInPts;
- Size<short> size;
- bool resetControls;
-public:
- DialogBuilder() : title(L""), fontName(L""), style(0), exstyle(0), fontSizeInPts(0), size(), resetControls(false) { }
- DialogBuilder &WithTitle(const std::wstring &Title) { this->title = Title; return *this; }
- DialogBuilder &WithFont(const std::wstring &FontName, uint16_t FontSizeInPts) { this->fontName = FontName; this->fontSizeInPts = FontSizeInPts; return *this; }
- DialogBuilder &WithSize(short Width, short Height) { this->size.width = Width; this->size.height = Height; return *this; }
- DialogBuilder &WithSize(const Size<short> &Sz) { this->size = Sz; return *this; }
- DialogBuilder &ResetControls(bool Reset = true) { this->resetControls = Reset; return *this; }
- DialogBuilder &IsOverlapped() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_OVERLAPPED; return *this; }
- DialogBuilder &IsPopup() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_POPUP; return *this; }
- DialogBuilder &IsChild() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_CHILD; return *this; }
- DialogBuilder &WithBorder(bool Border = true) { if (Border) this->style |= WS_BORDER; else this->style &= ~WS_BORDER; return *this; }
- DialogBuilder &WithDialogFrame(bool DialogFrame = true) { if (DialogFrame) this->style |= WS_DLGFRAME; else this->style &= ~WS_DLGFRAME; return *this; }
- DialogBuilder &WithVerticalScrollbar(bool VerticalScrollbar = true) { if (VerticalScrollbar) this->style |= WS_VSCROLL; else this->style &= ~WS_VSCROLL; return *this; }
- DialogBuilder &WithHorizontalScrollbar(bool HorizontalScrollbar = true) { if (HorizontalScrollbar) this->style |= WS_HSCROLL; else this->style &= ~WS_HSCROLL; return *this; }
- DialogBuilder &WithSystemMenu(bool SystemMenu = true) { if (SystemMenu) this->style |= WS_SYSMENU; else this->style &= ~WS_SYSMENU; return *this; }
- DialogBuilder &WithSizingBorder(bool SizingBorder = true) { if (SizingBorder) this->style |= WS_THICKFRAME; else this->style &= ~WS_THICKFRAME; return *this; }
- DialogBuilder &WithMinimizeBox(bool MinimizeBox = true) { if (MinimizeBox) this->style |= WS_MINIMIZEBOX; else this->style &= ~WS_MINIMIZEBOX; return *this; }
- DialogBuilder &WithMaximizeBox(bool MaximizeBox = true) { if (MaximizeBox) this->style |= WS_MAXIMIZEBOX; else this->style &= ~WS_MAXIMIZEBOX; return *this; }
- DialogBuilder &WithDialogModalFrame(bool DialogModalFrame = true) { if (DialogModalFrame) this->exstyle |= WS_EX_DLGMODALFRAME; else this->exstyle &= ~WS_EX_DLGMODALFRAME; return *this; }
-#if WINVER >= 0x0400
- DialogBuilder &WithRaisedEdge(bool RaisedEdge = true) { if (RaisedEdge) this->exstyle |= WS_EX_WINDOWEDGE; else this->exstyle &= ~WS_EX_WINDOWEDGE; return *this; }
- DialogBuilder &WithSunkenEdge(bool SunkenEdge = true) { if (SunkenEdge) this->exstyle |= WS_EX_CLIENTEDGE; else this->exstyle &= ~WS_EX_CLIENTEDGE; return *this; }
- DialogBuilder &WithContextHelp(bool ContextHelp = true) { if (ContextHelp) this->exstyle |= WS_EX_CONTEXTHELP; else this->exstyle &= ~WS_EX_CONTEXTHELP; return *this; }
- DialogBuilder &IsControlWindow(bool ControlWindow = true) { if (ControlWindow) this->style |= DS_CONTROL; else this->style &= ~DS_CONTROL; return *this; }
- DialogBuilder &IsCentered(bool Centered = true) { if (Centered) this->style |= DS_CENTER; else this->style &= ~DS_CENTER; return *this; }
-#endif
-};
-
-template<class T> class DialogControlBuilder
-{
-protected:
- friend class DialogTemplate;
- DialogControlType controlType;
- uint32_t style, exstyle;
- Rect<short> rect;
- short id;
- int index;
- std::unique_ptr<RelativePosition> relativePosition;
-
- T &me() { return dynamic_cast<T &>(*this); }
-public:
- DialogControlBuilder(DialogControlType Type = NO_CONTROL) : controlType(Type), style(0), exstyle(0), rect(), id(-1), index(-1), relativePosition() { }
- virtual ~DialogControlBuilder() { }
- T &WithPosition(short X, short Y) { this->rect.position.x = X; this->rect.position.y = Y; return this->me(); }
- T &WithPosition(const Point<short> &Position) { this->rect.position = Position; return this->me(); }
- T &WithRelativePositionToParent(RelativePosition::PositionType PosType, const Point<short> &RelativePosition)
- {
- this->relativePosition.reset(new RelativePositionToParent(RelativePosition, PosType));
- return this->me();
- }
- T &WithRelativePositionToSibling(RelativePosition::PositionType PosType, const Point<short> &RelativePosition, short SiblingsBack = 1)
- {
- this->relativePosition.reset(new RelativePositionToSibling(RelativePosition, PosType, SiblingsBack));
- return this->me();
- }
- T &WithSize(short Width, short Height) { this->rect.size.width = Width; this->rect.size.height = Height; return this->me(); }
- T &WithSize(const Size<short> &Sz) { this->rect.size = Sz; return this->me(); }
- T &WithID(short ID) { this->id = ID; return this->me(); }
- T &AtIndex(int Index) { this->index = Index; return this->me(); }
- T &IsDisabled(bool Disabled = true) { if (Disabled) this->style |= WS_DISABLED; else this->style &= ~WS_DISABLED; return this->me(); }
- T &WithBorder(bool ThinBorder = true) { if (ThinBorder) this->style |= WS_BORDER; else this->style &= ~WS_BORDER; return this->me(); }
- T &WithVerticalScrollbar(bool VerticalScrollbar = true) { if (VerticalScrollbar) this->style |= WS_VSCROLL; else this->style &= ~WS_VSCROLL; return this->me(); }
- T &WithHorizontalScrollbar(bool HorizontalScrollbar = true) { if (HorizontalScrollbar) this->style |= WS_HSCROLL; else this->style &= ~WS_HSCROLL; return this->me(); }
- T &WithTabStop(bool TabStop = true) { if (TabStop) this->style |= WS_TABSTOP; else this->style &= ~WS_TABSTOP; return this->me(); }
-#if WINVER >= 0x0400
- T &WithRaisedEdge(bool RaisedEdge = true) { if (RaisedEdge) this->exstyle |= WS_EX_WINDOWEDGE; else this->exstyle &= ~WS_EX_WINDOWEDGE; return this->me(); }
- T &WithSunkenEdge(bool SunkenEdge = true) { if (SunkenEdge) this->exstyle |= WS_EX_CLIENTEDGE; else this->exstyle &= ~WS_EX_CLIENTEDGE; return this->me(); }
-#endif
-};
-
-class DialogGroupBuilder : public DialogControlBuilder<DialogGroupBuilder>
-{
-protected:
- friend class DialogTemplate;
- std::wstring groupName;
-public:
- DialogGroupBuilder(const std::wstring &newGroupName) : DialogControlBuilder(GROUP_CONTROL), groupName(newGroupName) { }
-};
-
-template<class T> class DialogInGroupBuilder : public DialogControlBuilder<T>
-{
-protected:
- friend class DialogTemplate;
- std::wstring groupName;
-public:
- DialogInGroupBuilder(DialogControlType Type) : DialogControlBuilder<T>(Type), groupName(L"") { }
- T &InGroup(const std::wstring &GroupName) { this->groupName = GroupName; return this->me(); }
-};
-
-class DialogEditBoxBuilder : public DialogInGroupBuilder<DialogEditBoxBuilder>
-{
-protected:
- friend class DialogTemplate;
-public:
- DialogEditBoxBuilder() : DialogInGroupBuilder(EDITBOX_CONTROL) { }
- DialogEditBoxBuilder &IsLeftJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_LEFT; return this->me(); }
- DialogEditBoxBuilder &IsCenterJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_CENTER; return this->me(); }
- DialogEditBoxBuilder &IsRightJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_RIGHT; return this->me(); }
- DialogEditBoxBuilder &IsMultiline(bool Multiline = true) { if (Multiline) this->style |= ES_MULTILINE; else this->style &= ~ES_MULTILINE; return this->me(); }
- DialogEditBoxBuilder &WithAllUppercase(bool AllUppercase = true) { if (AllUppercase) this->style |= ES_UPPERCASE; else this->style &= ~ES_UPPERCASE; return this->me(); }
- DialogEditBoxBuilder &WithAllLowercase(bool AllLowercase = true) { if (AllLowercase) this->style |= ES_LOWERCASE; else this->style &= ~ES_LOWERCASE; return this->me(); }
- DialogEditBoxBuilder &IsPasswordInput(bool PasswordInput = true) { if (PasswordInput) this->style |= ES_PASSWORD; else this->style &= ~ES_PASSWORD; return this->me(); }
- DialogEditBoxBuilder &WithAutoVScroll(bool AutoVScroll = true) { if (AutoVScroll) this->style |= ES_AUTOVSCROLL; else this->style &= ~ES_AUTOVSCROLL; return this->me(); }
- DialogEditBoxBuilder &WithAutoHScroll(bool AutoHScroll = true) { if (AutoHScroll) this->style |= ES_AUTOHSCROLL; else this->style &= ~ES_AUTOHSCROLL; return this->me(); }
- DialogEditBoxBuilder &WithDontHideSelection(bool DontHideSelection = true) { if (DontHideSelection) this->style |= ES_NOHIDESEL; else this->style &= ~ES_NOHIDESEL; return this->me(); }
- DialogEditBoxBuilder &IsReadOnly(bool ReadOnly = true) { if (ReadOnly) this->style |= ES_READONLY; else this->style &= ~ES_READONLY; return this->me(); }
- DialogEditBoxBuilder &WithWantReturn(bool WantReturn = true) { if (WantReturn) this->style |= ES_WANTRETURN; else this->style &= ~ES_WANTRETURN; return this->me(); }
-};
-
-template<class T> class DialogControlWithLabelBuilder : public DialogInGroupBuilder<T>
-{
-protected:
- friend class DialogTemplate;
- std::wstring label;
-public:
- DialogControlWithLabelBuilder(DialogControlType Type, const std::wstring &Label) : DialogInGroupBuilder<T>(Type), label(Label) { }
-};
-
-class DialogLabelBuilder : public DialogControlWithLabelBuilder<DialogLabelBuilder>
-{
-protected:
- friend class DialogTemplate;
-public:
- DialogLabelBuilder(const std::wstring &Label) : DialogControlWithLabelBuilder(LABEL_CONTROL, Label) { }
- DialogLabelBuilder &IsLeftJustified(bool WithWordWrap = false)
- {
- this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP);
- if (WithWordWrap)
- this->style |= SS_LEFTNOWORDWRAP;
- else
- this->style |= SS_LEFT;
- return this->me();
- }
- DialogLabelBuilder &IsCenterJustified() { this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); this->style |= SS_CENTER; return this->me(); }
- DialogLabelBuilder &IsRightJustified() { this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); this->style |= SS_RIGHT; return this->me(); }
- DialogLabelBuilder &WithAmpsNotTranslated(bool AmpsNotTranslated = true) { if (AmpsNotTranslated) this->style |= SS_NOPREFIX; else this->style &= ~SS_NOPREFIX; return this->me(); }
-#if WINVER >= 0x0400
- DialogLabelBuilder &WithNotify(bool Notify = true) { if (Notify) this->style |= SS_NOTIFY; else this->style &= ~SS_NOTIFY; return this->me(); }
-#endif
-};
-
-template<class T> class DialogButtonBaseBuilder : public DialogControlWithLabelBuilder<T>
-{
-protected:
- friend class DialogTemplate;
-public:
- DialogButtonBaseBuilder(DialogControlType Type, const std::wstring &Label) : DialogControlWithLabelBuilder<T>(Type, Label) { }
-#if WINVER >= 0x0400
- T &IsLeftJustified(bool LeftJustified = true)
- {
- if (LeftJustified)
- {
- this->style |= BS_LEFT;
- this->style &= ~BS_RIGHT;
- }
- else
- this->style &= ~BS_LEFT;
- return this->me();
- }
- T &IsRightJustified(bool RightJustified = true)
- {
- if (RightJustified)
- {
- this->style |= BS_RIGHT;
- this->style &= ~BS_LEFT;
- }
- else
- this->style &= ~BS_RIGHT;
- return this->me();
- }
- T &IsCenterJustified(bool CenterJustified = true) { if (CenterJustified) this->style |= BS_CENTER; else this->style &= ~BS_CENTER; return this->me(); }
- T &WithVerticalTop(bool VerticalTop = true)
- {
- if (VerticalTop)
- {
- this->style |= BS_TOP;
- this->style &= ~BS_BOTTOM;
- }
- else
- this->style &= ~BS_TOP;
- return this->me();
- }
- T &WithVerticalBottom(bool VerticalBottom = true)
- {
- if (VerticalBottom)
- {
- this->style |= BS_BOTTOM;
- this->style &= ~BS_TOP;
- }
- else
- this->style &= ~BS_BOTTOM;
- return this->me();
- }
- T &WithVerticalCenter(bool VerticalCenter = true) { if (VerticalCenter) this->style |= BS_VCENTER; else this->style &= ~BS_VCENTER; return this->me(); }
- T &IsMultiline(bool Multiline = true) { if (Multiline) this->style |= BS_MULTILINE; else this->style &= ~BS_MULTILINE; return this->me(); }
- T &WithNotify(bool Notify = true) { if (Notify) this->style |= BS_NOTIFY; else this->style &= ~BS_NOTIFY; return this->me(); }
- T &IsFlat(bool Flat = true) { if (Flat) this->style |= BS_FLAT; else this->style &= ~BS_FLAT; return this->me(); }
-#endif
-};
-
-class DialogButtonBuilder : public DialogButtonBaseBuilder<DialogButtonBuilder>
-{
-protected:
- friend class DialogTemplate;
-public:
- DialogButtonBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(BUTTON_CONTROL, Label) { }
- DialogButtonBuilder &IsDefault(bool Default = true) { if (Default) this->style |= BS_DEFPUSHBUTTON; else this->style &= ~BS_DEFPUSHBUTTON; return this->me(); }
-};
-
-class DialogCheckBoxBuilder : public DialogButtonBaseBuilder<DialogCheckBoxBuilder>
-{
-protected:
- friend class DialogTemplate;
-public:
- DialogCheckBoxBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(CHECKBOX_CONTROL, Label) { this->style |= BS_AUTOCHECKBOX; }
- DialogCheckBoxBuilder &WithTextOnLeft(bool TextOnLeft = true) { if (TextOnLeft) this->style |= BS_LEFTTEXT; else this->style &= ~BS_LEFTTEXT; return this->me(); }
- DialogCheckBoxBuilder &LikePushButton(bool PushButton = true) { if (PushButton) this->style |= BS_PUSHLIKE; else this->style &= ~BS_PUSHLIKE; return this->me(); }
-};
-
-class DialogListBoxBuilder : public DialogInGroupBuilder<DialogListBoxBuilder>
-{
-protected:
- friend class DialogTemplate;
-public:
- DialogListBoxBuilder() : DialogInGroupBuilder(LISTBOX_CONTROL) { }
- DialogListBoxBuilder &WithNotify(bool Notify = true) { if (Notify) this->style |= LBS_NOTIFY; else this->style &= ~LBS_NOTIFY; return this->me(); }
- DialogListBoxBuilder &WithSort(bool Sort = true) { if (Sort) this->style |= LBS_SORT; else this->style &= ~LBS_SORT; return this->me(); }
- DialogListBoxBuilder &WithMultipleSelect(bool MultipleSelect = true) { if (MultipleSelect) this->style |= LBS_MULTIPLESEL; else this->style &= ~LBS_MULTIPLESEL; return this->me(); }
- DialogListBoxBuilder &WithExactHeight(bool ExactHeight = true) { if (ExactHeight) this->style |= LBS_NOINTEGRALHEIGHT; else this->style &= ~LBS_NOINTEGRALHEIGHT; return this->me(); }
- DialogListBoxBuilder &WithMultipleColumns(bool MultipleColumns = true) { if (MultipleColumns) this->style |= LBS_MULTICOLUMN; else this->style &= ~LBS_MULTICOLUMN; return this->me(); }
- DialogListBoxBuilder &WithExtendedSelect(bool ExtendedSelect = true) { if (ExtendedSelect) this->style |= LBS_EXTENDEDSEL; else this->style &= ~LBS_EXTENDEDSEL; return this->me(); }
- DialogListBoxBuilder &WithDisabledNoScroll(bool DisabledNoScroll = true) { if (DisabledNoScroll) this->style |= LBS_DISABLENOSCROLL; else this->style &= ~LBS_DISABLENOSCROLL; return this->me(); }
-#if WINVER >= 0x0400
- DialogListBoxBuilder &WithNoSelect(bool NoSelect = true) { if (NoSelect) this->style |= LBS_NOSEL; else this->style &= ~LBS_NOSEL; return this->me(); }
-#endif
-};
-
-class DialogComboBoxBuilder : public DialogInGroupBuilder<DialogComboBoxBuilder>
-{
-protected:
- friend class DialogTemplate;
-public:
- DialogComboBoxBuilder() : DialogInGroupBuilder(COMBOBOX_CONTROL) { }
- DialogComboBoxBuilder &IsSimple() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_SIMPLE; return this->me(); }
- DialogComboBoxBuilder &IsDropDown() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_DROPDOWN; return this->me(); }
- DialogComboBoxBuilder &IsDropDownList() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_DROPDOWNLIST; return this->me(); }
- DialogComboBoxBuilder &WithAutoHScroll(bool AutoHScroll = true) { if (AutoHScroll) this->style |= CBS_AUTOHSCROLL; else this->style &= ~CBS_AUTOHSCROLL; return this->me(); }
- DialogComboBoxBuilder &WithSort(bool Sort = true) { if (Sort) this->style |= CBS_SORT; else this->style &= ~CBS_SORT; return this->me(); }
- DialogComboBoxBuilder &WithExactHeight(bool ExactHeight = true) { if (ExactHeight) this->style |= CBS_NOINTEGRALHEIGHT; else this->style &= ~CBS_NOINTEGRALHEIGHT; return this->me(); }
- DialogComboBoxBuilder &WithDisabledNoScroll(bool DisabledNoScroll = true) { if (DisabledNoScroll) this->style |= CBS_DISABLENOSCROLL; else this->style &= ~CBS_DISABLENOSCROLL; return this->me(); }
-#if WINVER >= 0x0400
- DialogComboBoxBuilder &WithAllLowercase(bool AllLowercase = true) { if (AllLowercase) this->style |= CBS_LOWERCASE; else this->style &= ~CBS_LOWERCASE; return this->me(); }
- DialogComboBoxBuilder &WithAllUppercase(bool AllUppercase = true) { if (AllUppercase) this->style |= CBS_UPPERCASE; else this->style &= ~CBS_UPPERCASE; return this->me(); }
-#endif
-};
-
-class DialogTemplate
-{
- class DialogControl;
-
- typedef std::vector<std::unique_ptr<DialogControl>> Controls;
-
- class DialogControl
- {
- protected:
- DialogControlType controlType;
- uint32_t style, exstyle;
- Rect<short> rect;
- short id;
- std::unique_ptr<RelativePosition> relativePosition;
-
- friend class DialogTemplate;
- DialogControl() : controlType(NO_CONTROL), style(0), exstyle(0), rect(), id(-1), relativePosition() { }
- DialogControl(const DialogControl &control) : controlType(control.controlType), style(control.style), exstyle(control.exstyle), rect(control.rect), id(control.id),
- relativePosition(control.relativePosition ? control.relativePosition->Clone() : nullptr) { }
- DialogControl &operator=(const DialogControl &control)
- {
- this->controlType = control.controlType;
- this->style = control.style;
- this->exstyle = control.exstyle;
- this->rect = control.rect;
- this->id = control.id;
- if (control.relativePosition)
- this->relativePosition.reset(control.relativePosition->Clone());
- else
- this->relativePosition.reset();
-
- return *this;
- }
- public:
- virtual ~DialogControl() { }
- template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder)
- {
- auto control = std::unique_ptr<Control>(new Control());
-
- control->controlType = builder.controlType;
- control->style = builder.style;
- control->exstyle = builder.exstyle;
- control->rect = builder.rect;
- control->id = builder.id;
- if (builder.relativePosition)
- control->relativePosition.reset(builder.relativePosition->Clone());
-
- return control;
- }
- virtual uint16_t GetControlCount() const { return 1; }
- virtual short GetControlHeight() const { return this->rect.size.height; }
- virtual std::vector<uint8_t> GenerateControlTemplate() const = 0;
- virtual DialogControl *Clone() const = 0;
- };
-
- class DialogGroup : public DialogControl
- {
- protected:
- DialogTemplate::Controls controls;
- std::wstring groupName;
-
- friend class DialogTemplate;
- friend class DialogControl;
- DialogGroup() : DialogControl(), controls(), groupName(L"") { }
- DialogGroup(const DialogGroup &control) : DialogControl(control), controls(), groupName(control.groupName)
- {
- std::for_each(control.controls.begin(), control.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
- }
- DialogGroup &operator=(const DialogGroup &control)
- {
- DialogControl::operator=(control);
-
- this->controls.clear();
- std::for_each(control.controls.begin(), control.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
-
- this->groupName = control.groupName;
-
- return *this;
- }
- public:
- static std::unique_ptr<DialogGroup> CreateControl(const DialogControlBuilder<DialogGroupBuilder> &builder)
- {
- auto control = DialogControl::CreateControl<DialogGroup>(builder);
-
- control->groupName = dynamic_cast<const DialogGroupBuilder &>(builder).groupName;
-
- return control;
- }
- void CalculatePositions(bool doRightAndBottom = false);
- void CalculateSize();
- uint16_t GetControlCount() const;
- std::vector<uint8_t> GenerateControlTemplate() const;
- DialogGroup *Clone() const { return new DialogGroup(*this); }
- };
-
- class DialogControlWithoutLabel : public DialogControl
- {
- protected:
- uint16_t type;
-
- friend class DialogTemplate;
- friend class DialogControl;
- DialogControlWithoutLabel() : DialogControl(), type(0) { }
- DialogControlWithoutLabel(const DialogControlWithoutLabel &control) : DialogControl(control), type(control.type) { }
- DialogControlWithoutLabel &operator=(const DialogControlWithoutLabel &control)
- {
- DialogControl::operator=(control);
-
- this->type = control.type;
-
- return *this;
- }
- public:
- template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type)
- {
- auto control = DialogControl::CreateControl<Control>(builder);
-
- control->type = Type;
-
- return control;
- }
- virtual std::vector<uint8_t> GenerateControlTemplate() const;
- virtual DialogControlWithoutLabel *Clone() const { return new DialogControlWithoutLabel(*this); }
- };
-
- class DialogControlWithLabel : public DialogControl
- {
- protected:
- uint16_t type;
- std::wstring label;
-
- friend class DialogTemplate;
- friend class DialogControl;
- DialogControlWithLabel() : DialogControl(), type(0), label(L"") { }
- DialogControlWithLabel(const DialogControlWithLabel &control) : DialogControl(control), type(control.type), label(control.label) { }
- DialogControlWithLabel &operator=(const DialogControlWithLabel &control)
- {
- DialogControl::operator=(control);
-
- this->type = control.type;
- this->label = control.label;
-
- return *this;
- }
- public:
- template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type)
- {
- auto control = DialogControl::CreateControl<Control>(builder);
-
- control->type = Type;
- control->label = dynamic_cast<const DialogControlWithLabelBuilder<Builder> &>(builder).label;
-
- return control;
- }
- virtual std::vector<uint8_t> GenerateControlTemplate() const;
- virtual DialogControlWithLabel *Clone() const { return new DialogControlWithLabel(*this); }
- };
-
- class DialogEditBox : public DialogControlWithoutLabel
- {
- protected:
- friend class DialogTemplate;
- friend class DialogControl;
- DialogEditBox() : DialogControlWithoutLabel() { }
- public:
- static std::unique_ptr<DialogEditBox> CreateControl(const DialogControlBuilder<DialogEditBoxBuilder> &builder)
- {
- return DialogControlWithoutLabel::CreateControl<DialogEditBox>(builder, 0x0081);
- }
- };
-
- class DialogLabel : public DialogControlWithLabel
- {
- protected:
- friend class DialogTemplate;
- friend class DialogControl;
- DialogLabel() : DialogControlWithLabel() { }
- public:
- static std::unique_ptr<DialogLabel> CreateControl(const DialogControlBuilder<DialogLabelBuilder> &builder)
- {
- return DialogControlWithLabel::CreateControl<DialogLabel>(builder, 0x0082);
- }
- };
-
- class DialogButton : public DialogControlWithLabel
- {
- protected:
- friend class DialogTemplate;
- friend class DialogControl;
- DialogButton() : DialogControlWithLabel() { }
- public:
- template<typename Builder> static std::unique_ptr<DialogButton> CreateControl(const DialogControlBuilder<Builder> &builder)
- {
- return DialogControlWithLabel::CreateControl<DialogButton>(builder, 0x0080);
- }
- };
-
- class DialogListBox : public DialogControlWithoutLabel
- {
- protected:
- friend class DialogTemplate;
- friend class DialogControl;
- DialogListBox() : DialogControlWithoutLabel() { }
- public:
- static std::unique_ptr<DialogListBox> CreateControl(const DialogControlBuilder<DialogListBoxBuilder> &builder)
- {
- return DialogControlWithoutLabel::CreateControl<DialogListBox>(builder, 0x0083);
- }
- };
-
- class DialogComboBox : public DialogControlWithoutLabel
- {
- protected:
- friend class DialogTemplate;
- friend class DialogControl;
- DialogComboBox() : DialogControlWithoutLabel() { }
- public:
- static std::unique_ptr<DialogComboBox> CreateControl(const DialogControlBuilder<DialogComboBoxBuilder> &builder)
- {
- return DialogControlWithoutLabel::CreateControl<DialogComboBox>(builder, 0x0085);
- }
- short GetControlHeight() const { return (this->style & CBS_SIMPLE && !(this->style & CBS_DROPDOWNLIST)) ? this->rect.size.height : 14; }
- };
-
- std::wstring title;
- uint32_t style, exstyle;
- std::wstring fontName;
- uint16_t fontSizeInPts;
- Size<short> size;
- DialogTemplate::Controls controls;
- std::vector<uint8_t> templateData;
-
- template<typename Builder> void AddControlToGroup(std::unique_ptr<DialogControl> &&control, const DialogControlBuilder<Builder> &builder)
- {
- const auto &groupBuilder = dynamic_cast<const DialogInGroupBuilder<Builder> &>(builder);
- if (groupBuilder.groupName.empty())
- {
- if (builder.index == -1)
- this->controls.push_back(std::move(control));
- else
- this->controls.insert(this->controls.begin() + builder.index, std::move(control));
- }
- else
- {
- for (auto curr = this->controls.begin(), end = this->controls.end(); curr != end; ++curr)
- {
- if ((*curr)->controlType != GROUP_CONTROL)
- continue;
- DialogGroup *group = dynamic_cast<DialogGroup *>(curr->get());
- if (group->groupName == groupBuilder.groupName)
- {
- if (builder.index == -1)
- group->controls.push_back(std::move(control));
- else
- group->controls.insert(group->controls.begin() + builder.index, std::move(control));
- return;
- }
- }
- throw std::runtime_error("Group " + UtfConverter::ToUtf8(groupBuilder.groupName) + " was not found.");
- }
- }
- uint16_t GetTotalControlCount() const;
- bool CalculateControlPosition(short index, bool doRightAndBottom = false);
- void CalculateSize();
-public:
- DialogTemplate() : title(L""), style(0), exstyle(0), fontName(L""), fontSizeInPts(0), size(), controls(), templateData() { }
- DialogTemplate(const DialogBuilder &builder) : title(builder.title), style(builder.style), exstyle(builder.exstyle), fontName(builder.fontName), fontSizeInPts(builder.fontSizeInPts),
- size(builder.size), controls(), templateData() { }
- DialogTemplate(const DialogTemplate &dlg) : title(dlg.title), style(dlg.style), exstyle(dlg.style), fontName(dlg.fontName), fontSizeInPts(dlg.fontSizeInPts), size(dlg.size),
- controls(), templateData()
- {
- std::for_each(dlg.controls.begin(), dlg.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
- }
- DialogTemplate &operator=(const DialogBuilder &builder)
- {
- this->title = builder.title;
- this->style = builder.style;
- this->exstyle = builder.exstyle;
- this->fontName = builder.fontName;
- this->fontSizeInPts = builder.fontSizeInPts;
- this->size = builder.size;
- if (builder.resetControls)
- this->controls.clear();
-
- return *this;
- }
- DialogTemplate &operator=(const DialogTemplate &dlg)
- {
- this->title = dlg.title;
- this->style = dlg.style;
- this->exstyle = dlg.exstyle;
- this->fontName = dlg.fontName;
- this->fontSizeInPts = dlg.fontSizeInPts;
- this->size = dlg.size;
- this->controls.clear();
- std::for_each(dlg.controls.begin(), dlg.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
-
- return *this;
- }
- void AddGroupControl(const DialogControlBuilder<DialogGroupBuilder> &builder);
- void AddEditBoxControl(const DialogControlBuilder<DialogEditBoxBuilder> &builder);
- void AddLabelControl(const DialogControlBuilder<DialogLabelBuilder> &builder);
- void AddCheckBoxControl(const DialogControlBuilder<DialogCheckBoxBuilder> &builder);
- void AddButtonControl(const DialogControlBuilder<DialogButtonBuilder> &builder);
- void AddListBoxControl(const DialogControlBuilder<DialogListBoxBuilder> &builder);
- void AddComboBoxControl(const DialogControlBuilder<DialogComboBoxBuilder> &builder);
- void AutoSize();
- const DLGTEMPLATE *GenerateTemplate();
-};
-
-#endif
-
--- a/src/in_xsf_framework/in_xsf.cpp
+++ b/src/in_xsf_framework/in_xsf.cpp
@@ -1,7 +1,7 @@
/*
* xSF - Winamp plugin
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-04-23
+ * Last modification on 2014-09-17
*
* Partially based on the vio*sf framework
*/
@@ -361,6 +361,7 @@
}
}
+#ifdef _MSC_VER
extern "C" __declspec(dllexport) int winampGetExtendedFileInfoW(const wchar_t *fn, const char *data, wchar_t *dest, size_t destlen)
{
try
@@ -373,6 +374,7 @@
return 0;
}
}
+#endif
std::unique_ptr<XSFFile> extendedXSFFile;
@@ -396,6 +398,7 @@
}
}
+#ifdef _MSC_VER
extern "C" __declspec(dllexport) int winampSetExtendedFileInfoW(const wchar_t *fn, const char *data, const wchar_t *val)
{
try
@@ -409,6 +412,7 @@
return 0;
}
}
+#endif
extern "C" __declspec(dllexport) int winampWriteExtendedFileInfo()
{
@@ -454,6 +458,7 @@
}
}
+#ifdef _MSC_VER
extern "C" __declspec(dllexport) intptr_t winampGetExtendedRead_openW(const wchar_t *fn, int *size, int *bps, int *nch, int *srate)
{
try
@@ -466,6 +471,7 @@
return 0;
}
}
+#endif
int extendedSeekNeeded = -1;