diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f24ff3f..29145467 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,6 +126,7 @@ option(USE_AUDIO "Build with audio support (SDL2_mixer)." ON) option(USE_ZIP "Build with .zip package support." ON) option(USE_CPACK "Add a 'package' target, used to prepare a release for binary distribution. Currently only used to create Windows installers. Requires CPack and NSIS." OFF) option(USE_COTIRE "Use cotire (COmpile TIme REducer) to speed up builds." OFF) +option(USE_INTEL_INTRIN "Use some x86-specific intrinsics for optimizations where appropriate (if possible). Note that this is not equivalent to e.g. supplying -march in CFLAGS." ON) option(DEBUG_USE_UBSAN "Enable the Undefined Behaviour Sanitizer (UBSan) in debug builds. Only disable if the compiler or target platform doesn't support it." ON) option(DEBUG_USE_ASAN "Enable the Address Sanitizer (ASan) and leak detection in debug builds." OFF) option(RELWITHDEBINFO_USE_DEBUG_FLAGS "Use debug flags in RelWithDebInfo builds (e.g. sanitizers)." OFF) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 367e047b..c84fb52c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,19 +28,17 @@ check_symbol_exists(__STDC_NO_COMPLEX__ "unistd.h" COMPLEX_MISSING) check_symbol_exists(__STDC_NO_VLA__ "unistd.h" VLA_MISSING) # This doesn't work on gcc... -# check_symbol_exists(_mm_crc32_u8 "immintrin.h" HAVE_CRC32_INTRIN) +# check_symbol_exists(_mm_crc32_u8 "immintrin.h" HAVE_INTEL_INTRIN) + +unset(HAVE_INTEL_INTRIN CACHE) check_c_source_compiles(" #include __attribute__((target(\"sse4.2\"))) int main(int argc, char **argv) { - return _mm_crc32_u8(0, 42); + return _mm_crc32_u8(argc, 42); } -" HAVE_CRC32_INTRIN) - -if(HAVE_CRC32_INTRIN) - add_definitions(-DHAVE_CRC32_INTRIN) -endif() +" HAVE_INTEL_INTRIN) if(COMPLEX_MISSING OR VLA_MISSING) message(FATAL_ERROR "Your C implementation needs to support complex numbers and variable length arrays.") @@ -144,15 +142,24 @@ set(SRCs "${CMAKE_CURRENT_BINARY_DIR}/version_auto.c" ) +if(USE_INTEL_INTRIN AND HAVE_INTEL_INTRIN) + set(SRCs ${SRCs} + util_sse42.c + ) + add_definitions(-DHAVE_INTEL_INTRIN) + set_property(SOURCE util_sse42.c APPEND_STRING PROPERTY COMPILE_FLAGS "-msse4.2") +endif() + if(USE_ZIP AND ZIP_SUPPORTED) set(SRCs ${SRCs} rwops/rwops_zipfile.c vfs/zipfile.c - vfs/zippath.c) + vfs/zippath.c + ) else() set(SRCs ${SRCs} vfs/zipfile_null.c - ) + ) endif() if(WIN32) diff --git a/src/compat.h b/src/compat.h index 3ca60d5b..d7088bfe 100644 --- a/src/compat.h +++ b/src/compat.h @@ -21,5 +21,3 @@ #else #define FORMAT_ATTR printf #endif - -void shut_up_stupid_warning(void); diff --git a/src/util.c b/src/util.c index e1cd0dc7..f4602f82 100644 --- a/src/util.c +++ b/src/util.c @@ -709,20 +709,6 @@ uint32_t crc32str(uint32_t crc, const char *str) { return crc ^ ~0U; } -#ifdef HAVE_CRC32_INTRIN -#include -__attribute__((target("sse4.2"))) -uint32_t crc32str_sse42(uint32_t crc, const char *str) { - const uint8_t *s = (const uint8_t*)str; - - while(*s) { - crc = _mm_crc32_u8(crc, *s++); - } - - return crc; -} -#endif - #ifdef DEBUG bool _in_draw_code; diff --git a/src/util.h b/src/util.h index 985a2462..a551ef53 100644 --- a/src/util.h +++ b/src/util.h @@ -15,6 +15,7 @@ #include // compiling under mingw may fail without this... #include #include +#include "util_sse42.h" #include "hashtable.h" #include "vfs/public.h" #include "log.h" @@ -139,10 +140,6 @@ int getenvint(const char *v, int defaultval) __attribute__((pure)); void png_setup_error_handlers(png_structp png); uint32_t crc32str(uint32_t crc, const char *str) __attribute__((hot, pure)); -#if defined(HAVE_CRC32_INTRIN) && defined(DISABLE_CRC32_INTRIN) -#undef HAVE_CRC32_INTRIN -#endif - #ifdef HAVE_CRC32_INTRIN uint32_t crc32str_sse42(uint32_t crc, const char *str) __attribute__((hot, pure)); #else @@ -152,6 +149,9 @@ uint32_t crc32str_sse42(uint32_t crc, const char *str) __attribute__((hot, pure) noreturn void _ts_assert_fail(const char *cond, const char *func, const char *file, int line, bool use_log); #undef assert +#undef static_assert + +#define static_assert _Static_assert #ifdef NDEBUG #define _assert(cond,uselog) diff --git a/src/util_sse42.c b/src/util_sse42.c new file mode 100644 index 00000000..786a929a --- /dev/null +++ b/src/util_sse42.c @@ -0,0 +1,21 @@ +/* + * This software is licensed under the terms of the MIT-License + * See COPYING for further information. + * --- + * Copyright (c) 2011-2017, Lukas Weber . + * Copyright (c) 2012-2017, Andrei Alexeyev . + */ + +#include +#include "util_sse42.h" + +__attribute__((target("sse4.2"))) +uint32_t crc32str_sse42(uint32_t crc, const char *str) { + const uint8_t *s = (const uint8_t*)str; + + while(*s) { + crc = _mm_crc32_u8(crc, *s++); + } + + return crc; +} diff --git a/src/util_sse42.h b/src/util_sse42.h new file mode 100644 index 00000000..cc2c3721 --- /dev/null +++ b/src/util_sse42.h @@ -0,0 +1,18 @@ +/* + * This software is licensed under the terms of the MIT-License + * See COPYING for further information. + * --- + * Copyright (c) 2011-2017, Lukas Weber . + * Copyright (c) 2012-2017, Andrei Alexeyev . + */ + +#pragma once + +#include +#include "compat.h" + +#ifdef HAVE_INTEL_INTRIN + uint32_t crc32str_sse42(uint32_t crc, const char *str) __attribute__((hot, pure)); +#else + #define crc32str_sse42 crc32str +#endif