summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asmjit/src/asmjit/x86/x86operand.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asmjit/src/asmjit/x86/x86operand.h')
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86operand.h1151
1 files changed, 627 insertions, 524 deletions
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86operand.h b/3rdparty/asmjit/src/asmjit/x86/x86operand.h
index ccbe87e9ea3..ac56731c982 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86operand.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86operand.h
@@ -1,92 +1,21 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86OPERAND_H_INCLUDED
#define ASMJIT_X86_X86OPERAND_H_INCLUDED
-#include "../core/arch.h"
+#include "../core/archtraits.h"
#include "../core/operand.h"
#include "../core/type.h"
#include "../x86/x86globals.h"
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-#define ASMJIT_MEM_PTR(FUNC, SIZE) \
- static constexpr Mem FUNC(const Gp& base, int32_t offset = 0) noexcept { \
- return Mem(base, offset, SIZE); \
- } \
- static constexpr Mem FUNC(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
- return Mem(base, index, shift, offset, SIZE); \
- } \
- static constexpr Mem FUNC(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
- return Mem(base, index, shift, offset, SIZE); \
- } \
- static constexpr Mem FUNC(const Label& base, int32_t offset = 0) noexcept { \
- return Mem(base, offset, SIZE); \
- } \
- static constexpr Mem FUNC(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
- return Mem(base, index, shift, offset, SIZE); \
- } \
- static constexpr Mem FUNC(const Rip& rip_, int32_t offset = 0) noexcept { \
- return Mem(rip_, offset, SIZE); \
- } \
- static constexpr Mem FUNC(uint64_t base) noexcept { \
- return Mem(base, SIZE); \
- } \
- static constexpr Mem FUNC(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE); \
- } \
- static constexpr Mem FUNC(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE); \
- } \
- \
- static constexpr Mem FUNC##_abs(uint64_t base) noexcept { \
- return Mem(base, SIZE, BaseMem::kSignatureMemAbs); \
- } \
- static constexpr Mem FUNC##_abs(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemAbs); \
- } \
- static constexpr Mem FUNC##_abs(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemAbs); \
- } \
- \
- static constexpr Mem FUNC##_rel(uint64_t base) noexcept { \
- return Mem(base, SIZE, BaseMem::kSignatureMemRel); \
- } \
- static constexpr Mem FUNC##_rel(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemRel); \
- } \
- static constexpr Mem FUNC##_rel(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemRel); \
- }
-
//! \addtogroup asmjit_x86
//! \{
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
class Reg;
class Mem;
@@ -108,41 +37,38 @@ class CReg;
class DReg;
class St;
class Bnd;
+class Tmm;
class Rip;
-// ============================================================================
-// [asmjit::x86::Reg]
-// ============================================================================
-
//! Register traits (X86).
//!
-//! Register traits contains information about a particular register type. It's
-//! used by asmjit to setup register information on-the-fly and to populate
-//! tables that contain register information (this way it's possible to change
+//! Register traits contains information about a particular register type. It's used by asmjit to setup register
+//! information on-the-fly and to populate tables that contain register information (this way it's possible to change
//! register types and groups without having to reorder these tables).
-template<uint32_t REG_TYPE>
+template<RegType kRegType>
struct RegTraits : public BaseRegTraits {};
//! \cond
-// <--------------------+-----+-------------------------+------------------------+---+---+----------------+
-// | Reg | Reg-Type | Reg-Group |Sz |Cnt| TypeId |
-// <--------------------+-----+-------------------------+------------------------+---+---+----------------+
-ASMJIT_DEFINE_REG_TRAITS(GpbLo, BaseReg::kTypeGp8Lo , BaseReg::kGroupGp , 1 , 16, Type::kIdI8 );
-ASMJIT_DEFINE_REG_TRAITS(GpbHi, BaseReg::kTypeGp8Hi , BaseReg::kGroupGp , 1 , 4 , Type::kIdI8 );
-ASMJIT_DEFINE_REG_TRAITS(Gpw , BaseReg::kTypeGp16 , BaseReg::kGroupGp , 2 , 16, Type::kIdI16 );
-ASMJIT_DEFINE_REG_TRAITS(Gpd , BaseReg::kTypeGp32 , BaseReg::kGroupGp , 4 , 16, Type::kIdI32 );
-ASMJIT_DEFINE_REG_TRAITS(Gpq , BaseReg::kTypeGp64 , BaseReg::kGroupGp , 8 , 16, Type::kIdI64 );
-ASMJIT_DEFINE_REG_TRAITS(Xmm , BaseReg::kTypeVec128 , BaseReg::kGroupVec , 16, 32, Type::kIdI32x4 );
-ASMJIT_DEFINE_REG_TRAITS(Ymm , BaseReg::kTypeVec256 , BaseReg::kGroupVec , 32, 32, Type::kIdI32x8 );
-ASMJIT_DEFINE_REG_TRAITS(Zmm , BaseReg::kTypeVec512 , BaseReg::kGroupVec , 64, 32, Type::kIdI32x16);
-ASMJIT_DEFINE_REG_TRAITS(Mm , BaseReg::kTypeOther0 , BaseReg::kGroupOther0 , 8 , 8 , Type::kIdMmx64 );
-ASMJIT_DEFINE_REG_TRAITS(KReg , BaseReg::kTypeOther1 , BaseReg::kGroupOther1 , 0 , 8 , Type::kIdVoid );
-ASMJIT_DEFINE_REG_TRAITS(SReg , BaseReg::kTypeCustom + 0, BaseReg::kGroupVirt + 0, 2 , 7 , Type::kIdVoid );
-ASMJIT_DEFINE_REG_TRAITS(CReg , BaseReg::kTypeCustom + 1, BaseReg::kGroupVirt + 1, 0 , 16, Type::kIdVoid );
-ASMJIT_DEFINE_REG_TRAITS(DReg , BaseReg::kTypeCustom + 2, BaseReg::kGroupVirt + 2, 0 , 16, Type::kIdVoid );
-ASMJIT_DEFINE_REG_TRAITS(St , BaseReg::kTypeCustom + 3, BaseReg::kGroupVirt + 3, 10, 8 , Type::kIdF80 );
-ASMJIT_DEFINE_REG_TRAITS(Bnd , BaseReg::kTypeCustom + 4, BaseReg::kGroupVirt + 4, 16, 4 , Type::kIdVoid );
-ASMJIT_DEFINE_REG_TRAITS(Rip , BaseReg::kTypeIP , BaseReg::kGroupVirt + 5, 0 , 1 , Type::kIdVoid );
+// <--------------------+------------------------+------------------------+---+------------------+
+// | Reg-Type | Reg-Group |Sz | TypeId |
+// <--------------------+------------------------+------------------------+---+------------------+
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Rip , RegGroup::kX86_Rip , 0 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_GpbLo , RegGroup::kGp , 1 , TypeId::kInt8 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_GpbHi , RegGroup::kGp , 1 , TypeId::kInt8 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Gpw , RegGroup::kGp , 2 , TypeId::kInt16 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Gpd , RegGroup::kGp , 4 , TypeId::kInt32 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Gpq , RegGroup::kGp , 8 , TypeId::kInt64 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Xmm , RegGroup::kVec , 16, TypeId::kInt32x4 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Ymm , RegGroup::kVec , 32, TypeId::kInt32x8 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Zmm , RegGroup::kVec , 64, TypeId::kInt32x16);
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_KReg , RegGroup::kX86_K , 0 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Mm , RegGroup::kX86_MM , 8 , TypeId::kMmx64 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_SReg , RegGroup::kX86_SReg , 2 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_CReg , RegGroup::kX86_CReg , 0 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_DReg , RegGroup::kX86_DReg , 0 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_St , RegGroup::kX86_St , 10, TypeId::kFloat80 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Bnd , RegGroup::kX86_Bnd , 16, TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Tmm , RegGroup::kX86_Tmm , 0 , TypeId::kVoid );
//! \endcond
//! Register (X86).
@@ -150,156 +76,136 @@ class Reg : public BaseReg {
public:
ASMJIT_DEFINE_ABSTRACT_REG(Reg, BaseReg)
- //! Register type.
- enum RegType : uint32_t {
- kTypeNone = BaseReg::kTypeNone, //!< No register type or invalid register.
- kTypeGpbLo = BaseReg::kTypeGp8Lo, //!< Low GPB register (AL, BL, CL, DL, ...).
- kTypeGpbHi = BaseReg::kTypeGp8Hi, //!< High GPB register (AH, BH, CH, DH only).
- kTypeGpw = BaseReg::kTypeGp16, //!< GPW register.
- kTypeGpd = BaseReg::kTypeGp32, //!< GPD register.
- kTypeGpq = BaseReg::kTypeGp64, //!< GPQ register (64-bit).
- kTypeXmm = BaseReg::kTypeVec128, //!< XMM register (SSE+).
- kTypeYmm = BaseReg::kTypeVec256, //!< YMM register (AVX+).
- kTypeZmm = BaseReg::kTypeVec512, //!< ZMM register (AVX512+).
- kTypeMm = BaseReg::kTypeOther0, //!< MMX register.
- kTypeKReg = BaseReg::kTypeOther1, //!< K register (AVX512+).
- kTypeSReg = BaseReg::kTypeCustom+0, //!< Segment register (None, ES, CS, SS, DS, FS, GS).
- kTypeCReg = BaseReg::kTypeCustom+1, //!< Control register (CR).
- kTypeDReg = BaseReg::kTypeCustom+2, //!< Debug register (DR).
- kTypeSt = BaseReg::kTypeCustom+3, //!< FPU (x87) register.
- kTypeBnd = BaseReg::kTypeCustom+4, //!< Bound register (BND).
- kTypeRip = BaseReg::kTypeIP, //!< Instruction pointer (EIP, RIP).
- kTypeCount = BaseReg::kTypeCustom+5 //!< Count of register types.
- };
-
- //! Register group.
- enum RegGroup : uint32_t {
- kGroupGp = BaseReg::kGroupGp, //!< GP register group or none (universal).
- kGroupVec = BaseReg::kGroupVec, //!< XMM|YMM|ZMM register group (universal).
- kGroupMm = BaseReg::kGroupOther0, //!< MMX register group (legacy).
- kGroupKReg = BaseReg::kGroupOther1, //!< K register group.
-
- // These are not managed by BaseCompiler nor used by Func-API:
- kGroupSReg = BaseReg::kGroupVirt+0, //!< Segment register group.
- kGroupCReg = BaseReg::kGroupVirt+1, //!< Control register group.
- kGroupDReg = BaseReg::kGroupVirt+2, //!< Debug register group.
- kGroupSt = BaseReg::kGroupVirt+3, //!< FPU register group.
- kGroupBnd = BaseReg::kGroupVirt+4, //!< Bound register group.
- kGroupRip = BaseReg::kGroupVirt+5, //!< Instrucion pointer (IP).
- kGroupCount //!< Count of all register groups.
- };
-
//! Tests whether the register is a GPB register (8-bit).
- constexpr bool isGpb() const noexcept { return size() == 1; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpb() const noexcept { return size() == 1; }
//! Tests whether the register is a low GPB register (8-bit).
- constexpr bool isGpbLo() const noexcept { return hasSignature(RegTraits<kTypeGpbLo>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpbLo() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_GpbLo>::kSignature); }
//! Tests whether the register is a high GPB register (8-bit).
- constexpr bool isGpbHi() const noexcept { return hasSignature(RegTraits<kTypeGpbHi>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpbHi() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_GpbHi>::kSignature); }
//! Tests whether the register is a GPW register (16-bit).
- constexpr bool isGpw() const noexcept { return hasSignature(RegTraits<kTypeGpw>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpw() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpw>::kSignature); }
//! Tests whether the register is a GPD register (32-bit).
- constexpr bool isGpd() const noexcept { return hasSignature(RegTraits<kTypeGpd>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpd() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpd>::kSignature); }
//! Tests whether the register is a GPQ register (64-bit).
- constexpr bool isGpq() const noexcept { return hasSignature(RegTraits<kTypeGpq>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpq() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpq>::kSignature); }
+
+ //! Tests whether the register is a 32-bit general purpose register, alias of \ref isGpd().
+ ASMJIT_INLINE_NODEBUG constexpr bool isGp32() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpd>::kSignature); }
+ //! Tests whether the register is a 64-bit general purpose register, alias of \ref isGpq()
+ ASMJIT_INLINE_NODEBUG constexpr bool isGp64() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpq>::kSignature); }
+
//! Tests whether the register is an XMM register (128-bit).
- constexpr bool isXmm() const noexcept { return hasSignature(RegTraits<kTypeXmm>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isXmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Xmm>::kSignature); }
//! Tests whether the register is a YMM register (256-bit).
- constexpr bool isYmm() const noexcept { return hasSignature(RegTraits<kTypeYmm>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isYmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Ymm>::kSignature); }
//! Tests whether the register is a ZMM register (512-bit).
- constexpr bool isZmm() const noexcept { return hasSignature(RegTraits<kTypeZmm>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isZmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Zmm>::kSignature); }
+
+ //! Tests whether the register is a 128-bit vector register, alias of \ref isXmm().
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec128() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Xmm>::kSignature); }
+ //! Tests whether the register is a 256-bit vector register, alias of \ref isYmm().
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec256() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Ymm>::kSignature); }
+ //! Tests whether the register is a 512-bit vector register, alias of \ref isZmm().
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec512() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Zmm>::kSignature); }
+
//! Tests whether the register is an MMX register (64-bit).
- constexpr bool isMm() const noexcept { return hasSignature(RegTraits<kTypeMm>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isMm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Mm>::kSignature); }
//! Tests whether the register is a K register (64-bit).
- constexpr bool isKReg() const noexcept { return hasSignature(RegTraits<kTypeKReg>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isKReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_KReg>::kSignature); }
//! Tests whether the register is a segment register.
- constexpr bool isSReg() const noexcept { return hasSignature(RegTraits<kTypeSReg>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isSReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_SReg>::kSignature); }
//! Tests whether the register is a control register.
- constexpr bool isCReg() const noexcept { return hasSignature(RegTraits<kTypeCReg>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isCReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_CReg>::kSignature); }
//! Tests whether the register is a debug register.
- constexpr bool isDReg() const noexcept { return hasSignature(RegTraits<kTypeDReg>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isDReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_DReg>::kSignature); }
//! Tests whether the register is an FPU register (80-bit).
- constexpr bool isSt() const noexcept { return hasSignature(RegTraits<kTypeSt>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isSt() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_St>::kSignature); }
//! Tests whether the register is a bound register.
- constexpr bool isBnd() const noexcept { return hasSignature(RegTraits<kTypeBnd>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isBnd() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Bnd>::kSignature); }
+ //! Tests whether the register is a TMM register.
+ ASMJIT_INLINE_NODEBUG constexpr bool isTmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Tmm>::kSignature); }
//! Tests whether the register is RIP.
- constexpr bool isRip() const noexcept { return hasSignature(RegTraits<kTypeRip>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isRip() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Rip>::kSignature); }
- template<uint32_t REG_TYPE>
- inline void setRegT(uint32_t rId) noexcept {
- setSignature(RegTraits<REG_TYPE>::kSignature);
+ template<RegType REG_TYPE>
+ ASMJIT_INLINE_NODEBUG void setRegT(uint32_t rId) noexcept {
+ setSignature(OperandSignature{RegTraits<REG_TYPE>::kSignature});
setId(rId);
}
- inline void setTypeAndId(uint32_t rType, uint32_t rId) noexcept {
- ASMJIT_ASSERT(rType < kTypeCount);
- setSignature(signatureOf(rType));
- setId(rId);
+ ASMJIT_INLINE_NODEBUG void setTypeAndId(RegType type, uint32_t id) noexcept {
+ setSignature(signatureOf(type));
+ setId(id);
}
- static inline uint32_t groupOf(uint32_t rType) noexcept;
- template<uint32_t REG_TYPE>
- static inline uint32_t groupOfT() noexcept { return RegTraits<REG_TYPE>::kGroup; }
+ static ASMJIT_INLINE_NODEBUG RegGroup groupOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToGroup(type); }
+ static ASMJIT_INLINE_NODEBUG TypeId typeIdOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToTypeId(type); }
+ static ASMJIT_INLINE_NODEBUG OperandSignature signatureOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToSignature(type); }
+
+ template<RegType REG_TYPE>
+ static ASMJIT_INLINE_NODEBUG RegGroup groupOfT() noexcept { return RegGroup(RegTraits<REG_TYPE>::kGroup); }
- static inline uint32_t typeIdOf(uint32_t rType) noexcept;
- template<uint32_t REG_TYPE>
- static inline uint32_t typeIdOfT() noexcept { return RegTraits<REG_TYPE>::kTypeId; }
+ template<RegType REG_TYPE>
+ static ASMJIT_INLINE_NODEBUG TypeId typeIdOfT() noexcept { return TypeId(RegTraits<REG_TYPE>::kTypeId); }
- static inline uint32_t signatureOf(uint32_t rType) noexcept;
- template<uint32_t REG_TYPE>
- static inline uint32_t signatureOfT() noexcept { return RegTraits<REG_TYPE>::kSignature; }
+ template<RegType REG_TYPE>
+ static ASMJIT_INLINE_NODEBUG OperandSignature signatureOfT() noexcept { return OperandSignature{RegTraits<REG_TYPE>::kSignature}; }
- static inline uint32_t signatureOfVecByType(uint32_t typeId) noexcept {
- return typeId <= Type::_kIdVec128End ? RegTraits<kTypeXmm>::kSignature :
- typeId <= Type::_kIdVec256End ? RegTraits<kTypeYmm>::kSignature : RegTraits<kTypeZmm>::kSignature;
+ static ASMJIT_INLINE_NODEBUG OperandSignature signatureOfVecByType(TypeId typeId) noexcept {
+ return OperandSignature{typeId <= TypeId::_kVec128End ? uint32_t(RegTraits<RegType::kX86_Xmm>::kSignature) :
+ typeId <= TypeId::_kVec256End ? uint32_t(RegTraits<RegType::kX86_Ymm>::kSignature) :
+ uint32_t(RegTraits<RegType::kX86_Zmm>::kSignature)};
}
- static inline uint32_t signatureOfVecBySize(uint32_t size) noexcept {
- return size <= 16 ? RegTraits<kTypeXmm>::kSignature :
- size <= 32 ? RegTraits<kTypeYmm>::kSignature : RegTraits<kTypeZmm>::kSignature;
+ static ASMJIT_INLINE_NODEBUG OperandSignature signatureOfVecBySize(uint32_t size) noexcept {
+ return OperandSignature{size <= 16 ? uint32_t(RegTraits<RegType::kX86_Xmm>::kSignature) :
+ size <= 32 ? uint32_t(RegTraits<RegType::kX86_Ymm>::kSignature) :
+ uint32_t(RegTraits<RegType::kX86_Zmm>::kSignature)};
}
//! Tests whether the `op` operand is either a low or high 8-bit GPB register.
- static inline bool isGpb(const Operand_& op) noexcept {
+ static ASMJIT_INLINE_NODEBUG bool isGpb(const Operand_& op) noexcept {
// Check operand type, register group, and size. Not interested in register type.
- const uint32_t kSgn = (Operand::kOpReg << kSignatureOpShift ) |
- (1 << kSignatureSizeShift) ;
- return (op.signature() & (kSignatureOpMask | kSignatureSizeMask)) == kSgn;
+ return op.signature().subset(Signature::kOpTypeMask | Signature::kRegGroupMask | Signature::kSizeMask) ==
+ (Signature::fromOpType(OperandType::kReg) | Signature::fromRegGroup(RegGroup::kGp) | Signature::fromSize(1));
}
- static inline bool isGpbLo(const Operand_& op) noexcept { return op.as<Reg>().isGpbLo(); }
- static inline bool isGpbHi(const Operand_& op) noexcept { return op.as<Reg>().isGpbHi(); }
- static inline bool isGpw(const Operand_& op) noexcept { return op.as<Reg>().isGpw(); }
- static inline bool isGpd(const Operand_& op) noexcept { return op.as<Reg>().isGpd(); }
- static inline bool isGpq(const Operand_& op) noexcept { return op.as<Reg>().isGpq(); }
- static inline bool isXmm(const Operand_& op) noexcept { return op.as<Reg>().isXmm(); }
- static inline bool isYmm(const Operand_& op) noexcept { return op.as<Reg>().isYmm(); }
- static inline bool isZmm(const Operand_& op) noexcept { return op.as<Reg>().isZmm(); }
- static inline bool isMm(const Operand_& op) noexcept { return op.as<Reg>().isMm(); }
- static inline bool isKReg(const Operand_& op) noexcept { return op.as<Reg>().isKReg(); }
- static inline bool isSReg(const Operand_& op) noexcept { return op.as<Reg>().isSReg(); }
- static inline bool isCReg(const Operand_& op) noexcept { return op.as<Reg>().isCReg(); }
- static inline bool isDReg(const Operand_& op) noexcept { return op.as<Reg>().isDReg(); }
- static inline bool isSt(const Operand_& op) noexcept { return op.as<Reg>().isSt(); }
- static inline bool isBnd(const Operand_& op) noexcept { return op.as<Reg>().isBnd(); }
- static inline bool isRip(const Operand_& op) noexcept { return op.as<Reg>().isRip(); }
-
- static inline bool isGpb(const Operand_& op, uint32_t rId) noexcept { return isGpb(op) & (op.id() == rId); }
- static inline bool isGpbLo(const Operand_& op, uint32_t rId) noexcept { return isGpbLo(op) & (op.id() == rId); }
- static inline bool isGpbHi(const Operand_& op, uint32_t rId) noexcept { return isGpbHi(op) & (op.id() == rId); }
- static inline bool isGpw(const Operand_& op, uint32_t rId) noexcept { return isGpw(op) & (op.id() == rId); }
- static inline bool isGpd(const Operand_& op, uint32_t rId) noexcept { return isGpd(op) & (op.id() == rId); }
- static inline bool isGpq(const Operand_& op, uint32_t rId) noexcept { return isGpq(op) & (op.id() == rId); }
- static inline bool isXmm(const Operand_& op, uint32_t rId) noexcept { return isXmm(op) & (op.id() == rId); }
- static inline bool isYmm(const Operand_& op, uint32_t rId) noexcept { return isYmm(op) & (op.id() == rId); }
- static inline bool isZmm(const Operand_& op, uint32_t rId) noexcept { return isZmm(op) & (op.id() == rId); }
- static inline bool isMm(const Operand_& op, uint32_t rId) noexcept { return isMm(op) & (op.id() == rId); }
- static inline bool isKReg(const Operand_& op, uint32_t rId) noexcept { return isKReg(op) & (op.id() == rId); }
- static inline bool isSReg(const Operand_& op, uint32_t rId) noexcept { return isSReg(op) & (op.id() == rId); }
- static inline bool isCReg(const Operand_& op, uint32_t rId) noexcept { return isCReg(op) & (op.id() == rId); }
- static inline bool isDReg(const Operand_& op, uint32_t rId) noexcept { return isDReg(op) & (op.id() == rId); }
- static inline bool isSt(const Operand_& op, uint32_t rId) noexcept { return isSt(op) & (op.id() == rId); }
- static inline bool isBnd(const Operand_& op, uint32_t rId) noexcept { return isBnd(op) & (op.id() == rId); }
- static inline bool isRip(const Operand_& op, uint32_t rId) noexcept { return isRip(op) & (op.id() == rId); }
+ static ASMJIT_INLINE_NODEBUG bool isGpbLo(const Operand_& op) noexcept { return op.as<Reg>().isGpbLo(); }
+ static ASMJIT_INLINE_NODEBUG bool isGpbHi(const Operand_& op) noexcept { return op.as<Reg>().isGpbHi(); }
+ static ASMJIT_INLINE_NODEBUG bool isGpw(const Operand_& op) noexcept { return op.as<Reg>().isGpw(); }
+ static ASMJIT_INLINE_NODEBUG bool isGpd(const Operand_& op) noexcept { return op.as<Reg>().isGpd(); }
+ static ASMJIT_INLINE_NODEBUG bool isGpq(const Operand_& op) noexcept { return op.as<Reg>().isGpq(); }
+ static ASMJIT_INLINE_NODEBUG bool isXmm(const Operand_& op) noexcept { return op.as<Reg>().isXmm(); }
+ static ASMJIT_INLINE_NODEBUG bool isYmm(const Operand_& op) noexcept { return op.as<Reg>().isYmm(); }
+ static ASMJIT_INLINE_NODEBUG bool isZmm(const Operand_& op) noexcept { return op.as<Reg>().isZmm(); }
+ static ASMJIT_INLINE_NODEBUG bool isMm(const Operand_& op) noexcept { return op.as<Reg>().isMm(); }
+ static ASMJIT_INLINE_NODEBUG bool isKReg(const Operand_& op) noexcept { return op.as<Reg>().isKReg(); }
+ static ASMJIT_INLINE_NODEBUG bool isSReg(const Operand_& op) noexcept { return op.as<Reg>().isSReg(); }
+ static ASMJIT_INLINE_NODEBUG bool isCReg(const Operand_& op) noexcept { return op.as<Reg>().isCReg(); }
+ static ASMJIT_INLINE_NODEBUG bool isDReg(const Operand_& op) noexcept { return op.as<Reg>().isDReg(); }
+ static ASMJIT_INLINE_NODEBUG bool isSt(const Operand_& op) noexcept { return op.as<Reg>().isSt(); }
+ static ASMJIT_INLINE_NODEBUG bool isBnd(const Operand_& op) noexcept { return op.as<Reg>().isBnd(); }
+ static ASMJIT_INLINE_NODEBUG bool isTmm(const Operand_& op) noexcept { return op.as<Reg>().isTmm(); }
+ static ASMJIT_INLINE_NODEBUG bool isRip(const Operand_& op) noexcept { return op.as<Reg>().isRip(); }
+
+ static ASMJIT_INLINE_NODEBUG bool isGpb(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isGpb(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isGpbLo(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isGpbLo(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isGpbHi(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isGpbHi(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isGpw(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isGpw(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isGpd(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isGpd(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isGpq(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isGpq(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isXmm(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isXmm(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isYmm(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isYmm(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isZmm(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isZmm(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isMm(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isMm(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isKReg(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isKReg(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isSReg(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isSReg(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isCReg(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isCReg(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isDReg(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isDReg(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isSt(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isSt(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isBnd(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isBnd(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isTmm(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isTmm(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isRip(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isRip(op)) & unsigned(op.id() == rId)); }
};
//! General purpose register (X86).
@@ -309,9 +215,8 @@ public:
//! Physical id (X86).
//!
- //! \note Register indexes have been reduced to only support general purpose
- //! registers. There is no need to have enumerations with number suffix that
- //! expands to the exactly same value as the suffix value itself.
+ //! \note Register indexes have been reduced to only support general purpose registers. There is no need to
+ //! have enumerations with number suffix that expands to the exactly same value as the suffix value itself.
enum Id : uint32_t {
kIdAx = 0, //!< Physical id of AL|AH|AX|EAX|RAX registers.
kIdCx = 1, //!< Physical id of CL|CH|CX|ECX|RCX registers.
@@ -332,17 +237,17 @@ public:
};
//! Casts this register to 8-bit (LO) part.
- inline GpbLo r8() const noexcept;
+ ASMJIT_INLINE_NODEBUG GpbLo r8() const noexcept;
//! Casts this register to 8-bit (LO) part.
- inline GpbLo r8Lo() const noexcept;
+ ASMJIT_INLINE_NODEBUG GpbLo r8Lo() const noexcept;
//! Casts this register to 8-bit (HI) part.
- inline GpbHi r8Hi() const noexcept;
+ ASMJIT_INLINE_NODEBUG GpbHi r8Hi() const noexcept;
//! Casts this register to 16-bit.
- inline Gpw r16() const noexcept;
+ ASMJIT_INLINE_NODEBUG Gpw r16() const noexcept;
//! Casts this register to 32-bit.
- inline Gpd r32() const noexcept;
+ ASMJIT_INLINE_NODEBUG Gpd r32() const noexcept;
//! Casts this register to 64-bit.
- inline Gpq r64() const noexcept;
+ ASMJIT_INLINE_NODEBUG Gpq r64() const noexcept;
};
//! Vector register (XMM|YMM|ZMM) (X86).
@@ -350,39 +255,51 @@ class Vec : public Reg {
ASMJIT_DEFINE_ABSTRACT_REG(Vec, Reg)
//! Casts this register to XMM (clone).
- inline Xmm xmm() const noexcept;
- //! Casts this register to YMM.
- inline Ymm ymm() const noexcept;
- //! Casts this register to ZMM.
- inline Zmm zmm() const noexcept;
+ ASMJIT_INLINE_NODEBUG Xmm xmm() const noexcept;
+ //! Casts this register to YMM (clone).
+ ASMJIT_INLINE_NODEBUG Ymm ymm() const noexcept;
+ //! Casts this register to ZMM (clone).
+ ASMJIT_INLINE_NODEBUG Zmm zmm() const noexcept;
+
+ //! Casts this register to XMM (clone).
+ ASMJIT_INLINE_NODEBUG Vec v128() const noexcept;
+ //! Casts this register to YMM (clone).
+ ASMJIT_INLINE_NODEBUG Vec v256() const noexcept;
+ //! Casts this register to ZMM (clone).
+ ASMJIT_INLINE_NODEBUG Vec v512() const noexcept;
//! Casts this register to a register that has half the size (or XMM if it's already XMM).
- inline Vec half() const noexcept {
- return Vec(type() == kTypeZmm ? signatureOf(kTypeYmm) : signatureOf(kTypeXmm), id());
+ ASMJIT_INLINE_NODEBUG Vec half() const noexcept {
+ return Vec(type() == RegType::kX86_Zmm ? signatureOfT<RegType::kX86_Ymm>() : signatureOfT<RegType::kX86_Xmm>(), id());
}
};
//! Segment register (X86).
class SReg : public Reg {
- ASMJIT_DEFINE_FINAL_REG(SReg, Reg, RegTraits<kTypeSReg>)
+ ASMJIT_DEFINE_FINAL_REG(SReg, Reg, RegTraits<RegType::kX86_SReg>)
//! X86 segment id.
enum Id : uint32_t {
- kIdNone = 0, //!< No segment (default).
- kIdEs = 1, //!< ES segment.
- kIdCs = 2, //!< CS segment.
- kIdSs = 3, //!< SS segment.
- kIdDs = 4, //!< DS segment.
- kIdFs = 5, //!< FS segment.
- kIdGs = 6, //!< GS segment.
-
- //! Count of segment registers supported by AsmJit.
+ //! No segment (default).
+ kIdNone = 0,
+ //! ES segment.
+ kIdEs = 1,
+ //! CS segment.
+ kIdCs = 2,
+ //! SS segment.
+ kIdSs = 3,
+ //! DS segment.
+ kIdDs = 4,
+ //! FS segment.
+ kIdFs = 5,
+ //! GS segment.
+ kIdGs = 6,
+
+ //! Count of X86 segment registers supported by AsmJit.
//!
- //! \note X86 architecture has 6 segment registers - ES, CS, SS, DS, FS, GS.
- //! X64 architecture lowers them down to just FS and GS. AsmJit supports 7
- //! segment registers - all addressable in both and X64 modes and one
- //! extra called `SReg::kIdNone`, which is AsmJit specific and means that
- //! there is no segment register specified.
+ //! \note X86 architecture has 6 segment registers - ES, CS, SS, DS, FS, GS. X64 architecture lowers them down to
+ //! just FS and GS. AsmJit supports 7 segment registers - all addressable in both X86 and X64 modes and one extra
+ //! called `SReg::kIdNone`, which is AsmJit specific and means that there is no segment register specified.
kIdCount = 7
};
};
@@ -390,178 +307,183 @@ class SReg : public Reg {
//! GPB low or high register (X86).
class Gpb : public Gp { ASMJIT_DEFINE_ABSTRACT_REG(Gpb, Gp) };
//! GPB low register (X86).
-class GpbLo : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbLo, Gpb, RegTraits<kTypeGpbLo>) };
+class GpbLo : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbLo, Gpb, RegTraits<RegType::kX86_GpbLo>) };
//! GPB high register (X86).
-class GpbHi : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbHi, Gpb, RegTraits<kTypeGpbHi>) };
+class GpbHi : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbHi, Gpb, RegTraits<RegType::kX86_GpbHi>) };
//! GPW register (X86).
-class Gpw : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpw, Gp, RegTraits<kTypeGpw>) };
+class Gpw : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpw, Gp, RegTraits<RegType::kX86_Gpw>) };
//! GPD register (X86).
-class Gpd : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpd, Gp, RegTraits<kTypeGpd>) };
+class Gpd : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpd, Gp, RegTraits<RegType::kX86_Gpd>) };
//! GPQ register (X86_64).
-class Gpq : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpq, Gp, RegTraits<kTypeGpq>) };
+class Gpq : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpq, Gp, RegTraits<RegType::kX86_Gpq>) };
//! 128-bit XMM register (SSE+).
class Xmm : public Vec {
- ASMJIT_DEFINE_FINAL_REG(Xmm, Vec, RegTraits<kTypeXmm>)
+ ASMJIT_DEFINE_FINAL_REG(Xmm, Vec, RegTraits<RegType::kX86_Xmm>)
//! Casts this register to a register that has half the size (XMM).
- inline Xmm half() const noexcept { return Xmm(id()); }
+ ASMJIT_INLINE_NODEBUG Xmm half() const noexcept { return Xmm(id()); }
};
//! 256-bit YMM register (AVX+).
class Ymm : public Vec {
- ASMJIT_DEFINE_FINAL_REG(Ymm, Vec, RegTraits<kTypeYmm>)
+ ASMJIT_DEFINE_FINAL_REG(Ymm, Vec, RegTraits<RegType::kX86_Ymm>)
//! Casts this register to a register that has half the size (XMM).
- inline Xmm half() const noexcept { return Xmm(id()); }
+ ASMJIT_INLINE_NODEBUG Xmm half() const noexcept { return Xmm(id()); }
};
//! 512-bit ZMM register (AVX512+).
class Zmm : public Vec {
- ASMJIT_DEFINE_FINAL_REG(Zmm, Vec, RegTraits<kTypeZmm>)
+ ASMJIT_DEFINE_FINAL_REG(Zmm, Vec, RegTraits<RegType::kX86_Zmm>)
//! Casts this register to a register that has half the size (YMM).
- inline Ymm half() const noexcept { return Ymm(id()); }
+ ASMJIT_INLINE_NODEBUG Ymm half() const noexcept { return Ymm(id()); }
};
//! 64-bit MMX register (MMX+).
-class Mm : public Reg { ASMJIT_DEFINE_FINAL_REG(Mm, Reg, RegTraits<kTypeMm>) };
+class Mm : public Reg { ASMJIT_DEFINE_FINAL_REG(Mm, Reg, RegTraits<RegType::kX86_Mm>) };
//! 64-bit K register (AVX512+).
-class KReg : public Reg { ASMJIT_DEFINE_FINAL_REG(KReg, Reg, RegTraits<kTypeKReg>) };
+class KReg : public Reg { ASMJIT_DEFINE_FINAL_REG(KReg, Reg, RegTraits<RegType::kX86_KReg>) };
//! 32-bit or 64-bit control register (X86).
-class CReg : public Reg { ASMJIT_DEFINE_FINAL_REG(CReg, Reg, RegTraits<kTypeCReg>) };
+class CReg : public Reg { ASMJIT_DEFINE_FINAL_REG(CReg, Reg, RegTraits<RegType::kX86_CReg>) };
//! 32-bit or 64-bit debug register (X86).
-class DReg : public Reg { ASMJIT_DEFINE_FINAL_REG(DReg, Reg, RegTraits<kTypeDReg>) };
+class DReg : public Reg { ASMJIT_DEFINE_FINAL_REG(DReg, Reg, RegTraits<RegType::kX86_DReg>) };
//! 80-bit FPU register (X86).
-class St : public Reg { ASMJIT_DEFINE_FINAL_REG(St, Reg, RegTraits<kTypeSt>) };
+class St : public Reg { ASMJIT_DEFINE_FINAL_REG(St, Reg, RegTraits<RegType::kX86_St>) };
//! 128-bit BND register (BND+).
-class Bnd : public Reg { ASMJIT_DEFINE_FINAL_REG(Bnd, Reg, RegTraits<kTypeBnd>) };
+class Bnd : public Reg { ASMJIT_DEFINE_FINAL_REG(Bnd, Reg, RegTraits<RegType::kX86_Bnd>) };
+//! 8192-bit TMM register (AMX).
+class Tmm : public Reg { ASMJIT_DEFINE_FINAL_REG(Tmm, Reg, RegTraits<RegType::kX86_Tmm>) };
//! RIP register (X86).
-class Rip : public Reg { ASMJIT_DEFINE_FINAL_REG(Rip, Reg, RegTraits<kTypeRip>) };
+class Rip : public Reg { ASMJIT_DEFINE_FINAL_REG(Rip, Reg, RegTraits<RegType::kX86_Rip>) };
//! \cond
-inline GpbLo Gp::r8() const noexcept { return GpbLo(id()); }
-inline GpbLo Gp::r8Lo() const noexcept { return GpbLo(id()); }
-inline GpbHi Gp::r8Hi() const noexcept { return GpbHi(id()); }
-inline Gpw Gp::r16() const noexcept { return Gpw(id()); }
-inline Gpd Gp::r32() const noexcept { return Gpd(id()); }
-inline Gpq Gp::r64() const noexcept { return Gpq(id()); }
-inline Xmm Vec::xmm() const noexcept { return Xmm(id()); }
-inline Ymm Vec::ymm() const noexcept { return Ymm(id()); }
-inline Zmm Vec::zmm() const noexcept { return Zmm(id()); }
+ASMJIT_INLINE_NODEBUG GpbLo Gp::r8() const noexcept { return GpbLo(id()); }
+ASMJIT_INLINE_NODEBUG GpbLo Gp::r8Lo() const noexcept { return GpbLo(id()); }
+ASMJIT_INLINE_NODEBUG GpbHi Gp::r8Hi() const noexcept { return GpbHi(id()); }
+ASMJIT_INLINE_NODEBUG Gpw Gp::r16() const noexcept { return Gpw(id()); }
+ASMJIT_INLINE_NODEBUG Gpd Gp::r32() const noexcept { return Gpd(id()); }
+ASMJIT_INLINE_NODEBUG Gpq Gp::r64() const noexcept { return Gpq(id()); }
+ASMJIT_INLINE_NODEBUG Xmm Vec::xmm() const noexcept { return Xmm(id()); }
+ASMJIT_INLINE_NODEBUG Ymm Vec::ymm() const noexcept { return Ymm(id()); }
+ASMJIT_INLINE_NODEBUG Zmm Vec::zmm() const noexcept { return Zmm(id()); }
+ASMJIT_INLINE_NODEBUG Vec Vec::v128() const noexcept { return Xmm(id()); }
+ASMJIT_INLINE_NODEBUG Vec Vec::v256() const noexcept { return Ymm(id()); }
+ASMJIT_INLINE_NODEBUG Vec Vec::v512() const noexcept { return Zmm(id()); }
//! \endcond
//! \namespace asmjit::x86::regs
//!
-//! Registers provided by X86 and X64 ISAs are in both `asmjit::x86` and
-//! `asmjit::x86::regs` namespaces so they can be included with using directive.
-//! For example `using namespace asmjit::x86::regs` would include all registers,
-//! but not other X86-specific API, whereas `using namespace asmjit::x86` would
-//! include everything X86-specific.
+//! Registers provided by X86 and X64 ISAs are in both `asmjit::x86` and `asmjit::x86::regs` namespaces so they can
+//! be included with using directive. For example `using namespace asmjit::x86::regs` would include all registers,
+//! but not other X86-specific API, whereas `using namespace asmjit::x86` would include everything X86-specific.
#ifndef _DOXYGEN
namespace regs {
#endif
//! Creates an 8-bit low GPB register operand.
-static constexpr GpbLo gpb(uint32_t rId) noexcept { return GpbLo(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr GpbLo gpb(uint32_t rId) noexcept { return GpbLo(rId); }
//! Creates an 8-bit low GPB register operand.
-static constexpr GpbLo gpb_lo(uint32_t rId) noexcept { return GpbLo(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr GpbLo gpb_lo(uint32_t rId) noexcept { return GpbLo(rId); }
//! Creates an 8-bit high GPB register operand.
-static constexpr GpbHi gpb_hi(uint32_t rId) noexcept { return GpbHi(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr GpbHi gpb_hi(uint32_t rId) noexcept { return GpbHi(rId); }
//! Creates a 16-bit GPW register operand.
-static constexpr Gpw gpw(uint32_t rId) noexcept { return Gpw(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Gpw gpw(uint32_t rId) noexcept { return Gpw(rId); }
//! Creates a 32-bit GPD register operand.
-static constexpr Gpd gpd(uint32_t rId) noexcept { return Gpd(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Gpd gpd(uint32_t rId) noexcept { return Gpd(rId); }
//! Creates a 64-bit GPQ register operand (64-bit).
-static constexpr Gpq gpq(uint32_t rId) noexcept { return Gpq(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Gpq gpq(uint32_t rId) noexcept { return Gpq(rId); }
//! Creates a 128-bit XMM register operand.
-static constexpr Xmm xmm(uint32_t rId) noexcept { return Xmm(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Xmm xmm(uint32_t rId) noexcept { return Xmm(rId); }
//! Creates a 256-bit YMM register operand.
-static constexpr Ymm ymm(uint32_t rId) noexcept { return Ymm(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Ymm ymm(uint32_t rId) noexcept { return Ymm(rId); }
//! Creates a 512-bit ZMM register operand.
-static constexpr Zmm zmm(uint32_t rId) noexcept { return Zmm(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Zmm zmm(uint32_t rId) noexcept { return Zmm(rId); }
//! Creates a 64-bit Mm register operand.
-static constexpr Mm mm(uint32_t rId) noexcept { return Mm(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Mm mm(uint32_t rId) noexcept { return Mm(rId); }
//! Creates a 64-bit K register operand.
-static constexpr KReg k(uint32_t rId) noexcept { return KReg(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr KReg k(uint32_t rId) noexcept { return KReg(rId); }
//! Creates a 32-bit or 64-bit control register operand.
-static constexpr CReg cr(uint32_t rId) noexcept { return CReg(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr CReg cr(uint32_t rId) noexcept { return CReg(rId); }
//! Creates a 32-bit or 64-bit debug register operand.
-static constexpr DReg dr(uint32_t rId) noexcept { return DReg(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr DReg dr(uint32_t rId) noexcept { return DReg(rId); }
//! Creates an 80-bit st register operand.
-static constexpr St st(uint32_t rId) noexcept { return St(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr St st(uint32_t rId) noexcept { return St(rId); }
//! Creates a 128-bit bound register operand.
-static constexpr Bnd bnd(uint32_t rId) noexcept { return Bnd(rId); }
-
-static constexpr Gp al = Gp(GpbLo::kSignature, Gp::kIdAx);
-static constexpr Gp bl = Gp(GpbLo::kSignature, Gp::kIdBx);
-static constexpr Gp cl = Gp(GpbLo::kSignature, Gp::kIdCx);
-static constexpr Gp dl = Gp(GpbLo::kSignature, Gp::kIdDx);
-static constexpr Gp spl = Gp(GpbLo::kSignature, Gp::kIdSp);
-static constexpr Gp bpl = Gp(GpbLo::kSignature, Gp::kIdBp);
-static constexpr Gp sil = Gp(GpbLo::kSignature, Gp::kIdSi);
-static constexpr Gp dil = Gp(GpbLo::kSignature, Gp::kIdDi);
-static constexpr Gp r8b = Gp(GpbLo::kSignature, Gp::kIdR8);
-static constexpr Gp r9b = Gp(GpbLo::kSignature, Gp::kIdR9);
-static constexpr Gp r10b = Gp(GpbLo::kSignature, Gp::kIdR10);
-static constexpr Gp r11b = Gp(GpbLo::kSignature, Gp::kIdR11);
-static constexpr Gp r12b = Gp(GpbLo::kSignature, Gp::kIdR12);
-static constexpr Gp r13b = Gp(GpbLo::kSignature, Gp::kIdR13);
-static constexpr Gp r14b = Gp(GpbLo::kSignature, Gp::kIdR14);
-static constexpr Gp r15b = Gp(GpbLo::kSignature, Gp::kIdR15);
-
-static constexpr Gp ah = Gp(GpbHi::kSignature, Gp::kIdAx);
-static constexpr Gp bh = Gp(GpbHi::kSignature, Gp::kIdBx);
-static constexpr Gp ch = Gp(GpbHi::kSignature, Gp::kIdCx);
-static constexpr Gp dh = Gp(GpbHi::kSignature, Gp::kIdDx);
-
-static constexpr Gp ax = Gp(Gpw::kSignature, Gp::kIdAx);
-static constexpr Gp bx = Gp(Gpw::kSignature, Gp::kIdBx);
-static constexpr Gp cx = Gp(Gpw::kSignature, Gp::kIdCx);
-static constexpr Gp dx = Gp(Gpw::kSignature, Gp::kIdDx);
-static constexpr Gp sp = Gp(Gpw::kSignature, Gp::kIdSp);
-static constexpr Gp bp = Gp(Gpw::kSignature, Gp::kIdBp);
-static constexpr Gp si = Gp(Gpw::kSignature, Gp::kIdSi);
-static constexpr Gp di = Gp(Gpw::kSignature, Gp::kIdDi);
-static constexpr Gp r8w = Gp(Gpw::kSignature, Gp::kIdR8);
-static constexpr Gp r9w = Gp(Gpw::kSignature, Gp::kIdR9);
-static constexpr Gp r10w = Gp(Gpw::kSignature, Gp::kIdR10);
-static constexpr Gp r11w = Gp(Gpw::kSignature, Gp::kIdR11);
-static constexpr Gp r12w = Gp(Gpw::kSignature, Gp::kIdR12);
-static constexpr Gp r13w = Gp(Gpw::kSignature, Gp::kIdR13);
-static constexpr Gp r14w = Gp(Gpw::kSignature, Gp::kIdR14);
-static constexpr Gp r15w = Gp(Gpw::kSignature, Gp::kIdR15);
-
-static constexpr Gp eax = Gp(Gpd::kSignature, Gp::kIdAx);
-static constexpr Gp ebx = Gp(Gpd::kSignature, Gp::kIdBx);
-static constexpr Gp ecx = Gp(Gpd::kSignature, Gp::kIdCx);
-static constexpr Gp edx = Gp(Gpd::kSignature, Gp::kIdDx);
-static constexpr Gp esp = Gp(Gpd::kSignature, Gp::kIdSp);
-static constexpr Gp ebp = Gp(Gpd::kSignature, Gp::kIdBp);
-static constexpr Gp esi = Gp(Gpd::kSignature, Gp::kIdSi);
-static constexpr Gp edi = Gp(Gpd::kSignature, Gp::kIdDi);
-static constexpr Gp r8d = Gp(Gpd::kSignature, Gp::kIdR8);
-static constexpr Gp r9d = Gp(Gpd::kSignature, Gp::kIdR9);
-static constexpr Gp r10d = Gp(Gpd::kSignature, Gp::kIdR10);
-static constexpr Gp r11d = Gp(Gpd::kSignature, Gp::kIdR11);
-static constexpr Gp r12d = Gp(Gpd::kSignature, Gp::kIdR12);
-static constexpr Gp r13d = Gp(Gpd::kSignature, Gp::kIdR13);
-static constexpr Gp r14d = Gp(Gpd::kSignature, Gp::kIdR14);
-static constexpr Gp r15d = Gp(Gpd::kSignature, Gp::kIdR15);
-
-static constexpr Gp rax = Gp(Gpq::kSignature, Gp::kIdAx);
-static constexpr Gp rbx = Gp(Gpq::kSignature, Gp::kIdBx);
-static constexpr Gp rcx = Gp(Gpq::kSignature, Gp::kIdCx);
-static constexpr Gp rdx = Gp(Gpq::kSignature, Gp::kIdDx);
-static constexpr Gp rsp = Gp(Gpq::kSignature, Gp::kIdSp);
-static constexpr Gp rbp = Gp(Gpq::kSignature, Gp::kIdBp);
-static constexpr Gp rsi = Gp(Gpq::kSignature, Gp::kIdSi);
-static constexpr Gp rdi = Gp(Gpq::kSignature, Gp::kIdDi);
-static constexpr Gp r8 = Gp(Gpq::kSignature, Gp::kIdR8);
-static constexpr Gp r9 = Gp(Gpq::kSignature, Gp::kIdR9);
-static constexpr Gp r10 = Gp(Gpq::kSignature, Gp::kIdR10);
-static constexpr Gp r11 = Gp(Gpq::kSignature, Gp::kIdR11);
-static constexpr Gp r12 = Gp(Gpq::kSignature, Gp::kIdR12);
-static constexpr Gp r13 = Gp(Gpq::kSignature, Gp::kIdR13);
-static constexpr Gp r14 = Gp(Gpq::kSignature, Gp::kIdR14);
-static constexpr Gp r15 = Gp(Gpq::kSignature, Gp::kIdR15);
+static ASMJIT_INLINE_NODEBUG constexpr Bnd bnd(uint32_t rId) noexcept { return Bnd(rId); }
+//! Creates a TMM register operand.
+static ASMJIT_INLINE_NODEBUG constexpr Tmm tmm(uint32_t rId) noexcept { return Tmm(rId); }
+
+static constexpr GpbLo al = GpbLo(Gp::kIdAx);
+static constexpr GpbLo bl = GpbLo(Gp::kIdBx);
+static constexpr GpbLo cl = GpbLo(Gp::kIdCx);
+static constexpr GpbLo dl = GpbLo(Gp::kIdDx);
+static constexpr GpbLo spl = GpbLo(Gp::kIdSp);
+static constexpr GpbLo bpl = GpbLo(Gp::kIdBp);
+static constexpr GpbLo sil = GpbLo(Gp::kIdSi);
+static constexpr GpbLo dil = GpbLo(Gp::kIdDi);
+static constexpr GpbLo r8b = GpbLo(Gp::kIdR8);
+static constexpr GpbLo r9b = GpbLo(Gp::kIdR9);
+static constexpr GpbLo r10b = GpbLo(Gp::kIdR10);
+static constexpr GpbLo r11b = GpbLo(Gp::kIdR11);
+static constexpr GpbLo r12b = GpbLo(Gp::kIdR12);
+static constexpr GpbLo r13b = GpbLo(Gp::kIdR13);
+static constexpr GpbLo r14b = GpbLo(Gp::kIdR14);
+static constexpr GpbLo r15b = GpbLo(Gp::kIdR15);
+
+static constexpr GpbHi ah = GpbHi(Gp::kIdAx);
+static constexpr GpbHi bh = GpbHi(Gp::kIdBx);
+static constexpr GpbHi ch = GpbHi(Gp::kIdCx);
+static constexpr GpbHi dh = GpbHi(Gp::kIdDx);
+
+static constexpr Gpw ax = Gpw(Gp::kIdAx);
+static constexpr Gpw bx = Gpw(Gp::kIdBx);
+static constexpr Gpw cx = Gpw(Gp::kIdCx);
+static constexpr Gpw dx = Gpw(Gp::kIdDx);
+static constexpr Gpw sp = Gpw(Gp::kIdSp);
+static constexpr Gpw bp = Gpw(Gp::kIdBp);
+static constexpr Gpw si = Gpw(Gp::kIdSi);
+static constexpr Gpw di = Gpw(Gp::kIdDi);
+static constexpr Gpw r8w = Gpw(Gp::kIdR8);
+static constexpr Gpw r9w = Gpw(Gp::kIdR9);
+static constexpr Gpw r10w = Gpw(Gp::kIdR10);
+static constexpr Gpw r11w = Gpw(Gp::kIdR11);
+static constexpr Gpw r12w = Gpw(Gp::kIdR12);
+static constexpr Gpw r13w = Gpw(Gp::kIdR13);
+static constexpr Gpw r14w = Gpw(Gp::kIdR14);
+static constexpr Gpw r15w = Gpw(Gp::kIdR15);
+
+static constexpr Gpd eax = Gpd(Gp::kIdAx);
+static constexpr Gpd ebx = Gpd(Gp::kIdBx);
+static constexpr Gpd ecx = Gpd(Gp::kIdCx);
+static constexpr Gpd edx = Gpd(Gp::kIdDx);
+static constexpr Gpd esp = Gpd(Gp::kIdSp);
+static constexpr Gpd ebp = Gpd(Gp::kIdBp);
+static constexpr Gpd esi = Gpd(Gp::kIdSi);
+static constexpr Gpd edi = Gpd(Gp::kIdDi);
+static constexpr Gpd r8d = Gpd(Gp::kIdR8);
+static constexpr Gpd r9d = Gpd(Gp::kIdR9);
+static constexpr Gpd r10d = Gpd(Gp::kIdR10);
+static constexpr Gpd r11d = Gpd(Gp::kIdR11);
+static constexpr Gpd r12d = Gpd(Gp::kIdR12);
+static constexpr Gpd r13d = Gpd(Gp::kIdR13);
+static constexpr Gpd r14d = Gpd(Gp::kIdR14);
+static constexpr Gpd r15d = Gpd(Gp::kIdR15);
+
+static constexpr Gpq rax = Gpq(Gp::kIdAx);
+static constexpr Gpq rbx = Gpq(Gp::kIdBx);
+static constexpr Gpq rcx = Gpq(Gp::kIdCx);
+static constexpr Gpq rdx = Gpq(Gp::kIdDx);
+static constexpr Gpq rsp = Gpq(Gp::kIdSp);
+static constexpr Gpq rbp = Gpq(Gp::kIdBp);
+static constexpr Gpq rsi = Gpq(Gp::kIdSi);
+static constexpr Gpq rdi = Gpq(Gp::kIdDi);
+static constexpr Gpq r8 = Gpq(Gp::kIdR8);
+static constexpr Gpq r9 = Gpq(Gp::kIdR9);
+static constexpr Gpq r10 = Gpq(Gp::kIdR10);
+static constexpr Gpq r11 = Gpq(Gp::kIdR11);
+static constexpr Gpq r12 = Gpq(Gp::kIdR12);
+static constexpr Gpq r13 = Gpq(Gp::kIdR13);
+static constexpr Gpq r14 = Gpq(Gp::kIdR14);
+static constexpr Gpq r15 = Gpq(Gp::kIdR15);
static constexpr Xmm xmm0 = Xmm(0);
static constexpr Xmm xmm1 = Xmm(1);
@@ -736,6 +658,15 @@ static constexpr Bnd bnd1 = Bnd(1);
static constexpr Bnd bnd2 = Bnd(2);
static constexpr Bnd bnd3 = Bnd(3);
+static constexpr Tmm tmm0 = Tmm(0);
+static constexpr Tmm tmm1 = Tmm(1);
+static constexpr Tmm tmm2 = Tmm(2);
+static constexpr Tmm tmm3 = Tmm(3);
+static constexpr Tmm tmm4 = Tmm(4);
+static constexpr Tmm tmm5 = Tmm(5);
+static constexpr Tmm tmm6 = Tmm(6);
+static constexpr Tmm tmm7 = Tmm(7);
+
static constexpr Rip rip = Rip(0);
#ifndef _DOXYGEN
@@ -745,225 +676,427 @@ static constexpr Rip rip = Rip(0);
using namespace regs;
#endif
-// ============================================================================
-// [asmjit::x86::Mem]
-// ============================================================================
-
-//! Memory operand.
+//! Memory operand specific to X86 and X86_64 architecture.
class Mem : public BaseMem {
public:
- //! Additional bits of operand's signature used by `Mem`.
- enum AdditionalBits : uint32_t {
- kSignatureMemSegmentShift = 16,
- kSignatureMemSegmentMask = 0x07u << kSignatureMemSegmentShift,
-
- kSignatureMemShiftShift = 19,
- kSignatureMemShiftMask = 0x03u << kSignatureMemShiftShift,
+ //! \name Constants
+ //! \{
+ //! Additional bits of operand's signature used by `x86::Mem`.
+ enum AdditionalBits : uint32_t {
+ // Memory address type (2 bits).
+ // |........|........|XX......|........|
+ kSignatureMemAddrTypeShift = 14,
+ kSignatureMemAddrTypeMask = 0x03u << kSignatureMemAddrTypeShift,
+
+ // Memory shift amount (2 bits).
+ // |........|......XX|........|........|
+ kSignatureMemShiftValueShift = 16,
+ kSignatureMemShiftValueMask = 0x03u << kSignatureMemShiftValueShift,
+
+ // Memory segment reg (3 bits).
+ // |........|...XXX..|........|........|
+ kSignatureMemSegmentShift = 18,
+ kSignatureMemSegmentMask = 0x07u << kSignatureMemSegmentShift,
+
+ // Memory broadcast type (3 bits).
+ // |........|XXX.....|........|........|
kSignatureMemBroadcastShift = 21,
- kSignatureMemBroadcastMask = 0x7u << kSignatureMemBroadcastShift
+ kSignatureMemBroadcastMask = 0x7u << kSignatureMemBroadcastShift
+ };
+
+ //! Address type.
+ enum class AddrType : uint32_t {
+ //! Default address type, Assembler will select the best type when necessary.
+ kDefault = 0,
+ //! Absolute address type.
+ kAbs = 1,
+ //! Relative address type.
+ kRel = 2,
+
+ //! Maximum value of `AddrType`.
+ kMaxValue = kRel
};
- enum Broadcast : uint32_t {
- kBroadcast1To1 = 0,
- kBroadcast1To2 = 1,
- kBroadcast1To4 = 2,
- kBroadcast1To8 = 3,
- kBroadcast1To16 = 4,
- kBroadcast1To32 = 5,
- kBroadcast1To64 = 6
+ //! Memory broadcast type.
+ enum class Broadcast : uint32_t {
+ //! No broadcast (regular memory operand).
+ kNone = 0,
+ //! Broadcast {1to2}.
+ k1To2 = 1,
+ //! Broadcast {1to4}.
+ k1To4 = 2,
+ //! Broadcast {1to8}.
+ k1To8 = 3,
+ //! Broadcast {1to16}.
+ k1To16 = 4,
+ //! Broadcast {1to32}.
+ k1To32 = 5,
+ //! Broadcast {1to64}.
+ k1To64 = 6,
+
+ //! Maximum value of `Broadcast`.
+ kMaxValue = k1To64
};
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
+ //! \}
+
+ //! \name Construction & Destruction
+ //! \{
//! Creates a default `Mem` operand that points to [0].
- constexpr Mem() noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Mem() noexcept
: BaseMem() {}
- constexpr Mem(const Mem& other) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Mem(const Mem& other) noexcept
: BaseMem(other) {}
- //! \cond INTERNAL
- //!
- //! A constructor used internally to create `Mem` operand from `Decomposed` data.
- constexpr explicit Mem(const Decomposed& d) noexcept
- : BaseMem(d) {}
- //! \endcond
-
- constexpr Mem(const Label& base, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept
- : BaseMem(Decomposed { Label::kLabelTag, base.id(), 0, 0, off, size, flags }) {}
-
- constexpr Mem(const Label& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept
- : BaseMem(Decomposed { Label::kLabelTag, base.id(), index.type(), index.id(), off, size, flags | (shift << kSignatureMemShiftShift) }) {}
-
- constexpr Mem(const BaseReg& base, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept
- : BaseMem(Decomposed { base.type(), base.id(), 0, 0, off, size, flags }) {}
-
- constexpr Mem(const BaseReg& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept
- : BaseMem(Decomposed { base.type(), base.id(), index.type(), index.id(), off, size, flags | (shift << kSignatureMemShiftShift) }) {}
-
- constexpr explicit Mem(uint64_t base, uint32_t size = 0, uint32_t flags = 0) noexcept
- : BaseMem(Decomposed { 0, uint32_t(base >> 32), 0, 0, int32_t(uint32_t(base & 0xFFFFFFFFu)), size, flags }) {}
-
- constexpr Mem(uint64_t base, const BaseReg& index, uint32_t shift = 0, uint32_t size = 0, uint32_t flags = 0) noexcept
- : BaseMem(Decomposed { 0, uint32_t(base >> 32), index.type(), index.id(), int32_t(uint32_t(base & 0xFFFFFFFFu)), size, flags | (shift << kSignatureMemShiftShift) }) {}
-
- constexpr Mem(Globals::Init_, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) noexcept
- : BaseMem(Globals::Init, u0, u1, u2, u3) {}
-
- inline explicit Mem(Globals::NoInit_) noexcept
+ ASMJIT_INLINE_NODEBUG explicit Mem(Globals::NoInit_) noexcept
: BaseMem(Globals::NoInit) {}
+ ASMJIT_INLINE_NODEBUG constexpr Mem(const Signature& signature, uint32_t baseId, uint32_t indexId, int32_t offset) noexcept
+ : BaseMem(signature, baseId, indexId, offset) {}
+
+ ASMJIT_INLINE_NODEBUG constexpr Mem(const Label& base, int32_t off, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ Signature::fromMemBaseType(RegType::kLabelTag) |
+ Signature::fromSize(size) |
+ signature, base.id(), 0, off) {}
+
+ ASMJIT_INLINE_NODEBUG constexpr Mem(const Label& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ Signature::fromMemBaseType(RegType::kLabelTag) |
+ Signature::fromMemIndexType(index.type()) |
+ Signature::fromValue<kSignatureMemShiftValueMask>(shift) |
+ Signature::fromSize(size) |
+ signature, base.id(), index.id(), off) {}
+
+ ASMJIT_INLINE_NODEBUG constexpr Mem(const BaseReg& base, int32_t off, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ Signature::fromMemBaseType(base.type()) |
+ Signature::fromSize(size) |
+ signature, base.id(), 0, off) {}
+
+ ASMJIT_INLINE_NODEBUG constexpr Mem(const BaseReg& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ Signature::fromMemBaseType(base.type()) |
+ Signature::fromMemIndexType(index.type()) |
+ Signature::fromValue<kSignatureMemShiftValueMask>(shift) |
+ Signature::fromSize(size) |
+ signature, base.id(), index.id(), off) {}
+
+ ASMJIT_INLINE_NODEBUG constexpr explicit Mem(uint64_t base, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ Signature::fromSize(size) |
+ signature, uint32_t(base >> 32), 0, int32_t(uint32_t(base & 0xFFFFFFFFu))) {}
+
+ ASMJIT_INLINE_NODEBUG constexpr Mem(uint64_t base, const BaseReg& index, uint32_t shift = 0, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ Signature::fromMemIndexType(index.type()) |
+ Signature::fromValue<kSignatureMemShiftValueMask>(shift) |
+ Signature::fromSize(size) |
+ signature, uint32_t(base >> 32), index.id(), int32_t(uint32_t(base & 0xFFFFFFFFu))) {}
+
+ //! \}
+
+ //! \name Overloaded Operators
+ //! \{
+
+ ASMJIT_INLINE_NODEBUG Mem& operator=(const Mem& other) noexcept = default;
+
+ //! \}
+
+ //! \name Clone
+ //! \{
+
//! Clones the memory operand.
- constexpr Mem clone() const noexcept { return Mem(*this); }
+ ASMJIT_INLINE_NODEBUG constexpr Mem clone() const noexcept { return Mem(*this); }
- //! Creates a new copy of this memory operand adjusted by `off`.
+ //! Creates a copy of this memory operand adjusted by `off`.
inline Mem cloneAdjusted(int64_t off) const noexcept {
Mem result(*this);
result.addOffset(off);
return result;
}
+ //! Creates a copy of this memory operand resized to `size`.
+ inline Mem cloneResized(uint32_t size) const noexcept {
+ Mem result(*this);
+ result.setSize(size);
+ return result;
+ }
+
+ //! Creates a copy of this memory operand with a broadcast `bcst`.
+ ASMJIT_INLINE_NODEBUG constexpr Mem cloneBroadcasted(Broadcast bcst) const noexcept {
+ return Mem((_signature & ~Signature{kSignatureMemBroadcastMask}) | Signature::fromValue<kSignatureMemBroadcastMask>(bcst), _baseId, _data[0], int32_t(_data[1]));
+ }
+
+ //! \}
+
+ //! \name Base & Index
+ //! \{
+
//! Converts memory `baseType` and `baseId` to `x86::Reg` instance.
//!
//! The memory must have a valid base register otherwise the result will be wrong.
- inline Reg baseReg() const noexcept { return Reg::fromTypeAndId(baseType(), baseId()); }
+ ASMJIT_INLINE_NODEBUG Reg baseReg() const noexcept { return Reg::fromTypeAndId(baseType(), baseId()); }
//! Converts memory `indexType` and `indexId` to `x86::Reg` instance.
//!
//! The memory must have a valid index register otherwise the result will be wrong.
- inline Reg indexReg() const noexcept { return Reg::fromTypeAndId(indexType(), indexId()); }
-
- constexpr Mem _1to1() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To1 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
- constexpr Mem _1to2() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To2 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
- constexpr Mem _1to4() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To4 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
- constexpr Mem _1to8() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To8 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
- constexpr Mem _1to16() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To16 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
- constexpr Mem _1to32() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To32 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
- constexpr Mem _1to64() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To64 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
-
- // --------------------------------------------------------------------------
- // [Mem]
- // --------------------------------------------------------------------------
+ ASMJIT_INLINE_NODEBUG Reg indexReg() const noexcept { return Reg::fromTypeAndId(indexType(), indexId()); }
using BaseMem::setIndex;
- inline void setIndex(const BaseReg& index, uint32_t shift) noexcept {
+ ASMJIT_INLINE_NODEBUG void setIndex(const BaseReg& index, uint32_t shift) noexcept {
setIndex(index);
setShift(shift);
}
+ //! \}
+
+ //! \name Memory Size
+ //! \{
+
+ //! Tests whether the memory operand specifies a size (i.e. the size is not zero).
+ ASMJIT_INLINE_NODEBUG constexpr bool hasSize() const noexcept { return _signature.hasField<Signature::kSizeMask>(); }
+ //! Tests whether the memory operand size matches size `s`.
+ ASMJIT_INLINE_NODEBUG constexpr bool hasSize(uint32_t s) const noexcept { return size() == s; }
+
+ //! Returns the size of the memory operand in bytes.
+ //!
+ //! \note Most instructions would deduce the size of the memory operand, so in most cases it's expected that the
+ //! returned value would be zero. However, some instruction require the size to select between multiple variations,
+ //! so in some cases size is required would be non-zero (for example `inc [mem], immediate` requires size to
+ //! distinguish between 8-bit, 16-bit, 32-bit, and 64-bit increments.
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t size() const noexcept { return _signature.getField<Signature::kSizeMask>(); }
+
+ //! \}
+
+ //! \name Address Type
+ //! \{
+
+ //! Returns the address type of the memory operand.
+ //!
+ //! By default, address type of newly created memory operands is always \ref AddrType::kDefault.
+ ASMJIT_INLINE_NODEBUG constexpr AddrType addrType() const noexcept { return (AddrType)_signature.getField<kSignatureMemAddrTypeMask>(); }
+ //! Sets the address type to `addrType`.
+ ASMJIT_INLINE_NODEBUG void setAddrType(AddrType addrType) noexcept { _signature.setField<kSignatureMemAddrTypeMask>(uint32_t(addrType)); }
+ //! Resets the address type to \ref AddrType::kDefault.
+ ASMJIT_INLINE_NODEBUG void resetAddrType() noexcept { _signature.setField<kSignatureMemAddrTypeMask>(uint32_t(AddrType::kDefault)); }
+
+ //! Tests whether the address type is \ref AddrType::kAbs.
+ ASMJIT_INLINE_NODEBUG constexpr bool isAbs() const noexcept { return addrType() == AddrType::kAbs; }
+ //! Sets the address type to \ref AddrType::kAbs.
+ ASMJIT_INLINE_NODEBUG void setAbs() noexcept { setAddrType(AddrType::kAbs); }
+
+ //! Tests whether the address type is \ref AddrType::kRel.
+ ASMJIT_INLINE_NODEBUG constexpr bool isRel() const noexcept { return addrType() == AddrType::kRel; }
+ //! Sets the address type to \ref AddrType::kRel.
+ ASMJIT_INLINE_NODEBUG void setRel() noexcept { setAddrType(AddrType::kRel); }
+
+ //! \}
+
+ //! \name Segment
+ //! \{
+
//! Tests whether the memory operand has a segment override.
- constexpr bool hasSegment() const noexcept { return _hasSignaturePart<kSignatureMemSegmentMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr bool hasSegment() const noexcept { return _signature.hasField<kSignatureMemSegmentMask>(); }
//! Returns the associated segment override as `SReg` operand.
- constexpr SReg segment() const noexcept { return SReg(segmentId()); }
+ ASMJIT_INLINE_NODEBUG constexpr SReg segment() const noexcept { return SReg(segmentId()); }
//! Returns segment override register id, see `SReg::Id`.
- constexpr uint32_t segmentId() const noexcept { return _getSignaturePart<kSignatureMemSegmentMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t segmentId() const noexcept { return _signature.getField<kSignatureMemSegmentMask>(); }
//! Sets the segment override to `seg`.
- inline void setSegment(const SReg& seg) noexcept { setSegment(seg.id()); }
+ ASMJIT_INLINE_NODEBUG void setSegment(const SReg& seg) noexcept { setSegment(seg.id()); }
//! Sets the segment override to `id`.
- inline void setSegment(uint32_t rId) noexcept { _setSignaturePart<kSignatureMemSegmentMask>(rId); }
+ ASMJIT_INLINE_NODEBUG void setSegment(uint32_t rId) noexcept { _signature.setField<kSignatureMemSegmentMask>(rId); }
//! Resets the segment override.
- inline void resetSegment() noexcept { _setSignaturePart<kSignatureMemSegmentMask>(0); }
+ ASMJIT_INLINE_NODEBUG void resetSegment() noexcept { _signature.setField<kSignatureMemSegmentMask>(0); }
+
+ //! \}
+
+ //! \name Shift
+ //! \{
//! Tests whether the memory operand has shift (aka scale) value.
- constexpr bool hasShift() const noexcept { return _hasSignaturePart<kSignatureMemShiftMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr bool hasShift() const noexcept { return _signature.hasField<kSignatureMemShiftValueMask>(); }
//! Returns the memory operand's shift (aka scale) value.
- constexpr uint32_t shift() const noexcept { return _getSignaturePart<kSignatureMemShiftMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t shift() const noexcept { return _signature.getField<kSignatureMemShiftValueMask>(); }
//! Sets the memory operand's shift (aka scale) value.
- inline void setShift(uint32_t shift) noexcept { _setSignaturePart<kSignatureMemShiftMask>(shift); }
+ ASMJIT_INLINE_NODEBUG void setShift(uint32_t shift) noexcept { _signature.setField<kSignatureMemShiftValueMask>(shift); }
//! Resets the memory operand's shift (aka scale) value to zero.
- inline void resetShift() noexcept { _setSignaturePart<kSignatureMemShiftMask>(0); }
+ ASMJIT_INLINE_NODEBUG void resetShift() noexcept { _signature.setField<kSignatureMemShiftValueMask>(0); }
+
+ //! \}
+
+ //! \name Broadcast
+ //! \{
//! Tests whether the memory operand has broadcast {1tox}.
- constexpr bool hasBroadcast() const noexcept { return _hasSignaturePart<kSignatureMemBroadcastMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr bool hasBroadcast() const noexcept { return _signature.hasField<kSignatureMemBroadcastMask>(); }
//! Returns the memory operand's broadcast.
- constexpr uint32_t getBroadcast() const noexcept { return _getSignaturePart<kSignatureMemBroadcastMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr Broadcast getBroadcast() const noexcept { return (Broadcast)_signature.getField<kSignatureMemBroadcastMask>(); }
//! Sets the memory operand's broadcast.
- inline void setBroadcast(uint32_t bcst) noexcept { _setSignaturePart<kSignatureMemBroadcastMask>(bcst); }
+ ASMJIT_INLINE_NODEBUG void setBroadcast(Broadcast b) noexcept { _signature.setField<kSignatureMemBroadcastMask>(uint32_t(b)); }
//! Resets the memory operand's broadcast to none.
- inline void resetBroadcast() noexcept { _setSignaturePart<kSignatureMemBroadcastMask>(0); }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
- inline Mem& operator=(const Mem& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG void resetBroadcast() noexcept { _signature.setField<kSignatureMemBroadcastMask>(0); }
+
+ //! Returns a new `Mem` without a broadcast (the possible broadcast is cleared).
+ ASMJIT_INLINE_NODEBUG constexpr Mem _1to1() const noexcept { return cloneBroadcasted(Broadcast::kNone); }
+ //! Returns a new `Mem` with {1to2} broadcast (AVX-512).
+ ASMJIT_INLINE_NODEBUG constexpr Mem _1to2() const noexcept { return cloneBroadcasted(Broadcast::k1To2); }
+ //! Returns a new `Mem` with {1to4} broadcast (AVX-512).
+ ASMJIT_INLINE_NODEBUG constexpr Mem _1to4() const noexcept { return cloneBroadcasted(Broadcast::k1To4); }
+ //! Returns a new `Mem` with {1to8} broadcast (AVX-512).
+ ASMJIT_INLINE_NODEBUG constexpr Mem _1to8() const noexcept { return cloneBroadcasted(Broadcast::k1To8); }
+ //! Returns a new `Mem` with {1to16} broadcast (AVX-512).
+ ASMJIT_INLINE_NODEBUG constexpr Mem _1to16() const noexcept { return cloneBroadcasted(Broadcast::k1To16); }
+ //! Returns a new `Mem` with {1to32} broadcast (AVX-512).
+ ASMJIT_INLINE_NODEBUG constexpr Mem _1to32() const noexcept { return cloneBroadcasted(Broadcast::k1To32); }
+ //! Returns a new `Mem` with {1to64} broadcast (AVX-512).
+ ASMJIT_INLINE_NODEBUG constexpr Mem _1to64() const noexcept { return cloneBroadcasted(Broadcast::k1To64); }
+
+ //! \}
};
//! Creates `[base.reg + offset]` memory operand.
-static constexpr Mem ptr(const Gp& base, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(const Gp& base, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(base, offset, size);
}
//! Creates `[base.reg + (index << shift) + offset]` memory operand (scalar index).
-static constexpr Mem ptr(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(base, index, shift, offset, size);
}
//! Creates `[base.reg + (index << shift) + offset]` memory operand (vector index).
-static constexpr Mem ptr(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(base, index, shift, offset, size);
}
//! Creates `[base + offset]` memory operand.
-static constexpr Mem ptr(const Label& base, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(const Label& base, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(base, offset, size);
}
//! Creates `[base + (index << shift) + offset]` memory operand.
-static constexpr Mem ptr(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(base, index, shift, offset, size);
}
//! Creates `[base + (index << shift) + offset]` memory operand.
-static constexpr Mem ptr(const Label& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(const Label& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(base, index, shift, offset, size);
}
//! Creates `[rip + offset]` memory operand.
-static constexpr Mem ptr(const Rip& rip_, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(const Rip& rip_, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(rip_, offset, size);
}
//! Creates `[base]` absolute memory operand.
-static constexpr Mem ptr(uint64_t base, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(uint64_t base, uint32_t size = 0) noexcept {
return Mem(base, size);
}
//! Creates `[base + (index.reg << shift)]` absolute memory operand.
-static constexpr Mem ptr(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
return Mem(base, index, shift, size);
}
//! Creates `[base + (index.reg << shift)]` absolute memory operand.
-static constexpr Mem ptr(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
return Mem(base, index, shift, size);
}
//! Creates `[base]` absolute memory operand (absolute).
-static constexpr Mem ptr_abs(uint64_t base, uint32_t size = 0) noexcept {
- return Mem(base, size, BaseMem::kSignatureMemAbs);
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr_abs(uint64_t base, uint32_t size = 0) noexcept {
+ return Mem(base, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs));
}
//! Creates `[base + (index.reg << shift)]` absolute memory operand (absolute).
-static constexpr Mem ptr_abs(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
- return Mem(base, index, shift, size, BaseMem::kSignatureMemAbs);
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr_abs(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+ return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs));
}
//! Creates `[base + (index.reg << shift)]` absolute memory operand (absolute).
-static constexpr Mem ptr_abs(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
- return Mem(base, index, shift, size, BaseMem::kSignatureMemAbs);
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr_abs(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+ return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs));
}
//! Creates `[base]` relative memory operand (relative).
-static constexpr Mem ptr_rel(uint64_t base, uint32_t size = 0) noexcept {
- return Mem(base, size, BaseMem::kSignatureMemRel);
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr_rel(uint64_t base, uint32_t size = 0) noexcept {
+ return Mem(base, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel));
}
//! Creates `[base + (index.reg << shift)]` relative memory operand (relative).
-static constexpr Mem ptr_rel(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
- return Mem(base, index, shift, size, BaseMem::kSignatureMemRel);
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr_rel(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+ return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel));
}
//! Creates `[base + (index.reg << shift)]` relative memory operand (relative).
-static constexpr Mem ptr_rel(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
- return Mem(base, index, shift, size, BaseMem::kSignatureMemRel);
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr_rel(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+ return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel));
}
+#define ASMJIT_MEM_PTR(FUNC, SIZE) \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ const Gp& base, int32_t offset = 0) noexcept \
+ { return Mem(base, offset, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept \
+ { return Mem(base, index, shift, offset, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0) noexcept \
+ { return Mem(base, index, shift, offset, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ const Label& base, int32_t offset = 0) noexcept \
+ { return Mem(base, offset, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept \
+ { return Mem(base, index, shift, offset, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ const Rip& rip_, int32_t offset = 0) noexcept \
+ { return Mem(rip_, offset, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ uint64_t base) noexcept \
+ { return Mem(base, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ uint64_t base, const Gp& index, uint32_t shift = 0) noexcept \
+ { return Mem(base, index, shift, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ uint64_t base, const Vec& index, uint32_t shift = 0) noexcept \
+ { return Mem(base, index, shift, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC##_abs( \
+ uint64_t base) noexcept \
+ { return Mem(base, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs)); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC##_abs( \
+ uint64_t base, const Gp& index, uint32_t shift = 0) noexcept \
+ { return Mem(base, index, shift, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs)); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC##_abs( \
+ uint64_t base, const Vec& index, uint32_t shift = 0) noexcept \
+ { return Mem(base, index, shift, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs)); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC##_rel( \
+ uint64_t base) noexcept \
+ { return Mem(base, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel)); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC##_rel( \
+ uint64_t base, const Gp& index, uint32_t shift = 0) noexcept \
+ { return Mem(base, index, shift, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel)); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC##_rel( \
+ uint64_t base, const Vec& index, uint32_t shift = 0) noexcept \
+ { return Mem(base, index, shift, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel)); }
+
// Definition of memory operand constructors that use platform independent naming.
ASMJIT_MEM_PTR(ptr_8, 1)
ASMJIT_MEM_PTR(ptr_16, 2)
@@ -979,7 +1112,9 @@ ASMJIT_MEM_PTR(ptr_512, 64)
ASMJIT_MEM_PTR(byte_ptr, 1)
ASMJIT_MEM_PTR(word_ptr, 2)
ASMJIT_MEM_PTR(dword_ptr, 4)
+ASMJIT_MEM_PTR(fword_ptr, 6)
ASMJIT_MEM_PTR(qword_ptr, 8)
+ASMJIT_MEM_PTR(tbyte_ptr, 10)
ASMJIT_MEM_PTR(tword_ptr, 10)
ASMJIT_MEM_PTR(oword_ptr, 16)
ASMJIT_MEM_PTR(dqword_ptr, 16)
@@ -988,55 +1123,23 @@ ASMJIT_MEM_PTR(xmmword_ptr, 16)
ASMJIT_MEM_PTR(ymmword_ptr, 32)
ASMJIT_MEM_PTR(zmmword_ptr, 64)
-// ============================================================================
-// [asmjit::x86::OpData]
-// ============================================================================
-
-struct OpData {
- //! Information about all architecture registers.
- ArchRegs archRegs;
-};
-ASMJIT_VARAPI const OpData opData;
-
-//! \cond
-// ... Reg methods that require `opData`.
-inline uint32_t Reg::groupOf(uint32_t rType) noexcept {
- ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
- return opData.archRegs.regInfo[rType].group();
-}
-
-inline uint32_t Reg::typeIdOf(uint32_t rType) noexcept {
- ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
- return opData.archRegs.regTypeToTypeId[rType];
-}
-
-inline uint32_t Reg::signatureOf(uint32_t rType) noexcept {
- ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
- return opData.archRegs.regInfo[rType].signature();
-}
-//! \endcond
+#undef ASMJIT_MEM_PTR
//! \}
ASMJIT_END_SUB_NAMESPACE
-// ============================================================================
-// [asmjit::Type::IdOfT<x86::Reg>]
-// ============================================================================
-
//! \cond INTERNAL
ASMJIT_BEGIN_NAMESPACE
-ASMJIT_DEFINE_TYPE_ID(x86::Gpb, kIdI8);
-ASMJIT_DEFINE_TYPE_ID(x86::Gpw, kIdI16);
-ASMJIT_DEFINE_TYPE_ID(x86::Gpd, kIdI32);
-ASMJIT_DEFINE_TYPE_ID(x86::Gpq, kIdI64);
-ASMJIT_DEFINE_TYPE_ID(x86::Mm , kIdMmx64);
-ASMJIT_DEFINE_TYPE_ID(x86::Xmm, kIdI32x4);
-ASMJIT_DEFINE_TYPE_ID(x86::Ymm, kIdI32x8);
-ASMJIT_DEFINE_TYPE_ID(x86::Zmm, kIdI32x16);
+ASMJIT_DEFINE_TYPE_ID(x86::Gpb, TypeId::kInt8);
+ASMJIT_DEFINE_TYPE_ID(x86::Gpw, TypeId::kInt16);
+ASMJIT_DEFINE_TYPE_ID(x86::Gpd, TypeId::kInt32);
+ASMJIT_DEFINE_TYPE_ID(x86::Gpq, TypeId::kInt64);
+ASMJIT_DEFINE_TYPE_ID(x86::Mm , TypeId::kMmx64);
+ASMJIT_DEFINE_TYPE_ID(x86::Xmm, TypeId::kInt32x4);
+ASMJIT_DEFINE_TYPE_ID(x86::Ymm, TypeId::kInt32x8);
+ASMJIT_DEFINE_TYPE_ID(x86::Zmm, TypeId::kInt32x16);
ASMJIT_END_NAMESPACE
//! \endcond
-#undef ASMJIT_MEM_PTR
-
#endif // ASMJIT_X86_X86OPERAND_H_INCLUDED