LeechCraft  0.6.70-15082-g543737046d
Modular cross-platform feature rich live environment.
cpufeatures.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * LeechCraft - modular cross-platform feature rich internet client.
3  * Copyright (C) 2006-2014 Georg Rudoy
4  *
5  * Distributed under the Boost Software License, Version 1.0.
6  * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7  **********************************************************************/
8 
9 #include "cpufeatures.h"
10 #include <mutex>
11 #include <QStringList>
12 #include <QtDebug>
13 
14 #if defined (Q_PROCESSOR_X86)
15 #define HAS_CPUID
16 #endif
17 
18 #ifdef HAS_CPUID
19 #include <cpuid.h>
20 #endif
21 
22 #include <util/sll/unreachable.h>
23 
24 namespace LC::Util
25 {
27  {
28 #ifdef HAS_CPUID
29  uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
30  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
31  qWarning () << Q_FUNC_INFO
32  << "failed to get CPUID eax = 1";
33  else
34  Ecx1_ = ecx;
35 
36  if (__get_cpuid_max (0, nullptr) < 7)
37  qWarning () << Q_FUNC_INFO
38  << "cpuid max less than 7";
39  else
40  {
41  __cpuid_count (7, 0, eax, ebx, ecx, edx);
42  Ebx7_ = ebx;
43  }
44 #endif
45 
46  static std::once_flag dbgFlag;
47  std::call_once (dbgFlag,
48  [this] { DumpDetectedFeatures (); });
49  }
50 
51  QString CpuFeatures::GetFeatureName (Feature feature)
52  {
53  switch (feature)
54  {
55  case Feature::SSSE3:
56  return "ssse3";
58  return "sse4.1";
59  case Feature::AVX:
60  return "avx";
61  case Feature::XSave:
62  return "xsave";
63  case Feature::AVX2:
64  return "avx2";
65  case Feature::None:
66  return "";
67  }
68 
70  }
71 
72  bool CpuFeatures::HasFeature (Feature feature) const
73  {
74  switch (feature)
75  {
76  case Feature::SSSE3:
77  return Ecx1_ & (1 << 9);
79  return Ecx1_ & (1 << 19);
80  case Feature::AVX:
81  return Ecx1_ & (1 << 28);
82  case Feature::XSave:
83  return Ecx1_ & (1 << 26);
84  case Feature::AVX2:
85  return HasFeature (Feature::XSave) && (Ebx7_ & (1 << 5));
86  case Feature::None:
87  return true;
88  }
89 
91  }
92 
93  void CpuFeatures::DumpDetectedFeatures () const
94  {
95  if (qEnvironmentVariableIsEmpty ("DUMP_CPUFEATURES"))
96  return;
97 
98  QStringList detected;
99  QStringList undetected;
100 
101  for (int i = 0; i < static_cast<int> (Feature::None); ++i)
102  {
103  const auto feature = static_cast<Feature> (i);
104  const auto& featureName = GetFeatureName (feature);
105  if (HasFeature (feature))
106  detected << featureName;
107  else
108  undetected << featureName;
109  }
110 
111  qDebug () << Q_FUNC_INFO;
112  qDebug () << "detected the following CPU features:" << detected.join (' ').toUtf8 ().constData ();
113  qDebug () << "couldn't detect the following CPU features:" << undetected.join (' ').toUtf8 ().constData ();
114  }
115 }
LC::Util::CpuFeatures::Feature::None
@ None
LC::Util::CpuFeatures::Feature
Feature
Definition: cpufeatures.h:26
LC::Util
Definition: icoreproxy.h:33
LC::Util::CpuFeatures::CpuFeatures
CpuFeatures()
Definition: cpufeatures.cpp:32
LC::Util::CpuFeatures::Feature::AVX2
@ AVX2
cpufeatures.h
LC::Util::Unreachable
void Unreachable()
Definition: unreachable.h:27
LC::Util::CpuFeatures::Feature::XSave
@ XSave
LC::Util::CpuFeatures::Feature::SSE41
@ SSE41
LC::Util::CpuFeatures::HasFeature
bool HasFeature(Feature) const
Definition: cpufeatures.cpp:78
LC::Util::CpuFeatures::GetFeatureName
static QString GetFeatureName(Feature)
Definition: cpufeatures.cpp:57
LC::Util::CpuFeatures::Feature::SSSE3
@ SSSE3
unreachable.h
LC::Util::CpuFeatures::Feature::AVX
@ AVX