* Add support for cross-compiling using clang 13 and later for PowerPC64 little-endian and big-endian
* Fix detection for availability of Power9 intrinsics
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
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
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) {
/* 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) {
/* 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;
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
}
# 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 <sys/auxv.h>
+ #ifdef __FreeBSD__
+ #include <machine/cpu.h>
+ #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
)
--- /dev/null
+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)
--- /dev/null
+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)
check_power9_intrinsics() {
# Check whether features needed by POWER9 optimisations are available
cat > $test.c << EOF
-int main() { return 0; }
+#ifdef __FreeBSD__
+#include <machine/cpu.h>
+#endif
+#include <sys/auxv.h>
+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