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
|