summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Asteborg <maastebo@microsoft.com>2022-07-06 21:35:16 -0700
committerMark Harris <mark.hsj@gmail.com>2022-07-07 22:07:33 -0700
commit510e1029b45aa01a7047e5b3b82169be40911b96 (patch)
tree862a8e1b774311edb4b2beab2ede4b400623896d
parenta80e9e9533d4edeaae282b82f77b8bd8a4903eca (diff)
downloadopus-510e1029b45aa01a7047e5b3b82169be40911b96.tar.gz
cmake - fix rtcd detection on x86 non windows
Signed-off-by: Mark Harris <mark.hsj@gmail.com>
-rw-r--r--CMakeLists.txt14
-rw-r--r--Makefile.am2
-rw-r--r--cmake/OpusFunctions.cmake30
-rw-r--r--cmake/cpu_info_by_asm.c31
-rw-r--r--cmake/cpu_info_by_c.c9
5 files changed, 76 insertions, 10 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 589d1794..75362ccf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -366,11 +366,21 @@ if(NOT OPUS_ENABLE_FLOAT_API)
endif()
if(NOT OPUS_DISABLE_INTRINSICS)
- if((OPUS_X86_MAY_HAVE_SSE AND NOT OPUS_X86_PRESUME_SSE) OR
+ if(((OPUS_X86_MAY_HAVE_SSE AND NOT OPUS_X86_PRESUME_SSE) OR
(OPUS_X86_MAY_HAVE_SSE2 AND NOT OPUS_X86_PRESUME_SSE2) OR
(OPUS_X86_MAY_HAVE_SSE4_1 AND NOT OPUS_X86_PRESUME_SSE4_1) OR
- (OPUS_X86_MAY_HAVE_AVX AND NOT OPUS_X86_PRESUME_AVX))
+ (OPUS_X86_MAY_HAVE_AVX AND NOT OPUS_X86_PRESUME_AVX)) AND
+ RUNTIME_CPU_CAPABILITY_DETECTION)
target_compile_definitions(opus PRIVATE OPUS_HAVE_RTCD)
+ if(NOT MSVC)
+ if(CPU_INFO_BY_ASM_SUPPORTED)
+ target_compile_definitions(opus PRIVATE CPU_INFO_BY_ASM)
+ elseif(CPU_INFO_BY_C_SUPPORTED)
+ target_compile_definitions(opus PRIVATE CPU_INFO_BY_C)
+ else()
+ message(ERROR "Runtime cpu capability detection is enabled while CPU_INFO is not supported")
+ endif()
+ endif()
endif()
if(SSE1_SUPPORTED)
diff --git a/Makefile.am b/Makefile.am
index 70a2ebfa..e1f8c2c4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -225,6 +225,8 @@ EXTRA_DIST = opus.pc.in \
cmake/RunTest.cmake \
cmake/config.h.cmake.in \
cmake/vla.c \
+ cmake/cpu_info_by_asm.c \
+ cmake/cpu_info_by_c.c \
meson/get-version.py \
meson/read-sources-list.py \
meson.build \
diff --git a/cmake/OpusFunctions.cmake b/cmake/OpusFunctions.cmake
index fcf3351f..3f22ad81 100644
--- a/cmake/OpusFunctions.cmake
+++ b/cmake/OpusFunctions.cmake
@@ -142,14 +142,28 @@ function(opus_detect_neon COMPILER_SUPPORT_NEON)
endfunction()
function(opus_supports_cpu_detection RUNTIME_CPU_CAPABILITY_DETECTION)
- if(MSVC)
- check_include_file(intrin.h HAVE_INTRIN_H)
- else()
- check_include_file(cpuid.h HAVE_CPUID_H)
- endif()
- if(HAVE_INTRIN_H OR HAVE_CPUID_H)
- set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE)
- elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(arm|aarch64)")
+ set(RUNTIME_CPU_CAPABILITY_DETECTION 0 PARENT_SCOPE)
+ if(OPUS_CPU_X86 OR OPUS_CPU_X64)
+ if(MSVC)
+ check_include_file(intrin.h HAVE_INTRIN_H)
+ if(HAVE_INTRIN_H)
+ # if intrin.h is available we assume __cpuid is there
+ set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE)
+ endif()
+ else()
+ include(CFeatureCheck)
+ c_feature_check(CPU_INFO_BY_ASM)
+ set(CPU_INFO_BY_ASM_SUPPORTED ${CPU_INFO_BY_ASM_SUPPORTED} PARENT_SCOPE)
+ check_include_file(cpuid.h HAVE_CPUID_H)
+ if(HAVE_CPUID_H)
+ c_feature_check(CPU_INFO_BY_C)
+ set(CPU_INFO_BY_C_SUPPORTED ${CPU_INFO_BY_C_SUPPORTED} PARENT_SCOPE)
+ endif()
+ if(CPU_INFO_BY_ASM_SUPPORTED OR CPU_INFO_BY_C_SUPPORTED)
+ set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE)
+ endif()
+ endif()
+ elseif(OPUS_CPU_ARM)
# ARM cpu detection is implemented for Windows and anything
# using a Linux kernel (such as Android).
if (CMAKE_SYSTEM_NAME MATCHES "(Windows|Linux|Android)")
diff --git a/cmake/cpu_info_by_asm.c b/cmake/cpu_info_by_asm.c
new file mode 100644
index 00000000..1a70a815
--- /dev/null
+++ b/cmake/cpu_info_by_asm.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+int main() {
+ unsigned int CPUInfo0;
+ unsigned int CPUInfo1;
+ unsigned int CPUInfo2;
+ unsigned int CPUInfo3;
+ unsigned int InfoType;
+#if defined(__i386__) && defined(__PIC__)
+/* %ebx is PIC register in 32-bit, so mustn't clobber it. */
+ __asm__ __volatile__ (
+ "xchg %%ebx, %1\n"
+ "cpuid\n"
+ "xchg %%ebx, %1\n":
+ "=a" (CPUInfo0),
+ "=r" (CPUInfo1),
+ "=c" (CPUInfo2),
+ "=d" (CPUInfo3) :
+ "0" (InfoType), "2" (0)
+ );
+#else
+ __asm__ __volatile__ (
+ "cpuid":
+ "=a" (CPUInfo0),
+ "=b" (CPUInfo1),
+ "=c" (CPUInfo2),
+ "=d" (CPUInfo3) :
+ "0" (InfoType), "2" (0)
+ );
+#endif
+ return 0;
+}
diff --git a/cmake/cpu_info_by_c.c b/cmake/cpu_info_by_c.c
new file mode 100644
index 00000000..117084eb
--- /dev/null
+++ b/cmake/cpu_info_by_c.c
@@ -0,0 +1,9 @@
+#include <cpuid.h>
+int main() {
+ unsigned int CPUInfo0;
+ unsigned int CPUInfo1;
+ unsigned int CPUInfo2;
+ unsigned int CPUInfo3;
+ unsigned int InfoType;
+ return __get_cpuid_count(InfoType, 0, &CPUInfo0, &CPUInfo1, &CPUInfo2, &CPUInfo3);
+}