2 # tuklib_integer.cmake - see tuklib_integer.m4 for description and comments
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")
25 tuklib_add_definition_if("${TARGET_OR_ALL}" WORDS_BIGENDIAN)
27 # Look for a byteswapping method.
28 check_c_source_compiles("
37 HAVE___BUILTIN_BSWAPXX)
38 if(HAVE___BUILTIN_BSWAPXX)
39 tuklib_add_definitions("${TARGET_OR_ALL}" HAVE___BUILTIN_BSWAPXX)
41 check_include_file(byteswap.h 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)
51 check_include_file(sys/endian.h HAVE_SYS_ENDIAN_H)
53 tuklib_add_definitions("${TARGET_OR_ALL}" HAVE_SYS_ENDIAN_H)
55 check_include_file(sys/byteorder.h HAVE_SYS_BYTEORDER_H)
56 tuklib_add_definition_if("${TARGET_OR_ALL}"
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.
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.
70 # FIXME: The regex is based on guessing, not on factual information!
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)
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)."
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)