tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

detect_compiler_arch.h (12569B)


      1 // Copyright 2020 Google LLC
      2 // SPDX-License-Identifier: Apache-2.0
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 
     16 #ifndef HIGHWAY_HWY_DETECT_COMPILER_ARCH_H_
     17 #define HIGHWAY_HWY_DETECT_COMPILER_ARCH_H_
     18 
     19 // Detects compiler and arch from predefined macros. Zero dependencies for
     20 // inclusion by foreach_target.h.
     21 
     22 // Add to #if conditions to prevent IDE from graying out code.
     23 // Note for clangd users: There is no predefined macro in clangd, so you must
     24 // manually add these two lines (without the preceding '// ') to your project's
     25 // `.clangd` file:
     26 // CompileFlags:
     27 //   Add: [-D__CLANGD__]
     28 #if (defined __CDT_PARSER__) || (defined __INTELLISENSE__) || \
     29    (defined Q_CREATOR_RUN) || (defined __CLANGD__) ||        \
     30    (defined GROK_ELLIPSIS_BUILD)
     31 #define HWY_IDE 1
     32 #else
     33 #define HWY_IDE 0
     34 #endif
     35 
     36 //------------------------------------------------------------------------------
     37 // Compiler
     38 
     39 // Actual MSVC, not clang-cl, which defines _MSC_VER but doesn't behave like
     40 // MSVC in other aspects (e.g. HWY_DIAGNOSTICS).
     41 #if defined(_MSC_VER) && !defined(__clang__)
     42 #define HWY_COMPILER_MSVC _MSC_VER
     43 #else
     44 #define HWY_COMPILER_MSVC 0
     45 #endif
     46 
     47 #if defined(_MSC_VER) && defined(__clang__)
     48 #define HWY_COMPILER_CLANGCL _MSC_VER
     49 #else
     50 #define HWY_COMPILER_CLANGCL 0
     51 #endif
     52 
     53 #ifdef __INTEL_COMPILER
     54 #define HWY_COMPILER_ICC __INTEL_COMPILER
     55 #else
     56 #define HWY_COMPILER_ICC 0
     57 #endif
     58 
     59 #ifdef __INTEL_LLVM_COMPILER
     60 #define HWY_COMPILER_ICX __INTEL_LLVM_COMPILER
     61 #else
     62 #define HWY_COMPILER_ICX 0
     63 #endif
     64 
     65 // HWY_COMPILER_GCC is a generic macro for all compilers implementing the GNU
     66 // compiler extensions (eg. Clang, Intel...)
     67 #ifdef __GNUC__
     68 #define HWY_COMPILER_GCC (__GNUC__ * 100 + __GNUC_MINOR__)
     69 #else
     70 #define HWY_COMPILER_GCC 0
     71 #endif
     72 
     73 #ifndef HWY_COMPILER_CLANG  // Allow user override.
     74 #ifdef __clang__            // Clang or clang-cl, not GCC.
     75 // In case of Apple LLVM (whose version number is unrelated to that of LLVM) or
     76 // an invalid version number, deduce it from the presence of warnings.
     77 // Originally based on
     78 // https://github.com/simd-everywhere/simde/blob/47d6e603de9d04ee05cdfbc57cf282a02be1bf2a/simde/simde-detect-clang.h#L59.
     79 // Please send updates below to them as well, thanks!
     80 #if defined(__apple_build_version__) || __clang_major__ >= 999
     81 #if __has_builtin(__builtin_elementwise_fshl)
     82 #define HWY_COMPILER_CLANG 2201
     83 #elif __has_builtin(__builtin_structured_binding_size)
     84 #define HWY_COMPILER_CLANG 2101
     85 #elif __has_builtin(__builtin_common_type)
     86 #define HWY_COMPILER_CLANG 2001
     87 #elif __has_warning("-Wreturn-mismatch")
     88 #define HWY_COMPILER_CLANG 1901
     89 #elif __has_warning("-Woverriding-option")
     90 #define HWY_COMPILER_CLANG 1801
     91 // No new warnings in 17.0, and Apple LLVM 15.3, which should be 1600, already
     92 // has the unsafe_buffer_usage attribute, so we instead check for new builtins.
     93 #elif __has_builtin(__builtin_nondeterministic_value)
     94 #define HWY_COMPILER_CLANG 1700
     95 #elif __has_attribute(nouwtable)  // no new warnings in 16.0
     96 #define HWY_COMPILER_CLANG 1600
     97 #elif __has_warning("-Warray-parameter")
     98 #define HWY_COMPILER_CLANG 1500
     99 #elif __has_warning("-Wbitwise-instead-of-logical")
    100 #define HWY_COMPILER_CLANG 1400
    101 #elif __has_warning("-Wreserved-identifier")
    102 #define HWY_COMPILER_CLANG 1300
    103 #elif __has_warning("-Wformat-insufficient-args")
    104 #define HWY_COMPILER_CLANG 1200
    105 #elif __has_warning("-Wimplicit-const-int-float-conversion")
    106 #define HWY_COMPILER_CLANG 1100
    107 #elif __has_warning("-Wmisleading-indentation")
    108 #define HWY_COMPILER_CLANG 1000
    109 #elif defined(__FILE_NAME__)
    110 #define HWY_COMPILER_CLANG 900
    111 #elif __has_warning("-Wextra-semi-stmt") || \
    112    __has_builtin(__builtin_rotateleft32)
    113 #define HWY_COMPILER_CLANG 800
    114 // For reasons unknown, XCode 10.3 (Apple LLVM version 10.0.1) is apparently
    115 // based on Clang 7, but does not support the warning we test.
    116 // See https://en.wikipedia.org/wiki/Xcode#Toolchain_versions and
    117 // https://trac.macports.org/wiki/XcodeVersionInfo.
    118 #elif __has_warning("-Wc++98-compat-extra-semi") || \
    119    (defined(__apple_build_version__) && __apple_build_version__ >= 10010000)
    120 #define HWY_COMPILER_CLANG 700
    121 #else  // Anything older than 7.0 is not recommended for Highway.
    122 #define HWY_COMPILER_CLANG 600
    123 #endif  // __has_warning chain
    124 #else  // use normal version
    125 #define HWY_COMPILER_CLANG (__clang_major__ * 100 + __clang_minor__)
    126 #define HWY_COMPILER3_CLANG \
    127  (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
    128 #endif
    129 #else  // Not clang
    130 #define HWY_COMPILER_CLANG 0
    131 #define HWY_COMPILER3_CLANG 0
    132 #endif  // __clang__
    133 #endif  // HWY_COMPILER_CLANG
    134 
    135 // User-defined or deduced HWY_COMPILER_CLANG: derive HWY_COMPILER3_CLANG.
    136 #ifndef HWY_COMPILER3_CLANG
    137 #define HWY_COMPILER3_CLANG (HWY_COMPILER_CLANG * 100)
    138 #endif
    139 
    140 #if HWY_COMPILER_GCC && !HWY_COMPILER_CLANG && !HWY_COMPILER_ICC && \
    141    !HWY_COMPILER_ICX
    142 #define HWY_COMPILER_GCC_ACTUAL HWY_COMPILER_GCC
    143 #else
    144 #define HWY_COMPILER_GCC_ACTUAL 0
    145 #endif
    146 
    147 // More than one may be nonzero, but we want at least one.
    148 #if 0 == (HWY_COMPILER_MSVC + HWY_COMPILER_CLANGCL + HWY_COMPILER_ICC + \
    149          HWY_COMPILER_ICX + HWY_COMPILER_GCC + HWY_COMPILER_CLANG)
    150 #error "Unsupported compiler"
    151 #endif
    152 
    153 // We should only detect one of these (only clang/clangcl/icx overlap)
    154 #if 1 < (!!HWY_COMPILER_MSVC + (!!HWY_COMPILER_ICC & !HWY_COMPILER_ICX) + \
    155         !!HWY_COMPILER_GCC_ACTUAL +                                      \
    156         !!(HWY_COMPILER_ICX | HWY_COMPILER_CLANGCL | HWY_COMPILER_CLANG))
    157 #error "Detected multiple compilers"
    158 #endif
    159 
    160 //------------------------------------------------------------------------------
    161 // Compiler features and C++ version
    162 
    163 #ifdef __has_builtin
    164 #define HWY_HAS_BUILTIN(name) __has_builtin(name)
    165 #else
    166 #define HWY_HAS_BUILTIN(name) 0
    167 #endif
    168 
    169 #ifdef __has_attribute
    170 #define HWY_HAS_ATTRIBUTE(name) __has_attribute(name)
    171 #else
    172 #define HWY_HAS_ATTRIBUTE(name) 0
    173 #endif
    174 
    175 #ifdef __has_cpp_attribute
    176 #define HWY_HAS_CPP_ATTRIBUTE(name) __has_cpp_attribute(name)
    177 #else
    178 #define HWY_HAS_CPP_ATTRIBUTE(name) 0
    179 #endif
    180 
    181 #ifdef __has_feature
    182 #define HWY_HAS_FEATURE(name) __has_feature(name)
    183 #else
    184 #define HWY_HAS_FEATURE(name) 0
    185 #endif
    186 
    187 // NOTE: clang ~17 does not correctly handle wrapping __has_include in a macro.
    188 
    189 #if HWY_COMPILER_MSVC && defined(_MSVC_LANG) && _MSVC_LANG > __cplusplus
    190 #define HWY_CXX_LANG _MSVC_LANG
    191 #else
    192 #define HWY_CXX_LANG __cplusplus
    193 #endif
    194 
    195 #if defined(__cpp_constexpr) && __cpp_constexpr >= 201603L
    196 #define HWY_CXX17_CONSTEXPR constexpr
    197 #else
    198 #define HWY_CXX17_CONSTEXPR
    199 #endif
    200 
    201 #if defined(__cpp_constexpr) && __cpp_constexpr >= 201304L
    202 #define HWY_CXX14_CONSTEXPR constexpr
    203 #else
    204 #define HWY_CXX14_CONSTEXPR
    205 #endif
    206 
    207 #if HWY_CXX_LANG >= 201703L
    208 #define HWY_IF_CONSTEXPR if constexpr
    209 #else
    210 #define HWY_IF_CONSTEXPR if
    211 #endif
    212 
    213 // Use for constexpr variables at namespace scope in headers. Constexpr is
    214 // separate to allow using `HWY_CXX14_CONSTEXPR` if required.
    215 #ifndef HWY_INLINE_VAR
    216 #if __cplusplus > 201402L
    217 // C++17: mark as COMDAT to ensure linkers de-duplicate it. See
    218 // https://quuxplusone.github.io/blog/2022/07/08/inline-constexpr/
    219 #define HWY_INLINE_VAR inline
    220 #else
    221 #define HWY_INLINE_VAR
    222 #endif
    223 #endif
    224 
    225 //------------------------------------------------------------------------------
    226 // Architecture
    227 
    228 #if defined(__i386__) || defined(_M_IX86)
    229 #define HWY_ARCH_X86_32 1
    230 #else
    231 #define HWY_ARCH_X86_32 0
    232 #endif
    233 
    234 #if defined(__x86_64__) || defined(_M_X64)
    235 #define HWY_ARCH_X86_64 1
    236 #else
    237 #define HWY_ARCH_X86_64 0
    238 #endif
    239 
    240 #if HWY_ARCH_X86_32 && HWY_ARCH_X86_64
    241 #error "Cannot have both x86-32 and x86-64"
    242 #endif
    243 
    244 #if HWY_ARCH_X86_32 || HWY_ARCH_X86_64
    245 #define HWY_ARCH_X86 1
    246 #else
    247 #define HWY_ARCH_X86 0
    248 #endif
    249 
    250 #if defined(__powerpc64__) || defined(_M_PPC) || defined(__powerpc__)
    251 #define HWY_ARCH_PPC 1
    252 #else
    253 #define HWY_ARCH_PPC 0
    254 #endif
    255 
    256 #if defined(__powerpc64__) || (HWY_ARCH_PPC && defined(__64BIT__))
    257 #define HWY_ARCH_PPC_64 1
    258 #else
    259 #define HWY_ARCH_PPC_64 0
    260 #endif
    261 
    262 // aarch32 is currently not supported; please raise an issue if you want it.
    263 #if defined(__ARM_ARCH_ISA_A64) || defined(__aarch64__) || defined(_M_ARM64)
    264 #define HWY_ARCH_ARM_A64 1
    265 #else
    266 #define HWY_ARCH_ARM_A64 0
    267 #endif
    268 
    269 #if (defined(__ARM_ARCH) && __ARM_ARCH == 7) || (defined(_M_ARM) && _M_ARM == 7)
    270 #define HWY_ARCH_ARM_V7 1
    271 #else
    272 #define HWY_ARCH_ARM_V7 0
    273 #endif
    274 
    275 #if HWY_ARCH_ARM_A64 && HWY_ARCH_ARM_V7
    276 #error "Cannot have both A64 and V7"
    277 #endif
    278 
    279 // Any *supported* version of Arm, i.e. 7 or later
    280 #if HWY_ARCH_ARM_A64 || HWY_ARCH_ARM_V7
    281 #define HWY_ARCH_ARM 1
    282 #else
    283 #define HWY_ARCH_ARM 0
    284 #endif
    285 
    286 // Older than Armv7 (e.g. armel aka Armv5) => we do not support SIMD.
    287 #if (defined(__arm__) || defined(_M_ARM)) && !HWY_ARCH_ARM
    288 #define HWY_ARCH_ARM_OLD 1
    289 #else
    290 #define HWY_ARCH_ARM_OLD 0
    291 #endif
    292 
    293 #if defined(__EMSCRIPTEN__) || defined(__wasm__) || defined(__WASM__)
    294 #define HWY_ARCH_WASM 1
    295 #else
    296 #define HWY_ARCH_WASM 0
    297 #endif
    298 
    299 #ifdef __riscv
    300 #define HWY_ARCH_RISCV 1
    301 #else
    302 #define HWY_ARCH_RISCV 0
    303 #endif
    304 // DEPRECATED names; please use HWY_ARCH_RISCV instead.
    305 #define HWY_ARCH_RVV HWY_ARCH_RISCV
    306 
    307 #if HWY_ARCH_RISCV && defined(__riscv_xlen)
    308 
    309 #if __riscv_xlen == 32
    310 #define HWY_ARCH_RISCV_32 1
    311 #else
    312 #define HWY_ARCH_RISCV_32 0
    313 #endif
    314 
    315 #if __riscv_xlen == 64
    316 #define HWY_ARCH_RISCV_64 1
    317 #else
    318 #define HWY_ARCH_RISCV_64 0
    319 #endif
    320 
    321 #else  // !HWY_ARCH_RISCV || !defined(__riscv_xlen)
    322 #define HWY_ARCH_RISCV_32 0
    323 #define HWY_ARCH_RISCV_64 0
    324 #endif  // HWY_ARCH_RISCV && defined(__riscv_xlen)
    325 
    326 #if HWY_ARCH_RISCV_32 && HWY_ARCH_RISCV_64
    327 #error "Cannot have both RISCV_32 and RISCV_64"
    328 #endif
    329 
    330 #if defined(__s390x__)
    331 #define HWY_ARCH_S390X 1
    332 #else
    333 #define HWY_ARCH_S390X 0
    334 #endif
    335 
    336 #if defined(__loongarch64__) || defined(__loongarch64) || \
    337    (defined(__loongarch_grlen) && __loongarch_grlen == 64)
    338 #define HWY_ARCH_LOONGARCH_64 1
    339 #else
    340 #define HWY_ARCH_LOONGARCH_64 0
    341 #endif
    342 
    343 #if defined(__loongarch__) && !HWY_ARCH_LOONGARCH_64
    344 #define HWY_ARCH_LOONGARCH_32 1
    345 #else
    346 #define HWY_ARCH_LOONGARCH_32 0
    347 #endif
    348 
    349 #if HWY_ARCH_LOONGARCH_64 || HWY_ARCH_LOONGARCH_32
    350 #define HWY_ARCH_LOONGARCH 1
    351 #else
    352 #define HWY_ARCH_LOONGARCH 0
    353 #endif
    354 
    355 // It is an error to detect multiple architectures at the same time, but OK to
    356 // detect none of the above.
    357 #if (HWY_ARCH_X86 + HWY_ARCH_PPC + HWY_ARCH_ARM + HWY_ARCH_ARM_OLD + \
    358     HWY_ARCH_WASM + HWY_ARCH_RISCV + HWY_ARCH_S390X + HWY_ARCH_LOONGARCH) > 1
    359 #error "Must not detect more than one architecture"
    360 #endif
    361 
    362 //------------------------------------------------------------------------------
    363 // Operating system
    364 
    365 #if defined(_WIN32) || defined(_WIN64)
    366 #define HWY_OS_WIN 1
    367 #else
    368 #define HWY_OS_WIN 0
    369 #endif
    370 
    371 #if defined(linux) || defined(__linux__)
    372 #define HWY_OS_LINUX 1
    373 #else
    374 #define HWY_OS_LINUX 0
    375 #endif
    376 
    377 // iOS or Mac
    378 #if defined(__APPLE__)
    379 #define HWY_OS_APPLE 1
    380 #else
    381 #define HWY_OS_APPLE 0
    382 #endif
    383 
    384 #if defined(__FreeBSD__)
    385 #define HWY_OS_FREEBSD 1
    386 #else
    387 #define HWY_OS_FREEBSD 0
    388 #endif
    389 
    390 // It is an error to detect multiple OSes at the same time, but OK to
    391 // detect none of the above.
    392 #if (HWY_OS_WIN + HWY_OS_LINUX + HWY_OS_APPLE + HWY_OS_FREEBSD) > 1
    393 #error "Must not detect more than one OS"
    394 #endif
    395 
    396 //------------------------------------------------------------------------------
    397 // Endianness
    398 
    399 #if HWY_COMPILER_MSVC
    400 #if HWY_ARCH_PPC && defined(_XBOX_VER) && _XBOX_VER >= 200
    401 // XBox 360 is big-endian
    402 #define HWY_IS_LITTLE_ENDIAN 0
    403 #define HWY_IS_BIG_ENDIAN 1
    404 #else
    405 // All other targets supported by MSVC are little-endian
    406 #define HWY_IS_LITTLE_ENDIAN 1
    407 #define HWY_IS_BIG_ENDIAN 0
    408 #endif  // HWY_ARCH_PPC && defined(_XBOX_VER) && _XBOX_VER >= 200
    409 #elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
    410    __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    411 #define HWY_IS_LITTLE_ENDIAN 1
    412 #define HWY_IS_BIG_ENDIAN 0
    413 #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
    414    __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
    415 #define HWY_IS_LITTLE_ENDIAN 0
    416 #define HWY_IS_BIG_ENDIAN 1
    417 #else
    418 #error "Unable to detect endianness or unsupported byte order"
    419 #endif
    420 
    421 #if (HWY_IS_LITTLE_ENDIAN + HWY_IS_BIG_ENDIAN) != 1
    422 #error "Must only detect one byte order"
    423 #endif
    424 
    425 #endif  // HIGHWAY_HWY_DETECT_COMPILER_ARCH_H_