aboutsummaryrefslogtreecommitdiffstats
path: root/cpu_feature.c
diff options
context:
space:
mode:
authorPatrick Roth <roth@stettbacher.ch>2019-10-04 11:51:48 +0200
committerPatrick Roth <roth@stettbacher.ch>2019-10-04 11:51:48 +0200
commita0f501fa5650d0b6062cc8f26b34bce11137643d (patch)
tree8e31c5ac3409d4ce48887d88d4530b88a02c2660 /cpu_feature.c
downloado3000-color-pipe-a0f501fa5650d0b6062cc8f26b34bce11137643d.tar.gz
o3000-color-pipe-a0f501fa5650d0b6062cc8f26b34bce11137643d.zip
initial commit
import from github
Diffstat (limited to 'cpu_feature.c')
-rw-r--r--cpu_feature.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/cpu_feature.c b/cpu_feature.c
new file mode 100644
index 0000000..62080a5
--- /dev/null
+++ b/cpu_feature.c
@@ -0,0 +1,122 @@
+/**
+* @file cpu_feature.c
+* @brief CPU feature detection (CPU ID)
+* @author Patrick Roth - roth@stettbacher.ch
+* @version 1.0
+* @date 2015-11-12
+* @copyright 2012-2016 Stettbacher Signal Processing AG
+*
+* @remarks
+*
+* <PRE>
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+* </PRE>
+*
+*/
+
+
+#if __x86_64__
+
+#include <stdio.h>
+#include <cpuid.h>
+#include <stdint.h>
+
+#include "cpu_feature.h"
+
+
+// level 1
+static int cpu_feature_sse;
+static int cpu_feature_sse2;
+static int cpu_feature_sse3;
+static int cpu_feature_ssse3;
+static int cpu_feature_fma;
+static int cpu_feature_avx;
+
+// level 7
+static int cpu_feature_avx2;
+
+
+/**
+ * Check whether given CPU feature is available or not.
+ *
+ * @param type CPU feature type to check
+ * @return not 0 if available, 0 if not
+ */
+int cpu_feature_support(enum cpu_feature_t type) {
+
+ /*
+ * Any CPU feature is disabled on 32 bit machine.
+ */
+ switch(type) {
+ case CPU_FEATURE_SSE: return cpu_feature_sse;
+ case CPU_FEATURE_SSE2: return cpu_feature_sse2;
+ case CPU_FEATURE_SSE3: return cpu_feature_sse3;
+ case CPU_FEATURE_SSSE3: return cpu_feature_ssse3;
+ case CPU_FEATURE_FMA: return cpu_feature_fma;
+ case CPU_FEATURE_AVX: return cpu_feature_avx;
+ case CPU_FEATURE_AVX2: return cpu_feature_avx2;
+ }
+ return 0;
+}
+
+
+/**
+ * Initialize CPU features detection like MMX, SSE, SSE2, AVX etc.
+ * This function read and handles the CPU IDs.
+ *
+ * @return 0 on success otherwise -1
+ */
+int cpu_feature_init(void) {
+
+ unsigned int cpuid_basic, /*cpuid_highest, */sig;
+ unsigned int eax, ebx, ecx, edx;
+
+
+ cpuid_basic = __get_cpuid_max(0, &sig);
+ if(cpuid_basic == 0) {
+ printf("%s: Basic CPUID is not supported\n", __func__);
+ return -1;
+ }
+// cpuid_highest = __get_cpuid_max(0x8000000, NULL);
+
+ if(cpuid_basic >= 1) {
+ __cpuid_count(1, 0, eax, ebx, ecx, edx);
+
+ cpu_feature_sse = (edx & bit_SSE) != 0 ? 1:0;
+ cpu_feature_sse2 = (edx & bit_SSE2) != 0 ? 1:0;
+
+ cpu_feature_sse3 = (ecx & bit_SSE3) != 0 ? 1:0;
+ cpu_feature_ssse3 = (ecx & bit_SSSE3) != 0 ? 1:0;
+ cpu_feature_fma = (ecx & bit_FMA) != 0 ? 1:0;
+ cpu_feature_avx = (ecx & bit_AVX) != 0 ? 1:0;
+ }
+
+ if(cpuid_basic >= 7) {
+ __cpuid_count(7, 0, eax, ebx, ecx, edx);
+
+ cpu_feature_avx2 = (ebx & bit_AVX2) != 0 ? 1:0;
+ }
+
+// printf("%s: SSE %s\n", __func__, cpu_feature_sse != 0 ? "yes":"no");
+// printf("%s: SSE2 %s\n", __func__, cpu_feature_sse2 != 0 ? "yes":"no");
+// printf("%s: SSE3 %s\n", __func__, cpu_feature_sse3 != 0 ? "yes":"no");
+// printf("%s: SSSE3 %s\n", __func__, cpu_feature_ssse3 != 0 ? "yes":"no");
+// printf("%s: FMA %s\n", __func__, cpu_feature_fma != 0 ? "yes":"no");
+// printf("%s: AVX %s\n", __func__, cpu_feature_avx != 0 ? "yes":"no");
+// printf("%s: AVX2 %s\n", __func__, cpu_feature_avx2 != 0 ? "yes":"no");
+ return 0;
+}
+
+#endif // __x86_64__