Windows: Include <intrin.h> when needed.
[xz/debian.git] / cmake / tuklib_integer.cmake
blob949d2d9fb4414d1b467e383c2b7c0e1048501f0a
2 # tuklib_integer.cmake - see tuklib_integer.m4 for description and comments
4 # Author: Lasse Collin
6 # This file has been put into the public domain.
7 # You can do whatever you want with this file.
10 include("${CMAKE_CURRENT_LIST_DIR}/tuklib_common.cmake")
11 include(TestBigEndian)
12 include(CheckCSourceCompiles)
13 include(CheckIncludeFile)
14 include(CheckSymbolExists)
16 function(tuklib_integer TARGET_OR_ALL)
17     # Check for endianness. Unlike the Autoconf's AC_C_BIGENDIAN, this doesn't
18     # support Apple universal binaries. The CMake module will leave the
19     # variable unset so we can catch that situation here instead of continuing
20     # as if we were little endian.
21     test_big_endian(WORDS_BIGENDIAN)
22     if(NOT DEFINED WORDS_BIGENDIAN)
23         message(FATAL_ERROR "Cannot determine endianness")
24     endif()
25     tuklib_add_definition_if("${TARGET_OR_ALL}" WORDS_BIGENDIAN)
27     # Look for a byteswapping method.
28     check_c_source_compiles("
29             int main(void)
30             {
31                 __builtin_bswap16(1);
32                 __builtin_bswap32(1);
33                 __builtin_bswap64(1);
34                 return 0;
35             }
36         "
37         HAVE___BUILTIN_BSWAPXX)
38     if(HAVE___BUILTIN_BSWAPXX)
39         tuklib_add_definitions("${TARGET_OR_ALL}" HAVE___BUILTIN_BSWAPXX)
40     else()
41         check_include_file(byteswap.h HAVE_BYTESWAP_H)
42         if(HAVE_BYTESWAP_H)
43             tuklib_add_definitions("${TARGET_OR_ALL}" HAVE_BYTESWAP_H)
44             check_symbol_exists(bswap_16 byteswap.h HAVE_BSWAP_16)
45             tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE_BSWAP_16)
46             check_symbol_exists(bswap_32 byteswap.h HAVE_BSWAP_32)
47             tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE_BSWAP_32)
48             check_symbol_exists(bswap_64 byteswap.h HAVE_BSWAP_64)
49             tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE_BSWAP_64)
50         else()
51             check_include_file(sys/endian.h HAVE_SYS_ENDIAN_H)
52             if(HAVE_SYS_ENDIAN_H)
53                 tuklib_add_definitions("${TARGET_OR_ALL}" HAVE_SYS_ENDIAN_H)
54             else()
55                 check_include_file(sys/byteorder.h HAVE_SYS_BYTEORDER_H)
56                 tuklib_add_definition_if("${TARGET_OR_ALL}"
57                                          HAVE_SYS_BYTEORDER_H)
58             endif()
59         endif()
60     endif()
62     # Unaligned access is fast on x86(-64), big endian PowerPC, and usually on
63     # 32/64-bit ARM too. There are others too and ARM could be a false match.
64     #
65     # Guess the default value for the option.
66     # CMake's ability to give info about the target arch seems bad.
67     # The the same arch can have different name depending on the OS.
68     #
69     # FIXME: The regex is based on guessing, not on factual information!
70     #
71     # NOTE: Compared to the Autoconf test, this lacks the GCC/Clang test
72     #       on ARM and always assumes that unaligned is fast on ARM.
73     set(FAST_UNALIGNED_GUESS OFF)
74     if(CMAKE_SYSTEM_PROCESSOR MATCHES
75        "[Xx3456]86|^[Xx]64|^[Aa][Mm][Dd]64|^[Aa][Rr][Mm]|^aarch|^powerpc|^ppc")
76         if(NOT WORDS_BIGENDIAN OR
77            NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc|^ppc")
78            set(FAST_UNALIGNED_GUESS ON)
79         endif()
80     endif()
81     option(TUKLIB_FAST_UNALIGNED_ACCESS
82            "Enable if the system supports *fast* unaligned memory access \
83 with 16-bit, 32-bit, and 64-bit integers."
84            "${FAST_UNALIGNED_GUESS}")
85     tuklib_add_definition_if("${TARGET_OR_ALL}" TUKLIB_FAST_UNALIGNED_ACCESS)
87     # Unsafe type punning:
88     option(TUKLIB_USE_UNSAFE_TYPE_PUNNING
89            "This introduces strict aliasing violations and \
90 may result in broken code. However, this might improve performance \
91 in some cases, especially with old compilers \
92 (e.g. GCC 3 and early 4.x on x86, GCC < 6 on ARMv6 and ARMv7)."
93            OFF)
94     tuklib_add_definition_if("${TARGET_OR_ALL}" TUKLIB_USE_UNSAFE_TYPE_PUNNING)
96     # Check for GCC/Clang __builtin_assume_aligned().
97     check_c_source_compiles(
98         "int main(void) { __builtin_assume_aligned(\"\", 1); return 0; }"
99         HAVE___BUILTIN_ASSUME_ALIGNED)
100     tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE___BUILTIN_ASSUME_ALIGNED)
101 endfunction()