aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2020-03-20 15:29:29 -0700
committerChris Robinson <[email protected]>2020-03-20 15:30:41 -0700
commit0d11de3e8d7f5df5bed784d102fc659809ccb9a9 (patch)
treeb0c5c80991828a26a1f8310db9dc8f0eef4c1566
parentf56ef433d8bbf8709b559276bea79c6acb8167ef (diff)
Move CPUCapFlags and FillCPUCaps to their own source
-rw-r--r--CMakeLists.txt1
-rw-r--r--alc/cpu_caps.cpp147
-rw-r--r--alc/helpers.cpp133
3 files changed, 148 insertions, 133 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 35c748f1..599273a5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -600,6 +600,7 @@ SET(ALC_OBJS
alc/compat.h
alc/converter.cpp
alc/converter.h
+ alc/cpu_caps.cpp
alc/cpu_caps.h
alc/devformat.h
alc/effects/base.h
diff --git a/alc/cpu_caps.cpp b/alc/cpu_caps.cpp
new file mode 100644
index 00000000..9470d7a0
--- /dev/null
+++ b/alc/cpu_caps.cpp
@@ -0,0 +1,147 @@
+
+#include "config.h"
+
+#include "cpu_caps.h"
+
+#ifdef HAVE_INTRIN_H
+#include <intrin.h>
+#endif
+#ifdef HAVE_CPUID_H
+#include <cpuid.h>
+#endif
+
+#include <cctype>
+#include <fstream>
+#include <string>
+
+#include "logging.h"
+
+
+int CPUCapFlags{0};
+
+namespace {
+
+#if defined(HAVE_GCC_GET_CPUID) \
+ && (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64))
+using reg_type = unsigned int;
+inline void get_cpuid(unsigned int f, reg_type *regs)
+{ __get_cpuid(f, &regs[0], &regs[1], &regs[2], &regs[3]); }
+#define CAN_GET_CPUID
+#elif defined(HAVE_CPUID_INTRINSIC) \
+ && (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64))
+using reg_type = int;
+inline void get_cpuid(unsigned int f, reg_type *regs)
+{ (__cpuid)(regs, f); }
+#define CAN_GET_CPUID
+#endif
+
+} // namespace
+
+
+void FillCPUCaps(int capfilter)
+{
+ int caps{0};
+
+/* FIXME: We really should get this for all available CPUs in case different
+ * CPUs have different caps (is that possible on one machine?).
+ */
+#ifdef CAN_GET_CPUID
+ union {
+ reg_type regs[4];
+ char str[sizeof(reg_type[4])];
+ } cpuinf[3]{};
+
+ get_cpuid(0, cpuinf[0].regs);
+ if(cpuinf[0].regs[0] == 0)
+ ERR("Failed to get CPUID\n");
+ else
+ {
+ const reg_type maxfunc{cpuinf[0].regs[0]};
+
+ get_cpuid(0x80000000, cpuinf[0].regs);
+ const reg_type maxextfunc{cpuinf[0].regs[0]};
+
+ TRACE("Detected max CPUID function: 0x%x (ext. 0x%x)\n", maxfunc, maxextfunc);
+
+ TRACE("Vendor ID: \"%.4s%.4s%.4s\"\n", cpuinf[0].str+4, cpuinf[0].str+12, cpuinf[0].str+8);
+ if(maxextfunc >= 0x80000004)
+ {
+ get_cpuid(0x80000002, cpuinf[0].regs);
+ get_cpuid(0x80000003, cpuinf[1].regs);
+ get_cpuid(0x80000004, cpuinf[2].regs);
+ TRACE("Name: \"%.16s%.16s%.16s\"\n", cpuinf[0].str, cpuinf[1].str, cpuinf[2].str);
+ }
+
+ if(maxfunc >= 1)
+ {
+ get_cpuid(1, cpuinf[0].regs);
+ if((cpuinf[0].regs[3]&(1<<25)))
+ caps |= CPU_CAP_SSE;
+ if((caps&CPU_CAP_SSE) && (cpuinf[0].regs[3]&(1<<26)))
+ caps |= CPU_CAP_SSE2;
+ if((caps&CPU_CAP_SSE2) && (cpuinf[0].regs[2]&(1<<0)))
+ caps |= CPU_CAP_SSE3;
+ if((caps&CPU_CAP_SSE3) && (cpuinf[0].regs[2]&(1<<19)))
+ caps |= CPU_CAP_SSE4_1;
+ }
+ }
+#else
+ /* Assume support for whatever's supported if we can't check for it */
+#if defined(HAVE_SSE4_1)
+#warning "Assuming SSE 4.1 run-time support!"
+ caps |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
+#elif defined(HAVE_SSE3)
+#warning "Assuming SSE 3 run-time support!"
+ caps |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
+#elif defined(HAVE_SSE2)
+#warning "Assuming SSE 2 run-time support!"
+ caps |= CPU_CAP_SSE | CPU_CAP_SSE2;
+#elif defined(HAVE_SSE)
+#warning "Assuming SSE run-time support!"
+ caps |= CPU_CAP_SSE;
+#endif
+#endif
+#ifdef HAVE_NEON
+ al::ifstream file{"/proc/cpuinfo"};
+ if(!file.is_open())
+ ERR("Failed to open /proc/cpuinfo, cannot check for NEON support\n");
+ else
+ {
+ std::string features;
+
+ auto getline = [](std::istream &f, std::string &output) -> bool
+ {
+ while(f.good() && f.peek() == '\n')
+ f.ignore();
+ return std::getline(f, output) && !output.empty();
+ };
+ while(getline(file, features))
+ {
+ if(features.compare(0, 10, "Features\t:", 10) == 0)
+ break;
+ }
+ file.close();
+
+ size_t extpos{9};
+ while((extpos=features.find("neon", extpos+1)) != std::string::npos)
+ {
+ if((extpos == 0 || std::isspace(features[extpos-1])) &&
+ (extpos+4 == features.length() || std::isspace(features[extpos+4])))
+ {
+ caps |= CPU_CAP_NEON;
+ break;
+ }
+ }
+ }
+#endif
+
+ TRACE("Extensions:%s%s%s%s%s%s\n",
+ ((capfilter&CPU_CAP_SSE) ? ((caps&CPU_CAP_SSE) ? " +SSE" : " -SSE") : ""),
+ ((capfilter&CPU_CAP_SSE2) ? ((caps&CPU_CAP_SSE2) ? " +SSE2" : " -SSE2") : ""),
+ ((capfilter&CPU_CAP_SSE3) ? ((caps&CPU_CAP_SSE3) ? " +SSE3" : " -SSE3") : ""),
+ ((capfilter&CPU_CAP_SSE4_1) ? ((caps&CPU_CAP_SSE4_1) ? " +SSE4.1" : " -SSE4.1") : ""),
+ ((capfilter&CPU_CAP_NEON) ? ((caps&CPU_CAP_NEON) ? " +NEON" : " -NEON") : ""),
+ ((!capfilter) ? " -none-" : "")
+ );
+ CPUCapFlags = caps & capfilter;
+}
diff --git a/alc/helpers.cpp b/alc/helpers.cpp
index 5006bc51..5b3733d0 100644
--- a/alc/helpers.cpp
+++ b/alc/helpers.cpp
@@ -40,12 +40,6 @@
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
-#ifdef HAVE_INTRIN_H
-#include <intrin.h>
-#endif
-#ifdef HAVE_CPUID_H
-#include <cpuid.h>
-#endif
#ifdef HAVE_SYS_SYSCONF_H
#include <sys/sysconf.h>
#endif
@@ -71,138 +65,11 @@
#include "alspan.h"
#include "alstring.h"
#include "compat.h"
-#include "cpu_caps.h"
#include "logging.h"
#include "strutils.h"
#include "vector.h"
-#if defined(HAVE_GCC_GET_CPUID) && (defined(__i386__) || defined(__x86_64__) || \
- defined(_M_IX86) || defined(_M_X64))
-using reg_type = unsigned int;
-static inline void get_cpuid(unsigned int f, reg_type *regs)
-{ __get_cpuid(f, &regs[0], &regs[1], &regs[2], &regs[3]); }
-#define CAN_GET_CPUID
-#elif defined(HAVE_CPUID_INTRINSIC) && (defined(__i386__) || defined(__x86_64__) || \
- defined(_M_IX86) || defined(_M_X64))
-using reg_type = int;
-static inline void get_cpuid(unsigned int f, reg_type *regs)
-{ (__cpuid)(regs, f); }
-#define CAN_GET_CPUID
-#endif
-
-int CPUCapFlags = 0;
-
-void FillCPUCaps(int capfilter)
-{
- int caps = 0;
-
-/* FIXME: We really should get this for all available CPUs in case different
- * CPUs have different caps (is that possible on one machine?). */
-#ifdef CAN_GET_CPUID
- union {
- reg_type regs[4];
- char str[sizeof(reg_type[4])];
- } cpuinf[3]{};
-
- get_cpuid(0, cpuinf[0].regs);
- if(cpuinf[0].regs[0] == 0)
- ERR("Failed to get CPUID\n");
- else
- {
- unsigned int maxfunc = cpuinf[0].regs[0];
- unsigned int maxextfunc;
-
- get_cpuid(0x80000000, cpuinf[0].regs);
- maxextfunc = cpuinf[0].regs[0];
-
- TRACE("Detected max CPUID function: 0x%x (ext. 0x%x)\n", maxfunc, maxextfunc);
-
- TRACE("Vendor ID: \"%.4s%.4s%.4s\"\n", cpuinf[0].str+4, cpuinf[0].str+12, cpuinf[0].str+8);
- if(maxextfunc >= 0x80000004)
- {
- get_cpuid(0x80000002, cpuinf[0].regs);
- get_cpuid(0x80000003, cpuinf[1].regs);
- get_cpuid(0x80000004, cpuinf[2].regs);
- TRACE("Name: \"%.16s%.16s%.16s\"\n", cpuinf[0].str, cpuinf[1].str, cpuinf[2].str);
- }
-
- if(maxfunc >= 1)
- {
- get_cpuid(1, cpuinf[0].regs);
- if((cpuinf[0].regs[3]&(1<<25)))
- caps |= CPU_CAP_SSE;
- if((caps&CPU_CAP_SSE) && (cpuinf[0].regs[3]&(1<<26)))
- caps |= CPU_CAP_SSE2;
- if((caps&CPU_CAP_SSE2) && (cpuinf[0].regs[2]&(1<<0)))
- caps |= CPU_CAP_SSE3;
- if((caps&CPU_CAP_SSE3) && (cpuinf[0].regs[2]&(1<<19)))
- caps |= CPU_CAP_SSE4_1;
- }
- }
-#else
- /* Assume support for whatever's supported if we can't check for it */
-#if defined(HAVE_SSE4_1)
-#warning "Assuming SSE 4.1 run-time support!"
- caps |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
-#elif defined(HAVE_SSE3)
-#warning "Assuming SSE 3 run-time support!"
- caps |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
-#elif defined(HAVE_SSE2)
-#warning "Assuming SSE 2 run-time support!"
- caps |= CPU_CAP_SSE | CPU_CAP_SSE2;
-#elif defined(HAVE_SSE)
-#warning "Assuming SSE run-time support!"
- caps |= CPU_CAP_SSE;
-#endif
-#endif
-#ifdef HAVE_NEON
- al::ifstream file{"/proc/cpuinfo"};
- if(!file.is_open())
- ERR("Failed to open /proc/cpuinfo, cannot check for NEON support\n");
- else
- {
- std::string features;
-
- auto getline = [](std::istream &f, std::string &output) -> bool
- {
- while(f.good() && f.peek() == '\n')
- f.ignore();
- return std::getline(f, output) && !output.empty();
-
- };
- while(getline(file, features))
- {
- if(features.compare(0, 10, "Features\t:", 10) == 0)
- break;
- }
- file.close();
-
- size_t extpos{9};
- while((extpos=features.find("neon", extpos+1)) != std::string::npos)
- {
- if((extpos == 0 || std::isspace(features[extpos-1])) &&
- (extpos+4 == features.length() || std::isspace(features[extpos+4])))
- {
- caps |= CPU_CAP_NEON;
- break;
- }
- }
- }
-#endif
-
- TRACE("Extensions:%s%s%s%s%s%s\n",
- ((capfilter&CPU_CAP_SSE) ? ((caps&CPU_CAP_SSE) ? " +SSE" : " -SSE") : ""),
- ((capfilter&CPU_CAP_SSE2) ? ((caps&CPU_CAP_SSE2) ? " +SSE2" : " -SSE2") : ""),
- ((capfilter&CPU_CAP_SSE3) ? ((caps&CPU_CAP_SSE3) ? " +SSE3" : " -SSE3") : ""),
- ((capfilter&CPU_CAP_SSE4_1) ? ((caps&CPU_CAP_SSE4_1) ? " +SSE4.1" : " -SSE4.1") : ""),
- ((capfilter&CPU_CAP_NEON) ? ((caps&CPU_CAP_NEON) ? " +NEON" : " -NEON") : ""),
- ((!capfilter) ? " -none-" : "")
- );
- CPUCapFlags = caps & capfilter;
-}
-
-
#ifdef _WIN32
const PathNamePair &GetProcBinary()