From 68e425f869a78d9cda721a1c7ed34ac15ea78974 Mon Sep 17 00:00:00 2001 From: Piotr Kubaj Date: Wed, 13 Oct 2021 18:19:57 +0200 Subject: [PATCH] Add support for runtime CPU feature check on POWER on FreeBSD. 1. Code uses PPC_FEATURE_HAS_VSX, but it's not checked similarly to PPC_FEATURE2_ARCH_3_00 and PPC_FEATURE2_ARCH_3_00 for availability. FreeBSD has those macros in machine/cpu.h, but I went with the way chosen for PPC_FEATURE2_ARCH_3_00 and PPC_FEATURE2_ARCH_3_00. Other than that, FreeBSD also has sys/auxv.h and that's where elf_aux_info() is defined. 2. getauxval() is actually Linux-only, but code checked for __unix__. It won't work on all UNIX, so change it back to __linux__. Add another code variant strictly for FreeBSD. 3. Update comment. This commit adds code for FreeBSD, but recently there appeared support for powerpc64 in OpenBSD. --- modules/core/src/system.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index 49e146372e..16e5c749ef 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -155,6 +155,9 @@ void* allocSingletonNewBuffer(size_t size) { return malloc(size); } # ifndef PPC_FEATURE2_ARCH_3_00 # define PPC_FEATURE2_ARCH_3_00 0x00800000 # endif +# ifndef PPC_FEATURE_HAS_VSX +# define PPC_FEATURE_HAS_VSX 0x00000080 +# endif #endif #if defined _WIN32 || defined WINCE @@ -607,7 +610,7 @@ struct HWFeatures have[CV_CPU_MSA] = true; #endif - #if (defined __ppc64__ || defined __PPC64__) && defined __unix__ + #if (defined __ppc64__ || defined __PPC64__) && defined __linux__ unsigned int hwcap = getauxval(AT_HWCAP); if (hwcap & PPC_FEATURE_HAS_VSX) { hwcap = getauxval(AT_HWCAP2); @@ -617,8 +620,19 @@ struct HWFeatures have[CV_CPU_VSX] = (hwcap & PPC_FEATURE2_ARCH_2_07) != 0; } } + #elif (defined __ppc64__ || defined __PPC64__) && defined __FreeBSD__ + unsigned int hwcap = 0; + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + if (hwcap & PPC_FEATURE_HAS_VSX) { + elf_aux_info(AT_HWCAP2, &hwcap, sizeof(hwcap)); + if (hwcap & PPC_FEATURE2_ARCH_3_00) { + have[CV_CPU_VSX] = have[CV_CPU_VSX3] = true; + } else { + have[CV_CPU_VSX] = (hwcap & PPC_FEATURE2_ARCH_2_07) != 0; + } + } #else - // TODO: AIX, FreeBSD + // TODO: AIX, OpenBSD #if CV_VSX || defined _ARCH_PWR8 || defined __POWER9_VECTOR__ have[CV_CPU_VSX] = true; #endif