cpuinfo.h 16.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.

// [Guard]
#ifndef _ASMJIT_BASE_CPUINFO_H
#define _ASMJIT_BASE_CPUINFO_H

11
12
// [Dependencies]
#include "../base/arch.h"
13
14

// [Api-Begin]
15
#include "../asmjit_apibegin.h"
16
17
18

namespace asmjit {

19
//! \addtogroup asmjit_base
20
21
22
//! \{

// ============================================================================
23
// [asmjit::CpuFeatures]
24
25
// ============================================================================

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
class CpuFeatures {
public:
  typedef uintptr_t BitWord;

  enum {
    kMaxFeatures = 128,
    kBitWordSize = static_cast<int>(sizeof(BitWord)) * 8,
    kNumBitWords = kMaxFeatures / kBitWordSize
  };

  // --------------------------------------------------------------------------
  // [Construction / Destruction]
  // --------------------------------------------------------------------------

  ASMJIT_INLINE CpuFeatures() noexcept { reset(); }
  ASMJIT_INLINE CpuFeatures(const CpuFeatures& other) noexcept = default;

  // --------------------------------------------------------------------------
  // [Init / Reset]
  // --------------------------------------------------------------------------

  ASMJIT_INLINE void init(const CpuFeatures& other) noexcept { ::memcpy(this, &other, sizeof(*this)); }
  ASMJIT_INLINE void reset() noexcept { ::memset(this, 0, sizeof(*this)); }

  // --------------------------------------------------------------------------
  // [Ops]
  // --------------------------------------------------------------------------

  //! Get all features as `BitWord` array.
  ASMJIT_INLINE BitWord* getBits() noexcept { return _bits; }
  //! Get all features as `BitWord` array (const).
  ASMJIT_INLINE const BitWord* getBits() const noexcept { return _bits; }

  //! Get if feature `feature` is present.
  ASMJIT_INLINE bool has(uint32_t feature) const noexcept {
    ASMJIT_ASSERT(feature < kMaxFeatures);

    uint32_t idx = feature / kBitWordSize;
    uint32_t bit = feature % kBitWordSize;

    return static_cast<bool>((_bits[idx] >> bit) & 0x1);
  }

  //! Get if all features as defined by `other` are  present.
  ASMJIT_INLINE bool hasAll(const CpuFeatures& other) const noexcept {
    for (uint32_t i = 0; i < kNumBitWords; i++)
      if ((_bits[i] & other._bits[i]) != other._bits[i])
        return false;
    return true;
  }

  //! Add a CPU `feature`.
  ASMJIT_INLINE CpuFeatures& add(uint32_t feature) noexcept {
    ASMJIT_ASSERT(feature < kMaxFeatures);

    uint32_t idx = feature / kBitWordSize;
    uint32_t bit = feature % kBitWordSize;

    _bits[idx] |= static_cast<BitWord>(1) << bit;
    return *this;
  }

  //! Remove a CPU `feature`.
  ASMJIT_INLINE CpuFeatures& remove(uint32_t feature) noexcept {
    ASMJIT_ASSERT(feature < kMaxFeatures);

    uint32_t idx = feature / kBitWordSize;
    uint32_t bit = feature % kBitWordSize;

    _bits[idx] &= ~(static_cast<BitWord>(1) << bit);
    return *this;
  }

  // --------------------------------------------------------------------------
  // [Members]
  // --------------------------------------------------------------------------

  BitWord _bits[kNumBitWords];
104
105
106
107
108
109
};

// ============================================================================
// [asmjit::CpuInfo]
// ============================================================================

110
111
112
113
114
115
116
117
118
119
//! CPU information.
class CpuInfo {
public:
  //! CPU vendor ID.
  ASMJIT_ENUM(Vendor) {
    kVendorNone  = 0,                    //!< Generic or unknown.
    kVendorIntel = 1,                    //!< Intel vendor.
    kVendorAMD   = 2,                    //!< AMD vendor.
    kVendorVIA   = 3                     //!< VIA vendor.
  };
120

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
  //! ARM/ARM64 CPU features.
  ASMJIT_ENUM(ArmFeatures) {
    kArmFeatureV6 = 1,                   //!< ARMv6 instruction set.
    kArmFeatureV7,                       //!< ARMv7 instruction set.
    kArmFeatureV8,                       //!< ARMv8 instruction set.
    kArmFeatureTHUMB,                    //!< CPU provides THUMB v1 instruction set (THUMB mode).
    kArmFeatureTHUMB2,                   //!< CPU provides THUMB v2 instruction set (THUMB mode).
    kArmFeatureVFPv2,                    //!< CPU provides VFPv2 instruction set.
    kArmFeatureVFPv3,                    //!< CPU provides VFPv3 instruction set.
    kArmFeatureVFPv4,                    //!< CPU provides VFPv4 instruction set.
    kArmFeatureVFP_D32,                  //!< CPU provides 32 VFP-D (64-bit) registers.
    kArmFeatureEDSP,                     //!< CPU provides EDSP extensions.
    kArmFeatureASIMD,                    //!< CPU provides 'Advanced SIMD'.
    kArmFeatureIDIVA,                    //!< CPU provides hardware SDIV and UDIV (ARM mode).
    kArmFeatureIDIVT,                    //!< CPU provides hardware SDIV and UDIV (THUMB mode).
    kArmFeatureAES,                      //!< CPU provides AES instructions (ARM64 only).
    kArmFeatureCRC32,                    //!< CPU provides CRC32 instructions.
    kArmFeaturePMULL,                    //!< CPU provides PMULL instructions (ARM64 only).
    kArmFeatureSHA1,                     //!< CPU provides SHA1 instructions.
    kArmFeatureSHA256,                   //!< CPU provides SHA256 instructions.
    kArmFeatureAtomics64,                //!< CPU provides 64-bit load/store atomics (ARM64 only).

    kArmFeaturesCount                    //!< Count of ARM/ARM64 CPU features.
  };

