Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2008-2017, Petr Kobalicek
3 :
4 : This software is provided 'as-is', without any express or implied
5 : warranty. In no event will the authors be held liable for any damages
6 : arising from the use of this software.
7 :
8 : Permission is granted to anyone to use this software for any purpose,
9 : including commercial applications, and to alter it and redistribute it
10 : freely, subject to the following restrictions:
11 :
12 : 1. The origin of this software must not be misrepresented; you must not
13 : claim that you wrote the original software. If you use this software
14 : in a product, an acknowledgment in the product documentation would be
15 : appreciated but is not required.
16 : 2. Altered source versions must be plainly marked as such, and must not be
17 : misrepresented as being the original software.
18 : 3. This notice may not be removed or altered from any source distribution.
19 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
20 : #ifndef __PLUMED_asmjit_cpuinfo_h
21 : #define __PLUMED_asmjit_cpuinfo_h
22 : #ifdef __PLUMED_HAS_ASMJIT
23 : #pragma GCC diagnostic push
24 : #pragma GCC diagnostic ignored "-Wpedantic"
25 : // [AsmJit]
26 : // Complete x86/x64 JIT and Remote Assembler for C++.
27 : //
28 : // [License]
29 : // Zlib - See LICENSE.md file in the package.
30 :
31 : // [Guard]
32 : #ifndef _ASMJIT_BASE_CPUINFO_H
33 : #define _ASMJIT_BASE_CPUINFO_H
34 :
35 : // [Dependencies]
36 : #include "./arch.h"
37 :
38 : // [Api-Begin]
39 : #include "./asmjit_apibegin.h"
40 :
41 : namespace PLMD {
42 : namespace asmjit {
43 :
44 : //! \addtogroup asmjit_base
45 : //! \{
46 :
47 : // ============================================================================
48 : // [asmjit::CpuFeatures]
49 : // ============================================================================
50 :
51 : class CpuFeatures {
52 : public:
53 : typedef uintptr_t BitWord;
54 :
55 : enum {
56 : kMaxFeatures = 128,
57 : kBitWordSize = static_cast<int>(sizeof(BitWord)) * 8,
58 : kNumBitWords = kMaxFeatures / kBitWordSize
59 : };
60 :
61 : // --------------------------------------------------------------------------
62 : // [Construction / Destruction]
63 : // --------------------------------------------------------------------------
64 :
65 69 : ASMJIT_INLINE CpuFeatures() noexcept { reset(); }
66 : ASMJIT_INLINE CpuFeatures(const CpuFeatures& other) noexcept = default;
67 :
68 : // --------------------------------------------------------------------------
69 : // [Init / Reset]
70 : // --------------------------------------------------------------------------
71 :
72 : ASMJIT_INLINE void init(const CpuFeatures& other) noexcept { ::memcpy(this, &other, sizeof(*this)); }
73 0 : ASMJIT_INLINE void reset() noexcept { ::memset(this, 0, sizeof(*this)); }
74 :
75 : // --------------------------------------------------------------------------
76 : // [Ops]
77 : // --------------------------------------------------------------------------
78 :
79 : //! Get all features as `BitWord` array.
80 : ASMJIT_INLINE BitWord* getBits() noexcept { return _bits; }
81 : //! Get all features as `BitWord` array (const).
82 : ASMJIT_INLINE const BitWord* getBits() const noexcept { return _bits; }
83 :
84 : //! Get if feature `feature` is present.
85 : ASMJIT_INLINE bool has(uint32_t feature) const noexcept {
86 : ASMJIT_ASSERT(feature < kMaxFeatures);
87 :
88 : uint32_t idx = feature / kBitWordSize;
89 : uint32_t bit = feature % kBitWordSize;
90 :
91 138 : return static_cast<bool>((_bits[idx] >> bit) & 0x1);
92 : }
93 :
94 : //! Get if all features as defined by `other` are present.
95 : ASMJIT_INLINE bool hasAll(const CpuFeatures& other) const noexcept {
96 : for (uint32_t i = 0; i < kNumBitWords; i++)
97 : if ((_bits[i] & other._bits[i]) != other._bits[i])
98 : return false;
99 : return true;
100 : }
101 :
102 : //! Add a CPU `feature`.
103 : ASMJIT_INLINE CpuFeatures& add(uint32_t feature) noexcept {
104 : ASMJIT_ASSERT(feature < kMaxFeatures);
105 :
106 0 : uint32_t idx = feature / kBitWordSize;
107 0 : uint32_t bit = feature % kBitWordSize;
108 :
109 138 : _bits[idx] |= static_cast<BitWord>(1) << bit;
110 : return *this;
111 : }
112 :
113 : //! Remove a CPU `feature`.
114 : ASMJIT_INLINE CpuFeatures& remove(uint32_t feature) noexcept {
115 : ASMJIT_ASSERT(feature < kMaxFeatures);
116 :
117 : uint32_t idx = feature / kBitWordSize;
118 : uint32_t bit = feature % kBitWordSize;
119 :
120 0 : _bits[idx] &= ~(static_cast<BitWord>(1) << bit);
121 0 : return *this;
122 : }
123 :
124 : // --------------------------------------------------------------------------
125 : // [Members]
126 : // --------------------------------------------------------------------------
127 :
128 : BitWord _bits[kNumBitWords];
129 : };
130 :
131 : // ============================================================================
132 : // [asmjit::CpuInfo]
133 : // ============================================================================
134 :
135 : //! CPU information.
136 : class CpuInfo {
137 : public:
138 : //! CPU vendor ID.
139 : ASMJIT_ENUM(Vendor) {
140 : kVendorNone = 0, //!< Generic or unknown.
141 : kVendorIntel = 1, //!< Intel vendor.
142 : kVendorAMD = 2, //!< AMD vendor.
143 : kVendorVIA = 3 //!< VIA vendor.
144 : };
145 :
146 : //! ARM/ARM64 CPU features.
147 : ASMJIT_ENUM(ArmFeatures) {
148 : kArmFeatureV6 = 1, //!< ARMv6 instruction set.
149 : kArmFeatureV7, //!< ARMv7 instruction set.
150 : kArmFeatureV8, //!< ARMv8 instruction set.
151 : kArmFeatureTHUMB, //!< CPU provides THUMB v1 instruction set (THUMB mode).
152 : kArmFeatureTHUMB2, //!< CPU provides THUMB v2 instruction set (THUMB mode).
153 : kArmFeatureVFPv2, //!< CPU provides VFPv2 instruction set.
154 : kArmFeatureVFPv3, //!< CPU provides VFPv3 instruction set.
155 : kArmFeatureVFPv4, //!< CPU provides VFPv4 instruction set.
156 : kArmFeatureVFP_D32, //!< CPU provides 32 VFP-D (64-bit) registers.
157 : kArmFeatureEDSP, //!< CPU provides EDSP extensions.
158 : kArmFeatureASIMD, //!< CPU provides 'Advanced SIMD'.
159 : kArmFeatureIDIVA, //!< CPU provides hardware SDIV and UDIV (ARM mode).
160 : kArmFeatureIDIVT, //!< CPU provides hardware SDIV and UDIV (THUMB mode).
161 : kArmFeatureAES, //!< CPU provides AES instructions (ARM64 only).
162 : kArmFeatureCRC32, //!< CPU provides CRC32 instructions.
163 : kArmFeaturePMULL, //!< CPU provides PMULL instructions (ARM64 only).
164 : kArmFeatureSHA1, //!< CPU provides SHA1 instructions.
165 : kArmFeatureSHA256, //!< CPU provides SHA256 instructions.
166 : kArmFeatureAtomics64, //!< CPU provides 64-bit load/store atomics (ARM64 only).
167 :
168 : kArmFeaturesCount //!< Count of ARM/ARM64 CPU features.
169 : };
170 :
171 : //! X86/X64 CPU features.
172 : ASMJIT_ENUM(X86Features) {
173 : kX86FeatureI486 = 1, //!< CPU is at least I486.
174 : kX86FeatureNX, //!< CPU has Not-Execute-Bit.
175 : kX86FeatureMT, //!< CPU has multi-threading.
176 : kX86FeatureALTMOVCR8, //!< CPU supports `LOCK MOV CR8` (AMD CPUs).
177 : kX86FeatureCMOV, //!< CPU has CMOV.
178 : kX86FeatureCMPXCHG8B, //!< CPU has CMPXCHG8B.
179 : kX86FeatureCMPXCHG16B, //!< CPU has CMPXCHG16B (x64).
180 : kX86FeatureMSR, //!< CPU has RDMSR/WRMSR.
181 : kX86FeatureRDTSC, //!< CPU has RDTSC.
182 : kX86FeatureRDTSCP, //!< CPU has RDTSCP.
183 : kX86FeatureCLFLUSH, //!< CPU has CLFUSH.
184 : kX86FeatureCLFLUSHOPT, //!< CPU has CLFUSHOPT.
185 : kX86FeatureCLWB, //!< CPU has CLWB.
186 : kX86FeatureCLZERO, //!< CPU has CLZERO.
187 : kX86FeaturePCOMMIT, //!< CPU has PCOMMIT.
188 : kX86FeaturePREFETCHW, //!< CPU has PREFETCHW.
189 : kX86FeaturePREFETCHWT1, //!< CPU has PREFETCHWT1.
190 : kX86FeatureLAHFSAHF, //!< CPU has LAHF/SAHF.
191 : kX86FeatureFXSR, //!< CPU has FXSAVE/FXRSTOR.
192 : kX86FeatureFXSROPT, //!< CPU has FXSAVE/FXRSTOR (optimized).
193 : kX86FeatureMMX, //!< CPU has MMX.
194 : kX86FeatureMMX2, //!< CPU has extended MMX.
195 : kX86Feature3DNOW, //!< CPU has 3DNOW.
196 : kX86Feature3DNOW2, //!< CPU has 3DNOW2 (enhanced).
197 : kX86FeatureGEODE, //!< CPU has GEODE extensions (few additions to 3DNOW).
198 : kX86FeatureSSE, //!< CPU has SSE.
199 : kX86FeatureSSE2, //!< CPU has SSE2.
200 : kX86FeatureSSE3, //!< CPU has SSE3.
201 : kX86FeatureSSSE3, //!< CPU has SSSE3.
202 : kX86FeatureSSE4A, //!< CPU has SSE4.A.
203 : kX86FeatureSSE4_1, //!< CPU has SSE4.1.
204 : kX86FeatureSSE4_2, //!< CPU has SSE4.2.
205 : kX86FeatureMSSE, //!< CPU has Misaligned SSE (MSSE).
206 : kX86FeatureMONITOR, //!< CPU has MONITOR and MWAIT.
207 : kX86FeatureMOVBE, //!< CPU has MOVBE.
208 : kX86FeaturePOPCNT, //!< CPU has POPCNT.
209 : kX86FeatureLZCNT, //!< CPU has LZCNT.
210 : kX86FeatureAESNI, //!< CPU has AESNI.
211 : kX86FeaturePCLMULQDQ, //!< CPU has PCLMULQDQ.
212 : kX86FeatureRDRAND, //!< CPU has RDRAND.
213 : kX86FeatureRDSEED, //!< CPU has RDSEED.
214 : kX86FeatureSMAP, //!< CPU has SMAP (supervisor-mode access prevention).
215 : kX86FeatureSMEP, //!< CPU has SMEP (supervisor-mode execution prevention).
216 : kX86FeatureSHA, //!< CPU has SHA-1 and SHA-256.
217 : kX86FeatureXSAVE, //!< CPU has XSAVE support (XSAVE/XRSTOR, XSETBV/XGETBV, and XCR).
218 : kX86FeatureXSAVEC, //!< CPU has XSAVEC support (XSAVEC).
219 : kX86FeatureXSAVES, //!< CPU has XSAVES support (XSAVES/XRSTORS).
220 : kX86FeatureXSAVEOPT, //!< CPU has XSAVEOPT support (XSAVEOPT/XSAVEOPT64).
221 : kX86FeatureOSXSAVE, //!< CPU has XSAVE enabled by OS.
222 : kX86FeatureAVX, //!< CPU has AVX.
223 : kX86FeatureAVX2, //!< CPU has AVX2.
224 : kX86FeatureF16C, //!< CPU has F16C.
225 : kX86FeatureFMA, //!< CPU has FMA.
226 : kX86FeatureFMA4, //!< CPU has FMA4.
227 : kX86FeatureXOP, //!< CPU has XOP.
228 : kX86FeatureBMI, //!< CPU has BMI (bit manipulation instructions #1).
229 : kX86FeatureBMI2, //!< CPU has BMI2 (bit manipulation instructions #2).
230 : kX86FeatureADX, //!< CPU has ADX (multi-precision add-carry instruction extensions).
231 : kX86FeatureTBM, //!< CPU has TBM (trailing bit manipulation).
232 : kX86FeatureMPX, //!< CPU has MPX (memory protection extensions).
233 : kX86FeatureHLE, //!< CPU has HLE.
234 : kX86FeatureRTM, //!< CPU has RTM.
235 : kX86FeatureTSX, //!< CPU has TSX.
236 : kX86FeatureERMS, //!< CPU has ERMS (enhanced REP MOVSB/STOSB).
237 : kX86FeatureFSGSBASE, //!< CPU has FSGSBASE.
238 : kX86FeatureAVX512_F, //!< CPU has AVX512-F (foundation).
239 : kX86FeatureAVX512_CDI, //!< CPU has AVX512-CDI (conflict detection).
240 : kX86FeatureAVX512_PFI, //!< CPU has AVX512-PFI (prefetch instructions).
241 : kX86FeatureAVX512_ERI, //!< CPU has AVX512-ERI (exponential and reciprocal).
242 : kX86FeatureAVX512_DQ, //!< CPU has AVX512-DQ (DWORD/QWORD).
243 : kX86FeatureAVX512_BW, //!< CPU has AVX512-BW (BYTE/WORD).
244 : kX86FeatureAVX512_VL, //!< CPU has AVX512-VL (vector length extensions).
245 : kX86FeatureAVX512_IFMA, //!< CPU has AVX512-IFMA (integer fused-multiply-add using 52-bit precision).
246 : kX86FeatureAVX512_VBMI, //!< CPU has AVX512-VBMI (vector byte manipulation).
247 : kX86FeatureAVX512_VPOPCNTDQ, //!< CPU has AVX512-VPOPCNTDQ (VPOPCNT[D|Q] instructions).
248 : kX86FeatureAVX512_4VNNIW, //!< CPU has AVX512-VNNIW (vector NN instructions word variable precision).
249 : kX86FeatureAVX512_4FMAPS, //!< CPU has AVX512-FMAPS (FMA packed single).
250 :
251 : kX86FeaturesCount //!< Count of X86/X64 CPU features.
252 : };
253 :
254 : // --------------------------------------------------------------------------
255 : // [ArmInfo]
256 : // --------------------------------------------------------------------------
257 :
258 : struct ArmData {
259 : };
260 :
261 : // --------------------------------------------------------------------------
262 : // [X86Info]
263 : // --------------------------------------------------------------------------
264 :
265 : struct X86Data {
266 : uint32_t _processorType; //!< Processor type.
267 : uint32_t _brandIndex; //!< Brand index.
268 : uint32_t _flushCacheLineSize; //!< Flush cache line size (in bytes).
269 : uint32_t _maxLogicalProcessors; //!< Maximum number of addressable IDs for logical processors.
270 : };
271 :
272 : // --------------------------------------------------------------------------
273 : // [Construction / Destruction]
274 : // --------------------------------------------------------------------------
275 :
276 69 : ASMJIT_INLINE CpuInfo() noexcept { reset(); }
277 : ASMJIT_INLINE CpuInfo(const CpuInfo& other) noexcept = default;
278 :
279 : // --------------------------------------------------------------------------
280 : // [Init / Reset]
281 : // --------------------------------------------------------------------------
282 :
283 : //! Initialize CpuInfo to the given architecture, see \ArchInfo.
284 : ASMJIT_INLINE void initArch(uint32_t archType, uint32_t archMode = 0) noexcept {
285 : _archInfo.init(archType, archMode);
286 : }
287 :
288 : ASMJIT_INLINE void init(const CpuInfo& other) noexcept { ::memcpy(this, &other, sizeof(*this)); }
289 : ASMJIT_INLINE void reset() noexcept { ::memset(this, 0, sizeof(*this)); }
290 :
291 : // --------------------------------------------------------------------------
292 : // [Detect]
293 : // --------------------------------------------------------------------------
294 :
295 : ASMJIT_API void detect() noexcept;
296 :
297 : // --------------------------------------------------------------------------
298 : // [Accessors]
299 : // --------------------------------------------------------------------------
300 :
301 : //! Get generic architecture information.
302 : ASMJIT_INLINE const ArchInfo& getArchInfo() const noexcept { return _archInfo; }
303 : //! Get CPU architecture type, see \ArchInfo::Type.
304 : ASMJIT_INLINE uint32_t getArchType() const noexcept { return _archInfo.getType(); }
305 : //! Get CPU architecture sub-type, see \ArchInfo::SubType.
306 : ASMJIT_INLINE uint32_t getArchSubType() const noexcept { return _archInfo.getSubType(); }
307 :
308 : //! Get CPU vendor ID.
309 69 : ASMJIT_INLINE uint32_t getVendorId() const noexcept { return _vendorId; }
310 : //! Get CPU family ID.
311 : ASMJIT_INLINE uint32_t getFamily() const noexcept { return _family; }
312 : //! Get CPU model ID.
313 : ASMJIT_INLINE uint32_t getModel() const noexcept { return _model; }
314 : //! Get CPU stepping.
315 : ASMJIT_INLINE uint32_t getStepping() const noexcept { return _stepping; }
316 :
317 : //! Get number of hardware threads available.
318 : ASMJIT_INLINE uint32_t getHwThreadsCount() const noexcept {
319 : return _hwThreadsCount;
320 : }
321 :
322 : //! Get all CPU features.
323 : ASMJIT_INLINE const CpuFeatures& getFeatures() const noexcept { return _features; }
324 : //! Get whether CPU has a `feature`.
325 : ASMJIT_INLINE bool hasFeature(uint32_t feature) const noexcept { return _features.has(feature); }
326 : //! Add a CPU `feature`.
327 3381 : ASMJIT_INLINE CpuInfo& addFeature(uint32_t feature) noexcept { _features.add(feature); return *this; }
328 :
329 : //! Get CPU vendor string.
330 : ASMJIT_INLINE const char* getVendorString() const noexcept { return _vendorString; }
331 : //! Get CPU brand string.
332 : ASMJIT_INLINE const char* getBrandString() const noexcept { return _brandString; }
333 :
334 : // --------------------------------------------------------------------------
335 : // [Accessors - ARM]
336 : // --------------------------------------------------------------------------
337 :
338 : // --------------------------------------------------------------------------
339 : // [Accessors - X86]
340 : // --------------------------------------------------------------------------
341 :
342 : //! Get processor type.
343 : ASMJIT_INLINE uint32_t getX86ProcessorType() const noexcept {
344 : return _x86Data._processorType;
345 : }
346 :
347 : //! Get brand index.
348 : ASMJIT_INLINE uint32_t getX86BrandIndex() const noexcept {
349 : return _x86Data._brandIndex;
350 : }
351 :
352 : //! Get flush cache line size.
353 : ASMJIT_INLINE uint32_t getX86FlushCacheLineSize() const noexcept {
354 : return _x86Data._flushCacheLineSize;
355 : }
356 :
357 : //! Get maximum logical processors count.
358 : ASMJIT_INLINE uint32_t getX86MaxLogicalProcessors() const noexcept {
359 : return _x86Data._maxLogicalProcessors;
360 : }
361 :
362 : // --------------------------------------------------------------------------
363 : // [Statics]
364 : // --------------------------------------------------------------------------
365 :
366 : //! Get the host CPU information.
367 : ASMJIT_API static const CpuInfo& getHost() noexcept;
368 :
369 : // --------------------------------------------------------------------------
370 : // [Members]
371 : // --------------------------------------------------------------------------
372 :
373 : ArchInfo _archInfo; //!< CPU architecture information.
374 : uint32_t _vendorId; //!< CPU vendor id, see \ref Vendor.
375 : uint32_t _family; //!< CPU family ID.
376 : uint32_t _model; //!< CPU model ID.
377 : uint32_t _stepping; //!< CPU stepping.
378 : uint32_t _hwThreadsCount; //!< Number of hardware threads.
379 : CpuFeatures _features; //!< CPU features.
380 : char _vendorString[16]; //!< CPU vendor string.
381 : char _brandString[64]; //!< CPU brand string.
382 :
383 : // Architecture specific data.
384 : union {
385 : ArmData _armData;
386 : X86Data _x86Data;
387 : };
388 : };
389 :
390 : //! \}
391 :
392 : } // asmjit namespace
393 : } // namespace PLMD
394 :
395 : // [Api-End]
396 : #include "./asmjit_apiend.h"
397 :
398 : // [Guard]
399 : #endif // _ASMJIT_BASE_CPUINFO_H
400 : #pragma GCC diagnostic pop
401 : #endif // __PLUMED_HAS_ASMJIT
402 : #endif
|