From 2cc1b3a3ee595c8be761fee309167b8a56393d3e Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 3 Feb 2019 16:39:37 +0100 Subject: Detect function multiversioning and sse4.2/crc32, enables i386 This fixes the build on kfreebsd-amd64, and due to the detection of sse4.2, should also enable the sse4.2 on i386. --- CMake/CheckCxxTarget.cmake | 35 +++++++++++++++++++++++++++++++++++ CMake/config.h.in | 4 ++++ CMakeLists.txt | 5 +++++ apt-pkg/pkgcache.cc | 8 ++++++-- 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 CMake/CheckCxxTarget.cmake diff --git a/CMake/CheckCxxTarget.cmake b/CMake/CheckCxxTarget.cmake new file mode 100644 index 000000000..373c0be4c --- /dev/null +++ b/CMake/CheckCxxTarget.cmake @@ -0,0 +1,35 @@ +# CMake support for target-based function multiversioning +# +# Copyright (C) 2019 Canonical Ltd +# +# Author: Julian Andres Klode . +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +function(check_cxx_target var target code) + check_cxx_source_compiles( + " + __attribute__((target(\"${target}\"))) static int foo() { ${code} return 1; } + __attribute__((target(\"default\"))) static int foo() { ${code} return 0; } + int main() { return foo(); } + " ${var}) +endfunction() diff --git a/CMake/config.h.in b/CMake/config.h.in index bd0da8649..98a81ad6c 100644 --- a/CMake/config.h.in +++ b/CMake/config.h.in @@ -81,3 +81,7 @@ /* unrolling is faster combined with an optimizing compiler */ #define SHA2_UNROLL_TRANSFORM + +/* defined if __builtin_ia32_crc32{s,d}i() exists in an sse4.2 target */ +#define HAVE_FMV_SSE42_AND_CRC32 +#define HAVE_FMV_SSE42_AND_CRC32DI diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b3cc73de..599c7ec1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,6 +180,11 @@ else() set(RESOLV_LIBRARIES -lresolv) endif() +# Check multiversioning +include(CheckCxxTarget) +check_cxx_target(HAVE_FMV_SSE42_AND_CRC32 "sse4.2" "__builtin_ia32_crc32si(0, 1llu);") +check_cxx_target(HAVE_FMV_SSE42_AND_CRC32DI "sse4.2" "__builtin_ia32_crc32di(0, 1llu);") + # Configure some variables like package, version and architecture. set(PACKAGE ${PROJECT_NAME}) set(PACKAGE_MAIL "APT Development Team ") diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 041f0b957..80dd1d1fa 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -231,15 +231,16 @@ map_id_t pkgCache::sHash(const char *Str) const return Hash % HeaderP->GetHashTableSize(); } -#if defined(__GNUC__) && defined(__x86_64__) && defined(__ELF__) +#if defined(HAVE_FMV_SSE42_AND_CRC32) -#if defined(__x86_64__) +#ifdef HAVE_FMV_SSE42_AND_CRC32 __attribute__((target("sse4.2"))) static uint32_t hash32(uint32_t crc32, const unsigned char *input, size_t size) { if (input == nullptr) return 0; crc32 ^= 0xffffffffU; +#ifdef HAVE_FMV_SSE42_AND_CRC32DI while (size >= 8) { crc32 = __builtin_ia32_crc32di(crc32, *(uint64_t *)input); input += 8; @@ -247,6 +248,9 @@ __attribute__((target("sse4.2"))) static uint32_t hash32(uint32_t crc32, const u } if (size >= 4) { +#else + while (size >= 4) { +#endif crc32 = __builtin_ia32_crc32si(crc32, *(uint32_t *)input); input += 4; size -= 4; -- cgit v1.2.3