  //! X86/X64 CPU features.
  ASMJIT_ENUM(X86Features) {
    kX86FeatureI486 = 1,                 //!< CPU is at least I486.
    kX86FeatureNX,                       //!< CPU has Not-Execute-Bit.
    kX86FeatureMT,                       //!< CPU has multi-threading.
    kX86FeatureALTMOVCR8,                //!< CPU supports `LOCK MOV CR8` (AMD CPUs).
    kX86FeatureCMOV,                     //!< CPU has CMOV.
    kX86FeatureCMPXCHG8B,                //!< CPU has CMPXCHG8B.
    kX86FeatureCMPXCHG16B,               //!< CPU has CMPXCHG16B (x64).
    kX86FeatureMSR,                      //!< CPU has RDMSR/WRMSR.
    kX86FeatureRDTSC,                    //!< CPU has RDTSC.
    kX86FeatureRDTSCP,                   //!< CPU has RDTSCP.
    kX86FeatureCLFLUSH,                  //!< CPU has CLFUSH.
    kX86FeatureCLFLUSHOPT,               //!< CPU has CLFUSHOPT.
    kX86FeatureCLWB,                     //!< CPU has CLWB.
    kX86FeatureCLZERO,                   //!< CPU has CLZERO.
    kX86FeaturePCOMMIT,                  //!< CPU has PCOMMIT.
    kX86FeaturePREFETCHW,                //!< CPU has PREFETCHW.
    kX86FeaturePREFETCHWT1,              //!< CPU has PREFETCHWT1.
    kX86FeatureLAHFSAHF,                 //!< CPU has LAHF/SAHF.
    kX86FeatureFXSR,                     //!< CPU has FXSAVE/FXRSTOR.
    kX86FeatureFXSROPT,                  //!< CPU has FXSAVE/FXRSTOR (optimized).
    kX86FeatureMMX,                      //!< CPU has MMX.
    kX86FeatureMMX2,                     //!< CPU has extended MMX.
    kX86Feature3DNOW,                    //!< CPU has 3DNOW.
    kX86Feature3DNOW2,                   //!< CPU has 3DNOW2 (enhanced).
    kX86FeatureGEODE,                    //!< CPU has GEODE extensions (few additions to 3DNOW).
    kX86FeatureSSE,                      //!< CPU has SSE.
    kX86FeatureSSE2,                     //!< CPU has SSE2.
    kX86FeatureSSE3,                     //!< CPU has SSE3.
    kX86FeatureSSSE3,                    //!< CPU has SSSE3.
    kX86FeatureSSE4A,                    //!< CPU has SSE4.A.
    kX86FeatureSSE4_1,                   //!< CPU has SSE4.1.
    kX86FeatureSSE4_2,                   //!< CPU has SSE4.2.
    kX86FeatureMSSE,                     //!< CPU has Misaligned SSE (MSSE).
    kX86FeatureMONITOR,                  //!< CPU has MONITOR and MWAIT.
    kX86FeatureMOVBE,                    //!< CPU has MOVBE.
    kX86FeaturePOPCNT,                   //!< CPU has POPCNT.
    kX86FeatureLZCNT,                    //!< CPU has LZCNT.
    kX86FeatureAESNI,                    //!< CPU has AESNI.
    kX86FeaturePCLMULQDQ,                //!< CPU has PCLMULQDQ.
    kX86FeatureRDRAND,                   //!< CPU has RDRAND.
    kX86FeatureRDSEED,                   //!< CPU has RDSEED.
    kX86FeatureSMAP,                     //!< CPU has SMAP (supervisor-mode access prevention).
    kX86FeatureSMEP,                     //!< CPU has SMEP (supervisor-mode execution prevention).
    kX86FeatureSHA,                      //!< CPU has SHA-1 and SHA-256.
    kX86FeatureXSAVE,                    //!< CPU has XSAVE support (XSAVE/XRSTOR, XSETBV/XGETBV, and XCR).
    kX86FeatureXSAVEC,                   //!< CPU has XSAVEC support (XSAVEC).
    kX86FeatureXSAVES,                   //!< CPU has XSAVES support (XSAVES/XRSTORS).
    kX86FeatureXSAVEOPT,                 //!< CPU has XSAVEOPT support (XSAVEOPT/XSAVEOPT64).
    kX86FeatureOSXSAVE,                  //!< CPU has XSAVE enabled by OS.
    kX86FeatureAVX,                      //!< CPU has AVX.
    kX86FeatureAVX2,                     //!< CPU has AVX2.
    kX86FeatureF16C,                     //!< CPU has F16C.
    kX86FeatureFMA,                      //!< CPU has FMA.
    kX86FeatureFMA4,                     //!< CPU has FMA4.
    kX86FeatureXOP,                      //!< CPU has XOP.
    kX86FeatureBMI,                      //!< CPU has BMI (bit manipulation instructions #1).
    kX86FeatureBMI2,                     //!< CPU has BMI2 (bit manipulation instructions #2).
    kX86FeatureADX,                      //!< CPU has ADX (multi-precision add-carry instruction extensions).
    kX86FeatureTBM,                      //!< CPU has TBM (trailing bit manipulation).
    kX86FeatureMPX,                      //!< CPU has MPX (memory protection extensions).
    kX86FeatureHLE,                      //!< CPU has HLE.
    kX86FeatureRTM,                      //!< CPU has RTM.
    kX86FeatureTSX,                      //!< CPU has TSX.
    kX86FeatureERMS,                     //!< CPU has ERMS (enhanced REP MOVSB/STOSB).
    kX86FeatureFSGSBASE,                 //!< CPU has FSGSBASE.
    kX86FeatureAVX512_F,                 //!< CPU has AVX512-F (foundation).
    kX86FeatureAVX512_CDI,               //!< CPU has AVX512-CDI (conflict detection).
    kX86FeatureAVX512_PFI,               //!< CPU has AVX512-PFI (prefetch instructions).
    kX86FeatureAVX512_ERI,               //!< CPU has AVX512-ERI (exponential and reciprocal).
    kX86FeatureAVX512_DQ,                //!< CPU has AVX512-DQ (DWORD/QWORD).
    kX86FeatureAVX512_BW,                //!< CPU has AVX512-BW (BYTE/WORD).
    kX86FeatureAVX512_VL,                //!< CPU has AVX512-VL (vector length extensions).
    kX86FeatureAVX512_IFMA,              //!< CPU has AVX512-IFMA (integer fused-multiply-add using 52-bit precision).
    kX86FeatureAVX512_VBMI,              //!< CPU has AVX512-VBMI (vector byte manipulation).
    kX86FeatureAVX512_VPOPCNTDQ,         //!< CPU has AVX512-VPOPCNTDQ (VPOPCNT[D|Q] instructions).
    kX86FeatureAVX512_4VNNIW,            //!< CPU has AVX512-VNNIW (vector NN instructions word variable precision).
    kX86FeatureAVX512_4FMAPS,            //!< CPU has AVX512-FMAPS (FMA packed single).

    kX86FeaturesCount                    //!< Count of X86/X64 CPU features.
  };

