LCOV - code coverage report
Current view: top level - asmjit - x86operand.h (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 2 11 18.2 %
Date: 2026-11-05 10:19:06 Functions: 1 2 50.0 %

          Line data    Source code
       1             : #ifdef __PLUMED_HAS_ASMJIT
       2             : // This file is part of AsmJit project <https://asmjit.com>
       3             : //
       4             : // See asmjit.h or LICENSE.md for license and copyright information
       5             : // SPDX-License-Identifier: Zlib
       6             : 
       7             : #ifndef ASMJIT_X86_X86OPERAND_H_INCLUDED
       8             : #define ASMJIT_X86_X86OPERAND_H_INCLUDED
       9             : 
      10             : #include "archtraits.h"
      11             : #include "operand.h"
      12             : #include "type.h"
      13             : #include "x86globals.h"
      14             : 
      15             : ASMJIT_BEGIN_SUB_NAMESPACE(x86)
      16             : 
      17             : //! \addtogroup asmjit_x86
      18             : //! \{
      19             : 
      20             : class Reg;
      21             : class Mem;
      22             : 
      23             : class Gp;
      24             : class Gpb;
      25             : class GpbLo;
      26             : class GpbHi;
      27             : class Gpw;
      28             : class Gpd;
      29             : class Gpq;
      30             : class Vec;
      31             : class Xmm;
      32             : class Ymm;
      33             : class Zmm;
      34             : class Mm;
      35             : class KReg;
      36             : class SReg;
      37             : class CReg;
      38             : class DReg;
      39             : class St;
      40             : class Bnd;
      41             : class Tmm;
      42             : class Rip;
      43             : 
      44             : //! Register traits (X86).
      45             : //!
      46             : //! Register traits contains information about a particular register type. It's used by asmjit to setup register
      47             : //! information on-the-fly and to populate tables that contain register information (this way it's possible to change
      48             : //! register types and groups without having to reorder these tables).
      49             : template<RegType kRegType>
      50             : struct RegTraits : public BaseRegTraits {};
      51             : 
      52             : //! \cond
      53             : // <--------------------+-----+-------------------------+------------------------+---+---+------------------+
      54             : //                      | Reg |        Reg-Type         |        Reg-Group       |Sz |Cnt|      TypeId      |
      55             : // <--------------------+-----+-------------------------+------------------------+---+---+------------------+
      56             : ASMJIT_DEFINE_REG_TRAITS(Rip  , RegType::kX86_Rip       , RegGroup::kX86_Rip     , 0 , 1 , TypeId::kVoid    );
      57             : ASMJIT_DEFINE_REG_TRAITS(GpbLo, RegType::kX86_GpbLo     , RegGroup::kGp          , 1 , 16, TypeId::kInt8    );
      58             : ASMJIT_DEFINE_REG_TRAITS(GpbHi, RegType::kX86_GpbHi     , RegGroup::kGp          , 1 , 4 , TypeId::kInt8    );
      59             : ASMJIT_DEFINE_REG_TRAITS(Gpw  , RegType::kX86_Gpw       , RegGroup::kGp          , 2 , 16, TypeId::kInt16   );
      60             : ASMJIT_DEFINE_REG_TRAITS(Gpd  , RegType::kX86_Gpd       , RegGroup::kGp          , 4 , 16, TypeId::kInt32   );
      61             : ASMJIT_DEFINE_REG_TRAITS(Gpq  , RegType::kX86_Gpq       , RegGroup::kGp          , 8 , 16, TypeId::kInt64   );
      62             : ASMJIT_DEFINE_REG_TRAITS(Xmm  , RegType::kX86_Xmm       , RegGroup::kVec         , 16, 32, TypeId::kInt32x4 );
      63             : ASMJIT_DEFINE_REG_TRAITS(Ymm  , RegType::kX86_Ymm       , RegGroup::kVec         , 32, 32, TypeId::kInt32x8 );
      64             : ASMJIT_DEFINE_REG_TRAITS(Zmm  , RegType::kX86_Zmm       , RegGroup::kVec         , 64, 32, TypeId::kInt32x16);
      65             : ASMJIT_DEFINE_REG_TRAITS(KReg , RegType::kX86_KReg      , RegGroup::kX86_K       , 0 , 8 , TypeId::kVoid    );
      66             : ASMJIT_DEFINE_REG_TRAITS(Mm   , RegType::kX86_Mm        , RegGroup::kX86_MM      , 8 , 8 , TypeId::kMmx64   );
      67             : ASMJIT_DEFINE_REG_TRAITS(SReg , RegType::kX86_SReg      , RegGroup::kX86_SReg    , 2 , 7 , TypeId::kVoid    );
      68             : ASMJIT_DEFINE_REG_TRAITS(CReg , RegType::kX86_CReg      , RegGroup::kX86_CReg    , 0 , 16, TypeId::kVoid    );
      69             : ASMJIT_DEFINE_REG_TRAITS(DReg , RegType::kX86_DReg      , RegGroup::kX86_DReg    , 0 , 16, TypeId::kVoid    );
      70             : ASMJIT_DEFINE_REG_TRAITS(St   , RegType::kX86_St        , RegGroup::kX86_St      , 10, 8 , TypeId::kFloat80 );
      71             : ASMJIT_DEFINE_REG_TRAITS(Bnd  , RegType::kX86_Bnd       , RegGroup::kX86_Bnd     , 16, 4 , TypeId::kVoid    );
      72             : ASMJIT_DEFINE_REG_TRAITS(Tmm  , RegType::kX86_Tmm       , RegGroup::kX86_Tmm     , 0 , 8 , TypeId::kVoid    );
      73             : //! \endcond
      74             : 
      75             : //! Register (X86).
      76             : class Reg : public BaseReg {
      77             : public:
      78             :   ASMJIT_DEFINE_ABSTRACT_REG(Reg, BaseReg)
      79             : 
      80             :   //! Tests whether the register is a GPB register (8-bit).
      81             :   inline constexpr bool isGpb() const noexcept { return size() == 1; }
      82             :   //! Tests whether the register is a low GPB register (8-bit).
      83             :   inline constexpr bool isGpbLo() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_GpbLo>::kSignature); }
      84             :   //! Tests whether the register is a high GPB register (8-bit).
      85             :   inline constexpr bool isGpbHi() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_GpbHi>::kSignature); }
      86             :   //! Tests whether the register is a GPW register (16-bit).
      87             :   inline constexpr bool isGpw() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpw>::kSignature); }
      88             :   //! Tests whether the register is a GPD register (32-bit).
      89             :   inline constexpr bool isGpd() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpd>::kSignature); }
      90             :   //! Tests whether the register is a GPQ register (64-bit).
      91             :   inline constexpr bool isGpq() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpq>::kSignature); }
      92             :   //! Tests whether the register is an XMM register (128-bit).
      93             :   inline constexpr bool isXmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Xmm>::kSignature); }
      94             :   //! Tests whether the register is a YMM register (256-bit).
      95             :   inline constexpr bool isYmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Ymm>::kSignature); }
      96             :   //! Tests whether the register is a ZMM register (512-bit).
      97             :   inline constexpr bool isZmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Zmm>::kSignature); }
      98             :   //! Tests whether the register is an MMX register (64-bit).
      99             :   inline constexpr bool isMm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Mm>::kSignature); }
     100             :   //! Tests whether the register is a K register (64-bit).
     101             :   inline constexpr bool isKReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_KReg>::kSignature); }
     102             :   //! Tests whether the register is a segment register.
     103             :   inline constexpr bool isSReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_SReg>::kSignature); }
     104             :   //! Tests whether the register is a control register.
     105             :   inline constexpr bool isCReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_CReg>::kSignature); }
     106             :   //! Tests whether the register is a debug register.
     107             :   inline constexpr bool isDReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_DReg>::kSignature); }
     108             :   //! Tests whether the register is an FPU register (80-bit).
     109             :   inline constexpr bool isSt() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_St>::kSignature); }
     110             :   //! Tests whether the register is a bound register.
     111             :   inline constexpr bool isBnd() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Bnd>::kSignature); }
     112             :   //! Tests whether the register is a TMM register.
     113             :   inline constexpr bool isTmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Tmm>::kSignature); }
     114             :   //! Tests whether the register is RIP.
     115             :   inline constexpr bool isRip() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Rip>::kSignature); }
     116             : 
     117             :   template<RegType REG_TYPE>
     118             :   inline void setRegT(uint32_t rId) noexcept {
     119             :     setSignature(OperandSignature{RegTraits<REG_TYPE>::kSignature});
     120             :     setId(rId);
     121           0 :   }
     122             : 
     123             :   inline void setTypeAndId(RegType type, uint32_t id) noexcept {
     124             :     setSignature(signatureOf(type));
     125             :     setId(id);
     126             :   }
     127             : 
     128             :   static inline RegGroup groupOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToGroup(type); }
     129             :   static inline TypeId typeIdOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToTypeId(type); }
     130             :   static inline OperandSignature signatureOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToSignature(type); }
     131             : 
     132             :   template<RegType REG_TYPE>
     133             :   static inline RegGroup groupOfT() noexcept { return RegGroup(RegTraits<REG_TYPE>::kGroup); }
     134             : 
     135             :   template<RegType REG_TYPE>
     136             :   static inline TypeId typeIdOfT() noexcept { return TypeId(RegTraits<REG_TYPE>::kTypeId); }
     137             : 
     138             :   template<RegType REG_TYPE>
     139             :   static inline OperandSignature signatureOfT() noexcept { return OperandSignature{RegTraits<REG_TYPE>::kSignature}; }
     140             : 
     141             :   static inline OperandSignature signatureOfVecByType(TypeId typeId) noexcept {
     142             :     return OperandSignature{typeId <= TypeId::_kVec128End ? uint32_t(RegTraits<RegType::kX86_Xmm>::kSignature) :
     143             :                             typeId <= TypeId::_kVec256End ? uint32_t(RegTraits<RegType::kX86_Ymm>::kSignature) :
     144             :                                                             uint32_t(RegTraits<RegType::kX86_Zmm>::kSignature)};
     145             :   }
     146             : 
     147           0 :   static inline OperandSignature signatureOfVecBySize(uint32_t size) noexcept {
     148           0 :     return OperandSignature{size <= 16 ? uint32_t(RegTraits<RegType::kX86_Xmm>::kSignature) :
     149           0 :                             size <= 32 ? uint32_t(RegTraits<RegType::kX86_Ymm>::kSignature) :
     150           0 :                                          uint32_t(RegTraits<RegType::kX86_Zmm>::kSignature)};
     151             :   }
     152             : 
     153             :   //! Tests whether the `op` operand is either a low or high 8-bit GPB register.
     154             :   static inline bool isGpb(const Operand_& op) noexcept {
     155             :     // Check operand type, register group, and size. Not interested in register type.
     156             :     return op.signature().subset(Signature::kOpTypeMask | Signature::kRegGroupMask | Signature::kSizeMask) ==
     157             :            (Signature::fromOpType(OperandType::kReg) | Signature::fromRegGroup(RegGroup::kGp) | Signature::fromSize(1));
     158             :   }
     159             : 
     160             :   static inline bool isGpbLo(const Operand_& op) noexcept { return op.as<Reg>().isGpbLo(); }
     161             :   static inline bool isGpbHi(const Operand_& op) noexcept { return op.as<Reg>().isGpbHi(); }
     162             :   static inline bool isGpw(const Operand_& op) noexcept { return op.as<Reg>().isGpw(); }
     163             :   static inline bool isGpd(const Operand_& op) noexcept { return op.as<Reg>().isGpd(); }
     164             :   static inline bool isGpq(const Operand_& op) noexcept { return op.as<Reg>().isGpq(); }
     165             :   static inline bool isXmm(const Operand_& op) noexcept { return op.as<Reg>().isXmm(); }
     166             :   static inline bool isYmm(const Operand_& op) noexcept { return op.as<Reg>().isYmm(); }
     167             :   static inline bool isZmm(const Operand_& op) noexcept { return op.as<Reg>().isZmm(); }
     168             :   static inline bool isMm(const Operand_& op) noexcept { return op.as<Reg>().isMm(); }
     169             :   static inline bool isKReg(const Operand_& op) noexcept { return op.as<Reg>().isKReg(); }
     170             :   static inline bool isSReg(const Operand_& op) noexcept { return op.as<Reg>().isSReg(); }
     171             :   static inline bool isCReg(const Operand_& op) noexcept { return op.as<Reg>().isCReg(); }
     172             :   static inline bool isDReg(const Operand_& op) noexcept { return op.as<Reg>().isDReg(); }
     173             :   static inline bool isSt(const Operand_& op) noexcept { return op.as<Reg>().isSt(); }
     174             :   static inline bool isBnd(const Operand_& op) noexcept { return op.as<Reg>().isBnd(); }
     175             :   static inline bool isTmm(const Operand_& op) noexcept { return op.as<Reg>().isTmm(); }
     176             :   static inline bool isRip(const Operand_& op) noexcept { return op.as<Reg>().isRip(); }
     177             : 
     178             :   static inline bool isGpb(const Operand_& op, uint32_t rId) noexcept { return isGpb(op) & (op.id() == rId); }
     179             :   static inline bool isGpbLo(const Operand_& op, uint32_t rId) noexcept { return isGpbLo(op) & (op.id() == rId); }
     180             :   static inline bool isGpbHi(const Operand_& op, uint32_t rId) noexcept { return isGpbHi(op) & (op.id() == rId); }
     181           0 :   static inline bool isGpw(const Operand_& op, uint32_t rId) noexcept { return isGpw(op) & (op.id() == rId); }
     182           0 :   static inline bool isGpd(const Operand_& op, uint32_t rId) noexcept { return isGpd(op) & (op.id() == rId); }
     183             :   static inline bool isGpq(const Operand_& op, uint32_t rId) noexcept { return isGpq(op) & (op.id() == rId); }
     184           0 :   static inline bool isXmm(const Operand_& op, uint32_t rId) noexcept { return isXmm(op) & (op.id() == rId); }
     185             :   static inline bool isYmm(const Operand_& op, uint32_t rId) noexcept { return isYmm(op) & (op.id() == rId); }
     186             :   static inline bool isZmm(const Operand_& op, uint32_t rId) noexcept { return isZmm(op) & (op.id() == rId); }
     187             :   static inline bool isMm(const Operand_& op, uint32_t rId) noexcept { return isMm(op) & (op.id() == rId); }
     188             :   static inline bool isKReg(const Operand_& op, uint32_t rId) noexcept { return isKReg(op) & (op.id() == rId); }
     189             :   static inline bool isSReg(const Operand_& op, uint32_t rId) noexcept { return isSReg(op) & (op.id() == rId); }
     190             :   static inline bool isCReg(const Operand_& op, uint32_t rId) noexcept { return isCReg(op) & (op.id() == rId); }
     191             :   static inline bool isDReg(const Operand_& op, uint32_t rId) noexcept { return isDReg(op) & (op.id() == rId); }
     192             :   static inline bool isSt(const Operand_& op, uint32_t rId) noexcept { return isSt(op) & (op.id() == rId); }
     193             :   static inline bool isBnd(const Operand_& op, uint32_t rId) noexcept { return isBnd(op) & (op.id() == rId); }
     194             :   static inline bool isTmm(const Operand_& op, uint32_t rId) noexcept { return isTmm(op) & (op.id() == rId); }
     195             :   static inline bool isRip(const Operand_& op, uint32_t rId) noexcept { return isRip(op) & (op.id() == rId); }
     196             : };
     197             : 
     198             : //! General purpose register (X86).
     199             : class Gp : public Reg {
     200             : public:
     201             :   ASMJIT_DEFINE_ABSTRACT_REG(Gp, Reg)
     202             : 
     203             :   //! Physical id (X86).
     204             :   //!
     205             :   //! \note Register indexes have been reduced to only support general purpose registers. There is no need to
     206             :   //! have enumerations with number suffix that expands to the exactly same value as the suffix value itself.
     207             :   enum Id : uint32_t {
     208             :     kIdAx  = 0,  //!< Physical id of AL|AH|AX|EAX|RAX registers.
     209             :     kIdCx  = 1,  //!< Physical id of CL|CH|CX|ECX|RCX registers.
     210             :     kIdDx  = 2,  //!< Physical id of DL|DH|DX|EDX|RDX registers.
     211             :     kIdBx  = 3,  //!< Physical id of BL|BH|BX|EBX|RBX registers.
     212             :     kIdSp  = 4,  //!< Physical id of SPL|SP|ESP|RSP registers.
     213             :     kIdBp  = 5,  //!< Physical id of BPL|BP|EBP|RBP registers.
     214             :     kIdSi  = 6,  //!< Physical id of SIL|SI|ESI|RSI registers.
     215             :     kIdDi  = 7,  //!< Physical id of DIL|DI|EDI|RDI registers.
     216             :     kIdR8  = 8,  //!< Physical id of R8B|R8W|R8D|R8 registers (64-bit only).
     217             :     kIdR9  = 9,  //!< Physical id of R9B|R9W|R9D|R9 registers (64-bit only).
     218             :     kIdR10 = 10, //!< Physical id of R10B|R10W|R10D|R10 registers (64-bit only).
     219             :     kIdR11 = 11, //!< Physical id of R11B|R11W|R11D|R11 registers (64-bit only).
     220             :     kIdR12 = 12, //!< Physical id of R12B|R12W|R12D|R12 registers (64-bit only).
     221             :     kIdR13 = 13, //!< Physical id of R13B|R13W|R13D|R13 registers (64-bit only).
     222             :     kIdR14 = 14, //!< Physical id of R14B|R14W|R14D|R14 registers (64-bit only).
     223             :     kIdR15 = 15  //!< Physical id of R15B|R15W|R15D|R15 registers (64-bit only).
     224             :   };
     225             : 
     226             :   //! Casts this register to 8-bit (LO) part.
     227             :   inline GpbLo r8() const noexcept;
     228             :   //! Casts this register to 8-bit (LO) part.
     229             :   inline GpbLo r8Lo() const noexcept;
     230             :   //! Casts this register to 8-bit (HI) part.
     231             :   inline GpbHi r8Hi() const noexcept;
     232             :   //! Casts this register to 16-bit.
     233             :   inline Gpw r16() const noexcept;
     234             :   //! Casts this register to 32-bit.
     235             :   inline Gpd r32() const noexcept;
     236             :   //! Casts this register to 64-bit.
     237             :   inline Gpq r64() const noexcept;
     238             : };
     239             : 
     240             : //! Vector register (XMM|YMM|ZMM) (X86).
     241             : class Vec : public Reg {
     242             :   ASMJIT_DEFINE_ABSTRACT_REG(Vec, Reg)
     243             : 
     244             :   //! Casts this register to XMM (clone).
     245             :   inline Xmm xmm() const noexcept;
     246             :   //! Casts this register to YMM.
     247             :   inline Ymm ymm() const noexcept;
     248             :   //! Casts this register to ZMM.
     249             :   inline Zmm zmm() const noexcept;
     250             : 
     251             :   //! Casts this register to a register that has half the size (or XMM if it's already XMM).
     252             :   inline Vec half() const noexcept {
     253             :     return Vec(type() == RegType::kX86_Zmm ? signatureOfT<RegType::kX86_Ymm>() : signatureOfT<RegType::kX86_Xmm>(), id());
     254             :   }
     255             : };
     256             : 
     257             : //! Segment register (X86).
     258             : class SReg : public Reg {
     259             :   ASMJIT_DEFINE_FINAL_REG(SReg, Reg, RegTraits<RegType::kX86_SReg>)
     260             : 
     261             :   //! X86 segment id.
     262             :   enum Id : uint32_t {
     263             :     //! No segment (default).
     264             :     kIdNone = 0,
     265             :     //! ES segment.
     266             :     kIdEs = 1,
     267             :     //! CS segment.
     268             :     kIdCs = 2,
     269             :     //! SS segment.
     270             :     kIdSs = 3,
     271             :     //! DS segment.
     272             :     kIdDs = 4,
     273             :     //! FS segment.
     274             :     kIdFs = 5,
     275             :     //! GS segment.
     276             :     kIdGs = 6,
     277             : 
     278             :     //! Count of X86 segment registers supported by AsmJit.
     279             :     //!
     280             :     //! \note X86 architecture has 6 segment registers - ES, CS, SS, DS, FS, GS. X64 architecture lowers them down to
     281             :     //! just FS and GS. AsmJit supports 7 segment registers - all addressable in both X86 and X64 modes and one extra
     282             :     //! called `SReg::kIdNone`, which is AsmJit specific and means that there is no segment register specified.
     283             :     kIdCount = 7
     284             :   };
     285             : };
     286             : 
     287             : //! GPB low or high register (X86).
     288             : class Gpb : public Gp { ASMJIT_DEFINE_ABSTRACT_REG(Gpb, Gp) };
     289             : //! GPB low register (X86).
     290             : class GpbLo : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbLo, Gpb, RegTraits<RegType::kX86_GpbLo>) };
     291             : //! GPB high register (X86).
     292             : class GpbHi : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbHi, Gpb, RegTraits<RegType::kX86_GpbHi>) };
     293             : //! GPW register (X86).
     294             : class Gpw : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpw, Gp, RegTraits<RegType::kX86_Gpw>) };
     295             : //! GPD register (X86).
     296             : class Gpd : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpd, Gp, RegTraits<RegType::kX86_Gpd>) };
     297             : //! GPQ register (X86_64).
     298             : class Gpq : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpq, Gp, RegTraits<RegType::kX86_Gpq>) };
     299             : 
     300             : //! 128-bit XMM register (SSE+).
     301             : class Xmm : public Vec {
     302             :   ASMJIT_DEFINE_FINAL_REG(Xmm, Vec, RegTraits<RegType::kX86_Xmm>)
     303             :   //! Casts this register to a register that has half the size (XMM).
     304             :   inline Xmm half() const noexcept { return Xmm(id()); }
     305             : };
     306             : 
     307             : //! 256-bit YMM register (AVX+).
     308             : class Ymm : public Vec {
     309             :   ASMJIT_DEFINE_FINAL_REG(Ymm, Vec, RegTraits<RegType::kX86_Ymm>)
     310             :   //! Casts this register to a register that has half the size (XMM).
     311             :   inline Xmm half() const noexcept { return Xmm(id()); }
     312             : };
     313             : 
     314             : //! 512-bit ZMM register (AVX512+).
     315             : class Zmm : public Vec {
     316             :   ASMJIT_DEFINE_FINAL_REG(Zmm, Vec, RegTraits<RegType::kX86_Zmm>)
     317             :   //! Casts this register to a register that has half the size (YMM).
     318             :   inline Ymm half() const noexcept { return Ymm(id()); }
     319             : };
     320             : 
     321             : //! 64-bit MMX register (MMX+).
     322             : class Mm : public Reg { ASMJIT_DEFINE_FINAL_REG(Mm, Reg, RegTraits<RegType::kX86_Mm>) };
     323             : //! 64-bit K register (AVX512+).
     324             : class KReg : public Reg { ASMJIT_DEFINE_FINAL_REG(KReg, Reg, RegTraits<RegType::kX86_KReg>) };
     325             : //! 32-bit or 64-bit control register (X86).
     326             : class CReg : public Reg { ASMJIT_DEFINE_FINAL_REG(CReg, Reg, RegTraits<RegType::kX86_CReg>) };
     327             : //! 32-bit or 64-bit debug register (X86).
     328             : class DReg : public Reg { ASMJIT_DEFINE_FINAL_REG(DReg, Reg, RegTraits<RegType::kX86_DReg>) };
     329             : //! 80-bit FPU register (X86).
     330             : class St : public Reg { ASMJIT_DEFINE_FINAL_REG(St, Reg, RegTraits<RegType::kX86_St>) };
     331             : //! 128-bit BND register (BND+).
     332             : class Bnd : public Reg { ASMJIT_DEFINE_FINAL_REG(Bnd, Reg, RegTraits<RegType::kX86_Bnd>) };
     333             : //! 8192-bit TMM register (AMX).
     334             : class Tmm : public Reg { ASMJIT_DEFINE_FINAL_REG(Tmm, Reg, RegTraits<RegType::kX86_Tmm>) };
     335             : //! RIP register (X86).
     336             : class Rip : public Reg { ASMJIT_DEFINE_FINAL_REG(Rip, Reg, RegTraits<RegType::kX86_Rip>) };
     337             : 
     338             : //! \cond
     339             : inline GpbLo Gp::r8() const noexcept { return GpbLo(id()); }
     340             : inline GpbLo Gp::r8Lo() const noexcept { return GpbLo(id()); }
     341             : inline GpbHi Gp::r8Hi() const noexcept { return GpbHi(id()); }
     342             : inline Gpw Gp::r16() const noexcept { return Gpw(id()); }
     343             : inline Gpd Gp::r32() const noexcept { return Gpd(id()); }
     344             : inline Gpq Gp::r64() const noexcept { return Gpq(id()); }
     345             : inline Xmm Vec::xmm() const noexcept { return Xmm(id()); }
     346             : inline Ymm Vec::ymm() const noexcept { return Ymm(id()); }
     347             : inline Zmm Vec::zmm() const noexcept { return Zmm(id()); }
     348             : //! \endcond
     349             : 
     350             : //! \namespace asmjit::x86::regs
     351             : //!
     352             : //! Registers provided by X86 and X64 ISAs are in both `asmjit::x86` and
     353             : //! `asmjit::x86::regs` namespaces so they can be included with using directive.
     354             : //! For example `using namespace asmjit::x86::regs` would include all registers,
     355             : //! but not other X86-specific API, whereas `using namespace asmjit::x86` would
     356             : //! include everything X86-specific.
     357             : #ifndef _DOXYGEN
     358             : namespace regs {
     359             : #endif
     360             : 
     361             : //! Creates an 8-bit low GPB register operand.
     362             : static constexpr GpbLo gpb(uint32_t rId) noexcept { return GpbLo(rId); }
     363             : //! Creates an 8-bit low GPB register operand.
     364             : static constexpr GpbLo gpb_lo(uint32_t rId) noexcept { return GpbLo(rId); }
     365             : //! Creates an 8-bit high GPB register operand.
     366             : static constexpr GpbHi gpb_hi(uint32_t rId) noexcept { return GpbHi(rId); }
     367             : //! Creates a 16-bit GPW register operand.
     368             : static constexpr Gpw gpw(uint32_t rId) noexcept { return Gpw(rId); }
     369             : //! Creates a 32-bit GPD register operand.
     370             : static constexpr Gpd gpd(uint32_t rId) noexcept { return Gpd(rId); }
     371             : //! Creates a 64-bit GPQ register operand (64-bit).
     372             : static constexpr Gpq gpq(uint32_t rId) noexcept { return Gpq(rId); }
     373             : //! Creates a 128-bit XMM register operand.
     374             : static constexpr Xmm xmm(uint32_t rId) noexcept { return Xmm(rId); }
     375             : //! Creates a 256-bit YMM register operand.
     376             : static constexpr Ymm ymm(uint32_t rId) noexcept { return Ymm(rId); }
     377             : //! Creates a 512-bit ZMM register operand.
     378             : static constexpr Zmm zmm(uint32_t rId) noexcept { return Zmm(rId); }
     379             : //! Creates a 64-bit Mm register operand.
     380             : static constexpr Mm mm(uint32_t rId) noexcept { return Mm(rId); }
     381             : //! Creates a 64-bit K register operand.
     382             : static constexpr KReg k(uint32_t rId) noexcept { return KReg(rId); }
     383             : //! Creates a 32-bit or 64-bit control register operand.
     384             : static constexpr CReg cr(uint32_t rId) noexcept { return CReg(rId); }
     385             : //! Creates a 32-bit or 64-bit debug register operand.
     386             : static constexpr DReg dr(uint32_t rId) noexcept { return DReg(rId); }
     387             : //! Creates an 80-bit st register operand.
     388             : static constexpr St st(uint32_t rId) noexcept { return St(rId); }
     389             : //! Creates a 128-bit bound register operand.
     390             : static constexpr Bnd bnd(uint32_t rId) noexcept { return Bnd(rId); }
     391             : //! Creates a TMM register operand.
     392             : static constexpr Tmm tmm(uint32_t rId) noexcept { return Tmm(rId); }
     393             : 
     394             : static constexpr GpbLo al = GpbLo(Gp::kIdAx);
     395             : static constexpr GpbLo bl = GpbLo(Gp::kIdBx);
     396             : static constexpr GpbLo cl = GpbLo(Gp::kIdCx);
     397             : static constexpr GpbLo dl = GpbLo(Gp::kIdDx);
     398             : static constexpr GpbLo spl = GpbLo(Gp::kIdSp);
     399             : static constexpr GpbLo bpl = GpbLo(Gp::kIdBp);
     400             : static constexpr GpbLo sil = GpbLo(Gp::kIdSi);
     401             : static constexpr GpbLo dil = GpbLo(Gp::kIdDi);
     402             : static constexpr GpbLo r8b = GpbLo(Gp::kIdR8);
     403             : static constexpr GpbLo r9b = GpbLo(Gp::kIdR9);
     404             : static constexpr GpbLo r10b = GpbLo(Gp::kIdR10);
     405             : static constexpr GpbLo r11b = GpbLo(Gp::kIdR11);
     406             : static constexpr GpbLo r12b = GpbLo(Gp::kIdR12);
     407             : static constexpr GpbLo r13b = GpbLo(Gp::kIdR13);
     408             : static constexpr GpbLo r14b = GpbLo(Gp::kIdR14);
     409             : static constexpr GpbLo r15b = GpbLo(Gp::kIdR15);
     410             : 
     411             : static constexpr GpbHi ah = GpbHi(Gp::kIdAx);
     412             : static constexpr GpbHi bh = GpbHi(Gp::kIdBx);
     413             : static constexpr GpbHi ch = GpbHi(Gp::kIdCx);
     414             : static constexpr GpbHi dh = GpbHi(Gp::kIdDx);
     415             : 
     416             : static constexpr Gpw ax = Gpw(Gp::kIdAx);
     417             : static constexpr Gpw bx = Gpw(Gp::kIdBx);
     418             : static constexpr Gpw cx = Gpw(Gp::kIdCx);
     419             : static constexpr Gpw dx = Gpw(Gp::kIdDx);
     420             : static constexpr Gpw sp = Gpw(Gp::kIdSp);
     421             : static constexpr Gpw bp = Gpw(Gp::kIdBp);
     422             : static constexpr Gpw si = Gpw(Gp::kIdSi);
     423             : static constexpr Gpw di = Gpw(Gp::kIdDi);
     424             : static constexpr Gpw r8w = Gpw(Gp::kIdR8);
     425             : static constexpr Gpw r9w = Gpw(Gp::kIdR9);
     426             : static constexpr Gpw r10w = Gpw(Gp::kIdR10);
     427             : static constexpr Gpw r11w = Gpw(Gp::kIdR11);
     428             : static constexpr Gpw r12w = Gpw(Gp::kIdR12);
     429             : static constexpr Gpw r13w = Gpw(Gp::kIdR13);
     430             : static constexpr Gpw r14w = Gpw(Gp::kIdR14);
     431             : static constexpr Gpw r15w = Gpw(Gp::kIdR15);
     432             : 
     433             : static constexpr Gpd eax = Gpd(Gp::kIdAx);
     434             : static constexpr Gpd ebx = Gpd(Gp::kIdBx);
     435             : static constexpr Gpd ecx = Gpd(Gp::kIdCx);
     436             : static constexpr Gpd edx = Gpd(Gp::kIdDx);
     437             : static constexpr Gpd esp = Gpd(Gp::kIdSp);
     438             : static constexpr Gpd ebp = Gpd(Gp::kIdBp);
     439             : static constexpr Gpd esi = Gpd(Gp::kIdSi);
     440             : static constexpr Gpd edi = Gpd(Gp::kIdDi);
     441             : static constexpr Gpd r8d = Gpd(Gp::kIdR8);
     442             : static constexpr Gpd r9d = Gpd(Gp::kIdR9);
     443             : static constexpr Gpd r10d = Gpd(Gp::kIdR10);
     444             : static constexpr Gpd r11d = Gpd(Gp::kIdR11);
     445             : static constexpr Gpd r12d = Gpd(Gp::kIdR12);
     446             : static constexpr Gpd r13d = Gpd(Gp::kIdR13);
     447             : static constexpr Gpd r14d = Gpd(Gp::kIdR14);
     448             : static constexpr Gpd r15d = Gpd(Gp::kIdR15);
     449             : 
     450             : static constexpr Gpq rax = Gpq(Gp::kIdAx);
     451             : static constexpr Gpq rbx = Gpq(Gp::kIdBx);
     452             : static constexpr Gpq rcx = Gpq(Gp::kIdCx);
     453             : static constexpr Gpq rdx = Gpq(Gp::kIdDx);
     454             : static constexpr Gpq rsp = Gpq(Gp::kIdSp);
     455             : static constexpr Gpq rbp = Gpq(Gp::kIdBp);
     456             : static constexpr Gpq rsi = Gpq(Gp::kIdSi);
     457             : static constexpr Gpq rdi = Gpq(Gp::kIdDi);
     458             : static constexpr Gpq r8 = Gpq(Gp::kIdR8);
     459             : static constexpr Gpq r9 = Gpq(Gp::kIdR9);
     460             : static constexpr Gpq r10 = Gpq(Gp::kIdR10);
     461             : static constexpr Gpq r11 = Gpq(Gp::kIdR11);
     462             : static constexpr Gpq r12 = Gpq(Gp::kIdR12);
     463             : static constexpr Gpq r13 = Gpq(Gp::kIdR13);
     464             : static constexpr Gpq r14 = Gpq(Gp::kIdR14);
     465             : static constexpr Gpq r15 = Gpq(Gp::kIdR15);
     466             : 
     467             : static constexpr Xmm xmm0 = Xmm(0);
     468             : static constexpr Xmm xmm1 = Xmm(1);
     469             : static constexpr Xmm xmm2 = Xmm(2);
     470             : static constexpr Xmm xmm3 = Xmm(3);
     471             : static constexpr Xmm xmm4 = Xmm(4);
     472             : static constexpr Xmm xmm5 = Xmm(5);
     473             : static constexpr Xmm xmm6 = Xmm(6);
     474             : static constexpr Xmm xmm7 = Xmm(7);
     475             : static constexpr Xmm xmm8 = Xmm(8);
     476             : static constexpr Xmm xmm9 = Xmm(9);
     477             : static constexpr Xmm xmm10 = Xmm(10);
     478             : static constexpr Xmm xmm11 = Xmm(11);
     479             : static constexpr Xmm xmm12 = Xmm(12);
     480             : static constexpr Xmm xmm13 = Xmm(13);
     481             : static constexpr Xmm xmm14 = Xmm(14);
     482             : static constexpr Xmm xmm15 = Xmm(15);
     483             : static constexpr Xmm xmm16 = Xmm(16);
     484             : static constexpr Xmm xmm17 = Xmm(17);
     485             : static constexpr Xmm xmm18 = Xmm(18);
     486             : static constexpr Xmm xmm19 = Xmm(19);
     487             : static constexpr Xmm xmm20 = Xmm(20);
     488             : static constexpr Xmm xmm21 = Xmm(21);
     489             : static constexpr Xmm xmm22 = Xmm(22);
     490             : static constexpr Xmm xmm23 = Xmm(23);
     491             : static constexpr Xmm xmm24 = Xmm(24);
     492             : static constexpr Xmm xmm25 = Xmm(25);
     493             : static constexpr Xmm xmm26 = Xmm(26);
     494             : static constexpr Xmm xmm27 = Xmm(27);
     495             : static constexpr Xmm xmm28 = Xmm(28);
     496             : static constexpr Xmm xmm29 = Xmm(29);
     497             : static constexpr Xmm xmm30 = Xmm(30);
     498             : static constexpr Xmm xmm31 = Xmm(31);
     499             : 
     500             : static constexpr Ymm ymm0 = Ymm(0);
     501             : static constexpr Ymm ymm1 = Ymm(1);
     502             : static constexpr Ymm ymm2 = Ymm(2);
     503             : static constexpr Ymm ymm3 = Ymm(3);
     504             : static constexpr Ymm ymm4 = Ymm(4);
     505             : static constexpr Ymm ymm5 = Ymm(5);
     506             : static constexpr Ymm ymm6 = Ymm(6);
     507             : static constexpr Ymm ymm7 = Ymm(7);
     508             : static constexpr Ymm ymm8 = Ymm(8);
     509             : static constexpr Ymm ymm9 = Ymm(9);
     510             : static constexpr Ymm ymm10 = Ymm(10);
     511             : static constexpr Ymm ymm11 = Ymm(11);
     512             : static constexpr Ymm ymm12 = Ymm(12);
     513             : static constexpr Ymm ymm13 = Ymm(13);
     514             : static constexpr Ymm ymm14 = Ymm(14);
     515             : static constexpr Ymm ymm15 = Ymm(15);
     516             : static constexpr Ymm ymm16 = Ymm(16);
     517             : static constexpr Ymm ymm17 = Ymm(17);
     518             : static constexpr Ymm ymm18 = Ymm(18);
     519             : static constexpr Ymm ymm19 = Ymm(19);
     520             : static constexpr Ymm ymm20 = Ymm(20);
     521             : static constexpr Ymm ymm21 = Ymm(21);
     522             : static constexpr Ymm ymm22 = Ymm(22);
     523             : static constexpr Ymm ymm23 = Ymm(23);
     524             : static constexpr Ymm ymm24 = Ymm(24);
     525             : static constexpr Ymm ymm25 = Ymm(25);
     526             : static constexpr Ymm ymm26 = Ymm(26);
     527             : static constexpr Ymm ymm27 = Ymm(27);
     528             : static constexpr Ymm ymm28 = Ymm(28);
     529             : static constexpr Ymm ymm29 = Ymm(29);
     530             : static constexpr Ymm ymm30 = Ymm(30);
     531             : static constexpr Ymm ymm31 = Ymm(31);
     532             : 
     533             : static constexpr Zmm zmm0 = Zmm(0);
     534             : static constexpr Zmm zmm1 = Zmm(1);
     535             : static constexpr Zmm zmm2 = Zmm(2);
     536             : static constexpr Zmm zmm3 = Zmm(3);
     537             : static constexpr Zmm zmm4 = Zmm(4);
     538             : static constexpr Zmm zmm5 = Zmm(5);
     539             : static constexpr Zmm zmm6 = Zmm(6);
     540             : static constexpr Zmm zmm7 = Zmm(7);
     541             : static constexpr Zmm zmm8 = Zmm(8);
     542             : static constexpr Zmm zmm9 = Zmm(9);
     543             : static constexpr Zmm zmm10 = Zmm(10);
     544             : static constexpr Zmm zmm11 = Zmm(11);
     545             : static constexpr Zmm zmm12 = Zmm(12);
     546             : static constexpr Zmm zmm13 = Zmm(13);
     547             : static constexpr Zmm zmm14 = Zmm(14);
     548             : static constexpr Zmm zmm15 = Zmm(15);
     549             : static constexpr Zmm zmm16 = Zmm(16);
     550             : static constexpr Zmm zmm17 = Zmm(17);
     551             : static constexpr Zmm zmm18 = Zmm(18);
     552             : static constexpr Zmm zmm19 = Zmm(19);
     553             : static constexpr Zmm zmm20 = Zmm(20);
     554             : static constexpr Zmm zmm21 = Zmm(21);
     555             : static constexpr Zmm zmm22 = Zmm(22);
     556             : static constexpr Zmm zmm23 = Zmm(23);
     557             : static constexpr Zmm zmm24 = Zmm(24);
     558             : static constexpr Zmm zmm25 = Zmm(25);
     559             : static constexpr Zmm zmm26 = Zmm(26);
     560             : static constexpr Zmm zmm27 = Zmm(27);
     561             : static constexpr Zmm zmm28 = Zmm(28);
     562             : static constexpr Zmm zmm29 = Zmm(29);
     563             : static constexpr Zmm zmm30 = Zmm(30);
     564             : static constexpr Zmm zmm31 = Zmm(31);
     565             : 
     566             : static constexpr Mm mm0 = Mm(0);
     567             : static constexpr Mm mm1 = Mm(1);
     568             : static constexpr Mm mm2 = Mm(2);
     569             : static constexpr Mm mm3 = Mm(3);
     570             : static constexpr Mm mm4 = Mm(4);
     571             : static constexpr Mm mm5 = Mm(5);
     572             : static constexpr Mm mm6 = Mm(6);
     573             : static constexpr Mm mm7 = Mm(7);
     574             : 
     575             : static constexpr KReg k0 = KReg(0);
     576             : static constexpr KReg k1 = KReg(1);
     577             : static constexpr KReg k2 = KReg(2);
     578             : static constexpr KReg k3 = KReg(3);
     579             : static constexpr KReg k4 = KReg(4);
     580             : static constexpr KReg k5 = KReg(5);
     581             : static constexpr KReg k6 = KReg(6);
     582             : static constexpr KReg k7 = KReg(7);
     583             : 
     584             : static constexpr SReg no_seg = SReg(SReg::kIdNone);
     585             : static constexpr SReg es = SReg(SReg::kIdEs);
     586             : static constexpr SReg cs = SReg(SReg::kIdCs);
     587             : static constexpr SReg ss = SReg(SReg::kIdSs);
     588             : static constexpr SReg ds = SReg(SReg::kIdDs);
     589             : static constexpr SReg fs = SReg(SReg::kIdFs);
     590             : static constexpr SReg gs = SReg(SReg::kIdGs);
     591             : 
     592             : static constexpr CReg cr0 = CReg(0);
     593             : static constexpr CReg cr1 = CReg(1);
     594             : static constexpr CReg cr2 = CReg(2);
     595             : static constexpr CReg cr3 = CReg(3);
     596             : static constexpr CReg cr4 = CReg(4);
     597             : static constexpr CReg cr5 = CReg(5);
     598             : static constexpr CReg cr6 = CReg(6);
     599             : static constexpr CReg cr7 = CReg(7);
     600             : static constexpr CReg cr8 = CReg(8);
     601             : static constexpr CReg cr9 = CReg(9);
     602             : static constexpr CReg cr10 = CReg(10);
     603             : static constexpr CReg cr11 = CReg(11);
     604             : static constexpr CReg cr12 = CReg(12);
     605             : static constexpr CReg cr13 = CReg(13);
     606             : static constexpr CReg cr14 = CReg(14);
     607             : static constexpr CReg cr15 = CReg(15);
     608             : 
     609             : static constexpr DReg dr0 = DReg(0);
     610             : static constexpr DReg dr1 = DReg(1);
     611             : static constexpr DReg dr2 = DReg(2);
     612             : static constexpr DReg dr3 = DReg(3);
     613             : static constexpr DReg dr4 = DReg(4);
     614             : static constexpr DReg dr5 = DReg(5);
     615             : static constexpr DReg dr6 = DReg(6);
     616             : static constexpr DReg dr7 = DReg(7);
     617             : static constexpr DReg dr8 = DReg(8);
     618             : static constexpr DReg dr9 = DReg(9);
     619             : static constexpr DReg dr10 = DReg(10);
     620             : static constexpr DReg dr11 = DReg(11);
     621             : static constexpr DReg dr12 = DReg(12);
     622             : static constexpr DReg dr13 = DReg(13);
     623             : static constexpr DReg dr14 = DReg(14);
     624             : static constexpr DReg dr15 = DReg(15);
     625             : 
     626             : static constexpr St st0 = St(0);
     627             : static constexpr St st1 = St(1);
     628             : static constexpr St st2 = St(2);
     629             : static constexpr St st3 = St(3);
     630             : static constexpr St st4 = St(4);
     631             : static constexpr St st5 = St(5);
     632             : static constexpr St st6 = St(6);
     633             : static constexpr St st7 = St(7);
     634             : 
     635             : static constexpr Bnd bnd0 = Bnd(0);
     636             : static constexpr Bnd bnd1 = Bnd(1);
     637             : static constexpr Bnd bnd2 = Bnd(2);
     638             : static constexpr Bnd bnd3 = Bnd(3);
     639             : 
     640             : static constexpr Tmm tmm0 = Tmm(0);
     641             : static constexpr Tmm tmm1 = Tmm(1);
     642             : static constexpr Tmm tmm2 = Tmm(2);
     643             : static constexpr Tmm tmm3 = Tmm(3);
     644             : static constexpr Tmm tmm4 = Tmm(4);
     645             : static constexpr Tmm tmm5 = Tmm(5);
     646             : static constexpr Tmm tmm6 = Tmm(6);
     647             : static constexpr Tmm tmm7 = Tmm(7);
     648             : 
     649             : static constexpr Rip rip = Rip(0);
     650             : 
     651             : #ifndef _DOXYGEN
     652             : } // {regs}
     653             : 
     654             : // Make `x86::regs` accessible through `x86` namespace as well.
     655             : using namespace regs;
     656             : #endif
     657             : 
     658             : //! Memory operand specific to X86 and X86_64 architecture.
     659             : class Mem : public BaseMem {
     660             : public:
     661             :   //! \name Constants
     662             :   //! \{
     663             : 
     664             :   //! Additional bits of operand's signature used by `x86::Mem`.
     665             :   enum AdditionalBits : uint32_t {
     666             :     // Memory address type (2 bits).
     667             :     // |........|........|XX......|........|
     668             :     kSignatureMemAddrTypeShift = 14,
     669             :     kSignatureMemAddrTypeMask = 0x03u << kSignatureMemAddrTypeShift,
     670             : 
     671             :     // Memory shift amount (2 bits).
     672             :     // |........|......XX|........|........|
     673             :     kSignatureMemShiftValueShift = 16,
     674             :     kSignatureMemShiftValueMask = 0x03u << kSignatureMemShiftValueShift,
     675             : 
     676             :     // Memory segment reg (3 bits).
     677             :     // |........|...XXX..|........|........|
     678             :     kSignatureMemSegmentShift = 18,
     679             :     kSignatureMemSegmentMask = 0x07u << kSignatureMemSegmentShift,
     680             : 
     681             :     // Memory broadcast type (3 bits).
     682             :     // |........|XXX.....|........|........|
     683             :     kSignatureMemBroadcastShift = 21,
     684             :     kSignatureMemBroadcastMask = 0x7u << kSignatureMemBroadcastShift
     685             :   };
     686             : 
     687             :   //! Address type.
     688             :   enum class AddrType : uint32_t {
     689             :     //! Default address type, Assembler will select the best type when necessary.
     690             :     kDefault = 0,
     691             :     //! Absolute address type.
     692             :     kAbs = 1,
     693             :     //! Relative address type.
     694             :     kRel = 2,
     695             : 
     696             :     //! Maximum value of `AddrType`.
     697             :     kMaxValue = kRel
     698             :   };
     699             : 
     700             :   //! Memory broadcast type.
     701             :   enum class Broadcast : uint32_t {
     702             :     //! No broadcast (regular memory operand).
     703             :     kNone = 0,
     704             :     //! Broadcast {1to2}.
     705             :     k1To2 = 1,
     706             :     //! Broadcast {1to4}.
     707             :     k1To4 = 2,
     708             :     //! Broadcast {1to8}.
     709             :     k1To8 = 3,
     710             :     //! Broadcast {1to16}.
     711             :     k1To16 = 4,
     712             :     //! Broadcast {1to32}.
     713             :     k1To32 = 5,
     714             :     //! Broadcast {1to64}.
     715             :     k1To64 = 6,
     716             : 
     717             :     //! Maximum value of `Broadcast`.
     718             :     kMaxValue = k1To64
     719             :   };
     720             : 
     721             :   //! \}
     722             : 
     723             :   //! \name Construction & Destruction
     724             :   //! \{
     725             : 
     726             :   //! Creates a default `Mem` operand that points to [0].
     727             :   inline constexpr Mem() noexcept
     728             :     : BaseMem() {}
     729             : 
     730             :   inline constexpr Mem(const Mem& other) noexcept
     731             :     : BaseMem(other) {}
     732             : 
     733             :   inline explicit Mem(Globals::NoInit_) noexcept
     734             :     : BaseMem(Globals::NoInit) {}
     735             : 
     736             :   inline constexpr Mem(const Signature& signature, uint32_t baseId, uint32_t indexId, int32_t offset) noexcept
     737             :     : BaseMem(signature, baseId, indexId, offset) {}
     738             : 
     739             :   inline constexpr Mem(const Label& base, int32_t off, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
     740             :     : BaseMem(Signature::fromOpType(OperandType::kMem) |
     741             :               Signature::fromMemBaseType(RegType::kLabelTag) |
     742             :               Signature::fromSize(size) |
     743             :               signature, base.id(), 0, off) {}
     744             : 
     745             :   inline constexpr Mem(const Label& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
     746             :     : BaseMem(Signature::fromOpType(OperandType::kMem) |
     747             :               Signature::fromMemBaseType(RegType::kLabelTag) |
     748             :               Signature::fromMemIndexType(index.type()) |
     749             :               Signature::fromValue<kSignatureMemShiftValueMask>(shift) |
     750             :               Signature::fromSize(size) |
     751             :               signature, base.id(), index.id(), off) {}
     752             : 
     753             :   inline constexpr Mem(const BaseReg& base, int32_t off, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
     754             :     : BaseMem(Signature::fromOpType(OperandType::kMem) |
     755             :               Signature::fromMemBaseType(base.type()) |
     756             :               Signature::fromSize(size) |
     757             :               signature, base.id(), 0, off) {}
     758             : 
     759             :   inline constexpr Mem(const BaseReg& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
     760             :     : BaseMem(Signature::fromOpType(OperandType::kMem) |
     761             :               Signature::fromMemBaseType(base.type()) |
     762             :               Signature::fromMemIndexType(index.type()) |
     763             :               Signature::fromValue<kSignatureMemShiftValueMask>(shift) |
     764             :               Signature::fromSize(size) |
     765             :               signature, base.id(), index.id(), off) {}
     766             : 
     767             :   inline constexpr explicit Mem(uint64_t base, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
     768             :     : BaseMem(Signature::fromOpType(OperandType::kMem) |
     769             :               Signature::fromSize(size) |
     770             :               signature, uint32_t(base >> 32), 0, int32_t(uint32_t(base & 0xFFFFFFFFu))) {}
     771             : 
     772             :   inline constexpr Mem(uint64_t base, const BaseReg& index, uint32_t shift = 0, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
     773             :     : BaseMem(Signature::fromOpType(OperandType::kMem) |
     774             :               Signature::fromMemIndexType(index.type()) |
     775             :               Signature::fromValue<kSignatureMemShiftValueMask>(shift) |
     776             :               Signature::fromSize(size) |
     777             :               signature, uint32_t(base >> 32), index.id(), int32_t(uint32_t(base & 0xFFFFFFFFu))) {}
     778             : 
     779             :   //! \}
     780             : 
     781             :   //! \name Overloaded Operators
     782             :   //! \{
     783             : 
     784             :   inline Mem& operator=(const Mem& other) noexcept = default;
     785             : 
     786             :   //! \}
     787             : 
     788             :   //! \name Clone
     789             :   //! \{
     790             : 
     791             :   //! Clones the memory operand.
     792             :   inline constexpr Mem clone() const noexcept { return Mem(*this); }
     793             : 
     794             :   //! Creates a new copy of this memory operand adjusted by `off`.
     795             :   inline Mem cloneAdjusted(int64_t off) const noexcept {
     796             :     Mem result(*this);
     797             :     result.addOffset(off);
     798             :     return result;
     799             :   }
     800             : 
     801             :   inline constexpr Mem cloneBroadcasted(Broadcast b) const noexcept {
     802             :     return Mem((_signature & ~Signature{kSignatureMemBroadcastMask}) | Signature::fromValue<kSignatureMemBroadcastMask>(b), _baseId, _data[0], int32_t(_data[1]));
     803             :   }
     804             : 
     805             :   //! \}
     806             : 
     807             :   //! \name Base & Index
     808             :   //! \{
     809             : 
     810             :   //! Converts memory `baseType` and `baseId` to `x86::Reg` instance.
     811             :   //!
     812             :   //! The memory must have a valid base register otherwise the result will be wrong.
     813             :   inline Reg baseReg() const noexcept { return Reg::fromTypeAndId(baseType(), baseId()); }
     814             : 
     815             :   //! Converts memory `indexType` and `indexId` to `x86::Reg` instance.
     816             :   //!
     817             :   //! The memory must have a valid index register otherwise the result will be wrong.
     818             :   inline Reg indexReg() const noexcept { return Reg::fromTypeAndId(indexType(), indexId()); }
     819             : 
     820             :   using BaseMem::setIndex;
     821             : 
     822             :   inline void setIndex(const BaseReg& index, uint32_t shift) noexcept {
     823             :     setIndex(index);
     824             :     setShift(shift);
     825             :   }
     826             : 
     827             :   //! \}
     828             : 
     829             :   //! \name Address Type
     830             :   //! \{
     831             : 
     832             :   //! Returns the address type of the memory operand.
     833             :   //!
     834             :   //! By default, address type of newly created memory operands is always \ref AddrType::kDefault.
     835             :   inline constexpr AddrType addrType() const noexcept { return (AddrType)_signature.getField<kSignatureMemAddrTypeMask>(); }
     836             :   //! Sets the address type to `addrType`.
     837             :   inline void setAddrType(AddrType addrType) noexcept { _signature.setField<kSignatureMemAddrTypeMask>(uint32_t(addrType)); }
     838             :   //! Resets the address type to \ref AddrType::kDefault.
     839             :   inline void resetAddrType() noexcept { _signature.setField<kSignatureMemAddrTypeMask>(uint32_t(AddrType::kDefault)); }
     840             : 
     841             :   //! Tests whether the address type is \ref AddrType::kAbs.
     842             :   inline constexpr bool isAbs() const noexcept { return addrType() == AddrType::kAbs; }
     843             :   //! Sets the address type to \ref AddrType::kAbs.
     844             :   inline void setAbs() noexcept { setAddrType(AddrType::kAbs); }
     845             : 
     846             :   //! Tests whether the address type is \ref AddrType::kRel.
     847           0 :   inline constexpr bool isRel() const noexcept { return addrType() == AddrType::kRel; }
     848             :   //! Sets the address type to \ref AddrType::kRel.
     849             :   inline void setRel() noexcept { setAddrType(AddrType::kRel); }
     850             : 
     851             :   //! \}
     852             : 
     853             :   //! \name Segment
     854             :   //! \{
     855             : 
     856             :   //! Tests whether the memory operand has a segment override.
     857             :   inline constexpr bool hasSegment() const noexcept { return _signature.hasField<kSignatureMemSegmentMask>(); }
     858             :   //! Returns the associated segment override as `SReg` operand.
     859             :   inline constexpr SReg segment() const noexcept { return SReg(segmentId()); }
     860             :   //! Returns segment override register id, see `SReg::Id`.
     861             :   inline constexpr uint32_t segmentId() const noexcept { return _signature.getField<kSignatureMemSegmentMask>(); }
     862             : 
     863             :   //! Sets the segment override to `seg`.
     864             :   inline void setSegment(const SReg& seg) noexcept { setSegment(seg.id()); }
     865             :   //! Sets the segment override to `id`.
     866             :   inline void setSegment(uint32_t rId) noexcept { _signature.setField<kSignatureMemSegmentMask>(rId); }
     867             :   //! Resets the segment override.
     868             :   inline void resetSegment() noexcept { _signature.setField<kSignatureMemSegmentMask>(0); }
     869             : 
     870             :   //! \}
     871             : 
     872             :   //! \name Shift
     873             :   //! \{
     874             : 
     875             :   //! Tests whether the memory operand has shift (aka scale) value.
     876             :   inline constexpr bool hasShift() const noexcept { return _signature.hasField<kSignatureMemShiftValueMask>(); }
     877             :   //! Returns the memory operand's shift (aka scale) value.
     878             :   inline constexpr uint32_t shift() const noexcept { return _signature.getField<kSignatureMemShiftValueMask>(); }
     879             :   //! Sets the memory operand's shift (aka scale) value.
     880             :   inline void setShift(uint32_t shift) noexcept { _signature.setField<kSignatureMemShiftValueMask>(shift); }
     881             :   //! Resets the memory operand's shift (aka scale) value to zero.
     882             :   inline void resetShift() noexcept { _signature.setField<kSignatureMemShiftValueMask>(0); }
     883             : 
     884             :   //! \}
     885             : 
     886             :   //! \name Broadcast
     887             :   //! \{
     888             : 
     889             :   //! Tests whether the memory operand has broadcast {1tox}.
     890             :   inline constexpr bool hasBroadcast() const noexcept { return _signature.hasField<kSignatureMemBroadcastMask>(); }
     891             :   //! Returns the memory operand's broadcast.
     892             :   inline constexpr Broadcast getBroadcast() const noexcept { return (Broadcast)_signature.getField<kSignatureMemBroadcastMask>(); }
     893             :   //! Sets the memory operand's broadcast.
     894             :   inline void setBroadcast(Broadcast b) noexcept { _signature.setField<kSignatureMemBroadcastMask>(uint32_t(b)); }
     895             :   //! Resets the memory operand's broadcast to none.
     896             :   inline void resetBroadcast() noexcept { _signature.setField<kSignatureMemBroadcastMask>(0); }
     897             : 
     898             :   //! Returns a new `Mem` without a broadcast (the possible broadcast is cleared).
     899             :   inline constexpr Mem _1to1() const noexcept { return cloneBroadcasted(Broadcast::kNone); }
     900             :   //! Returns a new `Mem` with {1to2} broadcast (AVX-512).
     901             :   inline constexpr Mem _1to2() const noexcept { return cloneBroadcasted(Broadcast::k1To2); }
     902             :   //! Returns a new `Mem` with {1to4} broadcast (AVX-512).
     903             :   inline constexpr Mem _1to4() const noexcept { return cloneBroadcasted(Broadcast::k1To4); }
     904             :   //! Returns a new `Mem` with {1to8} broadcast (AVX-512).
     905             :   inline constexpr Mem _1to8() const noexcept { return cloneBroadcasted(Broadcast::k1To8); }
     906             :   //! Returns a new `Mem` with {1to16} broadcast (AVX-512).
     907             :   inline constexpr Mem _1to16() const noexcept { return cloneBroadcasted(Broadcast::k1To16); }
     908             :   //! Returns a new `Mem` with {1to32} broadcast (AVX-512).
     909             :   inline constexpr Mem _1to32() const noexcept { return cloneBroadcasted(Broadcast::k1To32); }
     910             :   //! Returns a new `Mem` with {1to64} broadcast (AVX-512).
     911             :   inline constexpr Mem _1to64() const noexcept { return cloneBroadcasted(Broadcast::k1To64); }
     912             : 
     913             :   //! \}
     914             : };
     915             : 
     916             : //! Creates `[base.reg + offset]` memory operand.
     917       54984 : static inline constexpr Mem ptr(const Gp& base, int32_t offset = 0, uint32_t size = 0) noexcept {
     918       54984 :   return Mem(base, offset, size);
     919             : }
     920             : //! Creates `[base.reg + (index << shift) + offset]` memory operand (scalar index).
     921             : static inline constexpr Mem ptr(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
     922             :   return Mem(base, index, shift, offset, size);
     923             : }
     924             : //! Creates `[base.reg + (index << shift) + offset]` memory operand (vector index).
     925             : static inline constexpr Mem ptr(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
     926             :   return Mem(base, index, shift, offset, size);
     927             : }
     928             : 
     929             : //! Creates `[base + offset]` memory operand.
     930             : static inline constexpr Mem ptr(const Label& base, int32_t offset = 0, uint32_t size = 0) noexcept {
     931             :   return Mem(base, offset, size);
     932             : }
     933             : //! Creates `[base + (index << shift) + offset]` memory operand.
     934             : static inline constexpr Mem ptr(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
     935             :   return Mem(base, index, shift, offset, size);
     936             : }
     937             : //! Creates `[base + (index << shift) + offset]` memory operand.
     938             : static inline constexpr Mem ptr(const Label& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
     939             :   return Mem(base, index, shift, offset, size);
     940             : }
     941             : 
     942             : //! Creates `[rip + offset]` memory operand.
     943             : static inline constexpr Mem ptr(const Rip& rip_, int32_t offset = 0, uint32_t size = 0) noexcept {
     944             :   return Mem(rip_, offset, size);
     945             : }
     946             : 
     947             : //! Creates `[base]` absolute memory operand.
     948             : static inline constexpr Mem ptr(uint64_t base, uint32_t size = 0) noexcept {
     949             :   return Mem(base, size);
     950             : }
     951             : //! Creates `[base + (index.reg << shift)]` absolute memory operand.
     952             : static inline constexpr Mem ptr(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
     953             :   return Mem(base, index, shift, size);
     954             : }
     955             : //! Creates `[base + (index.reg << shift)]` absolute memory operand.
     956             : static inline constexpr Mem ptr(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
     957             :   return Mem(base, index, shift, size);
     958             : }
     959             : 
     960             : //! Creates `[base]` absolute memory operand (absolute).
     961             : static inline constexpr Mem ptr_abs(uint64_t base, uint32_t size = 0) noexcept {
     962             :   return Mem(base, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs));
     963             : }
     964             : //! Creates `[base + (index.reg << shift)]` absolute memory operand (absolute).
     965             : static inline constexpr Mem ptr_abs(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
     966             :   return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs));
     967             : }
     968             : //! Creates `[base + (index.reg << shift)]` absolute memory operand (absolute).
     969             : static inline constexpr Mem ptr_abs(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
     970             :   return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs));
     971             : }
     972             : 
     973             : //! Creates `[base]` relative memory operand (relative).
     974             : static inline constexpr Mem ptr_rel(uint64_t base, uint32_t size = 0) noexcept {
     975             :   return Mem(base, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel));
     976             : }
     977             : //! Creates `[base + (index.reg << shift)]` relative memory operand (relative).
     978             : static inline constexpr Mem ptr_rel(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
     979             :   return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel));
     980             : }
     981             : //! Creates `[base + (index.reg << shift)]` relative memory operand (relative).
     982             : static inline constexpr Mem ptr_rel(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
     983             :   return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel));
     984             : }
     985             : 
     986             : #define ASMJIT_MEM_PTR(FUNC, SIZE)                                                    \
     987             :   static constexpr Mem FUNC(const Gp& base, int32_t offset = 0) noexcept {            \
     988             :     return Mem(base, offset, SIZE);                                                   \
     989             :   }                                                                                   \
     990             :   static constexpr Mem FUNC(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
     991             :     return Mem(base, index, shift, offset, SIZE);                                     \
     992             :   }                                                                                   \
     993             :   static constexpr Mem FUNC(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
     994             :     return Mem(base, index, shift, offset, SIZE);                                     \
     995             :   }                                                                                   \
     996             :   static constexpr Mem FUNC(const Label& base, int32_t offset = 0) noexcept {         \
     997             :     return Mem(base, offset, SIZE);                                                   \
     998             :   }                                                                                   \
     999             :   static constexpr Mem FUNC(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
    1000             :     return Mem(base, index, shift, offset, SIZE);                                     \
    1001             :   }                                                                                   \
    1002             :   static constexpr Mem FUNC(const Rip& rip_, int32_t offset = 0) noexcept {           \
    1003             :     return Mem(rip_, offset, SIZE);                                                   \
    1004             :   }                                                                                   \
    1005             :   static constexpr Mem FUNC(uint64_t base) noexcept {                                 \
    1006             :     return Mem(base, SIZE);                                                           \
    1007             :   }                                                                                   \
    1008             :   static constexpr Mem FUNC(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
    1009             :     return Mem(base, index, shift, SIZE);                                             \
    1010             :   }                                                                                   \
    1011             :   static constexpr Mem FUNC(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
    1012             :     return Mem(base, index, shift, SIZE);                                             \
    1013             :   }                                                                                   \
    1014             :                                                                                       \
    1015             :   static constexpr Mem FUNC##_abs(uint64_t base) noexcept {                           \
    1016             :     return Mem(base, SIZE,                                                            \
    1017             :       OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs)); \
    1018             :   }                                                                                   \
    1019             :   static constexpr Mem FUNC##_abs(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
    1020             :     return Mem(base, index, shift, SIZE,                                              \
    1021             :       OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs)); \
    1022             :   }                                                                                   \
    1023             :   static constexpr Mem FUNC##_abs(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
    1024             :     return Mem(base, index, shift, SIZE,                                              \
    1025             :       OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs)); \
    1026             :   }                                                                                   \
    1027             :                                                                                       \
    1028             :   static constexpr Mem FUNC##_rel(uint64_t base) noexcept {                           \
    1029             :     return Mem(base, SIZE,                                                            \
    1030             :       OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel)); \
    1031             :   }                                                                                   \
    1032             :   static constexpr Mem FUNC##_rel(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
    1033             :     return Mem(base, index, shift, SIZE,                                              \
    1034             :       OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel)); \
    1035             :   }                                                                                   \
    1036             :   static constexpr Mem FUNC##_rel(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
    1037             :     return Mem(base, index, shift, SIZE,                                              \
    1038             :       OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel)); \
    1039             :   }
    1040             : 
    1041             : // Definition of memory operand constructors that use platform independent naming.
    1042             : ASMJIT_MEM_PTR(ptr_8, 1)
    1043             : ASMJIT_MEM_PTR(ptr_16, 2)
    1044             : ASMJIT_MEM_PTR(ptr_32, 4)
    1045             : ASMJIT_MEM_PTR(ptr_48, 6)
    1046             : ASMJIT_MEM_PTR(ptr_64, 8)
    1047             : ASMJIT_MEM_PTR(ptr_80, 10)
    1048             : ASMJIT_MEM_PTR(ptr_128, 16)
    1049             : ASMJIT_MEM_PTR(ptr_256, 32)
    1050             : ASMJIT_MEM_PTR(ptr_512, 64)
    1051             : 
    1052             : // Definition of memory operand constructors that use X86-specific convention.
    1053             : ASMJIT_MEM_PTR(byte_ptr, 1)
    1054             : ASMJIT_MEM_PTR(word_ptr, 2)
    1055             : ASMJIT_MEM_PTR(dword_ptr, 4)
    1056             : ASMJIT_MEM_PTR(fword_ptr, 6)
    1057             : ASMJIT_MEM_PTR(qword_ptr, 8)
    1058             : ASMJIT_MEM_PTR(tbyte_ptr, 10)
    1059             : ASMJIT_MEM_PTR(tword_ptr, 10)
    1060             : ASMJIT_MEM_PTR(oword_ptr, 16)
    1061             : ASMJIT_MEM_PTR(dqword_ptr, 16)
    1062             : ASMJIT_MEM_PTR(qqword_ptr, 32)
    1063             : ASMJIT_MEM_PTR(xmmword_ptr, 16)
    1064             : ASMJIT_MEM_PTR(ymmword_ptr, 32)
    1065             : ASMJIT_MEM_PTR(zmmword_ptr, 64)
    1066             : 
    1067             : #undef ASMJIT_MEM_PTR
    1068             : 
    1069             : //! \}
    1070             : 
    1071             : ASMJIT_END_SUB_NAMESPACE
    1072             : 
    1073             : //! \cond INTERNAL
    1074             : ASMJIT_BEGIN_NAMESPACE
    1075             : ASMJIT_DEFINE_TYPE_ID(x86::Gpb, TypeId::kInt8);
    1076             : ASMJIT_DEFINE_TYPE_ID(x86::Gpw, TypeId::kInt16);
    1077             : ASMJIT_DEFINE_TYPE_ID(x86::Gpd, TypeId::kInt32);
    1078             : ASMJIT_DEFINE_TYPE_ID(x86::Gpq, TypeId::kInt64);
    1079             : ASMJIT_DEFINE_TYPE_ID(x86::Mm , TypeId::kMmx64);
    1080             : ASMJIT_DEFINE_TYPE_ID(x86::Xmm, TypeId::kInt32x4);
    1081             : ASMJIT_DEFINE_TYPE_ID(x86::Ymm, TypeId::kInt32x8);
    1082             : ASMJIT_DEFINE_TYPE_ID(x86::Zmm, TypeId::kInt32x16);
    1083             : ASMJIT_END_NAMESPACE
    1084             : //! \endcond
    1085             : 
    1086             : #endif // ASMJIT_X86_X86OPERAND_H_INCLUDED
    1087             : 
    1088             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16