LCOV - code coverage report
Current view: top level - asmjit - x86instdb.h (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 6 20 30.0 %
Date: 2026-11-05 10:19:06 Functions: 0 1 0.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_X86INSTDB_H_INCLUDED
       8             : #define ASMJIT_X86_X86INSTDB_H_INCLUDED
       9             : 
      10             : #include "x86globals.h"
      11             : 
      12             : ASMJIT_BEGIN_SUB_NAMESPACE(x86)
      13             : 
      14             : //! \addtogroup asmjit_x86
      15             : //! \{
      16             : 
      17             : //! Instruction database (X86).
      18             : namespace InstDB {
      19             : 
      20             : //! Describes which operation mode is supported by an instruction.
      21             : enum class Mode : uint8_t {
      22             :   //! Invalid mode.
      23             :   kNone = 0x00u,
      24             :   //! X86 mode supported.
      25             :   kX86 = 0x01u,
      26             :   //! X64 mode supported.
      27             :   kX64 = 0x02u,
      28             :   //! Both X86 and X64 modes supported.
      29             :   kAny = 0x03u
      30             : };
      31             : ASMJIT_DEFINE_ENUM_FLAGS(Mode)
      32             : 
      33             : //! Converts architecture to operation mode, see \ref Mode.
      34           0 : static constexpr Mode modeFromArch(Arch arch) noexcept {
      35           0 :   return arch == Arch::kX86 ? Mode::kX86 :
      36           0 :          arch == Arch::kX64 ? Mode::kX64 : Mode::kNone;
      37             : }
      38             : 
      39             : //! Operand signature flags used by \ref OpSignature.
      40             : enum class OpFlags : uint64_t {
      41             :   //! No operand flags.
      42             :   kNone = 0u,
      43             : 
      44             :   kRegGpbLo        = 0x0000000000000001u, //!< Operand can be low 8-bit GPB register.
      45             :   kRegGpbHi        = 0x0000000000000002u, //!< Operand can be high 8-bit GPB register.
      46             :   kRegGpw          = 0x0000000000000004u, //!< Operand can be 16-bit GPW register.
      47             :   kRegGpd          = 0x0000000000000008u, //!< Operand can be 32-bit GPD register.
      48             :   kRegGpq          = 0x0000000000000010u, //!< Operand can be 64-bit GPQ register.
      49             :   kRegXmm          = 0x0000000000000020u, //!< Operand can be 128-bit XMM register.
      50             :   kRegYmm          = 0x0000000000000040u, //!< Operand can be 256-bit YMM register.
      51             :   kRegZmm          = 0x0000000000000080u, //!< Operand can be 512-bit ZMM register.
      52             :   kRegMm           = 0x0000000000000100u, //!< Operand can be 64-bit MM register.
      53             :   kRegKReg         = 0x0000000000000200u, //!< Operand can be 64-bit K register.
      54             :   kRegSReg         = 0x0000000000000400u, //!< Operand can be SReg (segment register).
      55             :   kRegCReg         = 0x0000000000000800u, //!< Operand can be CReg (control register).
      56             :   kRegDReg         = 0x0000000000001000u, //!< Operand can be DReg (debug register).
      57             :   kRegSt           = 0x0000000000002000u, //!< Operand can be 80-bit ST register (X87).
      58             :   kRegBnd          = 0x0000000000004000u, //!< Operand can be 128-bit BND register.
      59             :   kRegTmm          = 0x0000000000008000u, //!< Operand can be 0..8192-bit TMM register.
      60             :   kRegMask         = 0x000000000000FFFFu, //!< Mask of all possible register types.
      61             : 
      62             :   kMemUnspecified  = 0x0000000000040000u, //!< Operand can be a scalar memory pointer without size.
      63             :   kMem8            = 0x0000000000080000u, //!< Operand can be an 8-bit memory pointer.
      64             :   kMem16           = 0x0000000000100000u, //!< Operand can be a 16-bit memory pointer.
      65             :   kMem32           = 0x0000000000200000u, //!< Operand can be a 32-bit memory pointer.
      66             :   kMem48           = 0x0000000000400000u, //!< Operand can be a 48-bit memory pointer (FAR pointers only).
      67             :   kMem64           = 0x0000000000800000u, //!< Operand can be a 64-bit memory pointer.
      68             :   kMem80           = 0x0000000001000000u, //!< Operand can be an 80-bit memory pointer.
      69             :   kMem128          = 0x0000000002000000u, //!< Operand can be a 128-bit memory pointer.
      70             :   kMem256          = 0x0000000004000000u, //!< Operand can be a 256-bit memory pointer.
      71             :   kMem512          = 0x0000000008000000u, //!< Operand can be a 512-bit memory pointer.
      72             :   kMem1024         = 0x0000000010000000u, //!< Operand can be a 1024-bit memory pointer.
      73             :   kMemMask         = 0x000000001FFC0000u, //!< Mask of all possible scalar memory types.
      74             : 
      75             :   kVm32x           = 0x0000000040000000u, //!< Operand can be a vm32x (vector) pointer.
      76             :   kVm32y           = 0x0000000080000000u, //!< Operand can be a vm32y (vector) pointer.
      77             :   kVm32z           = 0x0000000100000000u, //!< Operand can be a vm32z (vector) pointer.
      78             :   kVm64x           = 0x0000000200000000u, //!< Operand can be a vm64x (vector) pointer.
      79             :   kVm64y           = 0x0000000400000000u, //!< Operand can be a vm64y (vector) pointer.
      80             :   kVm64z           = 0x0000000800000000u, //!< Operand can be a vm64z (vector) pointer.
      81             :   kVmMask          = 0x0000000FC0000000u, //!< Mask of all possible vector memory types.
      82             : 
      83             :   kImmI4           = 0x0000001000000000u, //!< Operand can be signed 4-bit immediate.
      84             :   kImmU4           = 0x0000002000000000u, //!< Operand can be unsigned 4-bit immediate.
      85             :   kImmI8           = 0x0000004000000000u, //!< Operand can be signed 8-bit immediate.
      86             :   kImmU8           = 0x0000008000000000u, //!< Operand can be unsigned 8-bit immediate.
      87             :   kImmI16          = 0x0000010000000000u, //!< Operand can be signed 16-bit immediate.
      88             :   kImmU16          = 0x0000020000000000u, //!< Operand can be unsigned 16-bit immediate.
      89             :   kImmI32          = 0x0000040000000000u, //!< Operand can be signed 32-bit immediate.
      90             :   kImmU32          = 0x0000080000000000u, //!< Operand can be unsigned 32-bit immediate.
      91             :   kImmI64          = 0x0000100000000000u, //!< Operand can be signed 64-bit immediate.
      92             :   kImmU64          = 0x0000200000000000u, //!< Operand can be unsigned 64-bit immediate.
      93             :   kImmMask         = 0x00003FF000000000u, //!< Mask of all immediate types.
      94             : 
      95             :   kRel8            = 0x0000400000000000u, //!< Operand can be relative 8-bit  displacement.
      96             :   kRel32           = 0x0000800000000000u, //!< Operand can be relative 32-bit displacement.
      97             :   kRelMask         = 0x0000C00000000000u, //!< Mask of all relative displacement types.
      98             : 
      99             :   kFlagMemBase     = 0x0001000000000000u, //!< Flag: Only memory base is allowed (no index, no offset).
     100             :   kFlagMemDs       = 0x0002000000000000u, //!< Flag: Implicit memory operand's DS segment.
     101             :   kFlagMemEs       = 0x0004000000000000u, //!< Flag: Implicit memory operand's ES segment.
     102             : 
     103             :   kFlagMib         = 0x0008000000000000u, //!< Flag: Operand is MIB (base+index) pointer.
     104             :   kFlagTMem        = 0x0010000000000000u, //!< Flag: Operand is TMEM (sib_mem), AMX memory pointer.
     105             : 
     106             :   kFlagImplicit    = 0x0080000000000000u, //!< Flag: Operand is implicit.
     107             :   kFlagMask        = 0x009F000000000000u, //!< Mask of all flags.
     108             : 
     109             :   //! Contains mask of all registers, memory operands, immediate operands, and displacement operands.
     110             :   kOpMask          = kRegMask | kMemMask | kVmMask | kImmMask | kRelMask
     111             : };
     112           0 : ASMJIT_DEFINE_ENUM_FLAGS(OpFlags)
     113             : 
     114             : //! Operand signature.
     115             : //!
     116             : //! Contains all possible operand combinations, memory size information, and a fixed register id (or `BaseReg::kIdBad`
     117             : //! if fixed id isn't required).
     118             : struct OpSignature {
     119             :   //! \name Members
     120             :   //! \{
     121             : 
     122             :   uint64_t _flags : 56;
     123             :   uint64_t _regMask : 8;
     124             : 
     125             :   //! \}
     126             : 
     127             :   //! \name Accessors
     128             :   //! \{
     129             : 
     130             :   //! Returns operand signature flags.
     131           0 :   inline OpFlags flags() const noexcept { return (OpFlags)_flags; }
     132             : 
     133             :   //! Tests whether the given `flag` is set.
     134           0 :   inline bool hasFlag(OpFlags flag) const noexcept { return (_flags & uint64_t(flag)) != 0; }
     135             : 
     136             :   //! Tests whether this signature contains at least one register operand of any type.
     137             :   inline bool hasReg() const noexcept { return hasFlag(OpFlags::kRegMask); }
     138             :   //! Tests whether this signature contains at least one scalar memory operand of any type.
     139             :   inline bool hasMem() const noexcept { return hasFlag(OpFlags::kMemMask); }
     140             :   //! Tests whether this signature contains at least one vector memory operand of any type.
     141             :   inline bool hasVm() const noexcept { return hasFlag(OpFlags::kVmMask); }
     142             :   //! Tests whether this signature contains at least one immediate operand of any type.
     143             :   inline bool hasImm() const noexcept { return hasFlag(OpFlags::kImmMask); }
     144             :   //! Tests whether this signature contains at least one relative displacement operand of any type.
     145             :   inline bool hasRel() const noexcept { return hasFlag(OpFlags::kRelMask); }
     146             : 
     147             :   //! Tests whether the operand is implicit.
     148             :   inline bool isImplicit() const noexcept { return hasFlag(OpFlags::kFlagImplicit); }
     149             : 
     150             :   //! Returns a physical register mask.
     151           0 :   inline RegMask regMask() const noexcept { return _regMask; }
     152             : 
     153             :   //! \}
     154             : };
     155             : 
     156             : ASMJIT_VARAPI const OpSignature _opSignatureTable[];
     157             : 
     158             : //! Instruction signature.
     159             : //!
     160             : //! Contains a sequence of operands' combinations and other metadata that defines a single instruction. This data is
     161             : //! used by instruction validator.
     162             : struct InstSignature {
     163             :   //! \name Members
     164             :   //! \{
     165             : 
     166             :   //! Count of operands in `opIndex` (0..6).
     167             :   uint8_t _opCount : 3;
     168             :   //! Architecture modes supported (X86 / X64).
     169             :   uint8_t _mode : 2;
     170             :   //! Number of implicit operands.
     171             :   uint8_t _implicitOpCount : 3;
     172             :   //! Reserved for future use.
     173             :   uint8_t _reserved;
     174             :   //! Indexes to `OpSignature` table.
     175             :   uint8_t _opSignatureIndexes[Globals::kMaxOpCount];
     176             : 
     177             :   //! \}
     178             : 
     179             :   //! \name Accessors
     180             :   //! \{
     181             : 
     182             :   //! Returns instruction operation mode.
     183             :   inline Mode mode() const noexcept { return (Mode)_mode; }
     184             :   //! Tests whether the instruction supports the given operating mode.
     185           0 :   inline bool supportsMode(Mode mode) const noexcept { return (uint8_t(_mode) & uint8_t(mode)) != 0; }
     186             : 
     187             :   //! Returns the number of operands of this signature.
     188           0 :   inline uint32_t opCount() const noexcept { return _opCount; }
     189             :   //! Returns the number of implicit operands this signature has.
     190           0 :   inline uint32_t implicitOpCount() const noexcept { return _implicitOpCount; }
     191             :   //! Tests whether this instruction signature has at least one implicit operand.
     192             :   inline bool hasImplicitOperands() const noexcept { return _implicitOpCount != 0; }
     193             : 
     194             :   //! Returns indexes to \ref _opSignatureTable for each operand of the instruction.
     195             :   //!
     196             :   //! \note The returned array always provides indexes for all operands (see \ref Globals::kMaxOpCount) even if the
     197             :   //! instruction provides less operands. Undefined operands have always index of zero.
     198             :   inline const uint8_t* opSignatureIndexes() const noexcept { return _opSignatureIndexes; }
     199             : 
     200             :   //! Returns index to \ref _opSignatureTable, corresponding to the requested operand `index` of the instruction.
     201             :   inline uint8_t opSignatureIndex(size_t index) const noexcept {
     202             :     ASMJIT_ASSERT(index < Globals::kMaxOpCount);
     203           0 :     return _opSignatureIndexes[index];
     204             :   }
     205             : 
     206             :   //! Returns \ref OpSignature corresponding to the requested operand `index` of the instruction.
     207             :   inline const OpSignature& opSignature(size_t index) const noexcept {
     208             :     ASMJIT_ASSERT(index < Globals::kMaxOpCount);
     209           0 :     return _opSignatureTable[_opSignatureIndexes[index]];
     210             :   }
     211             : 
     212             :   //! \}
     213             : };
     214             : 
     215             : ASMJIT_VARAPI const InstSignature _instSignatureTable[];
     216             : 
     217             : //! Instruction flags.
     218             : //!
     219             : //! Details about instruction encoding, operation, features, and some limitations.
     220             : enum class InstFlags : uint32_t {
     221             :   //! No flags.
     222             :   kNone = 0x00000000u,
     223             : 
     224             :   // Instruction Family
     225             :   // ------------------
     226             :   //
     227             :   // Instruction family information.
     228             : 
     229             :   //! Instruction that accesses FPU registers.
     230             :   kFpu = 0x00000100u,
     231             :   //! Instruction that accesses MMX registers (including 3DNOW and GEODE) and EMMS.
     232             :   kMmx = 0x00000200u,
     233             :   //! Instruction that accesses XMM registers (SSE, AVX, AVX512).
     234             :   kVec = 0x00000400u,
     235             : 
     236             :   // FPU Flags
     237             :   // ---------
     238             :   //
     239             :   // Used to tell the encoder which memory operand sizes are encodable.
     240             : 
     241             :   //! FPU instruction can address `word_ptr` (shared with M80).
     242             :   kFpuM16 = 0x00000800u,
     243             :   //! FPU instruction can address `dword_ptr`.
     244             :   kFpuM32 = 0x00001000u,
     245             :   //! FPU instruction can address `qword_ptr`.
     246             :   kFpuM64 = 0x00002000u,
     247             :   //! FPU instruction can address `tword_ptr` (shared with M16).
     248             :   kFpuM80 = 0x00000800u,
     249             : 
     250             :   // Prefixes and Encoding Flags
     251             :   // ---------------------------
     252             :   //
     253             :   // These describe optional X86 prefixes that can be used to change the instruction's operation.
     254             : 
     255             :   //! Instruction can be prefixed with using the REP(REPE) or REPNE prefix.
     256             :   kRep = 0x00004000u,
     257             :   //! Rep prefix is accepted, but it has no effect other than being emitted with the instruction (as an extra byte).
     258             :   kRepIgnored = 0x00008000u,
     259             :   //! Instruction can be prefixed with using the LOCK prefix.
     260             :   kLock = 0x00010000u,
     261             :   //! Instruction can be prefixed with using the XACQUIRE prefix.
     262             :   kXAcquire = 0x00020000u,
     263             :   //! Instruction can be prefixed with using the XRELEASE prefix.
     264             :   kXRelease = 0x00040000u,
     265             :   //! Instruction uses MIB (BNDLDX|BNDSTX) to encode two registers.
     266             :   kMib = 0x00080000u,
     267             :   //! Instruction uses VSIB instead of legacy SIB.
     268             :   kVsib = 0x00100000u,
     269             :   //! Instruction uses TSIB (or SIB_MEM) encoding (MODRM followed by SIB).
     270             :   kTsib = 0x00200000u,
     271             : 
     272             :   // If both `kPrefixVex` and `kPrefixEvex` flags are specified it means that the instructions can be encoded
     273             :   // by either VEX or EVEX prefix. In that case AsmJit checks global options and also instruction options to decide
     274             :   // whether to emit VEX or EVEX prefix.
     275             : 
     276             :   //! Instruction can be encoded by VEX|XOP (AVX|AVX2|BMI|XOP|...).
     277             :   kVex = 0x00400000u,
     278             :   //! Instruction can be encoded by EVEX (AVX512).
     279             :   kEvex = 0x00800000u,
     280             :   //! EVEX encoding is preferred over VEX encoding (AVX515_VNNI vs AVX_VNNI).
     281             :   kPreferEvex = 0x01000000u,
     282             :   //! EVEX and VEX signatures are compatible.
     283             :   kEvexCompat = 0x02000000u,
     284             :   //! EVEX instruction requires K register in the first operand (compare instructions).
     285             :   kEvexKReg = 0x04000000u,
     286             :   //! EVEX instruction requires two operands and K register as a selector (gather instructions).
     287             :   kEvexTwoOp = 0x08000000u,
     288             :   //! VEX instruction that can be transformed to a compatible EVEX instruction.
     289             :   kEvexTransformable = 0x10000000u,
     290             : 
     291             :   // Other Flags
     292             :   // -----------
     293             : 
     294             :   //! Instruction uses consecutive registers.
     295             :   //!
     296             :   //! Used by V4FMADDPS, V4FMADDSS, V4FNMADDPS, V4FNMADDSS, VP4DPWSSD, VP4DPWSSDS, VP2INTERSECTD, and VP2INTERSECTQ
     297             :   //! instructions
     298             :   kConsecutiveRegs = 0x20000000u
     299             : };
     300      142085 : ASMJIT_DEFINE_ENUM_FLAGS(InstFlags)
     301             : 
     302             : //! AVX-512 flags.
     303             : enum class Avx512Flags : uint32_t {
     304             :   //! No AVX-512 flags.
     305             :   kNone = 0,
     306             : 
     307             :   //! Internally used in tables, has no meaning.
     308             :   k_ = 0x00000000u,
     309             :   //! Supports masking {k1..k7}.
     310             :   kK = 0x00000001u,
     311             :   //! Supports zeroing {z}, must be used together with `kAvx512k`.
     312             :   kZ = 0x00000002u,
     313             :   //! Supports 'embedded-rounding' {er} with implicit {sae},
     314             :   kER = 0x00000004u,
     315             :   //! Supports 'suppress-all-exceptions' {sae}.
     316             :   kSAE = 0x00000008u,
     317             :   //! Supports 16-bit broadcast 'b16'.
     318             :   kB16 = 0x00000010u,
     319             :   //! Supports 32-bit broadcast 'b32'.
     320             :   kB32 = 0x00000020u,
     321             :   //! Supports 64-bit broadcast 'b64'.
     322             :   kB64 = 0x00000040u,
     323             :   //! Operates on a vector of consecutive registers (AVX512_4FMAPS and AVX512_4VNNIW).
     324             :   kT4X = 0x00000080u,
     325             : 
     326             :   //! Implicit zeroing if {k} masking is used. Using {z} is not valid in this case as it's implicit.
     327             :   kImplicitZ = 0x00000100,
     328             : };
     329             : ASMJIT_DEFINE_ENUM_FLAGS(Avx512Flags)
     330             : 
     331             : //! Instruction common information.
     332             : //!
     333             : //! Aggregated information shared across one or more instruction.
     334             : struct CommonInfo {
     335             :   //! Instruction flags.
     336             :   uint32_t _flags;
     337             :   //! Reserved for future use.
     338             :   uint32_t _avx512Flags : 11;
     339             :   //! First `InstSignature` entry in the database.
     340             :   uint32_t _iSignatureIndex : 11;
     341             :   //! Number of relevant `ISignature` entries.
     342             :   uint32_t _iSignatureCount : 5;
     343             :   //! Instruction control flow category, see \ref InstControlFlow.
     344             :   uint32_t _controlFlow : 3;
     345             :   //! Specifies what happens if all source operands share the same register.
     346             :   uint32_t _sameRegHint : 2;
     347             : 
     348             :   //! \name Accessors
     349             :   //! \{
     350             : 
     351             :   //! Returns instruction flags.
     352      142085 :   inline InstFlags flags() const noexcept { return (InstFlags)_flags; }
     353             :   //! Tests whether the instruction has a `flag`.
     354      703063 :   inline bool hasFlag(InstFlags flag) const noexcept { return Support::test(_flags, flag); }
     355             : 
     356             :   //! Returns instruction AVX-512 flags.
     357             :   inline Avx512Flags avx512Flags() const noexcept { return (Avx512Flags)_avx512Flags; }
     358             :   //! Tests whether the instruction has an AVX-512 `flag`.
     359           0 :   inline bool hasAvx512Flag(Avx512Flags flag) const noexcept { return Support::test(_avx512Flags, flag); }
     360             : 
     361             :   //! Tests whether the instruction is FPU instruction.
     362             :   inline bool isFpu() const noexcept { return hasFlag(InstFlags::kFpu); }
     363             :   //! Tests whether the instruction is MMX/3DNOW instruction that accesses MMX registers (includes EMMS and FEMMS).
     364             :   inline bool isMmx() const noexcept { return hasFlag(InstFlags::kMmx); }
     365             :   //! Tests whether the instruction is SSE|AVX|AVX512 instruction that accesses XMM|YMM|ZMM registers.
     366             :   inline bool isVec() const noexcept { return hasFlag(InstFlags::kVec); }
     367             :   //! Tests whether the instruction is SSE+ (SSE4.2, AES, SHA included) instruction that accesses XMM registers.
     368             :   inline bool isSse() const noexcept { return (flags() & (InstFlags::kVec | InstFlags::kVex | InstFlags::kEvex)) == InstFlags::kVec; }
     369             :   //! Tests whether the instruction is AVX+ (FMA included) instruction that accesses XMM|YMM|ZMM registers.
     370             :   inline bool isAvx() const noexcept { return isVec() && isVexOrEvex(); }
     371             : 
     372             :   //! Tests whether the instruction can be prefixed with LOCK prefix.
     373             :   inline bool hasLockPrefix() const noexcept { return hasFlag(InstFlags::kLock); }
     374             :   //! Tests whether the instruction can be prefixed with REP (REPE|REPZ) prefix.
     375             :   inline bool hasRepPrefix() const noexcept { return hasFlag(InstFlags::kRep); }
     376             :   //! Tests whether the instruction can be prefixed with XACQUIRE prefix.
     377             :   inline bool hasXAcquirePrefix() const noexcept { return hasFlag(InstFlags::kXAcquire); }
     378             :   //! Tests whether the instruction can be prefixed with XRELEASE prefix.
     379             :   inline bool hasXReleasePrefix() const noexcept { return hasFlag(InstFlags::kXRelease); }
     380             : 
     381             :   //! Tests whether the rep prefix is supported by the instruction, but ignored (has no effect).
     382             :   inline bool isRepIgnored() const noexcept { return hasFlag(InstFlags::kRepIgnored); }
     383             :   //! Tests whether the instruction uses MIB.
     384             :   inline bool isMibOp() const noexcept { return hasFlag(InstFlags::kMib); }
     385             :   //! Tests whether the instruction uses VSIB.
     386             :   inline bool isVsibOp() const noexcept { return hasFlag(InstFlags::kVsib); }
     387             :   //! Tests whether the instruction uses TSIB (AMX, instruction requires MOD+SIB).
     388             :   inline bool isTsibOp() const noexcept { return hasFlag(InstFlags::kTsib); }
     389             :   //! Tests whether the instruction uses VEX (can be set together with EVEX if both are encodable).
     390             :   inline bool isVex() const noexcept { return hasFlag(InstFlags::kVex); }
     391             :   //! Tests whether the instruction uses EVEX (can be set together with VEX if both are encodable).
     392             :   inline bool isEvex() const noexcept { return hasFlag(InstFlags::kEvex); }
     393             :   //! Tests whether the instruction uses EVEX (can be set together with VEX if both are encodable).
     394             :   inline bool isVexOrEvex() const noexcept { return hasFlag(InstFlags::kVex | InstFlags::kEvex); }
     395             : 
     396             :   //! Tests whether the instruction should prefer EVEX prefix instead of VEX prefix.
     397             :   inline bool preferEvex() const noexcept { return hasFlag(InstFlags::kPreferEvex); }
     398             : 
     399             :   inline bool isEvexCompatible() const noexcept { return hasFlag(InstFlags::kEvexCompat); }
     400             :   inline bool isEvexKRegOnly() const noexcept { return hasFlag(InstFlags::kEvexKReg); }
     401             :   inline bool isEvexTwoOpOnly() const noexcept { return hasFlag(InstFlags::kEvexTwoOp); }
     402             :   inline bool isEvexTransformable() const noexcept { return hasFlag(InstFlags::kEvexTransformable); }
     403             : 
     404             :   //! Tests whether the instruction supports AVX512 masking {k}.
     405             :   inline bool hasAvx512K() const noexcept { return hasAvx512Flag(Avx512Flags::kK); }
     406             :   //! Tests whether the instruction supports AVX512 zeroing {k}{z}.
     407             :   inline bool hasAvx512Z() const noexcept { return hasAvx512Flag(Avx512Flags::kZ); }
     408             :   //! Tests whether the instruction supports AVX512 embedded-rounding {er}.
     409             :   inline bool hasAvx512ER() const noexcept { return hasAvx512Flag(Avx512Flags::kER); }
     410             :   //! Tests whether the instruction supports AVX512 suppress-all-exceptions {sae}.
     411             :   inline bool hasAvx512SAE() const noexcept { return hasAvx512Flag(Avx512Flags::kSAE); }
     412             :   //! Tests whether the instruction supports AVX512 broadcast (either 32-bit or 64-bit).
     413             :   inline bool hasAvx512B() const noexcept { return hasAvx512Flag(Avx512Flags::kB16 | Avx512Flags::kB32 | Avx512Flags::kB64); }
     414             :   //! Tests whether the instruction supports AVX512 broadcast (16-bit).
     415             :   inline bool hasAvx512B16() const noexcept { return hasAvx512Flag(Avx512Flags::kB16); }
     416             :   //! Tests whether the instruction supports AVX512 broadcast (32-bit).
     417             :   inline bool hasAvx512B32() const noexcept { return hasAvx512Flag(Avx512Flags::kB32); }
     418             :   //! Tests whether the instruction supports AVX512 broadcast (64-bit).
     419             :   inline bool hasAvx512B64() const noexcept { return hasAvx512Flag(Avx512Flags::kB64); }
     420             : 
     421             :   // Returns the size of the broadcast - either 2, 4, or 8, or 0 if broadcast is not supported.
     422             :   inline uint32_t broadcastSize() const noexcept {
     423             :     constexpr uint32_t kShift = Support::ConstCTZ<uint32_t(Avx512Flags::kB16)>::value;
     424           0 :     return (uint32_t(_avx512Flags) & uint32_t(Avx512Flags::kB16 | Avx512Flags::kB32 | Avx512Flags::kB64)) >> (kShift - 1);
     425             :   }
     426             : 
     427             :   inline uint32_t signatureIndex() const noexcept { return _iSignatureIndex; }
     428             :   inline uint32_t signatureCount() const noexcept { return _iSignatureCount; }
     429             : 
     430             :   inline const InstSignature* signatureData() const noexcept { return _instSignatureTable + _iSignatureIndex; }
     431             :   inline const InstSignature* signatureEnd() const noexcept { return _instSignatureTable + _iSignatureIndex + _iSignatureCount; }
     432             : 
     433             :   //! Returns a control flow category of the instruction.
     434      304316 :   inline InstControlFlow controlFlow() const noexcept { return (InstControlFlow)_controlFlow; }
     435             : 
     436             :   //! Returns a hint that can be used when both inputs are the same register.
     437       28169 :   inline InstSameRegHint sameRegHint() const noexcept { return (InstSameRegHint)_sameRegHint; }
     438             : 
     439             :   //! \}
     440             : };
     441             : 
     442             : ASMJIT_VARAPI const CommonInfo _commonInfoTable[];
     443             : 
     444             : //! Instruction information.
     445             : struct InstInfo {
     446             :   //! Index to \ref _nameData.
     447             :   uint32_t _nameDataIndex : 14;
     448             :   //! Index to \ref _commonInfoTable.
     449             :   uint32_t _commonInfoIndex : 10;
     450             :   //! Index to \ref _additionalInfoTable.
     451             :   uint32_t _additionalInfoIndex : 8;
     452             : 
     453             :   //! Instruction encoding (internal encoding identifier used by \ref Assembler).
     454             :   uint8_t _encoding;
     455             :   //! Main opcode value (0..255).
     456             :   uint8_t _mainOpcodeValue;
     457             :   //! Index to \ref _mainOpcodeTable` that is combined with \ref _mainOpcodeValue to form the final opcode.
     458             :   uint8_t _mainOpcodeIndex;
     459             :   //! Index to \ref _altOpcodeTable that contains a full alternative opcode.
     460             :   uint8_t _altOpcodeIndex;
     461             : 
     462             :   //! \name Accessors
     463             :   //! \{
     464             : 
     465             :   //! Returns common information, see \ref CommonInfo.
     466     1056302 :   inline const CommonInfo& commonInfo() const noexcept { return _commonInfoTable[_commonInfoIndex]; }
     467             : 
     468             :   //! Returns instruction flags, see \ref Flags.
     469             :   inline InstFlags flags() const noexcept { return commonInfo().flags(); }
     470             :   //! Tests whether the instruction has flag `flag`, see \ref Flags.
     471             :   inline bool hasFlag(InstFlags flag) const noexcept { return commonInfo().hasFlag(flag); }
     472             : 
     473             :   //! Returns instruction AVX-512 flags, see \ref Avx512Flags.
     474             :   inline Avx512Flags avx512Flags() const noexcept { return commonInfo().avx512Flags(); }
     475             :   //! Tests whether the instruction has an AVX-512 `flag`, see \ref Avx512Flags.
     476             :   inline bool hasAvx512Flag(Avx512Flags flag) const noexcept { return commonInfo().hasAvx512Flag(flag); }
     477             : 
     478             :   //! Tests whether the instruction is FPU instruction.
     479             :   inline bool isFpu() const noexcept { return commonInfo().isFpu(); }
     480             :   //! Tests whether the instruction is MMX/3DNOW instruction that accesses MMX registers (includes EMMS and FEMMS).
     481             :   inline bool isMmx() const noexcept { return commonInfo().isMmx(); }
     482             :   //! Tests whether the instruction is SSE|AVX|AVX512 instruction that accesses XMM|YMM|ZMM registers.
     483             :   inline bool isVec() const noexcept { return commonInfo().isVec(); }
     484             :   //! Tests whether the instruction is SSE+ (SSE4.2, AES, SHA included) instruction that accesses XMM registers.
     485             :   inline bool isSse() const noexcept { return commonInfo().isSse(); }
     486             :   //! Tests whether the instruction is AVX+ (FMA included) instruction that accesses XMM|YMM|ZMM registers.
     487             :   inline bool isAvx() const noexcept { return commonInfo().isAvx(); }
     488             : 
     489             :   //! Tests whether the instruction can be prefixed with LOCK prefix.
     490             :   inline bool hasLockPrefix() const noexcept { return commonInfo().hasLockPrefix(); }
     491             :   //! Tests whether the instruction can be prefixed with REP (REPE|REPZ) prefix.
     492             :   inline bool hasRepPrefix() const noexcept { return commonInfo().hasRepPrefix(); }
     493             :   //! Tests whether the instruction can be prefixed with XACQUIRE prefix.
     494             :   inline bool hasXAcquirePrefix() const noexcept { return commonInfo().hasXAcquirePrefix(); }
     495             :   //! Tests whether the instruction can be prefixed with XRELEASE prefix.
     496             :   inline bool hasXReleasePrefix() const noexcept { return commonInfo().hasXReleasePrefix(); }
     497             : 
     498             :   //! Tests whether the rep prefix is supported by the instruction, but ignored (has no effect).
     499             :   inline bool isRepIgnored() const noexcept { return commonInfo().isRepIgnored(); }
     500             :   //! Tests whether the instruction uses MIB.
     501             :   inline bool isMibOp() const noexcept { return hasFlag(InstFlags::kMib); }
     502             :   //! Tests whether the instruction uses VSIB.
     503             :   inline bool isVsibOp() const noexcept { return hasFlag(InstFlags::kVsib); }
     504             :   //! Tests whether the instruction uses VEX (can be set together with EVEX if both are encodable).
     505             :   inline bool isVex() const noexcept { return hasFlag(InstFlags::kVex); }
     506             :   //! Tests whether the instruction uses EVEX (can be set together with VEX if both are encodable).
     507             :   inline bool isEvex() const noexcept { return hasFlag(InstFlags::kEvex); }
     508             :   //! Tests whether the instruction uses EVEX (can be set together with VEX if both are encodable).
     509             :   inline bool isVexOrEvex() const noexcept { return hasFlag(InstFlags::kVex | InstFlags::kEvex); }
     510             : 
     511             :   inline bool isEvexCompatible() const noexcept { return hasFlag(InstFlags::kEvexCompat); }
     512             :   inline bool isEvexKRegOnly() const noexcept { return hasFlag(InstFlags::kEvexKReg); }
     513             :   inline bool isEvexTwoOpOnly() const noexcept { return hasFlag(InstFlags::kEvexTwoOp); }
     514             :   inline bool isEvexTransformable() const noexcept { return hasFlag(InstFlags::kEvexTransformable); }
     515             : 
     516             :   //! Tests whether the instruction supports AVX512 masking {k}.
     517             :   inline bool hasAvx512K() const noexcept { return hasAvx512Flag(Avx512Flags::kK); }
     518             :   //! Tests whether the instruction supports AVX512 zeroing {k}{z}.
     519             :   inline bool hasAvx512Z() const noexcept { return hasAvx512Flag(Avx512Flags::kZ); }
     520             :   //! Tests whether the instruction supports AVX512 embedded-rounding {er}.
     521             :   inline bool hasAvx512ER() const noexcept { return hasAvx512Flag(Avx512Flags::kER); }
     522             :   //! Tests whether the instruction supports AVX512 suppress-all-exceptions {sae}.
     523             :   inline bool hasAvx512SAE() const noexcept { return hasAvx512Flag(Avx512Flags::kSAE); }
     524             :   //! Tests whether the instruction supports AVX512 broadcast (either 32-bit or 64-bit).
     525             :   inline bool hasAvx512B() const noexcept { return hasAvx512Flag(Avx512Flags::kB16 | Avx512Flags::kB32 | Avx512Flags::kB64); }
     526             :   //! Tests whether the instruction supports AVX512 broadcast (16-bit).
     527             :   inline bool hasAvx512B16() const noexcept { return hasAvx512Flag(Avx512Flags::kB16); }
     528             :   //! Tests whether the instruction supports AVX512 broadcast (32-bit).
     529             :   inline bool hasAvx512B32() const noexcept { return hasAvx512Flag(Avx512Flags::kB32); }
     530             :   //! Tests whether the instruction supports AVX512 broadcast (64-bit).
     531             :   inline bool hasAvx512B64() const noexcept { return hasAvx512Flag(Avx512Flags::kB64); }
     532             : 
     533             :   //! Returns a control flow category of the instruction.
     534             :   inline InstControlFlow controlFlow() const noexcept { return commonInfo().controlFlow(); }
     535             :   //! Returns a hint that can be used when both inputs are the same register.
     536             :   inline InstSameRegHint sameRegHint() const noexcept { return commonInfo().sameRegHint(); }
     537             : 
     538             :   inline uint32_t signatureIndex() const noexcept { return commonInfo().signatureIndex(); }
     539             :   inline uint32_t signatureCount() const noexcept { return commonInfo().signatureCount(); }
     540             : 
     541             :   inline const InstSignature* signatureData() const noexcept { return commonInfo().signatureData(); }
     542             :   inline const InstSignature* signatureEnd() const noexcept { return commonInfo().signatureEnd(); }
     543             : 
     544             :   //! \}
     545             : };
     546             : 
     547             : ASMJIT_VARAPI const InstInfo _instInfoTable[];
     548             : 
     549             : static inline const InstInfo& infoById(InstId instId) noexcept {
     550             :   ASMJIT_ASSERT(Inst::isDefinedId(instId));
     551             :   return _instInfoTable[instId];
     552             : }
     553             : 
     554             : //! \cond INTERNAL
     555             : static_assert(sizeof(OpSignature) == 8, "InstDB::OpSignature must be 8 bytes long");
     556             : //! \endcond
     557             : 
     558             : } // {InstDB}
     559             : 
     560             : //! \}
     561             : 
     562             : ASMJIT_END_SUB_NAMESPACE
     563             : 
     564             : #endif // ASMJIT_X86_X86INSTDB_H_INCLUDED
     565             : 
     566             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16