LCOV - code coverage report
Current view: top level - asmjit - cpuinfo.h (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 9 15 60.0 %
Date: 2026-11-05 10:19:06 Functions: 2 7 28.6 %

          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_CORE_CPUINFO_H_INCLUDED
       8             : #define ASMJIT_CORE_CPUINFO_H_INCLUDED
       9             : 
      10             : #include "archtraits.h"
      11             : #include "environment.h"
      12             : #include "globals.h"
      13             : #include "moved_string.h"
      14             : #include "support.h"
      15             : 
      16             : ASMJIT_BEGIN_NAMESPACE
      17             : 
      18             : //! \addtogroup asmjit_core
      19             : //! \{
      20             : 
      21             : //! CPU features information.
      22             : //!
      23             : //! Each feature is represented by a single bit in an embedded bit array.
      24             : class CpuFeatures {
      25             : public:
      26             :   //! A word that is used to represents feature bits.
      27             :   typedef Support::BitWord BitWord;
      28             :   //! Iterator that can iterate all CPU features set.
      29             :   typedef Support::BitVectorIterator<BitWord> Iterator;
      30             : 
      31             :   //! \name Constants
      32             :   //! \{
      33             : 
      34             :   //! \cond INTERNAL
      35             :   enum : uint32_t {
      36             :     kMaxFeatures = 256,
      37             :     kNumBitWords = kMaxFeatures / Support::kBitWordSizeInBits
      38             :   };
      39             :   //! \endcond
      40             : 
      41             :   //! \}
      42             : 
      43             :   //! \name Data
      44             :   //! \{
      45             : 
      46             :   //! CPU features data.
      47             :   struct Data {
      48             :     //! \name Members
      49             :     //! \{
      50             : 
      51             :     //! Data bits.
      52             :     Support::Array<BitWord, kNumBitWords> _bits;
      53             : 
      54             :     //! \}
      55             : 
      56             :     //! \name Overloaded Operators
      57             :     //! \{
      58             : 
      59             :     inline bool operator==(const Data& other) noexcept { return  eq(other); }
      60             :     inline bool operator!=(const Data& other) noexcept { return !eq(other); }
      61             : 
      62             :     //! \}
      63             : 
      64             :     //! \name Accessors
      65             :     //! \{
      66             : 
      67             :     //! Returns true if there are no features set.
      68             :     inline bool empty() const noexcept { return _bits.aggregate<Support::Or>(0) == 0; }
      69             : 
      70             :     //! Returns all features as array of bitwords (see \ref Support::BitWord).
      71             :     inline BitWord* bits() noexcept { return _bits.data(); }
      72             :     //! Returns all features as array of bitwords (const).
      73             :     inline const BitWord* bits() const noexcept { return _bits.data(); }
      74             : 
      75             :     //! Returns the number of BitWords returned by \ref bits().
      76             :     inline size_t bitWordCount() const noexcept { return kNumBitWords; }
      77             : 
      78             :     //! Returns \ref Support::BitVectorIterator, that can be used to iterate over all features efficiently.
      79             :     inline Iterator iterator() const noexcept { return Iterator(_bits.data(), kNumBitWords); }
      80             : 
      81             :     //! Tests whether the feature `featureId` is present.
      82             :     template<typename FeatureId>
      83             :     ASMJIT_FORCE_INLINE bool has(const FeatureId& featureId) const noexcept {
      84             :       ASMJIT_ASSERT(uint32_t(featureId) < kMaxFeatures);
      85             : 
      86             :       uint32_t idx = uint32_t(featureId) / Support::kBitWordSizeInBits;
      87             :       uint32_t bit = uint32_t(featureId) % Support::kBitWordSizeInBits;
      88             : 
      89       28557 :       return bool((_bits[idx] >> bit) & 0x1);
      90             :     }
      91             : 
      92             :     //! Tests whether all features as defined by `other` are present.
      93             :     ASMJIT_FORCE_INLINE bool hasAll(const Data& other) const noexcept {
      94             :       for (uint32_t i = 0; i < kNumBitWords; i++)
      95             :         if ((_bits[i] & other._bits[i]) != other._bits[i])
      96             :           return false;
      97             :       return true;
      98             :     }
      99             : 
     100             :     //! \}
     101             : 
     102             :     //! \name Manipulation
     103             :     //! \{
     104             : 
     105             :     inline void reset() noexcept { _bits.fill(0); }
     106             : 
     107             :     //! Adds the given CPU `featureId` to the list of features.
     108             :     template<typename FeatureId>
     109             :     ASMJIT_FORCE_INLINE void add(const FeatureId& featureId) noexcept {
     110             :       ASMJIT_ASSERT(uint32_t(featureId) < kMaxFeatures);
     111             : 
     112        1420 :       uint32_t idx = uint32_t(featureId) / Support::kBitWordSizeInBits;
     113           0 :       uint32_t bit = uint32_t(featureId) % Support::kBitWordSizeInBits;
     114             : 
     115        1420 :       _bits[idx] |= BitWord(1) << bit;
     116             :     }
     117             : 
     118             :     template<typename FeatureId, typename... Args>
     119             :     ASMJIT_FORCE_INLINE void add(const FeatureId& featureId, Args&&... otherFeatureIds) noexcept {
     120             :       add(featureId);
     121             :       add(std::forward<Args>(otherFeatureIds)...);
     122             :     }
     123             : 
     124             :     template<typename FeatureId>
     125             :     ASMJIT_FORCE_INLINE void addIf(bool condition, const FeatureId& featureId) noexcept {
     126             :       ASMJIT_ASSERT(uint32_t(featureId) < kMaxFeatures);
     127             : 
     128        3905 :       uint32_t idx = uint32_t(featureId) / Support::kBitWordSizeInBits;
     129             :       uint32_t bit = uint32_t(featureId) % Support::kBitWordSizeInBits;
     130             : 
     131        3905 :       _bits[idx] |= BitWord(condition) << bit;
     132             :     }
     133             : 
     134             :     template<typename FeatureId, typename... Args>
     135             :     ASMJIT_FORCE_INLINE void addIf(bool condition, const FeatureId& featureId, Args&&... otherFeatureIds) noexcept {
     136             :       addIf(condition, featureId);
     137             :       addIf(condition, std::forward<Args>(otherFeatureIds)...);
     138             :     }
     139             : 
     140             :     //! Removes the given CPU `featureId` from the list of features.
     141             :     template<typename FeatureId>
     142             :     ASMJIT_FORCE_INLINE void remove(const FeatureId& featureId) noexcept {
     143             :       ASMJIT_ASSERT(uint32_t(featureId) < kMaxFeatures);
     144             : 
     145           0 :       uint32_t idx = uint32_t(featureId) / Support::kBitWordSizeInBits;
     146           0 :       uint32_t bit = uint32_t(featureId) % Support::kBitWordSizeInBits;
     147             : 
     148           0 :       _bits[idx] &= ~(BitWord(1) << bit);
     149             :     }
     150             : 
     151             :     template<typename FeatureId, typename... Args>
     152             :     ASMJIT_FORCE_INLINE void remove(const FeatureId& featureId, Args&&... otherFeatureIds) noexcept {
     153             :       remove(featureId);
     154             :       remove(std::forward<Args>(otherFeatureIds)...);
     155             :     }
     156             : 
     157             :     //! Tests whether this CPU features data matches `other`.
     158             :     ASMJIT_FORCE_INLINE bool eq(const Data& other) const noexcept { return _bits == other._bits; }
     159             : 
     160             :     //! \}
     161             : 
     162             :   };
     163             : 
     164             :   //! X86 specific features data.
     165             :   struct X86 : public Data {
     166             :     //! X86 CPU feature identifiers.
     167             :     enum Id : uint8_t {
     168             :       // @EnumValuesBegin{"enum": "CpuFeatures::X86"}@
     169             :       kNone,                     //!< No feature (never set, used internally).
     170             : 
     171             :       kMT,                       //!< CPU has multi-threading capabilities.
     172             :       kNX,                       //!< CPU has Not-Execute-Bit aka DEP (data-execution prevention).
     173             :       k3DNOW,                    //!< CPU has 3DNOW            (3DNOW base instructions) [AMD].
     174             :       k3DNOW2,                   //!< CPU has 3DNOW2           (enhanced 3DNOW) [AMD].
     175             :       kADX,                      //!< CPU has ADX              (multi-precision add-carry instruction extensions).
     176             :       kAESNI,                    //!< CPU has AESNI            (AES encode/decode instructions).
     177             :       kALTMOVCR8,                //!< CPU has LOCK MOV R<->CR0 (supports `MOV R<->CR8` via `LOCK MOV R<->CR0` in 32-bit mode) [AMD].
     178             :       kAMX_BF16,                 //!< CPU has AMX_BF16         (advanced matrix extensions - BF16 instructions).
     179             :       kAMX_INT8,                 //!< CPU has AMX_INT8         (advanced matrix extensions - INT8 instructions).
     180             :       kAMX_TILE,                 //!< CPU has AMX_TILE         (advanced matrix extensions).
     181             :       kAVX,                      //!< CPU has AVX              (advanced vector extensions).
     182             :       kAVX2,                     //!< CPU has AVX2             (advanced vector extensions 2).
     183             :       kAVX512_4FMAPS,            //!< CPU has AVX512_FMAPS     (FMA packed single).
     184             :       kAVX512_4VNNIW,            //!< CPU has AVX512_VNNIW     (vector NN instructions word variable precision).
     185             :       kAVX512_BF16,              //!< CPU has AVX512_BF16      (BFLOAT16 support instruction).
     186             :       kAVX512_BITALG,            //!< CPU has AVX512_BITALG    (VPOPCNT[B|W], VPSHUFBITQMB).
     187             :       kAVX512_BW,                //!< CPU has AVX512_BW        (packed BYTE|WORD).
     188             :       kAVX512_CDI,               //!< CPU has AVX512_CDI       (conflict detection).
     189             :       kAVX512_DQ,                //!< CPU has AVX512_DQ        (packed DWORD|QWORD).
     190             :       kAVX512_ERI,               //!< CPU has AVX512_ERI       (exponential and reciprocal).
     191             :       kAVX512_F,                 //!< CPU has AVX512_F         (AVX512 foundation).
     192             :       kAVX512_FP16,              //!< CPU has AVX512_FP16      (FP16 extensions).
     193             :       kAVX512_IFMA,              //!< CPU has AVX512_IFMA      (integer fused-multiply-add using 52-bit precision).
     194             :       kAVX512_PFI,               //!< CPU has AVX512_PFI       (prefetch instructions).
     195             :       kAVX512_VBMI,              //!< CPU has AVX512_VBMI      (vector byte manipulation).
     196             :       kAVX512_VBMI2,             //!< CPU has AVX512_VBMI2     (vector byte manipulation 2).
     197             :       kAVX512_VL,                //!< CPU has AVX512_VL        (vector length extensions).
     198             :       kAVX512_VNNI,              //!< CPU has AVX512_VNNI      (vector neural network instructions).
     199             :       kAVX512_VP2INTERSECT,      //!< CPU has AVX512_VP2INTERSECT
     200             :       kAVX512_VPOPCNTDQ,         //!< CPU has AVX512_VPOPCNTDQ (VPOPCNT[D|Q] instructions).
     201             :       kAVX_VNNI,                 //!< CPU has AVX_VNNI         (VEX encoding of vpdpbusd/vpdpbusds/vpdpwssd/vpdpwssds).
     202             :       kBMI,                      //!< CPU has BMI              (bit manipulation instructions #1).
     203             :       kBMI2,                     //!< CPU has BMI2             (bit manipulation instructions #2).
     204             :       kCET_IBT,                  //!< CPU has CET-IBT          (indirect branch tracking).
     205             :       kCET_SS,                   //!< CPU has CET-SS.
     206             :       kCLDEMOTE,                 //!< CPU has CLDEMOTE         (cache line demote).
     207             :       kCLFLUSH,                  //!< CPU has CLFUSH           (Cache Line flush).
     208             :       kCLFLUSHOPT,               //!< CPU has CLFUSHOPT        (Cache Line flush - optimized).
     209             :       kCLWB,                     //!< CPU has CLWB.
     210             :       kCLZERO,                   //!< CPU has CLZERO.
     211             :       kCMOV,                     //!< CPU has CMOV             (CMOV and FCMOV instructions).
     212             :       kCMPXCHG16B,               //!< CPU has CMPXCHG16B       (compare-exchange 16 bytes) [X86_64].
     213             :       kCMPXCHG8B,                //!< CPU has CMPXCHG8B        (compare-exchange 8 bytes).
     214             :       kENCLV,                    //!< CPU has ENCLV.
     215             :       kENQCMD,                   //!< CPU has ENQCMD           (enqueue stores).
     216             :       kERMS,                     //!< CPU has ERMS             (enhanced REP MOVSB/STOSB).
     217             :       kF16C,                     //!< CPU has F16C.
     218             :       kFMA,                      //!< CPU has FMA              (fused-multiply-add 3 operand form).
     219             :       kFMA4,                     //!< CPU has FMA4             (fused-multiply-add 4 operand form).
     220             :       kFPU,                      //!< CPU has FPU              (FPU support).
     221             :       kFSGSBASE,                 //!< CPU has FSGSBASE.
     222             :       kFXSR,                     //!< CPU has FXSR             (FXSAVE/FXRSTOR instructions).
     223             :       kFXSROPT,                  //!< CPU has FXSROTP          (FXSAVE/FXRSTOR is optimized).
     224             :       kGEODE,                    //!< CPU has GEODE extensions (3DNOW additions).
     225             :       kGFNI,                     //!< CPU has GFNI             (Galois field instructions).
     226             :       kHLE,                      //!< CPU has HLE.
     227             :       kHRESET,                   //!< CPU has HRESET.
     228             :       kI486,                     //!< CPU has I486 features    (I486+ support).
     229             :       kLAHFSAHF,                 //!< CPU has LAHF/SAHF        (LAHF/SAHF in 64-bit mode) [X86_64].
     230             :       kLWP,                      //!< CPU has LWP              (lightweight profiling) [AMD].
     231             :       kLZCNT,                    //!< CPU has LZCNT            (LZCNT instruction).
     232             :       kMCOMMIT,                  //!< CPU has MCOMMIT          (MCOMMIT instruction).
     233             :       kMMX,                      //!< CPU has MMX              (MMX base instructions).
     234             :       kMMX2,                     //!< CPU has MMX2             (MMX extensions or MMX2).
     235             :       kMONITOR,                  //!< CPU has MONITOR          (MONITOR/MWAIT instructions).
     236             :       kMONITORX,                 //!< CPU has MONITORX         (MONITORX/MWAITX instructions).
     237             :       kMOVBE,                    //!< CPU has MOVBE            (move with byte-order swap).
     238             :       kMOVDIR64B,                //!< CPU has MOVDIR64B        (move 64 bytes as direct store).
     239             :       kMOVDIRI,                  //!< CPU has MOVDIRI          (move dword/qword as direct store).
     240             :       kMPX,                      //!< CPU has MPX              (memory protection extensions).
     241             :       kMSR,                      //!< CPU has MSR              (RDMSR/WRMSR instructions).
     242             :       kMSSE,                     //!< CPU has MSSE             (misaligned SSE support).
     243             :       kOSXSAVE,                  //!< CPU has OSXSAVE          (XSAVE enabled by OS).
     244             :       kOSPKE,                    //!< CPU has OSPKE            (PKE enabled by OS).
     245             :       kPCLMULQDQ,                //!< CPU has PCLMULQDQ        (packed carry-less multiplication).
     246             :       kPCONFIG,                  //!< CPU has PCONFIG          (PCONFIG instruction).
     247             :       kPOPCNT,                   //!< CPU has POPCNT           (POPCNT instruction).
     248             :       kPREFETCHW,                //!< CPU has PREFETCHW.
     249             :       kPREFETCHWT1,              //!< CPU has PREFETCHWT1.
     250             :       kPTWRITE,                  //!< CPU has PTWRITE.
     251             :       kRDPID,                    //!< CPU has RDPID.
     252             :       kRDPRU,                    //!< CPU has RDPRU.
     253             :       kRDRAND,                   //!< CPU has RDRAND.
     254             :       kRDSEED,                   //!< CPU has RDSEED.
     255             :       kRDTSC,                    //!< CPU has RDTSC.
     256             :       kRDTSCP,                   //!< CPU has RDTSCP.
     257             :       kRTM,                      //!< CPU has RTM.
     258             :       kSERIALIZE,                //!< CPU has SERIALIZE.
     259             :       kSHA,                      //!< CPU has SHA              (SHA-1 and SHA-256 instructions).
     260             :       kSKINIT,                   //!< CPU has SKINIT           (SKINIT/STGI instructions) [AMD].
     261             :       kSMAP,                     //!< CPU has SMAP             (supervisor-mode access prevention).
     262             :       kSMEP,                     //!< CPU has SMEP             (supervisor-mode execution prevention).
     263             :       kSMX,                      //!< CPU has SMX              (safer mode extensions).
     264             :       kSNP,                      //!< CPU has SNP.
     265             :       kSSE,                      //!< CPU has SSE.
     266             :       kSSE2,                     //!< CPU has SSE2.
     267             :       kSSE3,                     //!< CPU has SSE3.
     268             :       kSSE4_1,                   //!< CPU has SSE4.1.
     269             :       kSSE4_2,                   //!< CPU has SSE4.2.
     270             :       kSSE4A,                    //!< CPU has SSE4A [AMD].
     271             :       kSSSE3,                    //!< CPU has SSSE3.
     272             :       kSVM,                      //!< CPU has SVM              (virtualization) [AMD].
     273             :       kTBM,                      //!< CPU has TBM              (trailing bit manipulation) [AMD].
     274             :       kTSX,                      //!< CPU has TSX.
     275             :       kTSXLDTRK,                 //!< CPU has TSXLDTRK.
     276             :       kUINTR,                    //!< CPU has UINTR            (user interrupts).
     277             :       kVAES,                     //!< CPU has VAES             (vector AES 256|512 bit support).
     278             :       kVMX,                      //!< CPU has VMX              (virtualization) [INTEL].
     279             :       kVPCLMULQDQ,               //!< CPU has VPCLMULQDQ       (vector PCLMULQDQ 256|512-bit support).
     280             :       kWAITPKG,                  //!< CPU has WAITPKG          (UMONITOR, UMWAIT, TPAUSE).
     281             :       kWBNOINVD,                 //!< CPU has WBNOINVD.
     282             :       kXOP,                      //!< CPU has XOP              (XOP instructions) [AMD].
     283             :       kXSAVE,                    //!< CPU has XSAVE.
     284             :       kXSAVEC,                   //!< CPU has XSAVEC.
     285             :       kXSAVEOPT,                 //!< CPU has XSAVEOPT.
     286             :       kXSAVES,                   //!< CPU has XSAVES.
     287             :       // @EnumValuesEnd@
     288             : 
     289             :       kMaxValue = kXSAVES
     290             :     };
     291             : 
     292             :     #define ASMJIT_X86_FEATURE(FEATURE) \
     293             :       inline bool has##FEATURE() const noexcept { return has(X86::k##FEATURE); }
     294             : 
     295             :     ASMJIT_X86_FEATURE(MT)
     296             :     ASMJIT_X86_FEATURE(NX)
     297             :     ASMJIT_X86_FEATURE(3DNOW)
     298             :     ASMJIT_X86_FEATURE(3DNOW2)
     299             :     ASMJIT_X86_FEATURE(ADX)
     300             :     ASMJIT_X86_FEATURE(AESNI)
     301             :     ASMJIT_X86_FEATURE(ALTMOVCR8)
     302             :     ASMJIT_X86_FEATURE(AMX_BF16)
     303             :     ASMJIT_X86_FEATURE(AMX_INT8)
     304             :     ASMJIT_X86_FEATURE(AMX_TILE)
     305             :     ASMJIT_X86_FEATURE(AVX)
     306             :     ASMJIT_X86_FEATURE(AVX2)
     307             :     ASMJIT_X86_FEATURE(AVX512_4FMAPS)
     308             :     ASMJIT_X86_FEATURE(AVX512_4VNNIW)
     309             :     ASMJIT_X86_FEATURE(AVX512_BF16)
     310             :     ASMJIT_X86_FEATURE(AVX512_BITALG)
     311             :     ASMJIT_X86_FEATURE(AVX512_BW)
     312             :     ASMJIT_X86_FEATURE(AVX512_CDI)
     313             :     ASMJIT_X86_FEATURE(AVX512_DQ)
     314             :     ASMJIT_X86_FEATURE(AVX512_ERI)
     315             :     ASMJIT_X86_FEATURE(AVX512_F)
     316             :     ASMJIT_X86_FEATURE(AVX512_FP16)
     317             :     ASMJIT_X86_FEATURE(AVX512_IFMA)
     318             :     ASMJIT_X86_FEATURE(AVX512_PFI)
     319             :     ASMJIT_X86_FEATURE(AVX512_VBMI)
     320             :     ASMJIT_X86_FEATURE(AVX512_VBMI2)
     321             :     ASMJIT_X86_FEATURE(AVX512_VL)
     322             :     ASMJIT_X86_FEATURE(AVX512_VNNI)
     323             :     ASMJIT_X86_FEATURE(AVX512_VP2INTERSECT)
     324             :     ASMJIT_X86_FEATURE(AVX512_VPOPCNTDQ)
     325             :     ASMJIT_X86_FEATURE(AVX_VNNI)
     326             :     ASMJIT_X86_FEATURE(BMI)
     327             :     ASMJIT_X86_FEATURE(BMI2)
     328             :     ASMJIT_X86_FEATURE(CET_IBT)
     329             :     ASMJIT_X86_FEATURE(CET_SS)
     330             :     ASMJIT_X86_FEATURE(CLDEMOTE)
     331             :     ASMJIT_X86_FEATURE(CLFLUSH)
     332             :     ASMJIT_X86_FEATURE(CLFLUSHOPT)
     333             :     ASMJIT_X86_FEATURE(CLWB)
     334             :     ASMJIT_X86_FEATURE(CLZERO)
     335             :     ASMJIT_X86_FEATURE(CMOV)
     336             :     ASMJIT_X86_FEATURE(CMPXCHG16B)
     337             :     ASMJIT_X86_FEATURE(CMPXCHG8B)
     338             :     ASMJIT_X86_FEATURE(ENCLV)
     339             :     ASMJIT_X86_FEATURE(ENQCMD)
     340             :     ASMJIT_X86_FEATURE(ERMS)
     341             :     ASMJIT_X86_FEATURE(F16C)
     342             :     ASMJIT_X86_FEATURE(FMA)
     343             :     ASMJIT_X86_FEATURE(FMA4)
     344             :     ASMJIT_X86_FEATURE(FPU)
     345             :     ASMJIT_X86_FEATURE(FSGSBASE)
     346             :     ASMJIT_X86_FEATURE(FXSR)
     347             :     ASMJIT_X86_FEATURE(FXSROPT)
     348             :     ASMJIT_X86_FEATURE(GEODE)
     349             :     ASMJIT_X86_FEATURE(GFNI)
     350             :     ASMJIT_X86_FEATURE(HLE)
     351             :     ASMJIT_X86_FEATURE(HRESET)
     352             :     ASMJIT_X86_FEATURE(I486)
     353             :     ASMJIT_X86_FEATURE(LAHFSAHF)
     354             :     ASMJIT_X86_FEATURE(LWP)
     355             :     ASMJIT_X86_FEATURE(LZCNT)
     356             :     ASMJIT_X86_FEATURE(MCOMMIT)
     357             :     ASMJIT_X86_FEATURE(MMX)
     358             :     ASMJIT_X86_FEATURE(MMX2)
     359             :     ASMJIT_X86_FEATURE(MONITOR)
     360             :     ASMJIT_X86_FEATURE(MONITORX)
     361             :     ASMJIT_X86_FEATURE(MOVBE)
     362             :     ASMJIT_X86_FEATURE(MOVDIR64B)
     363             :     ASMJIT_X86_FEATURE(MOVDIRI)
     364             :     ASMJIT_X86_FEATURE(MPX)
     365             :     ASMJIT_X86_FEATURE(MSR)
     366             :     ASMJIT_X86_FEATURE(MSSE)
     367             :     ASMJIT_X86_FEATURE(OSXSAVE)
     368             :     ASMJIT_X86_FEATURE(OSPKE)
     369             :     ASMJIT_X86_FEATURE(PCLMULQDQ)
     370             :     ASMJIT_X86_FEATURE(PCONFIG)
     371             :     ASMJIT_X86_FEATURE(POPCNT)
     372             :     ASMJIT_X86_FEATURE(PREFETCHW)
     373             :     ASMJIT_X86_FEATURE(PREFETCHWT1)
     374             :     ASMJIT_X86_FEATURE(PTWRITE)
     375             :     ASMJIT_X86_FEATURE(RDPID)
     376             :     ASMJIT_X86_FEATURE(RDPRU)
     377             :     ASMJIT_X86_FEATURE(RDRAND)
     378             :     ASMJIT_X86_FEATURE(RDSEED)
     379             :     ASMJIT_X86_FEATURE(RDTSC)
     380             :     ASMJIT_X86_FEATURE(RDTSCP)
     381             :     ASMJIT_X86_FEATURE(RTM)
     382             :     ASMJIT_X86_FEATURE(SERIALIZE)
     383             :     ASMJIT_X86_FEATURE(SHA)
     384             :     ASMJIT_X86_FEATURE(SKINIT)
     385             :     ASMJIT_X86_FEATURE(SMAP)
     386             :     ASMJIT_X86_FEATURE(SMEP)
     387             :     ASMJIT_X86_FEATURE(SMX)
     388             :     ASMJIT_X86_FEATURE(SNP)
     389             :     ASMJIT_X86_FEATURE(SSE)
     390             :     ASMJIT_X86_FEATURE(SSE2)
     391             :     ASMJIT_X86_FEATURE(SSE3)
     392             :     ASMJIT_X86_FEATURE(SSE4_1)
     393             :     ASMJIT_X86_FEATURE(SSE4_2)
     394             :     ASMJIT_X86_FEATURE(SSE4A)
     395             :     ASMJIT_X86_FEATURE(SSSE3)
     396             :     ASMJIT_X86_FEATURE(SVM)
     397             :     ASMJIT_X86_FEATURE(TBM)
     398             :     ASMJIT_X86_FEATURE(TSX)
     399             :     ASMJIT_X86_FEATURE(TSXLDTRK)
     400             :     ASMJIT_X86_FEATURE(UINTR)
     401             :     ASMJIT_X86_FEATURE(VAES)
     402             :     ASMJIT_X86_FEATURE(VMX)
     403             :     ASMJIT_X86_FEATURE(VPCLMULQDQ)
     404             :     ASMJIT_X86_FEATURE(WAITPKG)
     405             :     ASMJIT_X86_FEATURE(WBNOINVD)
     406             :     ASMJIT_X86_FEATURE(XOP)
     407             :     ASMJIT_X86_FEATURE(XSAVE)
     408             :     ASMJIT_X86_FEATURE(XSAVEC)
     409             :     ASMJIT_X86_FEATURE(XSAVEOPT)
     410             :     ASMJIT_X86_FEATURE(XSAVES)
     411             : 
     412             :     #undef ASMJIT_X86_FEATURE
     413             :   };
     414             : 
     415             :   //! ARM specific features data.
     416             :   struct ARM : public Data {
     417             :     //! ARM CPU feature identifiers.
     418             :     enum Id : uint8_t {
     419             :       // @EnumValuesBegin{"enum": "CpuFeatures::ARM"}@
     420             :       kNone = 0,                 //!< No feature (never set, used internally).
     421             :       kTHUMB,                    //!< THUMB v1 ISA.
     422             :       kTHUMBv2,                  //!< THUMB v2 ISA.
     423             : 
     424             :       kARMv6,                    //!< ARMv6 ISA.
     425             :       kARMv7,                    //!< ARMv7 ISA.
     426             :       kARMv8a,                   //!< ARMv8-A ISA.
     427             :       kARMv8_1a,                 //!< ARMv8.1-A ISA.
     428             :       kARMv8_2a,                 //!< ARMv8.2-A ISA.
     429             :       kARMv8_3a,                 //!< ARMv8.3-A ISA.
     430             :       kARMv8_4a,                 //!< ARMv8.4-A ISA.
     431             :       kARMv8_5a,                 //!< ARMv8.5-A ISA.
     432             :       kARMv8_6a,                 //!< ARMv8.6-A ISA.
     433             :       kARMv8_7a,                 //!< ARMv8.7-A ISA.
     434             : 
     435             :       kVFPv2,                    //!< CPU has VFPv2 instruction set.
     436             :       kVFPv3,                    //!< CPU has VFPv3 instruction set.
     437             :       kVFPv4,                    //!< CPU has VFPv4 instruction set.
     438             :       kVFP_D32,                  //!< CPU has 32 VFP-D (64-bit) registers.
     439             : 
     440             :       kAES,                      //!< CPU has AES (AArch64 only).
     441             :       kALTNZCV,                  //!< CPU has ALTNZCV (AArch64 only).
     442             :       kASIMD,                    //!< CPU has Advanced SIMD (NEON on ARM/THUMB).
     443             :       kBF16,                     //!< CPU has BF16 (AArch64 only).
     444             :       kBTI,                      //!< CPU has BTI (branch target identification).
     445             :       kCPUID,                    //!< CPU has accessible CPUID register (ID_AA64ZFR0_EL1).
     446             :       kCRC32,                    //!< CPU has CRC32 .
     447             :       kDGH,                      //!< CPU has DGH (AArch64 only).
     448             :       kDIT,                      //!< CPU has data independent timing instructions (DIT).
     449             :       kDOTPROD,                  //!< CPU has DOTPROD (SDOT/UDOT).
     450             :       kEDSP,                     //!< CPU has EDSP (ARM/THUMB only).
     451             :       kFCMA,                     //!< CPU has FCMA (FCADD/FCMLA).
     452             :       kFJCVTZS,                  //!< CPU has FJCVTZS (AArch64 only).
     453             :       kFLAGM,                    //!< CPU has FLAGM (AArch64 only).
     454             :       kFP16CONV,                 //!< CPU has FP16 (half-float) conversion.
     455             :       kFP16FML,                  //!< CPU has FMLAL{2}/FMLSL{2}
     456             :       kFP16FULL,                 //!< CPU has full support for FP16.
     457             :       kFRINT,                    //!< CPU has FRINT[32|64][X|Z] (AArch64 only).
     458             :       kI8MM,                     //!< CPU has I8MM (AArch64 only).
     459             :       kIDIVA,                    //!< CPU has hardware SDIV and UDIV (ARM mode).
     460             :       kIDIVT,                    //!< CPU has hardware SDIV and UDIV (THUMB mode).
     461             :       kLSE,                      //!< CPU has large system extensions (LSE) (AArch64 only).
     462             :       kMTE,                      //!< CPU has MTE (AArch64 only).
     463             :       kRCPC_IMMO,                //!< CPU has RCPC_IMMO (AArch64 only).
     464             :       kRDM,                      //!< CPU has RDM (AArch64 only).
     465             :       kPMU,                      //!< CPU has PMU (AArch64 only).
     466             :       kPMULL,                    //!< CPU has PMULL (AArch64 only).
     467             :       kRNG,                      //!< CPU has random number generation (RNG).
     468             :       kSB,                       //!< CPU has speculative barrier SB (AArch64 only).
     469             :       kSHA1,                     //!< CPU has SHA1.
     470             :       kSHA2,                     //!< CPU has SHA2.
     471             :       kSHA3,                     //!< CPU has SHA3.
     472             :       kSHA512,                   //!< CPU has SHA512.
     473             :       kSM3,                      //!< CPU has SM3.
     474             :       kSM4,                      //!< CPU has SM4.
     475             :       kSSBS,                     //!< CPU has SSBS.
     476             :       kSVE,                      //!< CPU has SVE (AArch64 only).
     477             :       kSVE_BF16,                 //!< CPU has SVE-BF16 (AArch64 only).
     478             :       kSVE_F32MM,                //!< CPU has SVE-F32MM (AArch64 only).
     479             :       kSVE_F64MM,                //!< CPU has SVE-F64MM (AArch64 only).
     480             :       kSVE_I8MM,                 //!< CPU has SVE-I8MM (AArch64 only).
     481             :       kSVE_PMULL,                //!< CPU has SVE-PMULL (AArch64 only).
     482             :       kSVE2,                     //!< CPU has SVE2 (AArch64 only).
     483             :       kSVE2_AES,                 //!< CPU has SVE2-AES (AArch64 only).
     484             :       kSVE2_BITPERM,             //!< CPU has SVE2-BITPERM (AArch64 only).
     485             :       kSVE2_SHA3,                //!< CPU has SVE2-SHA3 (AArch64 only).
     486             :       kSVE2_SM4,                 //!< CPU has SVE2-SM4 (AArch64 only).
     487             :       kTME,                      //!< CPU has transactional memory extensions (TME).
     488             :       // @EnumValuesEnd@
     489             : 
     490             :       kMaxValue = kTME
     491             :     };
     492             : 
     493             :     #define ASMJIT_ARM_FEATURE(FEATURE) \
     494             :       inline bool has##FEATURE() const noexcept { return has(ARM::k##FEATURE); }
     495             : 
     496             :     ASMJIT_ARM_FEATURE(THUMB)
     497             :     ASMJIT_ARM_FEATURE(THUMBv2)
     498             : 
     499             :     ASMJIT_ARM_FEATURE(ARMv6)
     500             :     ASMJIT_ARM_FEATURE(ARMv7)
     501             :     ASMJIT_ARM_FEATURE(ARMv8a)
     502             :     ASMJIT_ARM_FEATURE(ARMv8_1a)
     503             :     ASMJIT_ARM_FEATURE(ARMv8_2a)
     504             :     ASMJIT_ARM_FEATURE(ARMv8_3a)
     505             :     ASMJIT_ARM_FEATURE(ARMv8_4a)
     506             :     ASMJIT_ARM_FEATURE(ARMv8_5a)
     507             :     ASMJIT_ARM_FEATURE(ARMv8_6a)
     508             :     ASMJIT_ARM_FEATURE(ARMv8_7a)
     509             : 
     510             :     ASMJIT_ARM_FEATURE(VFPv2)
     511             :     ASMJIT_ARM_FEATURE(VFPv3)
     512             :     ASMJIT_ARM_FEATURE(VFPv4)
     513             :     ASMJIT_ARM_FEATURE(VFP_D32)
     514             : 
     515             :     ASMJIT_ARM_FEATURE(AES)
     516             :     ASMJIT_ARM_FEATURE(ALTNZCV)
     517             :     ASMJIT_ARM_FEATURE(ASIMD)
     518             :     ASMJIT_ARM_FEATURE(BF16)
     519             :     ASMJIT_ARM_FEATURE(BTI)
     520             :     ASMJIT_ARM_FEATURE(CPUID)
     521             :     ASMJIT_ARM_FEATURE(CRC32)
     522             :     ASMJIT_ARM_FEATURE(DGH)
     523             :     ASMJIT_ARM_FEATURE(DIT)
     524             :     ASMJIT_ARM_FEATURE(DOTPROD)
     525             :     ASMJIT_ARM_FEATURE(EDSP)
     526             :     ASMJIT_ARM_FEATURE(FCMA)
     527             :     ASMJIT_ARM_FEATURE(FLAGM)
     528             :     ASMJIT_ARM_FEATURE(FP16CONV)
     529             :     ASMJIT_ARM_FEATURE(FP16FML)
     530             :     ASMJIT_ARM_FEATURE(FP16FULL)
     531             :     ASMJIT_ARM_FEATURE(FRINT)
     532             :     ASMJIT_ARM_FEATURE(IDIVA)
     533             :     ASMJIT_ARM_FEATURE(IDIVT)
     534             :     ASMJIT_ARM_FEATURE(LSE)
     535             :     ASMJIT_ARM_FEATURE(MTE)
     536             :     ASMJIT_ARM_FEATURE(FJCVTZS)
     537             :     ASMJIT_ARM_FEATURE(I8MM)
     538             :     ASMJIT_ARM_FEATURE(RCPC_IMMO)
     539             :     ASMJIT_ARM_FEATURE(RDM)
     540             :     ASMJIT_ARM_FEATURE(PMU)
     541             :     ASMJIT_ARM_FEATURE(PMULL)
     542             :     ASMJIT_ARM_FEATURE(RNG)
     543             :     ASMJIT_ARM_FEATURE(SB)
     544             :     ASMJIT_ARM_FEATURE(SHA1)
     545             :     ASMJIT_ARM_FEATURE(SHA2)
     546             :     ASMJIT_ARM_FEATURE(SHA3)
     547             :     ASMJIT_ARM_FEATURE(SHA512)
     548             :     ASMJIT_ARM_FEATURE(SM3)
     549             :     ASMJIT_ARM_FEATURE(SM4)
     550             :     ASMJIT_ARM_FEATURE(SSBS)
     551             :     ASMJIT_ARM_FEATURE(SVE)
     552             :     ASMJIT_ARM_FEATURE(SVE_BF16)
     553             :     ASMJIT_ARM_FEATURE(SVE_F32MM)
     554             :     ASMJIT_ARM_FEATURE(SVE_F64MM)
     555             :     ASMJIT_ARM_FEATURE(SVE_I8MM)
     556             :     ASMJIT_ARM_FEATURE(SVE_PMULL)
     557             :     ASMJIT_ARM_FEATURE(SVE2)
     558             :     ASMJIT_ARM_FEATURE(SVE2_AES)
     559             :     ASMJIT_ARM_FEATURE(SVE2_BITPERM)
     560             :     ASMJIT_ARM_FEATURE(SVE2_SHA3)
     561             :     ASMJIT_ARM_FEATURE(SVE2_SM4)
     562             :     ASMJIT_ARM_FEATURE(TME)
     563             : 
     564             :     #undef ASMJIT_ARM_FEATURE
     565             :   };
     566             : 
     567             :   static_assert(uint32_t(X86::kMaxValue) < kMaxFeatures, "The number of X86 CPU features cannot exceed CpuFeatures::kMaxFeatures");
     568             :   static_assert(uint32_t(ARM::kMaxValue) < kMaxFeatures, "The number of ARM CPU features cannot exceed CpuFeatures::kMaxFeatures");
     569             : 
     570             :   //! \}
     571             : 
     572             :   //! \name Members
     573             :   //! \{
     574             : 
     575             :   Data _data {};
     576             : 
     577             :   //! \}
     578             : 
     579             :   //! \name Construction & Destruction
     580             :   //! \{
     581             : 
     582         355 :   inline CpuFeatures() noexcept {}
     583             :   inline CpuFeatures(const CpuFeatures& other) noexcept = default;
     584             :   inline explicit CpuFeatures(Globals::NoInit_) noexcept {}
     585             : 
     586             :   //! \}
     587             : 
     588             :   //! \name Overloaded Operators
     589             :   //! \{
     590             : 
     591             :   inline CpuFeatures& operator=(const CpuFeatures& other) noexcept = default;
     592             : 
     593             :   inline bool operator==(const CpuFeatures& other) noexcept { return  eq(other); }
     594             :   inline bool operator!=(const CpuFeatures& other) noexcept { return !eq(other); }
     595             : 
     596             :   //! \}
     597             : 
     598             :   //! \name Accessors
     599             :   //! \{
     600             : 
     601             :   //! Returns true if there are no features set.
     602             :   inline bool empty() const noexcept { return _data.empty(); }
     603             : 
     604             :   //! Casts this base class into a derived type `T`.
     605             :   template<typename T = Data>
     606             :   inline T& data() noexcept { return static_cast<T&>(_data); }
     607             : 
     608             :   //! Casts this base class into a derived type `T` (const).
     609             :   template<typename T = Data>
     610             :   inline const T& data() const noexcept { return static_cast<const T&>(_data); }
     611             : 
     612             :   //! Returns CpuFeatures::Data as \ref CpuFeatures::X86.
     613             :   inline X86& x86() noexcept { return data<X86>(); }
     614             :   //! Returns CpuFeatures::Data as \ref CpuFeatures::X86 (const).
     615             :   inline const X86& x86() const noexcept { return data<X86>(); }
     616             : 
     617             :   //! Returns CpuFeatures::Data as \ref CpuFeatures::ARM.
     618             :   inline ARM& arm() noexcept { return data<ARM>(); }
     619             :   //! Returns CpuFeatures::Data as \ref CpuFeatures::ARM (const).
     620             :   inline const ARM& arm() const noexcept { return data<ARM>(); }
     621             : 
     622             :   //! Returns all features as array of bitwords (see \ref Support::BitWord).
     623             :   inline BitWord* bits() noexcept { return _data.bits(); }
     624             :   //! Returns all features as array of bitwords (const).
     625             :   inline const BitWord* bits() const noexcept { return _data.bits(); }
     626             :   //! Returns the number of BitWords returned by \ref bits().
     627             :   inline size_t bitWordCount() const noexcept { return _data.bitWordCount(); }
     628             : 
     629             :   //! Returns \ref Support::BitVectorIterator, that can be used to iterate over all features efficiently.
     630             :   inline Iterator iterator() const noexcept { return _data.iterator(); }
     631             : 
     632             :   //! Tests whether the feature `featureId` is present.
     633             :   template<typename FeatureId>
     634             :   inline bool has(const FeatureId& featureId) const noexcept { return _data.has(featureId); }
     635             : 
     636             :   //! Tests whether all features as defined by `other` are present.
     637             :   inline bool hasAll(const CpuFeatures& other) const noexcept { return _data.hasAll(other._data); }
     638             : 
     639             :   //! \}
     640             : 
     641             :   //! \name Manipulation
     642             :   //! \{
     643             : 
     644             :   inline void reset() noexcept { _data.reset(); }
     645             : 
     646             :   //! Adds the given CPU `featureId` to the list of features.
     647             :   template<typename... Args>
     648           0 :   inline void add(Args&&... args) noexcept { return _data.add(std::forward<Args>(args)...); }
     649             : 
     650             :   //! Adds the given CPU `featureId` to the list of features if `condition` is true.
     651             :   template<typename... Args>
     652             :   inline void addIf(bool condition, Args&&... args) noexcept { return _data.addIf(condition, std::forward<Args>(args)...); }
     653             : 
     654             :   //! Removes the given CPU `featureId` from the list of features.
     655             :   template<typename... Args>
     656           0 :   inline void remove(Args&&... args) noexcept { return _data.remove(std::forward<Args>(args)...); }
     657             : 
     658             :   //! Tests whether this CPU features matches `other`.
     659             :   inline bool eq(const CpuFeatures& other) const noexcept { return _data.eq(other._data); }
     660             : 
     661             :   //! \}
     662             : };
     663             : 
     664             : //! CPU information.
     665             : class CpuInfo {
     666             : public:
     667             :   //! \name Members
     668             :   //! \{
     669             : 
     670             :   //! Architecture.
     671             :   Arch _arch;
     672             :   //! Sub-architecture.
     673             :   SubArch _subArch;
     674             :   //! True if the CPU was detected, false if the detection failed or it's not available.
     675             :   bool _wasDetected;
     676             :   //! Reserved for future use.
     677             :   uint8_t _reserved;
     678             :   //! CPU family ID.
     679             :   uint32_t _familyId;
     680             :   //! CPU model ID.
     681             :   uint32_t _modelId;
     682             :   //! CPU brand ID.
     683             :   uint32_t _brandId;
     684             :   //! CPU stepping.
     685             :   uint32_t _stepping;
     686             :   //! Processor type.
     687             :   uint32_t _processorType;
     688             :   //! Maximum number of addressable IDs for logical processors.
     689             :   uint32_t _maxLogicalProcessors;
     690             :   //! Cache line size (in bytes).
     691             :   uint32_t _cacheLineSize;
     692             :   //! Number of hardware threads.
     693             :   uint32_t _hwThreadCount;
     694             : 
     695             :   //! CPU vendor string.
     696             :   FixedString<16> _vendor;
     697             :   //! CPU brand string.
     698             :   FixedString<64> _brand;
     699             :   //! CPU features.
     700             :   CpuFeatures _features;
     701             : 
     702             :   //! \}
     703             : 
     704             :   //! \name Construction & Destruction
     705             :   //! \{
     706             : 
     707         355 :   inline CpuInfo() noexcept { reset(); }
     708             :   inline CpuInfo(const CpuInfo& other) noexcept = default;
     709             : 
     710             :   inline explicit CpuInfo(Globals::NoInit_) noexcept
     711             :     : _features(Globals::NoInit) {};
     712             : 
     713             :   //! Returns the host CPU information.
     714             :   ASMJIT_API static const CpuInfo& host() noexcept;
     715             : 
     716             :   //! Initializes CpuInfo architecture and sub-architecture members to `arch` and `subArch`, respectively.
     717             :   inline void initArch(Arch arch, SubArch subArch = SubArch::kUnknown) noexcept {
     718             :     _arch = arch;
     719             :     _subArch = subArch;
     720             :   }
     721             : 
     722         355 :   inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
     723             : 
     724             :   //! \}
     725             : 
     726             :   //! \name Overloaded Operators
     727             :   //! \{
     728             : 
     729             :   inline CpuInfo& operator=(const CpuInfo& other) noexcept = default;
     730             : 
     731             :   //! \}
     732             : 
     733             :   //! \name Accessors
     734             :   //! \{
     735             : 
     736             :   //! Returns the CPU architecture this information relates to.
     737             :   inline Arch arch() const noexcept { return _arch; }
     738             : 
     739             :   //! Returns the CPU sub-architecture this information relates to.
     740             :   inline SubArch subArch() const noexcept { return _subArch; }
     741             : 
     742             :   //! Returns whether the CPU was detected successfully.
     743             :   //!
     744             :   //! If the returned value is false it means that AsmJit either failed to detect the CPU or it doesn't have
     745             :   //! implementation targeting the host architecture and operating system.
     746             :   inline bool wasDetected() const noexcept { return _wasDetected; }
     747             : 
     748             :   //! Returns the CPU family ID.
     749             :   //!
     750             :   //! Family identifier matches the FamilyId read by using CPUID on X86 architecture.
     751             :   inline uint32_t familyId() const noexcept { return _familyId; }
     752             : 
     753             :   //! Returns the CPU model ID.
     754             :   //!
     755             :   //! Family identifier matches the ModelId read by using CPUID on X86 architecture.
     756             : 
     757             :   inline uint32_t modelId() const noexcept { return _modelId; }
     758             :   //! Returns the CPU brand id.
     759             :   //!
     760             :   //! Family identifier matches the BrandId read by using CPUID on X86 architecture.
     761             :   inline uint32_t brandId() const noexcept { return _brandId; }
     762             : 
     763             :   //! Returns the CPU stepping.
     764             :   //!
     765             :   //! Family identifier matches the Stepping information read by using CPUID on X86 architecture.
     766             :   inline uint32_t stepping() const noexcept { return _stepping; }
     767             : 
     768             :   //! Returns the processor type.
     769             :   //!
     770             :   //! Family identifier matches the ProcessorType read by using CPUID on X86 architecture.
     771             :   inline uint32_t processorType() const noexcept { return _processorType; }
     772             : 
     773             :   //! Returns the maximum number of logical processors.
     774             :   inline uint32_t maxLogicalProcessors() const noexcept { return _maxLogicalProcessors; }
     775             : 
     776             :   //! Returns the size of a cache line flush.
     777             :   inline uint32_t cacheLineSize() const noexcept { return _cacheLineSize; }
     778             : 
     779             :   //! Returns number of hardware threads available.
     780             :   inline uint32_t hwThreadCount() const noexcept { return _hwThreadCount; }
     781             : 
     782             :   //! Returns a CPU vendor string.
     783             :   inline const char* vendor() const noexcept { return _vendor.str; }
     784             :   //! Tests whether the CPU vendor string is equal to `s`.
     785         355 :   inline bool isVendor(const char* s) const noexcept { return _vendor.eq(s); }
     786             : 
     787             :   //! Returns a CPU brand string.
     788             :   inline const char* brand() const noexcept { return _brand.str; }
     789             : 
     790             :   //! Returns CPU features.
     791             :   inline CpuFeatures& features() noexcept { return _features; }
     792             :   //! Returns CPU features (const).
     793             :   inline const CpuFeatures& features() const noexcept { return _features; }
     794             : 
     795             :   //! Tests whether the CPU has the given `feature`.
     796             :   template<typename FeatureId>
     797             :   inline bool hasFeature(const FeatureId& featureId) const noexcept { return _features.has(featureId); }
     798             : 
     799             :   //! Adds the given CPU `featureId` to the list of features.
     800             :   template<typename... Args>
     801             :   inline void addFeature(Args&&... args) noexcept { return _features.add(std::forward<Args>(args)...); }
     802             : 
     803             :   //! Removes the given CPU `featureId` from the list of features.
     804             :   template<typename... Args>
     805             :   inline void removeFeature(Args&&... args) noexcept { return _features.remove(std::forward<Args>(args)...); }
     806             : 
     807             :   //! \}
     808             : };
     809             : 
     810             : //! \}
     811             : 
     812             : ASMJIT_END_NAMESPACE
     813             : 
     814             : #endif // ASMJIT_CORE_CPUINFO_H_INCLUDED
     815             : 
     816             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16