Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:49

0001 /*  This file is part of the Vc library. {{{
0002 Copyright © 2009-2015 Matthias Kretz <kretz@kde.org>
0003 
0004 Redistribution and use in source and binary forms, with or without
0005 modification, are permitted provided that the following conditions are met:
0006     * Redistributions of source code must retain the above copyright
0007       notice, this list of conditions and the following disclaimer.
0008     * Redistributions in binary form must reproduce the above copyright
0009       notice, this list of conditions and the following disclaimer in the
0010       documentation and/or other materials provided with the distribution.
0011     * Neither the names of contributing organizations nor the
0012       names of its contributors may be used to endorse or promote products
0013       derived from this software without specific prior written permission.
0014 
0015 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
0016 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
0017 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0018 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
0019 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0020 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0021 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0022 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0023 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0024 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0025 
0026 }}}*/
0027 
0028 #ifndef VC_CPUID_H_
0029 #define VC_CPUID_H_
0030 
0031 #include "common/macros.h"
0032 namespace Vc_VERSIONED_NAMESPACE
0033 {
0034 
0035 /**
0036  * \ingroup Utilities
0037  * \headerfile cpuid.h <Vc/cpuid.h>
0038  *
0039  * This class is available for x86 / AMD64 systems to read and interpret information about the CPU's
0040  * capabilities.
0041  *
0042  * Before any of the getter functions may be called, the init() function must have been called. It
0043  * will be called automatically, but for any function executing before main, you better call
0044  * \c CpuId::init() first.
0045  *
0046  * %Vc users will most likely not need this class directly, but rely on the
0047  * isImplementationSupported, bestImplementationSupported, extraInstructionsSupported, and
0048  * currentImplementationSupported functions.
0049  */
0050 class CpuId
0051 {
0052     typedef unsigned char uchar;
0053     typedef unsigned short ushort;
0054     typedef unsigned int uint;
0055 
0056     public:
0057         enum ProcessorType {
0058             OriginalOemProcessor = 0,
0059             IntelOverDriveProcessor = 1,
0060             DualProcessor = 2,
0061             IntelReserved = 3
0062         };
0063 
0064         /**
0065          * Reads the CPU capabilities and stores them for faster subsequent access.
0066          *
0067          * Will be executed automatically before main, but not necessarily before other functions
0068          * executing before main.
0069          */
0070         static void Vc_VDECL init();
0071 
0072         //! Return the cache line size in bits.
0073         static inline ushort cacheLineSize() { return static_cast<ushort>(s_cacheLineSize) * 8u; }
0074         //! Return the ProcessorType.
0075         static inline ProcessorType processorType() { return s_processorType; }
0076         //! Return the family number of the processor (vendor dependent).
0077         static inline uint processorFamily() { return s_processorFamily; }
0078         //! Return the model number of the processor (vendor dependent).
0079         static inline uint processorModel() { return s_processorModel; }
0080         //! Return the number of logical processors.
0081         static inline uint logicalProcessors() { return s_logicalProcessors; }
0082         //! Return whether the CPU vendor is AMD.
0083         static inline bool isAmd   () { return s_ecx0 == 0x444D4163; }
0084         //! Return whether the CPU vendor is Intel.
0085         static inline bool isIntel () { return s_ecx0 == 0x6C65746E; }
0086         //! Return whether the CPU supports SSE3.
0087         static inline bool hasSse3 () { return s_processorFeaturesC & (1 << 0); }
0088         //! Return whether the CPU supports the PCLMULQDQ instruction.
0089         static inline bool hasPclmulqdq() { return (s_processorFeaturesC & (1 << 1)) != 0; }
0090         //! Return whether the CPU supports the MONITOR/MWAIT instructions.
0091         static inline bool hasMonitor() { return (s_processorFeaturesC & (1 << 3)) != 0; }
0092         //! Return whether the CPU supports the Virtual Machine Extensions.
0093         static inline bool hasVmx  () { return (s_processorFeaturesC & (1 << 5)) != 0; }
0094         //! Return whether the CPU supports the Safer Mode Extensions.
0095         static inline bool hasSmx  () { return (s_processorFeaturesC & (1 << 6)) != 0; }
0096         //! Return whether the CPU supports the Enhanced Intel SpeedStep technology.
0097         static inline bool hasEist () { return (s_processorFeaturesC & (1 << 7)) != 0; }
0098         //! Return whether the CPU supports Thermal Monitor 2.
0099         static inline bool hasTm2  () { return (s_processorFeaturesC & (1 << 8)) != 0; }
0100         //! Return whether the CPU supports SSSE3.
0101         static inline bool hasSsse3() { return (s_processorFeaturesC & (1 << 9)) != 0; }
0102         //! Return whether the CPU supports FMA extensions using YMM state.
0103         static inline bool hasFma  () { return (s_processorFeaturesC & (1 << 12)) != 0; }
0104         //! Return whether the CPU supports CMPXCHG16B.
0105         static inline bool hasCmpXchg16b() { return (s_processorFeaturesC & (1 << 13)) != 0; }
0106         //! Return whether the CPU supports the Perfmon and Debug Capability.
0107         static inline bool hasPdcm () { return (s_processorFeaturesC & (1 << 15)) != 0; }
0108         //! Return whether the CPU supports Direct Cache Access: prefetch data from a memory mapped device.
0109         static inline bool hasDca()   { return (s_processorFeaturesC & (1 << 18)) != 0; }
0110         //! Return whether the CPU supports SSE 4.1
0111         static inline bool hasSse41() { return (s_processorFeaturesC & (1 << 19)) != 0; }
0112         //! Return whether the CPU supports SSE 4.2
0113         static inline bool hasSse42() { return (s_processorFeaturesC & (1 << 20)) != 0; }
0114         //! Return whether the CPU supports the MOVBE instruction.
0115         static inline bool hasMovbe() { return (s_processorFeaturesC & (1 << 22)) != 0; }
0116         //! Return whether the CPU supports the POPCNT instruction.
0117         static inline bool hasPopcnt(){ return (s_processorFeaturesC & (1 << 23)) != 0; }
0118         //static inline bool hasTscDeadline() { return (s_processorFeaturesC & (1 << 24)) != 0; }
0119         //! Return whether the CPU supports the AESNI instructions.
0120         static inline bool hasAes  () { return (s_processorFeaturesC & (1 << 25)) != 0; }
0121         //static inline bool hasXsave() { return (s_processorFeaturesC & (1 << 26)) != 0; }
0122         //! Return whether the CPU and OS support the XSETBV/XGETBV instructions.
0123         static inline bool hasOsxsave() { return (s_processorFeaturesC & (1 << 27)) != 0; }
0124         //! Return whether the CPU supports AVX.
0125         static inline bool hasAvx  () { return (s_processorFeaturesC & (1 << 28)) != 0; }
0126         //! Return whether the CPU supports BMI1.
0127         static inline bool hasBmi1 () { return (s_processorFeatures7B& (1 << 3)) != 0; }
0128         //! Return whether the CPU supports transactional synchronization extensions.
0129         static inline bool hasHle  () { return (s_processorFeatures7B& (1 << 4)) != 0; }
0130         //! Return whether the CPU supports AVX2.
0131         static inline bool hasAvx2 () { return (s_processorFeatures7B& (1 << 5)) != 0; }
0132         //! Return whether the CPU supports BMI2.
0133         static inline bool hasBmi2 () { return (s_processorFeatures7B& (1 << 8)) != 0; }
0134         //! Return whether the CPU supports transactional synchronization extensions.
0135         static inline bool hasRtm  () { return (s_processorFeatures7B& (1 << 11)) != 0; }
0136 
0137         //! Return whether the CPU supports AVX512f.
0138         static inline bool hasAvx512f   () { return (s_processorFeatures7B & (1u << 16)) != 0; }
0139         //! Return whether the CPU supports AVX512dq.
0140         static inline bool hasAvx512dq  () { return (s_processorFeatures7B & (1u << 17)) != 0; }
0141         //! Return whether the CPU supports AVX512ifma.
0142         static inline bool hasAvx512ifma() { return (s_processorFeatures7B & (1u << 21)) != 0; }
0143         //! Return whether the CPU supports AVX512pf.
0144         static inline bool hasAvx512pf  () { return (s_processorFeatures7B & (1u << 26)) != 0; }
0145         //! Return whether the CPU supports AVX512er.
0146         static inline bool hasAvx512er  () { return (s_processorFeatures7B & (1u << 27)) != 0; }
0147         //! Return whether the CPU supports AVX512cd.
0148         static inline bool hasAvx512cd  () { return (s_processorFeatures7B & (1u << 28)) != 0; }
0149         //! Return whether the CPU supports AVX512bw.
0150         static inline bool hasAvx512bw  () { return (s_processorFeatures7B & (1u << 30)) != 0; }
0151         //! Return whether the CPU supports AVX512vl.
0152         static inline bool hasAvx512vl  () { return (s_processorFeatures7B & (1u << 31)) != 0; }
0153         //! Return whether the CPU supports AVX512vbmi.
0154         static inline bool hasAvx512vbmi() { return (s_processorFeatures7C & (1u <<  1)) != 0; }
0155 
0156         //! Return whether the CPU supports 16-bit floating-point conversion instructions.
0157         static inline bool hasF16c () { return (s_processorFeaturesC & (1 << 29)) != 0; }
0158         //! Return whether the CPU supports the RDRAND instruction.
0159         static inline bool hasRdrand(){ return (s_processorFeaturesC & (1 << 30)) != 0; }
0160         //! Return whether the CPU contains an x87 FPU.
0161         static inline bool hasFpu  () { return (s_processorFeaturesD & (1 << 0)) != 0; }
0162         static inline bool hasVme  () { return (s_processorFeaturesD & (1 << 1)) != 0; }
0163         //! Return whether the CPU contains Debugging Extensions.
0164         static inline bool hasDe   () { return (s_processorFeaturesD & (1 << 2)) != 0; }
0165         //! Return whether the CPU contains Page Size Extensions.
0166         static inline bool hasPse  () { return (s_processorFeaturesD & (1 << 3)) != 0; }
0167         //! Return whether the CPU supports the RDTSC instruction.
0168         static inline bool hasTsc  () { return (s_processorFeaturesD & (1 << 4)) != 0; }
0169         //! Return whether the CPU supports the Model Specific Registers instructions.
0170         static inline bool hasMsr  () { return (s_processorFeaturesD & (1 << 5)) != 0; }
0171         //! Return whether the CPU supports the Physical Address Extension.
0172         static inline bool hasPae  () { return (s_processorFeaturesD & (1 << 6)) != 0; }
0173         //! Return whether the CPU supports the CMPXCHG8B instruction.
0174         static inline bool hasCx8  () { return (s_processorFeaturesD & (1 << 8)) != 0; }
0175         //! Return whether the CPU supports Memory Type Range Registers.
0176         static inline bool hasMtrr () { return (s_processorFeaturesD & (1 << 12)) != 0; }
0177         //! Return whether the CPU supports CMOV instructions.
0178         static inline bool hasCmov () { return (s_processorFeaturesD & (1 << 15)) != 0; }
0179         //! Return whether the CPU supports the CLFLUSH instruction.
0180         static inline bool hasClfsh() { return (s_processorFeaturesD & (1 << 19)) != 0; }
0181         //! Return whether the CPU supports ACPI.
0182         static inline bool hasAcpi () { return (s_processorFeaturesD & (1 << 22)) != 0; }
0183         //! Return whether the CPU supports MMX.
0184         static inline bool hasMmx  () { return (s_processorFeaturesD & (1 << 23)) != 0; }
0185         //! Return whether the CPU supports SSE.
0186         static inline bool hasSse  () { return (s_processorFeaturesD & (1 << 25)) != 0; }
0187         //! Return whether the CPU supports SSE2.
0188         static inline bool hasSse2 () { return (s_processorFeaturesD & (1 << 26)) != 0; }
0189         static inline bool hasHtt  () { return (s_processorFeaturesD & (1 << 28)) != 0; }
0190         //! Return whether the CPU supports SSE4a.
0191         static inline bool hasSse4a() { return (s_processorFeatures8C & (1 << 6)) != 0; }
0192         //! Return whether the CPU supports misaligned SSE instructions.
0193         static inline bool hasMisAlignSse() { return (s_processorFeatures8C & (1 << 7)) != 0; }
0194         //! Return whether the CPU supports the AMD prefetchw instruction.
0195         static inline bool hasAmdPrefetch() { return (s_processorFeatures8C & (1 << 8)) != 0; }
0196         //! Return whether the CPU supports the XOP instructions.
0197         static inline bool hasXop ()        { return (s_processorFeatures8C & (1 << 11)) != 0; }
0198         //! Return whether the CPU supports the FMA4 instructions.
0199         static inline bool hasFma4 ()       { return (s_processorFeatures8C & (1 << 16)) != 0; }
0200         //! Return whether the CPU supports the RDTSCP instruction.
0201         static inline bool hasRdtscp()      { return (s_processorFeatures8D & (1 << 27)) != 0; }
0202         static inline bool has3DNow()       { return (s_processorFeatures8D & (1u << 31)) != 0; }
0203         static inline bool has3DNowExt()    { return (s_processorFeatures8D & (1 << 30)) != 0; }
0204         //! Return the size of the L1 instruction cache.
0205         static inline uint   L1Instruction() { return s_L1Instruction; }
0206         //! Return the size of the L1 data cache.
0207         static inline uint   L1Data() { return s_L1Data; }
0208         //! Return the size of the L2 cache.
0209         static inline uint   L2Data() { return s_L2Data; }
0210         //! Return the size of the L3 cache.
0211         static inline uint   L3Data() { return s_L3Data; }
0212         static inline ushort L1InstructionLineSize() { return s_L1InstructionLineSize; }
0213         static inline ushort L1DataLineSize() { return s_L1DataLineSize; }
0214         static inline ushort L2DataLineSize() { return s_L2DataLineSize; }
0215         static inline ushort L3DataLineSize() { return s_L3DataLineSize; }
0216         static inline uint   L1Associativity() { return s_L1Associativity; }
0217         static inline uint   L2Associativity() { return s_L2Associativity; }
0218         static inline uint   L3Associativity() { return s_L3Associativity; }
0219         static inline ushort prefetch() { return s_prefetch; }
0220 
0221     private:
0222         static void interpret(uchar byte, bool *checkLeaf4);
0223 
0224         static uint   s_ecx0;
0225         static uint   s_logicalProcessors;
0226         static uint   s_processorFeaturesC;
0227         static uint   s_processorFeaturesD;
0228         static uint   s_processorFeatures7B;
0229         static uint   s_processorFeatures7C;
0230         static uint   s_processorFeatures8C;
0231         static uint   s_processorFeatures8D;
0232         static uint   s_L1Instruction;
0233         static uint   s_L1Data;
0234         static uint   s_L2Data;
0235         static uint   s_L3Data;
0236         static ushort s_L1InstructionLineSize;
0237         static ushort s_L1DataLineSize;
0238         static ushort s_L2DataLineSize;
0239         static ushort s_L3DataLineSize;
0240         static uint   s_L1Associativity;
0241         static uint   s_L2Associativity;
0242         static uint   s_L3Associativity;
0243         static ushort s_prefetch;
0244         static uchar  s_brandIndex;
0245         static uchar  s_cacheLineSize;
0246         static uchar  s_processorModel;
0247         static uchar  s_processorFamily;
0248         static ProcessorType s_processorType;
0249         static bool   s_noL2orL3;
0250 };
0251 
0252 #ifndef Vc_COMPILE_LIB
0253 namespace detail
0254 {
0255 template <int = 0> struct RunCpuIdInit {
0256     RunCpuIdInit() { CpuId::init(); }
0257     static RunCpuIdInit tmp;
0258 };
0259 template <int N> RunCpuIdInit<N> RunCpuIdInit<N>::tmp;
0260 namespace
0261 {
0262 static auto ctor = RunCpuIdInit<>::tmp;
0263 }  // unnamed namespace
0264 }  // namespace detail
0265 #endif
0266 
0267 }
0268 
0269 #endif // VC_CPUID_H_