diff options
author | Patrick Roth <roth@stettbacher.ch> | 2019-10-04 11:51:48 +0200 |
---|---|---|
committer | Patrick Roth <roth@stettbacher.ch> | 2019-10-04 11:51:48 +0200 |
commit | a0f501fa5650d0b6062cc8f26b34bce11137643d (patch) | |
tree | 8e31c5ac3409d4ce48887d88d4530b88a02c2660 /cpu_feature.c | |
download | o3000-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.c | 122 |
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__ |