From: Mika T. Lindqvist Date: Sun, 11 Jun 2023 22:18:12 +0000 (+0300) Subject: Use endianess-specific built-in function for gcc < 12 on PowerPC64 X-Git-Tag: 2.1.3~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7cda3bf660b13f775f563740c9b99957a1383e01;p=thirdparty%2Fzlib-ng.git Use endianess-specific built-in function for gcc < 12 on PowerPC64 * Add support for cross-compiling using clang 13 and later for PowerPC64 little-endian and big-endian * Fix detection for availability of Power9 intrinsics --- diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index d00ecb4c4..752d628d9 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -230,6 +230,11 @@ jobs: ldflags: -static codecov: ubuntu_gcc_ppc64_power9 + - name: Ubuntu Clang PPC64 Power9 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64-clang.cmake + packages: qemu qemu-user clang binutils-powerpc64-linux-gnu libc-dev-ppc64-cross libgcc-11-dev-ppc64-cross libstdc++-11-dev-ppc64-cross + - name: Ubuntu GCC PPC64LE os: ubuntu-20.04 cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake @@ -248,6 +253,11 @@ jobs: packages: qemu qemu-user gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc-dev-ppc64el-cross codecov: ubuntu_gcc_ppc64le_power9 + - name: Ubuntu Clang PPC64LE Power9 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le-clang.cmake + packages: qemu qemu-user clang binutils-powerpc64le-linux-gnu libc-dev-ppc64el-cross libgcc-11-dev-ppc64el-cross libstdc++-11-dev-ppc64el-cross + - name: Ubuntu GCC SPARC64 os: ubuntu-20.04 cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sparc64.cmake diff --git a/arch/power/chunkset_power8.c b/arch/power/chunkset_power8.c index 443aae92f..7cbb8029b 100644 --- a/arch/power/chunkset_power8.c +++ b/arch/power/chunkset_power8.c @@ -29,7 +29,7 @@ static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { uint64_t tmp; memcpy(&tmp, from, sizeof(tmp)); - *chunk = (vector unsigned char)vec_splats(tmp); + *chunk = (vector unsigned char)vec_splats((unsigned long long)tmp); } static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { diff --git a/arch/power/compare256_power9.c b/arch/power/compare256_power9.c index be094350f..9b0ddaf80 100644 --- a/arch/power/compare256_power9.c +++ b/arch/power/compare256_power9.c @@ -10,12 +10,14 @@ /* Older versions of GCC misimplemented semantics for these bit counting builtins. * https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=3f30f2d1dbb3228b8468b26239fe60c2974ce2ac */ -#if defined(__GNUC__) && (__GNUC__ < 13) -# define zng_vec_vctzlsbb(vc, len) __asm__ volatile("vctzlsbb %0, %1\n\t" : "=r" (len) : "v" (vc)) -# define zng_vec_vclzlsbb(vc, len) __asm__ volatile("vclzlsbb %0, %1\n\t" : "=r" (len) : "v" (vc)) -#else +#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ < 12) +#if BYTE_ORDER == LITTLE_ENDIAN # define zng_vec_vctzlsbb(vc, len) len = __builtin_vec_vctzlsbb(vc) -# define zng_vec_vclzlsbb(vc, len) len = __builtin_vec_vclzlsbb(vc) +#else +# define zng_vec_vctzlsbb(vc, len) len = __builtin_vec_vclzlsbb(vc) +#endif +#else +# define zng_vec_vctzlsbb(vc, len) len = vec_cntlz_lsbb(vc) #endif static inline uint32_t compare256_power9_static(const uint8_t *src0, const uint8_t *src1) { @@ -34,11 +36,7 @@ static inline uint32_t compare256_power9_static(const uint8_t *src0, const uint8 /* Since the index of matching bytes will contain only zeroes * on vc (since we used cmpne), counting the number of consecutive * bytes where LSB == 0 is the same as counting the length of the match. */ -#if BYTE_ORDER == LITTLE_ENDIAN zng_vec_vctzlsbb(vc, cmplen); -#else - zng_vec_vclzlsbb(vc, cmplen); -#endif if (cmplen != 16) return len + cmplen; diff --git a/arch/power/power_features.c b/arch/power/power_features.c index 003a4c6e3..f73503734 100644 --- a/arch/power/power_features.c +++ b/arch/power/power_features.c @@ -34,9 +34,13 @@ void Z_INTERNAL power_check_features(struct power_cpu_features *features) { hwcap2 = getauxval(AT_HWCAP2); #endif +#ifdef POWER8_VSX if (hwcap2 & PPC_FEATURE2_ARCH_2_07) features->has_arch_2_07 = 1; +#endif +#ifdef POWER9 if (hwcap2 & PPC_FEATURE2_ARCH_3_00) features->has_arch_3_00 = 1; #endif +#endif } diff --git a/cmake/detect-intrinsics.cmake b/cmake/detect-intrinsics.cmake index e9e6d36da..9cbc59089 100644 --- a/cmake/detect-intrinsics.cmake +++ b/cmake/detect-intrinsics.cmake @@ -393,8 +393,18 @@ macro(check_power9_intrinsics) # Check if we have what we need for POWER9 optimizations set(CMAKE_REQUIRED_FLAGS "${POWER9FLAG} ${NATIVEFLAG}") check_c_source_compiles( - "int main() { - return 0; + "#include + #ifdef __FreeBSD__ + #include + #endif + int main() { + #ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP2, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE2_ARCH_3_00); + #else + return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00); + #endif }" HAVE_POWER9_INTRIN ) diff --git a/cmake/toolchain-powerpc64-clang.cmake b/cmake/toolchain-powerpc64-clang.cmake new file mode 100644 index 000000000..f986796f6 --- /dev/null +++ b/cmake/toolchain-powerpc64-clang.cmake @@ -0,0 +1,16 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR ppc64) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER clang) +set(CMAKE_C_COMPILER_TARGET powerpc64-linux-gnu) +set(CMAKE_CXX_COMPILER clang++) +set(CMAKE_CXX_COMPILER_TARGET powerpc64-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64 -cpu power9 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/cmake/toolchain-powerpc64le-clang.cmake b/cmake/toolchain-powerpc64le-clang.cmake new file mode 100644 index 000000000..b3423c590 --- /dev/null +++ b/cmake/toolchain-powerpc64le-clang.cmake @@ -0,0 +1,16 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR ppc64le) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER clang) +set(CMAKE_C_COMPILER_TARGET powerpc64le-linux-gnu) +set(CMAKE_CXX_COMPILER clang++) +set(CMAKE_CXX_COMPILER_TARGET powerpc64le-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64le -cpu power9 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/configure b/configure index a7ecc370b..9c0ea3431 100755 --- a/configure +++ b/configure @@ -1383,7 +1383,19 @@ EOF check_power9_intrinsics() { # Check whether features needed by POWER9 optimisations are available cat > $test.c << EOF -int main() { return 0; } +#ifdef __FreeBSD__ +#include +#endif +#include +int main() { +#ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP2, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE2_ARCH_3_00); +#else + return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00); +#endif +} EOF if test $buildpower9 -eq 1 && try $CC -c $CFLAGS -mcpu=power9 $test.c; then HAVE_POWER9_INTRIN=1