  // --------------------------------------------------------------------------
  // [ArmInfo]
  // --------------------------------------------------------------------------

  struct ArmData {
  };

  // --------------------------------------------------------------------------
  // [X86Info]
  // --------------------------------------------------------------------------

  struct X86Data {
    uint32_t _processorType;             //!< Processor type.
    uint32_t _brandIndex;                //!< Brand index.
    uint32_t _flushCacheLineSize;        //!< Flush cache line size (in bytes).
    uint32_t _maxLogicalProcessors;      //!< Maximum number of addressable IDs for logical processors.
245
246
247
248
249
250
  };

  // --------------------------------------------------------------------------
  // [Construction / Destruction]
  // --------------------------------------------------------------------------

251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
  ASMJIT_INLINE CpuInfo() noexcept { reset(); }
  ASMJIT_INLINE CpuInfo(const CpuInfo& other) noexcept = default;

  // --------------------------------------------------------------------------
  // [Init / Reset]
  // --------------------------------------------------------------------------

  //! Initialize CpuInfo to the given architecture, see \ArchInfo.
  ASMJIT_INLINE void initArch(uint32_t archType, uint32_t archMode = 0) noexcept {
    _archInfo.init(archType, archMode);
  }

  ASMJIT_INLINE void init(const CpuInfo& other) noexcept { ::memcpy(this, &other, sizeof(*this)); }
  ASMJIT_INLINE void reset() noexcept { ::memset(this, 0, sizeof(*this)); }

