diff --git a/.travis.yml b/.travis.yml index 72eb6be91..b68edf9f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ matrix: env: variant=test_barebones toolset=darwin target=osx-tests - sudo: required dist: trusty - env: arch=arm toolset=gcc-arm64 + env: arch=arm toolset=gcc-arm git: submodules: false @@ -78,8 +78,8 @@ install: - 'if [[ $toolset == "gcc-coverage" ]]; then echo "using gcc : coverage : ccache g++-5 --coverage : -std=c++11 --coverage ;" >> ~/user-config.jam; fi' - - 'if [[ $toolset == "gcc-arm64" ]]; then - echo "using gcc : arm64 : ccache aarch64-linux-gnu-g++ : -std=c++11 -fsigned-char -lm ;" >> ~/user-config.jam; + - 'if [[ $toolset == "gcc-arm" ]]; then + echo "using gcc : arm : ccache armv8l-linux-gnueabihf-g++ : \"-std=c++11 -fsigned-char -march=armv8-a+crc -mfpu=crypto-neon-fp-armv8 -DTORRENT_FORCE_ARM_CRC32\" -lm ;" >> ~/user-config.jam; fi;' - 'echo "using darwin : : ccache clang++ : -std=c11 -std=c++11 -Wno-deprecated-declarations ;" >> ~/user-config.jam' - 'echo "using python : 2.7 ;" >> ~/user-config.jam' @@ -92,16 +92,16 @@ install: - 'if [ $arch == "arm" ]; then cd test; - wget http://releases.linaro.org/components/toolchain/binaries/latest-5/aarch64-linux-gnu/gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu.tar.xz; - tar xf gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu.tar.xz; - export PATH=${PWD}/gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu/bin:${PATH}; - aarch64-linux-gnu-g++ --version; + wget https://releases.linaro.org/components/toolchain/binaries/latest-5/armv8l-linux-gnueabihf/gcc-linaro-5.3-2016.02-x86_64_armv8l-linux-gnueabihf.tar.xz; + tar xf gcc-linaro-5.3-2016.02-x86_64_armv8l-linux-gnueabihf.tar.xz; + export PATH=${PWD}/gcc-linaro-5.3-2016.02-x86_64_armv8l-linux-gnueabihf/bin:${PATH}; + armv8l-linux-gnueabihf-g++ --version; wget -O boost.zip http://pilotfiber.dl.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.zip; unzip -qq boost.zip; export BOOST_ROOT=$PWD/boost_1_55_0; sudo apt-get install -y qemu-user-static debootstrap; - sudo debootstrap --variant=minbase --arch arm64 --foreign --include=build-essential testing rootfs; - sudo cp /usr/bin/qemu-aarch64-static rootfs/usr/bin/; + sudo debootstrap --variant=minbase --arch armhf --foreign --include=build-essential testing rootfs; + sudo cp /usr/bin/qemu-arm-static rootfs/usr/bin/; sudo chroot rootfs /debootstrap/debootstrap --second-stage; sudo chroot rootfs mount -t proc none /proc; cd ..; diff --git a/include/libtorrent/aux_/cpuid.hpp b/include/libtorrent/aux_/cpuid.hpp index 16e000a2a..b18a570fb 100644 --- a/include/libtorrent/aux_/cpuid.hpp +++ b/include/libtorrent/aux_/cpuid.hpp @@ -41,6 +41,7 @@ namespace libtorrent { namespace aux TORRENT_EXTRA_EXPORT extern bool sse42_support; TORRENT_EXTRA_EXPORT extern bool mmx_support; TORRENT_EXTRA_EXPORT extern bool arm_neon_support; + TORRENT_EXTRA_EXPORT extern bool arm_crc32c_support; } } #endif // TORRENT_CPUID_HPP_INCLUDED diff --git a/include/libtorrent/config.hpp b/include/libtorrent/config.hpp index bc03d6731..172b0fb8a 100644 --- a/include/libtorrent/config.hpp +++ b/include/libtorrent/config.hpp @@ -184,13 +184,14 @@ POSSIBILITY OF SUCH DAMAGE. #if defined __ANDROID__ #define TORRENT_USE_PREADV 0 #define TORRENT_USE_PREAD 1 -#define TORRENT_ANDROID +#define TORRENT_ANDROID 1 #define TORRENT_HAS_FALLOCATE 0 #define TORRENT_USE_ICONV 0 #define TORRENT_USE_IFADDRS 0 #define TORRENT_USE_MEMALIGN 1 #define TORRENT_USE_FDATASYNC 0 #else // ANDROID +#define TORRENT_ANDROID 0 #define TORRENT_USE_IFADDRS 1 #define TORRENT_USE_POSIX_MEMALIGN 1 #define TORRENT_USE_FDATASYNC 1 @@ -544,4 +545,14 @@ POSSIBILITY OF SUCH DAMAGE. # define TORRENT_HAS_ARM_NEON 0 #endif // TORRENT_HAS_ARM_NEON +#if TORRENT_HAS_ARM && defined __ARM_FEATURE_CRC32 +# define TORRENT_HAS_ARM_CRC32 1 +#else +#if defined TORRENT_FORCE_ARM_CRC32 +# define TORRENT_HAS_ARM_CRC32 1 +#else +# define TORRENT_HAS_ARM_CRC32 0 +#endif +#endif // TORRENT_HAS_ARM_CRC32 + #endif // TORRENT_CONFIG_HPP_INCLUDED diff --git a/include/libtorrent/crc32c.hpp b/include/libtorrent/crc32c.hpp index 5cc443ccc..08e2b0615 100644 --- a/include/libtorrent/crc32c.hpp +++ b/include/libtorrent/crc32c.hpp @@ -38,7 +38,6 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { - // this is the crc32c (Castagnoli) polynomial TORRENT_EXTRA_EXPORT std::uint32_t crc32c_32(std::uint32_t v); TORRENT_EXTRA_EXPORT std::uint32_t crc32c(std::uint64_t const* v @@ -46,5 +45,3 @@ namespace libtorrent } #endif - - diff --git a/src/cpuid.cpp b/src/cpuid.cpp index c2d6e939e..143807cc7 100644 --- a/src/cpuid.cpp +++ b/src/cpuid.cpp @@ -100,7 +100,24 @@ namespace libtorrent { namespace aux #elif defined __aarch64__ //return (getauxval(AT_HWCAP) & HWCAP_ASIMD); return (getauxval(16) & (1 << 1)); -#endif // TORRENT_HAS_ARM +#endif +#else + return false; +#endif + } + + bool supports_arm_crc32c() + { +#if TORRENT_HAS_ARM_CRC32 +#if defined TORRENT_FORCE_ARM_CRC32 + return true; +#elif defined __arm__ + //return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); + return (getauxval(26) & (1 << 4)); +#elif defined __aarch64__ + //return (getauxval(AT_HWCAP) & HWCAP_CRC32); + return (getauxval(16) & (1 << 7)); +#endif #else return false; #endif @@ -111,4 +128,5 @@ namespace libtorrent { namespace aux bool sse42_support = supports_sse42(); bool mmx_support = supports_mmx(); bool arm_neon_support = supports_arm_neon(); + bool arm_crc32c_support = supports_arm_crc32c(); } } diff --git a/src/crc32c.cpp b/src/crc32c.cpp index ce9ba7243..fa1b6a7c5 100644 --- a/src/crc32c.cpp +++ b/src/crc32c.cpp @@ -42,6 +42,10 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/aux_/disable_warnings_pop.hpp" +#if TORRENT_HAS_ARM_CRC32 +#include +#endif + namespace libtorrent { std::uint32_t crc32c_32(std::uint32_t v) @@ -64,6 +68,14 @@ namespace libtorrent } #endif +#if TORRENT_HAS_ARM_CRC32 + if (aux::arm_crc32c_support) + { + std::uint32_t ret = 0xffffffff; + return __crc32cw(ret, v) ^ 0xffffffff; + } +#endif + boost::crc_optimal<32, 0x1EDC6F41, 0xFFFFFFFF, 0xFFFFFFFF, true, true> crc; crc.process_bytes(&v, 4); return crc.checksum(); @@ -116,11 +128,21 @@ namespace libtorrent #endif // amd64 or x86 } #endif // x86 or amd64 and gcc or msvc + +#if TORRENT_HAS_ARM_CRC32 + if (aux::arm_crc32c_support) + { + std::uint32_t ret = 0xffffffff; + for (int i = 0; i < num_words; ++i) + { + ret = __crc32cd(ret, buf[i]); + } + return ret ^ 0xffffffff; + } +#endif boost::crc_optimal<32, 0x1EDC6F41, 0xFFFFFFFF, 0xFFFFFFFF, true, true> crc; crc.process_bytes(buf, num_words * 8); return crc.checksum(); } } - - diff --git a/test/Jamfile b/test/Jamfile index cf22a0376..c470455e4 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -118,7 +118,6 @@ test-suite libtorrent : test_identify_client.cpp test_merkle.cpp test_resolve_links.cpp - test_crc32.cpp test_heterogeneous_queue.cpp test_ip_voter.cpp test_sliding_average.cpp @@ -160,6 +159,7 @@ test-suite libtorrent : [ run test_sha1_hash.cpp ] [ run test_bitfield.cpp ] + [ run test_crc32.cpp ] [ run test_receive_buffer.cpp ] [ run test_alert_manager.cpp ] [ run test_direct_dht.cpp ] @@ -272,6 +272,7 @@ explicit win-tests ; alias arm-tests : test_sha1_hash test_bitfield + test_crc32 ; explicit arm-tests ; diff --git a/test/test_crc32.cpp b/test/test_crc32.cpp index a2648891d..3ef3115ea 100644 --- a/test/test_crc32.cpp +++ b/test/test_crc32.cpp @@ -31,6 +31,8 @@ POSSIBILITY OF SUCH DAMAGE. */ #include "libtorrent/crc32c.hpp" +#include "libtorrent/aux_/cpuid.hpp" +#include "libtorrent/assert.hpp" #include "test.hpp" TORRENT_TEST(crc32) @@ -60,5 +62,10 @@ TORRENT_TEST(crc32) "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", 32); out = crc32c(buf, 4); TEST_EQUAL(out, htonl(0x4e79dd46)); -} +#if TORRENT_HAS_ARM + TORRENT_ASSERT(aux::arm_crc32c_support); +#else + TORRENT_ASSERT(!aux::arm_crc32c_support); +#endif +}