liblzma: Silence a warning from -Wsign-conversion in a 32-bit build.
[xz.git] / cmake / tuklib_integer.cmake
blobd7e2e28cca5dde693421f695cd0610fcda64f8a5
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     # 16-bit and 32-bit unaligned access is fast on x86(-64),
63     # big endian PowerPC, and usually on 32/64-bit ARM too.
64     # There are others too and ARM could be a false match.
65     #
66     # Guess the default value for the option.
67     # CMake's ability to give info about the target arch seems bad.
68     # The the same arch can have different name depending on the OS.
69     #
70     # FIXME: The regex is based on guessing, not on factual information!
71     #
72     # NOTE: Compared to the Autoconf test, this lacks the GCC/Clang test
73     #       on ARM and always assumes that unaligned is fast on ARM.
74     set(FAST_UNALIGNED_GUESS OFF)
75     if(CMAKE_SYSTEM_PROCESSOR MATCHES
76        "[Xx3456]86|^[Xx]64|^[Aa][Mm][Dd]64|^[Aa][Rr][Mm]|^aarch|^powerpc|^ppc")
77         if(NOT WORDS_BIGENDIAN OR
78            NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc|^ppc")
79            set(FAST_UNALIGNED_GUESS ON)
80         endif()
81     endif()
82     option(TUKLIB_FAST_UNALIGNED_ACCESS
83            "Enable if the system supports *fast* unaligned memory access \
84 with 16-bit and 32-bit integers."
85            "${FAST_UNALIGNED_GUESS}")
86     tuklib_add_definition_if("${TARGET_OR_ALL}" TUKLIB_FAST_UNALIGNED_ACCESS)
88     # Unsafe type punning:
89     option(TUKLIB_USE_UNSAFE_TYPE_PUNNING
90            "This introduces strict aliasing violations and \
91 may result in broken code. However, this might improve performance \
92 in some cases, especially with old compilers \
93 (e.g. GCC 3 and early 4.x on x86, GCC < 6 on ARMv6 and ARMv7)."
94            OFF)
95     tuklib_add_definition_if("${TARGET_OR_ALL}" TUKLIB_USE_UNSAFE_TYPE_PUNNING)
97     # Check for GCC/Clang __builtin_assume_aligned().
98     check_c_source_compiles(
99         "int main(void) { __builtin_assume_aligned(\"\", 1); return 0; }"
100         HAVE___BUILTIN_ASSUME_ALIGNED)
101     tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE___BUILTIN_ASSUME_ALIGNED)
102 endfunction()