  // --------------------------------------------------------------------------
  // [Detect]
  // --------------------------------------------------------------------------

  ASMJIT_API void detect() noexcept;
271
272
273
274
275

  // --------------------------------------------------------------------------
  // [Accessors]
  // --------------------------------------------------------------------------

276
277
278
279
280
281
  //! Get generic architecture information.
  ASMJIT_INLINE const ArchInfo& getArchInfo() const noexcept { return _archInfo; }
  //! Get CPU architecture type, see \ArchInfo::Type.
  ASMJIT_INLINE uint32_t getArchType() const noexcept { return _archInfo.getType(); }
  //! Get CPU architecture sub-type, see \ArchInfo::SubType.
  ASMJIT_INLINE uint32_t getArchSubType() const noexcept { return _archInfo.getSubType(); }
282

283
284
    //! Get CPU vendor ID.
  ASMJIT_INLINE uint32_t getVendorId() const noexcept { return _vendorId; }
285
  //! Get CPU family ID.
286
  ASMJIT_INLINE uint32_t getFamily() const noexcept { return _family; }
287
  //! Get CPU model ID.
288
  ASMJIT_INLINE uint32_t getModel() const noexcept { return _model; }
289
  //! Get CPU stepping.
290
  ASMJIT_INLINE uint32_t getStepping() const noexcept { return _stepping; }
291
292

  //! Get number of hardware threads available.
293
294
295
  ASMJIT_INLINE uint32_t getHwThreadsCount() const noexcept {
    return _hwThreadsCount;
  }
296

297
298
  //! Get all CPU features.
  ASMJIT_INLINE const CpuFeatures& getFeatures() const noexcept { return _features; }
299
  //! Get whether CPU has a `feature`.
300
301
302
303
304
305
306
307
  ASMJIT_INLINE bool hasFeature(uint32_t feature) const noexcept { return _features.has(feature); }
  //! Add a CPU `feature`.
  ASMJIT_INLINE CpuInfo& addFeature(uint32_t feature) noexcept { _features.add(feature); return *this; }

  //! Get CPU vendor string.
  ASMJIT_INLINE const char* getVendorString() const noexcept { return _vendorString; }
  //! Get CPU brand string.
  ASMJIT_INLINE const char* getBrandString() const noexcept { return _brandString; }
308

309
310
311
312
313
314
315
316
317
318
319
  // --------------------------------------------------------------------------
  // [Accessors - ARM]
  // --------------------------------------------------------------------------

  // --------------------------------------------------------------------------
  // [Accessors - X86]
  // --------------------------------------------------------------------------

  //! Get processor type.
  ASMJIT_INLINE uint32_t getX86ProcessorType() const noexcept {
    return _x86Data._processorType;
320
321
  }

322
323
324
325
  //! Get brand index.
  ASMJIT_INLINE uint32_t getX86BrandIndex() const noexcept {
    return _x86Data._brandIndex;
  }
326

327
328
329
330
331
332
333
334
  //! Get flush cache line size.
  ASMJIT_INLINE uint32_t getX86FlushCacheLineSize() const noexcept {
    return _x86Data._flushCacheLineSize;
  }

  //! Get maximum logical processors count.
  ASMJIT_INLINE uint32_t getX86MaxLogicalProcessors() const noexcept {
    return _x86Data._maxLogicalProcessors;
335
336
337
338
339
340
  }

  // --------------------------------------------------------------------------
  // [Statics]
  // --------------------------------------------------------------------------

341
342
  //! Get the host CPU information.
  ASMJIT_API static const CpuInfo& getHost() noexcept;
343
344
345
346
347

  // --------------------------------------------------------------------------
  // [Members]
  // --------------------------------------------------------------------------

348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
  ArchInfo _archInfo;                    //!< CPU architecture information.
  uint32_t _vendorId;                    //!< CPU vendor id, see \ref Vendor.
  uint32_t _family;                      //!< CPU family ID.
  uint32_t _model;                       //!< CPU model ID.
  uint32_t _stepping;                    //!< CPU stepping.
  uint32_t _hwThreadsCount;              //!< Number of hardware threads.
  CpuFeatures _features;                 //!< CPU features.
  char _vendorString[16];                //!< CPU vendor string.
  char _brandString[64];                 //!< CPU brand string.

  // Architecture specific data.
  union {
    ArmData _armData;
    X86Data _x86Data;
  };
363
364
365
366
367
368
369
};

//! \}

} // asmjit namespace

// [Api-End]
370
#include "../asmjit_apiend.h"
371
372
373

// [Guard]
#endif // _ASMJIT_BASE_CPUINFO_H