summaryrefslogtreecommitdiff
path: root/lib/AsmJit/OperandX86X64.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AsmJit/OperandX86X64.h')
-rw-r--r--lib/AsmJit/OperandX86X64.h2298
1 files changed, 2298 insertions, 0 deletions
diff --git a/lib/AsmJit/OperandX86X64.h b/lib/AsmJit/OperandX86X64.h
new file mode 100644
index 0000000..933a322
--- /dev/null
+++ b/lib/AsmJit/OperandX86X64.h
@@ -0,0 +1,2298 @@
+// AsmJit - Complete JIT Assembler for C++ Language.
+
+// Copyright (c) 2008-2010, Petr Kobalicek <kobalicek.petr@gmail.com>
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+// [Guard]
+#ifndef _ASMJIT_OPERANDX86X64_H
+#define _ASMJIT_OPERANDX86X64_H
+
+#if !defined(_ASMJIT_OPERAND_H)
+#warning "AsmJit/OperandX86X64.h can be only included by AsmJit/Operand.h"
+#endif // _ASMJIT_OPERAND_H
+
+// [Dependencies]
+#include "Build.h"
+#include "Defs.h"
+
+namespace AsmJit {
+
+// ============================================================================
+// [AsmJit::Forward Declarations]
+// ============================================================================
+
+struct BaseReg;
+struct BaseVar;
+struct Compiler;
+struct GPReg;
+struct GPVar;
+struct Imm;
+struct Label;
+struct Mem;
+struct MMReg;
+struct MMVar;
+struct Operand;
+struct X87Reg;
+struct X87Var;
+struct XMMReg;
+struct XMMVar;
+
+//! @addtogroup AsmJit_Core
+//! @{
+
+// ============================================================================
+// [AsmJit::Operand]
+// ============================================================================
+
+//! @brief Operand, abstract class for register, memory location and immediate
+//! value operands.
+struct ASMJIT_HIDDEN Operand
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! @brief Create an uninitialized operand.
+ inline Operand() ASMJIT_NOTHROW
+ {
+ memset(this, 0, sizeof(Operand));
+ _base.id = INVALID_VALUE;
+ }
+
+ //! @brief Create a reference to @a other operand.
+ inline Operand(const Operand& other) ASMJIT_NOTHROW
+ {
+ _init(other);
+ }
+
+#if !defined(ASMJIT_NODOC)
+ inline Operand(const _DontInitialize&) ASMJIT_NOTHROW
+ {
+ }
+#endif // ASMJIT_NODOC
+
+ // --------------------------------------------------------------------------
+ // [Init & Copy]
+ // --------------------------------------------------------------------------
+
+ //! @internal
+ //!
+ //! @brief Initialize operand to @a other (used by constructors).
+ inline void _init(const Operand& other) ASMJIT_NOTHROW { memcpy(this, &other, sizeof(Operand)); }
+ //! @internal
+ //!
+ //! @brief Initialize operand to @a other (used by assign operators).
+ inline void _copy(const Operand& other) ASMJIT_NOTHROW { memcpy(this, &other, sizeof(Operand)); }
+
+ // --------------------------------------------------------------------------
+ // [Identification]
+ // --------------------------------------------------------------------------
+
+ //! @brief Get type of operand, see @c OPERAND_TYPE.
+ inline uint32_t getType() const ASMJIT_NOTHROW
+ { return _base.op; }
+
+ //! @brief Get whether operand is none (@c OPERAND_NONE).
+ inline bool isNone() const ASMJIT_NOTHROW
+ { return (_base.op == OPERAND_NONE); }
+
+ //! @brief Get whether operand is any (general purpose, mmx or sse) register (@c OPERAND_REG).
+ inline bool isReg() const ASMJIT_NOTHROW
+ { return (_base.op == OPERAND_REG); }
+
+ //! @brief Get whether operand is memory address (@c OPERAND_MEM).
+ inline bool isMem() const ASMJIT_NOTHROW
+ { return (_base.op == OPERAND_MEM); }
+
+ //! @brief Get whether operand is immediate (@c OPERAND_IMM).
+ inline bool isImm() const ASMJIT_NOTHROW
+ { return (_base.op == OPERAND_IMM); }
+
+ //! @brief Get whether operand is label (@c OPERAND_LABEL).
+ inline bool isLabel() const ASMJIT_NOTHROW
+ { return (_base.op == OPERAND_LABEL); }
+
+ //! @brief Get whether operand is variable (@c OPERAND_VAR).
+ inline bool isVar() const ASMJIT_NOTHROW
+ { return (_base.op == OPERAND_VAR); }
+
+ //! @brief Get whether operand is variable or memory.
+ inline bool isVarMem() const ASMJIT_NOTHROW
+ { return ((_base.op & (OPERAND_VAR | OPERAND_MEM)) != 0); }
+
+ //! @brief Get whether operand is register and type of register is @a regType.
+ inline bool isRegType(uint32_t regType) const ASMJIT_NOTHROW
+ { return (_base.op == OPERAND_REG) & ((_reg.code & REG_TYPE_MASK) == regType); }
+
+ //! @brief Get whether operand is register and code of register is @a regCode.
+ inline bool isRegCode(uint32_t regCode) const ASMJIT_NOTHROW
+ { return (_base.op == OPERAND_REG) & (_reg.code == regCode); }
+
+ //! @brief Get whether operand is register and index of register is @a regIndex.
+ inline bool isRegIndex(uint32_t regIndex) const ASMJIT_NOTHROW
+ { return (_base.op == OPERAND_REG) & ((_reg.code & REG_INDEX_MASK) == (regIndex & REG_INDEX_MASK)); }
+
+ //! @brief Get whether operand is any register or memory.
+ inline bool isRegMem() const ASMJIT_NOTHROW
+ { return ((_base.op & (OPERAND_REG | OPERAND_MEM)) != 0); }
+
+ //! @brief Get whether operand is register of @a regType type or memory.
+ inline bool isRegTypeMem(uint32_t regType) const ASMJIT_NOTHROW
+ { return ((_base.op == OPERAND_REG) & ((_reg.code & REG_TYPE_MASK) == regType)) | (_base.op == OPERAND_MEM); }
+
+ // --------------------------------------------------------------------------
+ // [Operand Size]
+ // --------------------------------------------------------------------------
+
+ //! @brief Return size of operand in bytes.
+ inline uint32_t getSize() const ASMJIT_NOTHROW
+ { return _base.size; }
+
+ // --------------------------------------------------------------------------
+ // [Operand 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.
+ inline uint32_t getId() const ASMJIT_NOTHROW
+ { return _base.id; }
+
+ // --------------------------------------------------------------------------
+ // [Extensions]
+ // --------------------------------------------------------------------------
+
+ //! @brief Get whether the extended register (additional eight registers
+ //! introduced by 64-bit mode) is used.
+ inline bool isExtendedRegisterUsed() const ASMJIT_NOTHROW
+ {
+ // 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 INVALID_VALUE, 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 (isReg() && (_reg.code & REG_INDEX_MASK) >= 8) ||
+ (isMem() && ((((uint32_t)_mem.base - 8U) < 8U) ||
+ (((uint32_t)_mem.index - 8U) < 8U) ));
+ }
+
+ // --------------------------------------------------------------------------
+ // [Data Structures]
+ // --------------------------------------------------------------------------
+
+ //! @internal
+ //!
+ //! @brief Base operand data shared between all operands.
+ struct BaseData
+ {
+ //! @brief Type of operand, see @c OPERAND_TYPE.
+ 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 operands has id equal to zero.
+ uint32_t id;
+ };
+
+ //! @internal
+ //!
+ //! @brief Register data.
+ struct RegData
+ {
+ //! @brief Type of operand, see @c OPERAND_TYPE (in this case @c OPERAND_REG).
+ 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 code or variable, see @c REG and @c INVALID_VALUE.
+ uint32_t code;
+ };
+
+ //! @internal
+ //!
+ //! @brief Memory address data.
+ struct MemData
+ {
+ //! @brief Type of operand, see @c OPERAND_TYPE (in this case @c OPERAND_MEM).
+ uint8_t op;
+ //! @brief Size of pointer.
+ uint8_t size;
+
+ //! @brief Memory operand type, see @c OPERAND_MEM_TYPE.
+ uint8_t type;
+ //! @brief Segment override prefix, see @c SEGMENT_PREFIX.
+ uint8_t segmentPrefix : 4;
+ //! @brief Index register shift (0 to 3 inclusive).
+ uint8_t shift : 4;
+
+ //! @brief Operand ID.
+ uint32_t id;
+
+ //! @brief Base register index, variable or label id.
+ uint32_t base;
+ //! @brief Index register index or variable.
+ uint32_t index;
+
+ //! @brief Target (for 32-bit, absolute address).
+ void* target;
+
+ //! @brief Displacement.
+ sysint_t displacement;
+ };
+
+ //! @internal
+ //!
+ //! @brief Immediate value data.
+ struct ImmData
+ {
+ //! @brief Type of operand, see @c OPERAND_TYPE (in this case @c OPERAND_IMM)..
+ 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 Label data.
+ struct LblData
+ {
+ //! @brief Type of operand, see @c OPERAND_TYPE (in this case @c OPERAND_LABEL).
+ 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 Variable data.
+ struct VarData
+ {
+ //! @brief Type of operand, see @c OPERAND_TYPE (in this case @c OPERAND_VAR).
+ 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 REG_TYPE, @c REG_CODE.
+ //!
+ //! @note Register code and variable code are two different things. In most
+ //! cases registerCode is very related to variableType, but general purpose
+ //! registers are divided to 64-bit, 32-bit, 16-bit and 8-bit entities so
+ //! the registerCode can be used to access these, variableType remains
+ //! unchanged from the initialization state. Variable type describes mainly
+ //! variable type and home memory size.
+ uint32_t registerCode;
+
+ //! @brief Type of variable. See @c VARIABLE_TYPE enum.
+ uint32_t variableType;
+ };
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ union
+ {
+ //! @brief Generic operand data.
+ BaseData _base;
+ //! @brief Register operand data.
+ RegData _reg;
+ //! @brief Memory operand data.
+ MemData _mem;
+ //! @brief Immediate operand data.
+ ImmData _imm;
+ //! @brief Label data.
+ LblData _lbl;
+ //! @brief Variable data.
+ VarData _var;
+ };
+};
+
+// ============================================================================
+// [AsmJit::BaseReg]
+// ============================================================================
+
+//! @brief Base class for all registers.
+struct ASMJIT_HIDDEN BaseReg : public Operand
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! @brief Create a new base register.
+ inline BaseReg(uint32_t code, uint32_t size) ASMJIT_NOTHROW :
+ Operand(_DontInitialize())
+ {
+ _reg.op = OPERAND_REG;
+ _reg.size = (uint8_t)size;
+ _reg.id = INVALID_VALUE;
+ _reg.code = code;
+ }
+
+ //! @brief Create a new reference to @a other.
+ inline BaseReg(const BaseReg& other) ASMJIT_NOTHROW :
+ Operand(other)
+ {}
+
+#if !defined(ASMJIT_NODOC)
+ inline BaseReg(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW :
+ Operand(dontInitialize)
+ {}
+#endif // ASMJIT_NODOC
+
+ // --------------------------------------------------------------------------
+ // [BaseReg Specific]
+ // --------------------------------------------------------------------------
+
+ //! @brief Get register code, see @c REG.
+ inline uint32_t getRegCode() const ASMJIT_NOTHROW
+ { return (uint32_t)(_reg.code); }
+
+ //! @brief Get register type, see @c REG.
+ inline uint32_t getRegType() const ASMJIT_NOTHROW
+ { return (uint32_t)(_reg.code & REG_TYPE_MASK); }
+
+ //! @brief Get register index (value from 0 to 7/15).
+ inline uint32_t getRegIndex() const ASMJIT_NOTHROW
+ { return (uint32_t)(_reg.code & REG_INDEX_MASK); }
+
+ //! @brief Get whether register code is equal to @a code.
+ inline bool isRegCode(uint32_t code) const ASMJIT_NOTHROW
+ { return _reg.code == code; }
+
+ //! @brief Get whether register code is equal to @a type.
+ inline bool isRegType(uint32_t type) const ASMJIT_NOTHROW
+ { return (uint32_t)(_reg.code & REG_TYPE_MASK) == type; }
+
+ //! @brief Get whether register index is equal to @a index.
+ inline bool isRegIndex(uint32_t index) const ASMJIT_NOTHROW
+ { return (uint32_t)(_reg.code & REG_INDEX_MASK) == index; }
+
+ //! @brief Set register code to @a code.
+ inline void setCode(uint32_t code) ASMJIT_NOTHROW
+ { _reg.code = code; }
+
+ //! @brief Set register size to @a size.
+ inline void setSize(uint32_t size) ASMJIT_NOTHROW
+ { _reg.size = (uint8_t)size; }
+
+ // --------------------------------------------------------------------------
+ // [Overloaded Operators]
+ // --------------------------------------------------------------------------
+
+ inline BaseReg& operator=(const BaseReg& other) ASMJIT_NOTHROW
+ { _copy(other); return *this; }
+
+ inline bool operator==(const BaseReg& other) const ASMJIT_NOTHROW
+ { return getRegCode() == other.getRegCode(); }
+
+ inline bool operator!=(const BaseReg& other) const ASMJIT_NOTHROW
+ { return getRegCode() != other.getRegCode(); }
+};
+
+// ============================================================================
+// [AsmJit::Reg]
+// ============================================================================
+
+//! @brief General purpose register.
+//!
+//! This class is for all general purpose registers (64, 32, 16 and 8-bit).
+struct ASMJIT_HIDDEN GPReg : public BaseReg
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! @brief Create non-initialized general purpose register.
+ inline GPReg() ASMJIT_NOTHROW :
+ BaseReg(INVALID_VALUE, 0) {}
+
+ //! @brief Create a reference to @a other general purpose register.
+ inline GPReg(const GPReg& other) ASMJIT_NOTHROW :
+ BaseReg(other) {}
+
+#if !defined(ASMJIT_NODOC)
+ inline GPReg(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW :
+ BaseReg(dontInitialize) {}
+
+ inline GPReg(const _Initialize&, uint32_t code) ASMJIT_NOTHROW :
+ BaseReg(code, static_cast<uint32_t>(1U << ((code & REG_TYPE_MASK) >> 12))) {}
+#endif // ASMJIT_NODOC
+
+ // --------------------------------------------------------------------------
+ // [GPReg Specific]
+ // --------------------------------------------------------------------------
+
+ //! @brief Get whether the general purpose register is BYTE (8-bit) type.
+ inline bool isGPB() const ASMJIT_NOTHROW { return (_reg.code & REG_TYPE_MASK) <= REG_TYPE_GPB_HI; }
+ //! @brief Get whether the general purpose register is LO-BYTE (8-bit) type.
+ inline bool isGPBLo() const ASMJIT_NOTHROW { return (_reg.code & REG_TYPE_MASK) == REG_TYPE_GPB_LO; }
+ //! @brief Get whether the general purpose register is HI-BYTE (8-bit) type.
+ inline bool isGPBHi() const ASMJIT_NOTHROW { return (_reg.code & REG_TYPE_MASK) == REG_TYPE_GPB_HI; }
+
+ //! @brief Get whether the general purpose register is WORD (16-bit) type.
+ inline bool isGPW() const ASMJIT_NOTHROW { return (_reg.code & REG_TYPE_MASK) == REG_TYPE_GPW; }
+ //! @brief Get whether the general purpose register is DWORD (32-bit) type.
+ //!
+ //! This is default type for 32-bit platforms.
+ inline bool isGPD() const ASMJIT_NOTHROW { return (_reg.code & REG_TYPE_MASK) == REG_TYPE_GPD; }
+ //! @brief Get whether the general purpose register is QWORD (64-bit) type.
+ //!
+ //! This is default type for 64-bit platforms.
+ inline bool isGPQ() const ASMJIT_NOTHROW { return (_reg.code & REG_TYPE_MASK) == REG_TYPE_GPQ; }
+
+ // --------------------------------------------------------------------------
+ // [Overloaded Operators]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_NODOC)
+ inline GPReg& operator=(const GPReg& other) ASMJIT_NOTHROW { _copy(other); return *this; }
+ inline bool operator==(const GPReg& other) const ASMJIT_NOTHROW { return getRegCode() == other.getRegCode(); }
+ inline bool operator!=(const GPReg& other) const ASMJIT_NOTHROW { return getRegCode() != other.getRegCode(); }
+#endif // ASMJIT_NODOC
+};
+
+// ============================================================================
+// [AsmJit::X87Register]
+// ============================================================================
+
+//! @brief 80-bit x87 floating point register.
+//!
+//! To create instance of x87 register, use @c st() function.
+struct ASMJIT_HIDDEN X87Reg : public BaseReg
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! @brief Create non-initialized x87 register.
+ inline X87Reg() ASMJIT_NOTHROW :
+ BaseReg(INVALID_VALUE, 10) {}
+
+ //! @brief Create a reference to @a other x87 register.
+ inline X87Reg(const X87Reg& other) ASMJIT_NOTHROW :
+ BaseReg(other) {}
+
+#if !defined(ASMJIT_NODOC)
+ inline X87Reg(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW :
+ BaseReg(dontInitialize) {}
+
+ inline X87Reg(const _Initialize&, uint32_t code) ASMJIT_NOTHROW :
+ BaseReg(code | REG_TYPE_X87, 10) {}
+#endif // ASMJIT_NODOC
+
+ // --------------------------------------------------------------------------
+ // [Overloaded Operators]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_NODOC)
+ inline X87Reg& operator=(const X87Reg& other) ASMJIT_NOTHROW { _copy(other); return *this; }
+ inline bool operator==(const X87Reg& other) const ASMJIT_NOTHROW { return getRegCode() == other.getRegCode(); }
+ inline bool operator!=(const X87Reg& other) const ASMJIT_NOTHROW { return getRegCode() != other.getRegCode(); }
+#endif // ASMJIT_NODOC
+};
+
+// ============================================================================
+// [AsmJit::MMReg]
+// ============================================================================
+
+//! @brief 64-bit MMX register.
+struct ASMJIT_HIDDEN MMReg : public BaseReg
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! @brief Create non-initialized MM register.
+ inline MMReg() ASMJIT_NOTHROW :
+ BaseReg(INVALID_VALUE, 8) {}
+
+ //! @brief Create a reference to @a other MM register.
+ inline MMReg(const MMReg& other) ASMJIT_NOTHROW :
+ BaseReg(other) {}
+
+#if !defined(ASMJIT_NODOC)
+ inline MMReg(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW :
+ BaseReg(dontInitialize) {}
+
+ inline MMReg(const _Initialize&, uint32_t code) ASMJIT_NOTHROW :
+ BaseReg(code, 8) {}
+#endif // ASMJIT_NODOC
+
+ // --------------------------------------------------------------------------
+ // [Overloaded Operators]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_NODOC)
+ inline MMReg& operator=(const MMReg& other) ASMJIT_NOTHROW { _copy(other); return *this; }
+ inline bool operator==(const MMReg& other) const ASMJIT_NOTHROW { return getRegCode() == other.getRegCode(); }
+ inline bool operator!=(const MMReg& other) const ASMJIT_NOTHROW { return getRegCode() != other.getRegCode(); }
+#endif // ASMJIT_NODOC
+};
+
+// ============================================================================
+// [AsmJit::XMMReg]
+// ============================================================================
+
+//! @brief 128-bit SSE register.
+struct ASMJIT_HIDDEN XMMReg : public BaseReg
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! @brief Create non-initialized XMM register.
+ inline XMMReg() ASMJIT_NOTHROW :
+ BaseReg(INVALID_VALUE, 16) {}
+
+ //! @brief Create a reference to @a other XMM register.
+ inline XMMReg(const _Initialize&, uint32_t code) ASMJIT_NOTHROW :
+ BaseReg(code, 16) {}
+
+#if !defined(ASMJIT_NODOC)
+ inline XMMReg(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW :
+ BaseReg(dontInitialize) {}
+
+ inline XMMReg(const XMMReg& other) ASMJIT_NOTHROW :
+ BaseReg(other) {}
+#endif // ASMJIT_NODOC
+
+ // --------------------------------------------------------------------------
+ // [Overloaded Operators]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_NODOC)
+ inline XMMReg& operator=(const XMMReg& other) ASMJIT_NOTHROW { _copy(other); return *this; }
+ inline bool operator==(const XMMReg& other) const ASMJIT_NOTHROW { return getRegCode() == other.getRegCode(); }
+ inline bool operator!=(const XMMReg& other) const ASMJIT_NOTHROW { return getRegCode() != other.getRegCode(); }
+#endif // ASMJIT_NODOC
+};
+
+// ============================================================================
+// [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;
+
+#if defined(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;
+
+#if defined(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;
+
+#if defined(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]
+// ============================================================================
+
+#if defined(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 General purpose register.
+ASMJIT_VAR const GPReg nax;
+//! @brief 32-bit General purpose register.
+ASMJIT_VAR const GPReg ncx;
+//! @brief 32-bit General purpose register.
+ASMJIT_VAR const GPReg ndx;
+//! @brief 32-bit General purpose register.
+ASMJIT_VAR const GPReg nbx;
+//! @brief 32-bit General purpose register.
+ASMJIT_VAR const GPReg nsp;
+//! @brief 32-bit General purpose register.
+ASMJIT_VAR const GPReg nbp;
+//! @brief 32-bit General purpose register.
+ASMJIT_VAR const GPReg nsi;
+//! @brief 32-bit General purpose register.
+ASMJIT_VAR const GPReg ndi;
+
+// ============================================================================
+// [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;
+
+#if defined(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 - Register From Index]
+// ============================================================================
+
+//! @brief Get general purpose register of byte size.
+static inline GPReg gpb_lo(uint32_t index) ASMJIT_NOTHROW
+{ return GPReg(_Initialize(), static_cast<uint32_t>(index | REG_TYPE_GPB_LO)); }
+
+//! @brief Get general purpose register of byte size.
+static inline GPReg gpb_hi(uint32_t index) ASMJIT_NOTHROW
+{ return GPReg(_Initialize(), static_cast<uint32_t>(index | REG_TYPE_GPB_HI)); }
+
+//! @brief Get general purpose register of word size.
+static inline GPReg gpw(uint32_t index) ASMJIT_NOTHROW
+{ return GPReg(_Initialize(), static_cast<uint32_t>(index | REG_TYPE_GPW)); }
+
+//! @brief Get general purpose register of dword size.
+static inline GPReg gpd(uint32_t index) ASMJIT_NOTHROW
+{ return GPReg(_Initialize(), static_cast<uint32_t>(index | REG_TYPE_GPD)); }
+
+#if defined(ASMJIT_X64)
+//! @brief Get general purpose register of qword size (64-bit only).
+static inline GPReg gpq(uint32_t index) ASMJIT_NOTHROW
+{ return GPReg(_Initialize(), static_cast<uint32_t>(index | REG_TYPE_GPQ)); }
+#endif
+
+//! @brief Get general purpose dword/qword register (depending to architecture).
+static inline GPReg gpn(uint32_t index) ASMJIT_NOTHROW
+{ return GPReg(_Initialize(), static_cast<uint32_t>(index | REG_TYPE_GPN)); }
+
+//! @brief Get MMX (MM) register .
+static inline MMReg mm(uint32_t index) ASMJIT_NOTHROW
+{ return MMReg(_Initialize(), static_cast<uint32_t>(index | REG_TYPE_MM)); }
+
+//! @brief Get SSE (XMM) register.
+static inline XMMReg xmm(uint32_t index) ASMJIT_NOTHROW
+{ return XMMReg(_Initialize(), static_cast<uint32_t>(index | REG_TYPE_XMM)); }
+
+//! @brief Get x87 register with index @a i.
+static inline X87Reg st(uint32_t i) ASMJIT_NOTHROW
+{
+ ASMJIT_ASSERT(i < 8);
+ return X87Reg(_Initialize(), static_cast<uint32_t>(i));
+}
+
+// ============================================================================
+// [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 ASMJIT_HIDDEN Imm : public Operand
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! @brief Create a new immediate value (initial value is 0).
+ Imm() ASMJIT_NOTHROW :
+ Operand(_DontInitialize())
+ {
+ _imm.op = OPERAND_IMM;
+ _imm.size = 0;
+ _imm.isUnsigned = false;
+ _imm.reserved = 0;
+
+ _imm.id = INVALID_VALUE;
+ _imm.value = 0;
+ }
+
+ //! @brief Create a new signed immediate value, assigning the value to @a i.
+ Imm(sysint_t i) ASMJIT_NOTHROW :
+ Operand(_DontInitialize())
+ {
+ _imm.op = OPERAND_IMM;
+ _imm.size = 0;
+ _imm.isUnsigned = false;
+ _imm.reserved = 0;
+
+ _imm.id = INVALID_VALUE;
+ _imm.value = i;
+ }
+
+ //! @brief Create a new signed or unsigned immediate value, assigning the value to @a i.
+ Imm(sysint_t i, bool isUnsigned) ASMJIT_NOTHROW :
+ Operand(_DontInitialize())
+ {
+ _imm.op = OPERAND_IMM;
+ _imm.size = 0;
+ _imm.isUnsigned = isUnsigned;
+ _imm.reserved = 0;
+
+ _imm.id = INVALID_VALUE;
+ _imm.value = i;
+ }
+
+ //! @brief Create a new immediate value from @a other.
+ inline Imm(const Imm& other) ASMJIT_NOTHROW :
+ Operand(other) {}
+
+ // --------------------------------------------------------------------------
+ // [Immediate Specific]
+ // --------------------------------------------------------------------------
+
+ //! @brief Get whether an immediate is unsigned value.
+ inline bool isUnsigned() const ASMJIT_NOTHROW { return _imm.isUnsigned != 0; }
+
+ //! @brief Get signed immediate value.
+ inline sysint_t getValue() const ASMJIT_NOTHROW { return _imm.value; }
+
+ //! @brief Get unsigned immediate value.
+ inline sysuint_t getUValue() const ASMJIT_NOTHROW { return (sysuint_t)_imm.value; }
+
+ //! @brief Set immediate value as signed type to @a val.
+ inline void setValue(sysint_t val, bool isUnsigned = false) ASMJIT_NOTHROW
+ {
+ _imm.value = val;
+ _imm.isUnsigned = isUnsigned;
+ }
+
+ //! @brief Set immediate value as unsigned type to @a val.
+ inline void setUValue(sysuint_t val) ASMJIT_NOTHROW
+ {
+ _imm.value = (sysint_t)val;
+ _imm.isUnsigned = true;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Overloaded Operators]
+ // --------------------------------------------------------------------------
+
+ //! @brief Assign a signed value @a val to the immediate operand.
+ inline Imm& operator=(sysint_t val) ASMJIT_NOTHROW
+ { setValue(val); return *this; }
+
+ //! @brief Assign @a other to the immediate operand.
+ inline Imm& operator=(const Imm& other) ASMJIT_NOTHROW
+ { _copy(other); return *this; }
+};
+
+//! @brief Create signed immediate value operand.
+ASMJIT_API Imm imm(sysint_t i) ASMJIT_NOTHROW;
+
+//! @brief Create unsigned immediate value operand.
+ASMJIT_API Imm uimm(sysuint_t i) ASMJIT_NOTHROW;
+
+// ============================================================================
+// [AsmJit::Label]
+// ============================================================================
+
+//! @brief Label (jump target or data location).
+//!
+//! Label represents locations typically used as jump targets, but may be also
+//! used as position where are stored constants or static variables. 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.
+//! Assembler 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 ASMJIT_HIDDEN Label : public Operand
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! @brief Create new, unassociated label.
+ inline Label() ASMJIT_NOTHROW :
+ Operand(_DontInitialize())
+ {
+ _lbl.op = OPERAND_LABEL;
+ _lbl.size = 0;
+ _lbl.id = INVALID_VALUE;
+ }
+
+ //! @brief Create reference to another label.
+ inline Label(const Label& other) ASMJIT_NOTHROW :
+ Operand(other)
+ {
+ }
+
+ //! @brief Destroy the label.
+ inline ~Label() ASMJIT_NOTHROW
+ {
+ }
+
+ // --------------------------------------------------------------------------
+ // [Overloaded Operators]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_NODOC)
+ inline Label& operator=(const Label& other)
+ { _copy(other); return *this; }
+
+ inline bool operator==(const Label& other) const ASMJIT_NOTHROW { return _base.id == other._base.id; }
+ inline bool operator!=(const Label& other) const ASMJIT_NOTHROW { return _base.id != other._base.id; }
+#endif // ASMJIT_NODOC
+};
+
+// ============================================================================
+// [AsmJit::Mem]
+// ============================================================================
+
+//! @brief Memory operand.
+struct ASMJIT_HIDDEN Mem : public Operand
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ inline Mem() ASMJIT_NOTHROW :
+ Operand(_DontInitialize())
+ {
+ _mem.op = OPERAND_MEM;
+ _mem.size = 0;
+ _mem.type = OPERAND_MEM_NATIVE;
+ _mem.segmentPrefix = SEGMENT_NONE;
+
+ _mem.id = INVALID_VALUE;
+
+ _mem.base = INVALID_VALUE;
+ _mem.index = INVALID_VALUE;
+ _mem.shift = 0;
+
+ _mem.target = NULL;
+ _mem.displacement = 0;
+ }
+
+ inline Mem(const Label& label, sysint_t displacement, uint32_t size = 0) ASMJIT_NOTHROW :
+ Operand(_DontInitialize())
+ {
+ _mem.op = OPERAND_MEM;
+ _mem.size = (uint8_t)size;
+ _mem.type = OPERAND_MEM_LABEL;
+ _mem.segmentPrefix = SEGMENT_NONE;
+
+ _mem.id = INVALID_VALUE;
+
+ _mem.base = reinterpret_cast<const Operand&>(label)._base.id;
+ _mem.index = INVALID_VALUE;
+ _mem.shift = 0;
+
+ _mem.target = NULL;
+ _mem.displacement = displacement;
+ }
+
+ inline Mem(const GPReg& base, sysint_t displacement, uint32_t size = 0) ASMJIT_NOTHROW :
+ Operand(_DontInitialize())
+ {
+ _mem.op = OPERAND_MEM;
+ _mem.size = (uint8_t)size;
+ _mem.type = OPERAND_MEM_NATIVE;
+ _mem.segmentPrefix = SEGMENT_NONE;
+
+ _mem.id = INVALID_VALUE;
+
+ _mem.base = base.getRegCode() & REG_INDEX_MASK;
+ _mem.index = INVALID_VALUE;
+ _mem.shift = 0;
+
+ _mem.target = NULL;
+ _mem.displacement = displacement;
+ }
+
+ inline Mem(const GPVar& base, sysint_t displacement, uint32_t size = 0) ASMJIT_NOTHROW :
+ Operand(_DontInitialize())
+ {
+ _mem.op = OPERAND_MEM;
+ _mem.size = (uint8_t)size;
+ _mem.type = OPERAND_MEM_NATIVE;
+ _mem.segmentPrefix = SEGMENT_NONE;
+
+ _mem.id = INVALID_VALUE;
+
+ _mem.base = reinterpret_cast<const Operand&>(base).getId();
+ _mem.index = INVALID_VALUE;
+ _mem.shift = 0;
+
+ _mem.target = NULL;
+ _mem.displacement = displacement;
+ }
+
+ inline Mem(const GPReg& base, const GPReg& index, uint32_t shift, sysint_t displacement, uint32_t size = 0) ASMJIT_NOTHROW :
+ Operand(_DontInitialize())
+ {
+ ASMJIT_ASSERT(shift <= 3);
+
+ _mem.op = OPERAND_MEM;
+ _mem.size = (uint8_t)size;
+ _mem.type = OPERAND_MEM_NATIVE;
+ _mem.segmentPrefix = SEGMENT_NONE;
+
+ _mem.id = INVALID_VALUE;
+
+ _mem.base = base.getRegIndex();
+ _mem.index = index.getRegIndex();
+ _mem.shift = (uint8_t)shift;
+
+ _mem.target = NULL;
+ _mem.displacement = displacement;
+ }
+
+ inline Mem(const GPVar& base, const GPVar& index, uint32_t shift, sysint_t displacement, uint32_t size = 0) ASMJIT_NOTHROW :
+ Operand(_DontInitialize())
+ {
+ ASMJIT_ASSERT(shift <= 3);
+
+ _mem.op = OPERAND_MEM;
+ _mem.size = (uint8_t)size;
+ _mem.type = OPERAND_MEM_NATIVE;
+ _mem.segmentPrefix = SEGMENT_NONE;
+
+ _mem.id = INVALID_VALUE;
+
+ _mem.base = reinterpret_cast<const Operand&>(base).getId();
+ _mem.index = reinterpret_cast<const Operand&>(index).getId();
+ _mem.shift = (uint8_t)shift;
+
+ _mem.target = NULL;
+ _mem.displacement = displacement;
+ }
+
+ inline Mem(const Mem& other) ASMJIT_NOTHROW :
+ Operand(other)
+ {
+ }
+
+ inline Mem(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW :
+ Operand(dontInitialize)
+ {
+ }
+
+ // --------------------------------------------------------------------------
+ // [Mem Specific]
+ // --------------------------------------------------------------------------
+
+ //! @brief Get type of memory operand, see @c OPERAND_MEM_TYPE enum.
+ inline uint32_t getMemType() const ASMJIT_NOTHROW
+ { return _mem.type; }
+
+ //! @brief Get memory operand segment prefix, see @c SEGMENT_PREFIX enum.
+ inline uint32_t getSegmentPrefix() const ASMJIT_NOTHROW
+ { return _mem.segmentPrefix; }
+
+ //! @brief Get whether the memory operand has base register.
+ inline bool hasBase() const ASMJIT_NOTHROW
+ { return _mem.base != INVALID_VALUE; }
+
+ //! @brief Get whether the memory operand has index.
+ inline bool hasIndex() const ASMJIT_NOTHROW
+ { return _mem.index != INVALID_VALUE; }
+
+ //! @brief Get whether the memory operand has shift used.
+ inline bool hasShift() const ASMJIT_NOTHROW
+ { return _mem.shift != 0; }
+
+ //! @brief Get memory operand base register or @c INVALID_VALUE.
+ inline uint32_t getBase() const ASMJIT_NOTHROW
+ { return _mem.base; }
+
+ //! @brief Get memory operand index register or @c INVALID_VALUE.
+ inline uint32_t getIndex() const ASMJIT_NOTHROW
+ { return _mem.index; }
+
+ //! @brief Get memory operand index scale (0, 1, 2 or 3).
+ inline uint32_t getShift() const ASMJIT_NOTHROW
+ { return _mem.shift; }
+
+ //! @brief Get absolute target address.
+ //!
+ //! @note You should always check if operand contains address by @c getMemType().
+ inline void* getTarget() const ASMJIT_NOTHROW
+ { return _mem.target; }
+
+ //! @brief Set memory operand size.
+ inline void setSize(uint32_t size) ASMJIT_NOTHROW
+ { _mem.size = size; }
+
+ //! @brief Set absolute target address.
+ inline void setTarget(void* target) ASMJIT_NOTHROW
+ { _mem.target = target; }
+
+ //! @brief Get memory operand relative displacement.
+ inline sysint_t getDisplacement() const ASMJIT_NOTHROW
+ { return _mem.displacement; }
+
+ //! @brief Set memory operand relative displacement.
+ inline void setDisplacement(sysint_t displacement) ASMJIT_NOTHROW
+ { _mem.displacement = displacement; }
+
+ //! @brief Adjust memory operand relative displacement by @a displacement.
+ inline void adjust(sysint_t displacement) ASMJIT_NOTHROW
+ {
+ _mem.displacement += displacement;
+ }
+
+ //! @brief Return new memory operand adjusted by @a displacement.
+ inline Mem adjusted(sysint_t displacement) ASMJIT_NOTHROW
+ {
+ Mem result(*this);
+ result.adjust(displacement);
+ return result;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Overloaded Operators]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_NODOC)
+ inline Mem& operator=(const Mem& other) ASMJIT_NOTHROW { _copy(other); return *this; }
+
+ inline bool operator==(const Mem& other) const ASMJIT_NOTHROW
+ {
+ return
+ _mem.size == other._mem.size &&
+ _mem.type == other._mem.type &&
+ _mem.segmentPrefix == other._mem.segmentPrefix &&
+ _mem.base == other._mem.base &&
+ _mem.index == other._mem.index &&
+ _mem.shift == other._mem.shift &&
+ _mem.target == other._mem.target &&
+ _mem.displacement == other._mem.displacement;
+ }
+
+ inline bool operator!=(const Mem& other) const ASMJIT_NOTHROW { return *this == other; }
+#endif // ASMJIT_NODOC
+};
+
+// ============================================================================
+// [AsmJit::BaseVar]
+// ============================================================================
+
+//! @internal
+ASMJIT_API Mem _baseVarMem(const BaseVar& var, uint32_t ptrSize) ASMJIT_NOTHROW;
+
+//! @internal
+ASMJIT_API Mem _baseVarMem(const BaseVar& var, uint32_t ptrSize, sysint_t disp) ASMJIT_NOTHROW;
+
+//! @internal
+ASMJIT_API Mem _baseVarMem(const BaseVar& var, uint32_t ptrSize, const GPVar& index, uint32_t shift, sysint_t disp) ASMJIT_NOTHROW;
+
+//! @brief Base class for all variables.
+struct ASMJIT_HIDDEN BaseVar : public Operand
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_NODOC)
+ inline BaseVar(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW :
+ Operand(dontInitialize)
+ {
+ }
+#endif // ASMJIT_NODOC
+
+ inline BaseVar() ASMJIT_NOTHROW :
+ Operand(_DontInitialize())
+ {
+ _var.op = OPERAND_VAR;
+ _var.size = 0;
+ _var.registerCode = INVALID_VALUE;
+ _var.variableType = INVALID_VALUE;
+ _var.id = INVALID_VALUE;
+ }
+
+ inline BaseVar(const BaseVar& other) ASMJIT_NOTHROW :
+ Operand(other)
+ {
+ }
+
+ // --------------------------------------------------------------------------
+ // [Type]
+ // --------------------------------------------------------------------------
+
+ inline uint32_t getVariableType() const ASMJIT_NOTHROW
+ { return _var.variableType; }
+
+ inline bool isGPVar() const ASMJIT_NOTHROW
+ { return _var.variableType <= VARIABLE_TYPE_GPQ; }
+
+ inline bool isX87Var() const ASMJIT_NOTHROW
+ { return _var.variableType >= VARIABLE_TYPE_X87 && _var.variableType <= VARIABLE_TYPE_X87_1D; }
+
+ inline bool isMMVar() const ASMJIT_NOTHROW
+ { return _var.variableType == VARIABLE_TYPE_MM; }
+
+ inline bool isXMMVar() const ASMJIT_NOTHROW
+ { return _var.variableType >= VARIABLE_TYPE_XMM && _var.variableType <= VARIABLE_TYPE_XMM_2D; }
+
+ // --------------------------------------------------------------------------
+ // [Memory Cast]
+ // --------------------------------------------------------------------------
+
+ //! @brief Cast this variable to memory operand.
+ //!
+ //! @note Size of operand depends to native variable type, you can use other
+ //! variants if you want specific one.
+ inline Mem m() const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, INVALID_VALUE); }
+
+ //! @overload.
+ inline Mem m(sysint_t disp) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, INVALID_VALUE, disp); }
+
+ //! @overload.
+ inline Mem m(const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, INVALID_VALUE, index, shift, disp); }
+
+ //! @brief Cast this variable to 8-bit memory operand.
+ inline Mem m8() const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 1); }
+
+ //! @overload.
+ inline Mem m8(sysint_t disp) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 1, disp); }
+
+ //! @overload.
+ inline Mem m8(const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 1, index, shift, disp); }
+
+ //! @brief Cast this variable to 16-bit memory operand.
+ inline Mem m16() const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 2); }
+
+ //! @overload.
+ inline Mem m16(sysint_t disp) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 2, disp); }
+
+ //! @overload.
+ inline Mem m16(const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 2, index, shift, disp); }
+
+ //! @brief Cast this variable to 32-bit memory operand.
+ inline Mem m32() const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 4); }
+
+ //! @overload.
+ inline Mem m32(sysint_t disp) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 4, disp); }
+
+ //! @overload.
+ inline Mem m32(const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 4, index, shift, disp); }
+
+ //! @brief Cast this variable to 64-bit memory operand.
+ inline Mem m64() const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 8); }
+
+ //! @overload.
+ inline Mem m64(sysint_t disp) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 8, disp); }
+
+ //! @overload.
+ inline Mem m64(const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 8, index, shift, disp); }
+
+ //! @brief Cast this variable to 80-bit memory operand (long double).
+ inline Mem m80() const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 10); }
+
+ //! @overload.
+ inline Mem m80(sysint_t disp) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 10, disp); }
+
+ //! @overload.
+ inline Mem m80(const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 10, index, shift, disp); }
+
+ //! @brief Cast this variable to 128-bit memory operand.
+ inline Mem m128() const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 16); }
+
+ //! @overload.
+ inline Mem m128(sysint_t disp) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 16, disp); }
+
+ //! @overload.
+ inline Mem m128(const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) const ASMJIT_NOTHROW
+ { return _baseVarMem(*this, 16, index, shift, disp); }
+
+ // --------------------------------------------------------------------------
+ // [Overloaded Operators]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_NODOC)
+ inline BaseVar& operator=(const BaseVar& other) ASMJIT_NOTHROW
+ { _copy(other); return *this; }
+
+ inline bool operator==(const BaseVar& other) const ASMJIT_NOTHROW { return _base.id == other._base.id && _var.registerCode == other._var.registerCode; }
+ inline bool operator!=(const BaseVar& other) const ASMJIT_NOTHROW { return _base.id != other._base.id || _var.registerCode != other._var.registerCode; }
+#endif // ASMJIT_NODOC
+
+ // --------------------------------------------------------------------------
+ // [Private]
+ // --------------------------------------------------------------------------
+
+protected:
+ inline BaseVar(const BaseVar& other, uint32_t registerCode, uint32_t size) ASMJIT_NOTHROW :
+ Operand(_DontInitialize())
+ {
+ _var.op = OPERAND_VAR;
+ _var.size = (uint8_t)size;
+ _var.id = other._base.id;
+ _var.registerCode = registerCode;
+ _var.variableType = other._var.variableType;
+ }
+};
+
+// ============================================================================
+// [AsmJit::X87Var]
+// ============================================================================
+
+//! @brief X87 Variable operand.
+struct ASMJIT_HIDDEN X87Var : public BaseVar
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ inline X87Var(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW :
+ BaseVar(dontInitialize)
+ {
+ }
+
+ inline X87Var() ASMJIT_NOTHROW :
+ BaseVar(_DontInitialize())
+ {
+ _var.op = OPERAND_VAR;
+ _var.size = 12;
+ _var.id = INVALID_VALUE;
+
+ _var.registerCode = REG_TYPE_X87;
+ _var.variableType = VARIABLE_TYPE_X87;
+ }
+
+ inline X87Var(const X87Var& other) ASMJIT_NOTHROW :
+ BaseVar(other) {}
+
+ // --------------------------------------------------------------------------
+ // [Overloaded Operators]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_NODOC)
+ inline X87Var& operator=(const X87Var& other) ASMJIT_NOTHROW
+ { _copy(other); return *this; }
+
+ inline bool operator==(const X87Var& other) const ASMJIT_NOTHROW { return _base.id == other._base.id; }
+ inline bool operator!=(const X87Var& other) const ASMJIT_NOTHROW { return _base.id != other._base.id; }
+#endif // ASMJIT_NODOC
+};
+
+// ============================================================================
+// [AsmJit::GPVar]
+// ============================================================================
+
+//! @brief GP variable operand.
+struct ASMJIT_HIDDEN GPVar : public BaseVar
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! @brief Create new uninitialized @c GPVar instance (internal constructor).
+ inline GPVar(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW :
+ BaseVar(dontInitialize)
+ {
+ }
+
+ //! @brief Create new uninitialized @c GPVar instance.
+ inline GPVar() ASMJIT_NOTHROW :
+ BaseVar(_DontInitialize())
+ {
+ _var.op = OPERAND_VAR;
+ _var.size = sizeof(sysint_t);
+ _var.id = INVALID_VALUE;
+
+ _var.registerCode = REG_TYPE_GPN;
+ _var.variableType = VARIABLE_TYPE_GPN;
+ }
+
+ //! @brief Create new @c GPVar instance using @a other.
+ //!
+ //! Note this will not create a different variable, use @c Compiler::newGP()
+ //! if you want to do so. This is only copy-constructor that allows to store
+ //! the same variable in different places.
+ inline GPVar(const GPVar& other) ASMJIT_NOTHROW :
+ BaseVar(other) {}
+
+ // --------------------------------------------------------------------------
+ // [GPVar Specific]
+ // --------------------------------------------------------------------------
+
+ //! @brief Get whether this variable is general purpose BYTE register.
+ inline bool isGPB() const ASMJIT_NOTHROW { return (_var.registerCode & REG_TYPE_MASK) <= REG_TYPE_GPB_HI; }
+ //! @brief Get whether this variable is general purpose BYTE.LO register.
+ inline bool isGPBLo() const ASMJIT_NOTHROW { return (_var.registerCode & REG_TYPE_MASK) == REG_TYPE_GPB_LO; }
+ //! @brief Get whether this variable is general purpose BYTE.HI register.
+ inline bool isGPBHi() const ASMJIT_NOTHROW { return (_var.registerCode & REG_TYPE_MASK) == REG_TYPE_GPB_HI; }
+
+ //! @brief Get whether this variable is general purpose WORD register.
+ inline bool isGPW() const ASMJIT_NOTHROW { return (_var.registerCode & REG_TYPE_MASK) == REG_TYPE_GPW; }
+ //! @brief Get whether this variable is general purpose DWORD register.
+ inline bool isGPD() const ASMJIT_NOTHROW { return (_var.registerCode & REG_TYPE_MASK) == REG_TYPE_GPD; }
+ //! @brief Get whether this variable is general purpose QWORD (only 64-bit) register.
+ inline bool isGPQ() const ASMJIT_NOTHROW { return (_var.registerCode & REG_TYPE_MASK) == REG_TYPE_GPQ; }
+
+ // --------------------------------------------------------------------------
+ // [GPVar Cast]
+ // --------------------------------------------------------------------------
+
+ //! @brief Cast this variable to 8-bit (LO) part of variable
+ inline GPVar r8() const { return GPVar(*this, REG_TYPE_GPB_LO, 1); }
+ //! @brief Cast this variable to 8-bit (LO) part of variable
+ inline GPVar r8Lo() const { return GPVar(*this, REG_TYPE_GPB_LO, 1); }
+ //! @brief Cast this variable to 8-bit (HI) part of variable
+ inline GPVar r8Hi() const { return GPVar(*this, REG_TYPE_GPB_HI, 1); }
+
+ //! @brief Cast this variable to 16-bit part of variable
+ inline GPVar r16() const { return GPVar(*this, REG_TYPE_GPW, 2); }
+ //! @brief Cast this variable to 32-bit part of variable
+ inline GPVar r32() const { return GPVar(*this, REG_TYPE_GPD, 4); }
+#if defined(ASMJIT_X64)
+ //! @brief Cast this variable to 64-bit part of variable
+ inline GPVar r64() const { return GPVar(*this, REG_TYPE_GPQ, 8); }
+#endif // ASMJIT_X64
+
+ // --------------------------------------------------------------------------
+ // [Overloaded Operators]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_NODOC)
+ inline GPVar& operator=(const GPVar& other) ASMJIT_NOTHROW
+ { _copy(other); return *this; }
+
+ inline bool operator==(const GPVar& other) const ASMJIT_NOTHROW { return _base.id == other._base.id && _var.registerCode == other._var.registerCode; }
+ inline bool operator!=(const GPVar& other) const ASMJIT_NOTHROW { return _base.id != other._base.id || _var.registerCode != other._var.registerCode; }
+#endif // ASMJIT_NODOC
+
+ // --------------------------------------------------------------------------
+ // [Private]
+ // --------------------------------------------------------------------------
+
+protected:
+ inline GPVar(const GPVar& other, uint32_t registerCode, uint32_t size) ASMJIT_NOTHROW :
+ BaseVar(other, registerCode, size)
+ {
+ }
+};
+
+// ============================================================================
+// [AsmJit::MMVar]
+// ============================================================================
+
+//! @brief MM variable operand.
+struct ASMJIT_HIDDEN MMVar : public BaseVar
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! @brief Create new uninitialized @c MMVar instance (internal constructor).
+ inline MMVar(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW :
+ BaseVar(dontInitialize)
+ {
+ }
+
+ //! @brief Create new uninitialized @c MMVar instance.
+ inline MMVar() ASMJIT_NOTHROW :
+ BaseVar(_DontInitialize())
+ {
+ _var.op = OPERAND_VAR;
+ _var.size = 8;
+ _var.id = INVALID_VALUE;
+
+ _var.registerCode = REG_TYPE_MM;
+ _var.variableType = VARIABLE_TYPE_MM;
+ }
+
+ //! @brief Create new @c MMVar instance using @a other.
+ //!
+ //! Note this will not create a different variable, use @c Compiler::newMM()
+ //! if you want to do so. This is only copy-constructor that allows to store
+ //! the same variable in different places.
+ inline MMVar(const MMVar& other) ASMJIT_NOTHROW :
+ BaseVar(other) {}
+
+ // --------------------------------------------------------------------------
+ // [MMVar Cast]
+ // --------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------
+ // [Overloaded Operators]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_NODOC)
+ inline MMVar& operator=(const MMVar& other) ASMJIT_NOTHROW
+ { _copy(other); return *this; }
+
+ inline bool operator==(const MMVar& other) const ASMJIT_NOTHROW { return _base.id == other._base.id; }
+ inline bool operator!=(const MMVar& other) const ASMJIT_NOTHROW { return _base.id != other._base.id; }
+#endif // ASMJIT_NODOC
+};
+
+// ============================================================================
+// [AsmJit::XMMVar]
+// ============================================================================
+
+//! @brief XMM Variable operand.
+struct ASMJIT_HIDDEN XMMVar : public BaseVar
+{
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ inline XMMVar(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW :
+ BaseVar(dontInitialize)
+ {
+ }
+
+ inline XMMVar() ASMJIT_NOTHROW :
+ BaseVar(_DontInitialize())
+ {
+ _var.op = OPERAND_VAR;
+ _var.size = 16;
+ _var.id = INVALID_VALUE;
+
+ _var.registerCode = REG_TYPE_XMM;
+ _var.variableType = VARIABLE_TYPE_XMM;
+ }
+
+ inline XMMVar(const XMMVar& other) ASMJIT_NOTHROW :
+ BaseVar(other) {}
+
+ // --------------------------------------------------------------------------
+ // [XMMVar Access]
+ // --------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------
+ // [Overloaded Operators]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_NODOC)
+ inline XMMVar& operator=(const XMMVar& other) ASMJIT_NOTHROW
+ { _copy(other); return *this; }
+
+ inline bool operator==(const XMMVar& other) const ASMJIT_NOTHROW { return _base.id == other._base.id; }
+ inline bool operator!=(const XMMVar& other) const ASMJIT_NOTHROW { return _base.id != other._base.id; }
+#endif // ASMJIT_NODOC
+};
+
+// ============================================================================
+// [AsmJit::Mem - ptr[displacement]]
+// ============================================================================
+
+//! @internal
+ASMJIT_API Mem _MemPtrBuild(const Label& label, sysint_t disp, uint32_t ptrSize) ASMJIT_NOTHROW;
+
+//! @internal
+ASMJIT_API Mem _MemPtrBuild(const Label& label, const GPReg& index, uint32_t shift, sysint_t disp, uint32_t ptrSize) ASMJIT_NOTHROW;
+
+//! @internal
+ASMJIT_API Mem _MemPtrBuild(const Label& label, const GPVar& index, uint32_t shift, sysint_t disp, uint32_t ptrSize) ASMJIT_NOTHROW;
+
+
+
+//! @brief Create pointer operand with not specified size.
+static inline Mem ptr(const Label& label, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, disp, 0); }
+
+//! @brief Create byte pointer operand.
+static inline Mem byte_ptr(const Label& label, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, disp, SIZE_BYTE); }
+
+//! @brief Create word (2 Bytes) pointer operand.
+static inline Mem word_ptr(const Label& label, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, disp, SIZE_WORD); }
+
+//! @brief Create dword (4 Bytes) pointer operand.
+static inline Mem dword_ptr(const Label& label, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, disp, SIZE_DWORD); }
+
+//! @brief Create qword (8 Bytes) pointer operand.
+static inline Mem qword_ptr(const Label& label, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, disp, SIZE_QWORD); }
+
+//! @brief Create tword (10 Bytes) pointer operand (used for 80-bit floating points).
+static inline Mem tword_ptr(const Label& label, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, disp, SIZE_TWORD); }
+
+//! @brief Create dqword (16 Bytes) pointer operand.
+static inline Mem dqword_ptr(const Label& label, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, disp, SIZE_DQWORD); }
+
+//! @brief Create mmword (8 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for mmx programming.
+static inline Mem mmword_ptr(const Label& label, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, disp, SIZE_QWORD); }
+
+//! @brief Create xmmword (16 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for sse programming.
+static inline Mem xmmword_ptr(const Label& label, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, disp, SIZE_DQWORD); }
+
+//! @brief Create system dependent pointer operand (32-bit or 64-bit).
+static inline Mem sysint_ptr(const Label& label, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, disp, sizeof(sysint_t)); }
+
+
+
+//! @brief Create pointer operand with not specified size.
+static inline Mem ptr(const Label& label, const GPReg& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, 0); }
+
+//! @brief Create byte pointer operand.
+static inline Mem byte_ptr(const Label& label, const GPReg& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_BYTE); }
+
+//! @brief Create word (2 Bytes) pointer operand.
+static inline Mem word_ptr(const Label& label, const GPReg& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_WORD); }
+
+//! @brief Create dword (4 Bytes) pointer operand.
+static inline Mem dword_ptr(const Label& label, const GPReg& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_DWORD); }
+
+//! @brief Create qword (8 Bytes) pointer operand.
+static inline Mem qword_ptr(const Label& label, const GPReg& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_QWORD); }
+
+//! @brief Create tword (10 Bytes) pointer operand (used for 80-bit floating points).
+static inline Mem tword_ptr(const Label& label, const GPReg& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_TWORD); }
+
+//! @brief Create dqword (16 Bytes) pointer operand.
+static inline Mem dqword_ptr(const Label& label, const GPReg& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_DQWORD); }
+
+//! @brief Create mmword (8 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for mmx programming.
+static inline Mem mmword_ptr(const Label& label, const GPReg& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_QWORD); }
+
+//! @brief Create xmmword (16 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for sse programming.
+static inline Mem xmmword_ptr(const Label& label, const GPReg& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_DQWORD); }
+
+//! @brief Create system dependent pointer operand (32-bit or 64-bit).
+static inline Mem sysint_ptr(const Label& label, const GPReg& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, sizeof(sysint_t)); }
+
+
+
+//! @brief Create pointer operand with not specified size.
+static inline Mem ptr(const Label& label, const GPVar& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, 0); }
+
+//! @brief Create byte pointer operand.
+static inline Mem byte_ptr(const Label& label, const GPVar& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_BYTE); }
+
+//! @brief Create word (2 Bytes) pointer operand.
+static inline Mem word_ptr(const Label& label, const GPVar& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_WORD); }
+
+//! @brief Create dword (4 Bytes) pointer operand.
+static inline Mem dword_ptr(const Label& label, const GPVar& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_DWORD); }
+
+//! @brief Create qword (8 Bytes) pointer operand.
+static inline Mem qword_ptr(const Label& label, const GPVar& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_QWORD); }
+
+//! @brief Create tword (10 Bytes) pointer operand (used for 80-bit floating points).
+static inline Mem tword_ptr(const Label& label, const GPVar& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_TWORD); }
+
+//! @brief Create dqword (16 Bytes) pointer operand.
+static inline Mem dqword_ptr(const Label& label, const GPVar& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_DQWORD); }
+
+//! @brief Create mmword (8 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for mmx programming.
+static inline Mem mmword_ptr(const Label& label, const GPVar& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_QWORD); }
+
+//! @brief Create xmmword (16 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for sse programming.
+static inline Mem xmmword_ptr(const Label& label, const GPVar& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, SIZE_DQWORD); }
+
+//! @brief Create system dependent pointer operand (32-bit or 64-bit).
+static inline Mem sysint_ptr(const Label& label, const GPVar& index, uint32_t shift, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(label, index, shift, disp, sizeof(sysint_t)); }
+
+// ============================================================================
+// [AsmJit::Mem - Absolute Addressing]
+// ============================================================================
+
+//! @internal
+ASMJIT_API Mem _MemPtrAbs(
+ void* target,
+ sysint_t disp,
+ uint32_t segmentPrefix, uint32_t ptrSize) ASMJIT_NOTHROW;
+
+//! @internal
+ASMJIT_API Mem _MemPtrAbs(
+ void* target,
+ const GPReg& index, uint32_t shift, sysint_t disp,
+ uint32_t segmentPrefix, uint32_t ptrSize) ASMJIT_NOTHROW;
+
+//! @internal
+ASMJIT_API Mem _MemPtrAbs(
+ void* target,
+ const GPVar& index, uint32_t shift, sysint_t disp,
+ uint32_t segmentPrefix, uint32_t ptrSize) ASMJIT_NOTHROW;
+
+
+
+//! @brief Create pointer operand with not specified size.
+static inline Mem ptr_abs(void* target, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, disp, segmentPrefix, 0); }
+
+//! @brief Create byte pointer operand.
+static inline Mem byte_ptr_abs(void* target, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, disp, segmentPrefix, SIZE_BYTE); }
+
+//! @brief Create word (2 Bytes) pointer operand.
+static inline Mem word_ptr_abs(void* target, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, disp, segmentPrefix, SIZE_WORD); }
+
+//! @brief Create dword (4 Bytes) pointer operand.
+static inline Mem dword_ptr_abs(void* target, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, disp, segmentPrefix, SIZE_DWORD); }
+
+//! @brief Create qword (8 Bytes) pointer operand.
+static inline Mem qword_ptr_abs(void* target, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, disp, segmentPrefix, SIZE_QWORD); }
+
+//! @brief Create tword (10 Bytes) pointer operand (used for 80-bit floating points).
+static inline Mem tword_ptr_abs(void* target, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, disp, segmentPrefix, SIZE_TWORD); }
+
+//! @brief Create dqword (16 Bytes) pointer operand.
+static inline Mem dqword_ptr_abs(void* target, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, disp, segmentPrefix, SIZE_DQWORD); }
+
+//! @brief Create mmword (8 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for mmx programming.
+static inline Mem mmword_ptr_abs(void* target, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, disp, segmentPrefix, SIZE_QWORD); }
+
+//! @brief Create xmmword (16 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for sse programming.
+static inline Mem xmmword_ptr_abs(void* target, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, disp, segmentPrefix, SIZE_DQWORD); }
+
+//! @brief Create system dependent pointer operand (32-bit or 64-bit).
+static inline Mem sysint_ptr_abs(void* target, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, disp, segmentPrefix, sizeof(sysint_t)); }
+
+
+
+//! @brief Create pointer operand with not specified size.
+static inline Mem ptr_abs(void* target, const GPReg& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, 0); }
+
+//! @brief Create byte pointer operand.
+static inline Mem byte_ptr_abs(void* target, const GPReg& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_BYTE); }
+
+//! @brief Create word (2 Bytes) pointer operand.
+static inline Mem word_ptr_abs(void* target, const GPReg& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_WORD); }
+
+//! @brief Create dword (4 Bytes) pointer operand.
+static inline Mem dword_ptr_abs(void* target, const GPReg& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_DWORD); }
+
+//! @brief Create qword (8 Bytes) pointer operand.
+static inline Mem qword_ptr_abs(void* target, const GPReg& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_QWORD); }
+
+//! @brief Create tword (10 Bytes) pointer operand (used for 80-bit floating points).
+static inline Mem tword_ptr_abs(void* target, const GPReg& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_TWORD); }
+
+//! @brief Create dqword (16 Bytes) pointer operand.
+static inline Mem dqword_ptr_abs(void* target, const GPReg& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_DQWORD); }
+
+//! @brief Create mmword (8 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for mmx programming.
+static inline Mem mmword_ptr_abs(void* target, const GPReg& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_QWORD); }
+
+//! @brief Create xmmword (16 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for sse programming.
+static inline Mem xmmword_ptr_abs(void* target, const GPReg& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_DQWORD); }
+
+//! @brief Create system dependent pointer operand (32-bit or 64-bit).
+static inline Mem sysint_ptr_abs(void* target, const GPReg& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, sizeof(sysint_t)); }
+
+
+
+//! @brief Create pointer operand with not specified size.
+static inline Mem ptr_abs(void* target, const GPVar& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, 0); }
+
+//! @brief Create byte pointer operand.
+static inline Mem byte_ptr_abs(void* target, const GPVar& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_BYTE); }
+
+//! @brief Create word (2 Bytes) pointer operand.
+static inline Mem word_ptr_abs(void* target, const GPVar& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_WORD); }
+
+//! @brief Create dword (4 Bytes) pointer operand.
+static inline Mem dword_ptr_abs(void* target, const GPVar& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_DWORD); }
+
+//! @brief Create qword (8 Bytes) pointer operand.
+static inline Mem qword_ptr_abs(void* target, const GPVar& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_QWORD); }
+
+//! @brief Create tword (10 Bytes) pointer operand (used for 80-bit floating points).
+static inline Mem tword_ptr_abs(void* target, const GPVar& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_TWORD); }
+
+//! @brief Create dqword (16 Bytes) pointer operand.
+static inline Mem dqword_ptr_abs(void* target, const GPVar& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_DQWORD); }
+
+//! @brief Create mmword (8 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for mmx programming.
+static inline Mem mmword_ptr_abs(void* target, const GPVar& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_QWORD); }
+
+//! @brief Create xmmword (16 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for sse programming.
+static inline Mem xmmword_ptr_abs(void* target, const GPVar& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, SIZE_DQWORD); }
+
+//! @brief Create system dependent pointer operand (32-bit or 64-bit).
+static inline Mem sysint_ptr_abs(void* target, const GPVar& index, uint32_t shift, sysint_t disp = 0, uint32_t segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW
+{ return _MemPtrAbs(target, index, shift, disp, segmentPrefix, sizeof(sysint_t)); }
+
+// ============================================================================
+// [AsmJit::Mem - ptr[base + displacement]]
+// ============================================================================
+
+//! @internal
+ASMJIT_API Mem _MemPtrBuild(const GPReg& base, sysint_t disp, uint32_t ptrSize) ASMJIT_NOTHROW;
+
+//! @internal
+ASMJIT_API Mem _MemPtrBuild(const GPVar& base, sysint_t disp, uint32_t ptrSize) ASMJIT_NOTHROW;
+
+
+
+//! @brief Create pointer operand with not specified size.
+static inline Mem ptr(const GPReg& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, 0); }
+
+//! @brief Create byte pointer operand.
+static inline Mem byte_ptr(const GPReg& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_BYTE); }
+
+//! @brief Create word (2 Bytes) pointer operand.
+static inline Mem word_ptr(const GPReg& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_WORD); }
+
+//! @brief Create dword (4 Bytes) pointer operand.
+static inline Mem dword_ptr(const GPReg& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_DWORD); }
+
+//! @brief Create qword (8 Bytes) pointer operand.
+static inline Mem qword_ptr(const GPReg& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_QWORD); }
+
+//! @brief Create tword (10 Bytes) pointer operand (used for 80-bit floating points).
+static inline Mem tword_ptr(const GPReg& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_TWORD); }
+
+//! @brief Create dqword (16 Bytes) pointer operand.
+static inline Mem dqword_ptr(const GPReg& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_DQWORD); }
+
+//! @brief Create mmword (8 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for mmx programming.
+static inline Mem mmword_ptr(const GPReg& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_QWORD); }
+
+//! @brief Create xmmword (16 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for sse programming.
+static inline Mem xmmword_ptr(const GPReg& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_DQWORD); }
+
+//! @brief Create system dependent pointer operand (32-bit or 64-bit).
+static inline Mem sysint_ptr(const GPReg& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, sizeof(sysint_t)); }
+
+
+
+//! @brief Create pointer operand with not specified size.
+static inline Mem ptr(const GPVar& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, 0); }
+
+//! @brief Create byte pointer operand.
+static inline Mem byte_ptr(const GPVar& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_BYTE); }
+
+//! @brief Create word (2 Bytes) pointer operand.
+static inline Mem word_ptr(const GPVar& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_WORD); }
+
+//! @brief Create dword (4 Bytes) pointer operand.
+static inline Mem dword_ptr(const GPVar& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_DWORD); }
+
+//! @brief Create qword (8 Bytes) pointer operand.
+static inline Mem qword_ptr(const GPVar& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_QWORD); }
+
+//! @brief Create tword (10 Bytes) pointer operand (used for 80-bit floating points).
+static inline Mem tword_ptr(const GPVar& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_TWORD); }
+
+//! @brief Create dqword (16 Bytes) pointer operand.
+static inline Mem dqword_ptr(const GPVar& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_DQWORD); }
+
+//! @brief Create mmword (8 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for mmx programming.
+static inline Mem mmword_ptr(const GPVar& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_QWORD); }
+
+//! @brief Create xmmword (16 bytes) pointer operand
+//!
+//! @note This constructor is provided only for convenience for sse programming.
+static inline Mem xmmword_ptr(const GPVar& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, SIZE_DQWORD); }
+
+//! @brief Create system dependent pointer operand (32-bit or 64-bit).
+static inline Mem sysint_ptr(const GPVar& base, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, disp, sizeof(sysint_t)); }
+
+// ============================================================================
+// [AsmJit::Mem - ptr[base + (index << shift) + displacement]]
+// ============================================================================
+
+//! @internal
+ASMJIT_API Mem _MemPtrBuild(const GPReg& base, const GPReg& index, uint32_t shift, sysint_t disp, uint32_t ptrSize) ASMJIT_NOTHROW;
+
+//! @internal
+ASMJIT_API Mem _MemPtrBuild(const GPVar& base, const GPVar& index, uint32_t shift, sysint_t disp, uint32_t ptrSize) ASMJIT_NOTHROW;
+
+
+
+//! @brief Create pointer operand with not specified size.
+static inline Mem ptr(const GPReg& base, const GPReg& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, 0); }
+
+//! @brief Create byte pointer operand.
+static inline Mem byte_ptr(const GPReg& base, const GPReg& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_BYTE); }
+
+//! @brief Create word (2 Bytes) pointer operand.
+static inline Mem word_ptr(const GPReg& base, const GPReg& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_WORD); }
+
+//! @brief Create dword (4 Bytes) pointer operand.
+static inline Mem dword_ptr(const GPReg& base, const GPReg& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_DWORD); }
+
+//! @brief Create qword (8 Bytes) pointer operand.
+static inline Mem qword_ptr(const GPReg& base, const GPReg& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_QWORD); }
+
+//! @brief Create tword (10 Bytes) pointer operand (used for 80-bit floating points).
+static inline Mem tword_ptr(const GPReg& base, const GPReg& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_TWORD); }
+
+//! @brief Create dqword (16 Bytes) pointer operand.
+static inline Mem dqword_ptr(const GPReg& base, const GPReg& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_DQWORD); }
+
+//! @brief Create mmword (8 Bytes) pointer operand).
+//!
+//! @note This constructor is provided only for convenience for mmx programming.
+static inline Mem mmword_ptr(const GPReg& base, const GPReg& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_QWORD); }
+
+//! @brief Create xmmword (16 Bytes) pointer operand.
+//!
+//! @note This constructor is provided only for convenience for sse programming.
+static inline Mem xmmword_ptr(const GPReg& base, const GPReg& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_DQWORD); }
+
+//! @brief Create system dependent pointer operand (32-bit or 64-bit).
+static inline Mem sysint_ptr(const GPReg& base, const GPReg& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, sizeof(sysint_t)); }
+
+
+
+//! @brief Create pointer operand with not specified size.
+static inline Mem ptr(const GPVar& base, const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, 0); }
+
+//! @brief Create byte pointer operand.
+static inline Mem byte_ptr(const GPVar& base, const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_BYTE); }
+
+//! @brief Create word (2 Bytes) pointer operand.
+static inline Mem word_ptr(const GPVar& base, const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_WORD); }
+
+//! @brief Create dword (4 Bytes) pointer operand.
+static inline Mem dword_ptr(const GPVar& base, const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_DWORD); }
+
+//! @brief Create qword (8 Bytes) pointer operand.
+static inline Mem qword_ptr(const GPVar& base, const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_QWORD); }
+
+//! @brief Create tword (10 Bytes) pointer operand (used for 80-bit floating points).
+static inline Mem tword_ptr(const GPVar& base, const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_TWORD); }
+
+//! @brief Create dqword (16 Bytes) pointer operand.
+static inline Mem dqword_ptr(const GPVar& base, const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_DQWORD); }
+
+//! @brief Create mmword (8 Bytes) pointer operand).
+//!
+//! @note This constructor is provided only for convenience for mmx programming.
+static inline Mem mmword_ptr(const GPVar& base, const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_QWORD); }
+
+//! @brief Create xmmword (16 Bytes) pointer operand.
+//!
+//! @note This constructor is provided only for convenience for sse programming.
+static inline Mem xmmword_ptr(const GPVar& base, const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(base, index, shift, disp, SIZE_DQWORD); }
+
+//! @brief Create system dependent pointer operand (32-bit or 64-bit).
+static inline Mem sysint_ptr(const GPVar& base, const GPVar& index, uint32_t shift = 0, sysint_t disp = 0) ASMJIT_NOTHROW
+{ return _MemPtrBuild(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:
+//! - @c AsmJit::AssemblerIntrinsics::pshufw()
+//! - @c AsmJit::AssemblerIntrinsics::pshufd()
+//! - @c AsmJit::AssemblerIntrinsics::pshufhw()
+//! - @c AsmJit::AssemblerIntrinsics::pshuflw()
+//! - @c AsmJit::AssemblerIntrinsics::shufps()
+static inline uint8_t mm_shuffle(uint8_t z, uint8_t y, uint8_t x, uint8_t w) ASMJIT_NOTHROW
+{ return (z << 6) | (y << 4) | (x << 2) | w; }
+
+//! @}
+
+} // AsmJit namespace
+
+// [Guard]
+#endif // _ASMJIT_OPERANDX86X64_H