Build: Fix a typo in autogen.sh
[xz/debian.git] / cmake / tuklib_integer.cmake
blob7e1ed3c5f00fadf85b1350ab0c94caf1fbfd9be2
1 # SPDX-License-Identifier: 0BSD
3 #############################################################################
5 # tuklib_integer.cmake - see tuklib_integer.m4 for description and comments
7 # Author: Lasse Collin
9 #############################################################################
11 include("${CMAKE_CURRENT_LIST_DIR}/tuklib_common.cmake")
12 include(TestBigEndian)
13 include(CheckCSourceCompiles)
14 include(CheckIncludeFile)
15 include(CheckSymbolExists)
17 function(tuklib_integer TARGET_OR_ALL)
18     # Check for endianness. Unlike the Autoconf's AC_C_BIGENDIAN, this doesn't
19     # support Apple universal binaries. The CMake module will leave the
20     # variable unset so we can catch that situation here instead of continuing
21     # as if we were little endian.
22     test_big_endian(WORDS_BIGENDIAN)
23     if(NOT DEFINED WORDS_BIGENDIAN)
24         message(FATAL_ERROR "Cannot determine endianness")
25     endif()
26     tuklib_add_definition_if("${TARGET_OR_ALL}" WORDS_BIGENDIAN)
28     # Look for a byteswapping method.
29     check_c_source_compiles("
30             int main(void)
31             {
32                 __builtin_bswap16(1);
33                 __builtin_bswap32(1);
34                 __builtin_bswap64(1);
35                 return 0;
36             }
37         "
38         HAVE___BUILTIN_BSWAPXX)
39     if(HAVE___BUILTIN_BSWAPXX)
40         tuklib_add_definitions("${TARGET_OR_ALL}" HAVE___BUILTIN_BSWAPXX)
41     else()
42         check_include_file(byteswap.h HAVE_BYTESWAP_H)
43         if(HAVE_BYTESWAP_H)
44             tuklib_add_definitions("${TARGET_OR_ALL}" HAVE_BYTESWAP_H)
45             check_symbol_exists(bswap_16 byteswap.h HAVE_BSWAP_16)
46             tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE_BSWAP_16)
47             check_symbol_exists(bswap_32 byteswap.h HAVE_BSWAP_32)
48             tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE_BSWAP_32)
49             check_symbol_exists(bswap_64 byteswap.h HAVE_BSWAP_64)
50             tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE_BSWAP_64)
51         else()
52             check_include_file(sys/endian.h HAVE_SYS_ENDIAN_H)
53             if(HAVE_SYS_ENDIAN_H)
54                 tuklib_add_definitions("${TARGET_OR_ALL}" HAVE_SYS_ENDIAN_H)
55             else()
56                 check_include_file(sys/byteorder.h HAVE_SYS_BYTEORDER_H)
57                 tuklib_add_definition_if("${TARGET_OR_ALL}"
58                                          HAVE_SYS_BYTEORDER_H)
59             endif()
60         endif()
61     endif()
63     # Guess that unaligned access is fast on these archs:
64     #   - 32/64-bit x86 / x86-64
65     #   - 32/64-bit big endian PowerPC
66     #   - 64-bit little endian PowerPC
67     #   - Some 32-bit ARM
68     #   - Some 64-bit ARM64 (AArch64)
69     #   - Some 32/64-bit RISC-V
70     #
71     # CMake doesn't provide a standardized/normalized list of processor arch
72     # names. For example, x86-64 may be "x86_64" (Linux), "AMD64" (Windows),
73     # or even "EM64T" (64-bit WinXP).
74     set(FAST_UNALIGNED_GUESS OFF)
75     string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" PROCESSOR)
77     # There is no ^ in the first regex branch to allow "i" at the beginning
78     # so it can match "i386" to "i786", and "x86_64".
79     if(PROCESSOR MATCHES "[x34567]86|^x64|^amd64|^em64t")
80         set(FAST_UNALIGNED_GUESS ON)
82     elseif(PROCESSOR MATCHES "^powerpc|^ppc")
83         if(WORDS_BIGENDIAN OR PROCESSOR MATCHES "64")
84             set(FAST_UNALIGNED_GUESS ON)
85         endif()
87     elseif(PROCESSOR MATCHES "^arm|^aarch64|^riscv")
88         # On 32-bit and 64-bit ARM, GCC and Clang
89         # #define __ARM_FEATURE_UNALIGNED if
90         # unaligned access is supported.
91         #
92         # Exception: GCC at least up to 13.2.0
93         # defines it even when using -mstrict-align
94         # so in that case this autodetection goes wrong.
95         # Most of the time -mstrict-align isn't used so it
96         # shouldn't be a common problem in practice. See:
97         # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111555
98         #
99         # RISC-V C API Specification says that if
100         # __riscv_misaligned_fast is defined then
101         # unaligned access is known to be fast.
102         #
103         # MSVC is handled as a special case: We assume that
104         # 32/64-bit ARM supports fast unaligned access.
105         # If MSVC gets RISC-V support then this will assume
106         # fast unaligned access on RISC-V too.
107         check_c_source_compiles("
108                 #if !defined(__ARM_FEATURE_UNALIGNED) \
109                         && !defined(__riscv_misaligned_fast) \
110                         && !defined(_MSC_VER)
111                 compile error
112                 #endif
113                 int main(void) { return 0; }
114             "
115             TUKLIB_FAST_UNALIGNED_DEFINED_BY_PREPROCESSOR)
116         if(TUKLIB_FAST_UNALIGNED_DEFINED_BY_PREPROCESSOR)
117             set(FAST_UNALIGNED_GUESS ON)
118         endif()
119     endif()
121     option(TUKLIB_FAST_UNALIGNED_ACCESS
122            "Enable if the system supports *fast* unaligned memory access \
123 with 16-bit, 32-bit, and 64-bit integers."
124            "${FAST_UNALIGNED_GUESS}")
125     tuklib_add_definition_if("${TARGET_OR_ALL}" TUKLIB_FAST_UNALIGNED_ACCESS)
127     # Unsafe type punning:
128     option(TUKLIB_USE_UNSAFE_TYPE_PUNNING
129            "This introduces strict aliasing violations and \
130 may result in broken code. However, this might improve performance \
131 in some cases, especially with old compilers \
132 (e.g. GCC 3 and early 4.x on x86, GCC < 6 on ARMv6 and ARMv7)."
133            OFF)
134     tuklib_add_definition_if("${TARGET_OR_ALL}" TUKLIB_USE_UNSAFE_TYPE_PUNNING)
136     # Check for GCC/Clang __builtin_assume_aligned().
137     check_c_source_compiles(
138         "int main(void) { __builtin_assume_aligned(\"\", 1); return 0; }"
139         HAVE___BUILTIN_ASSUME_ALIGNED)
140     tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE___BUILTIN_ASSUME_ALIGNED)
141 endfunction()