Grok 10.0.3
detect_compiler_arch.h
Go to the documentation of this file.
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#if (defined __CDT_PARSER__) || (defined __INTELLISENSE__) || \
24 (defined Q_CREATOR_RUN) || (defined(__CLANGD__))
25#define HWY_IDE 1
26#else
27#define HWY_IDE 0
28#endif
29
30//------------------------------------------------------------------------------
31// Compiler
32
33// clang-cl defines _MSC_VER but doesn't behave like MSVC in other aspects like
34// used in HWY_DIAGNOSTICS(). We include a check that we are not clang for that
35// purpose.
36#if defined(_MSC_VER) && !defined(__clang__)
37#define HWY_COMPILER_MSVC _MSC_VER
38#else
39#define HWY_COMPILER_MSVC 0
40#endif
41
42#if defined(_MSC_VER) && defined(__clang__)
43#define HWY_COMPILER_CLANGCL _MSC_VER
44#else
45#define HWY_COMPILER_CLANGCL 0
46#endif
47
48#ifdef __INTEL_COMPILER
49#define HWY_COMPILER_ICC __INTEL_COMPILER
50#else
51#define HWY_COMPILER_ICC 0
52#endif
53
54#ifdef __GNUC__
55#define HWY_COMPILER_GCC (__GNUC__ * 100 + __GNUC_MINOR__)
56#else
57#define HWY_COMPILER_GCC 0
58#endif
59
60// Clang can masquerade as MSVC/GCC, in which case both are set.
61#ifdef __clang__
62#ifdef __APPLE__
63// Apple LLVM version is unrelated to the actual Clang version, which we need
64// for enabling workarounds. Use the presence of warning flags to deduce it.
65// Adapted from https://github.com/simd-everywhere/simde/ simde-detect-clang.h.
66#if __has_warning("-Wformat-insufficient-args")
67#define HWY_COMPILER_CLANG 1200
68#elif __has_warning("-Wimplicit-const-int-float-conversion")
69#define HWY_COMPILER_CLANG 1100
70#elif __has_warning("-Wmisleading-indentation")
71#define HWY_COMPILER_CLANG 1000
72#elif defined(__FILE_NAME__)
73#define HWY_COMPILER_CLANG 900
74#elif __has_warning("-Wextra-semi-stmt") || \
75 __has_builtin(__builtin_rotateleft32)
76#define HWY_COMPILER_CLANG 800
77#elif __has_warning("-Wc++98-compat-extra-semi")
78#define HWY_COMPILER_CLANG 700
79#else // Anything older than 7.0 is not recommended for Highway.
80#define HWY_COMPILER_CLANG 600
81#endif // __has_warning chain
82#else // Non-Apple: normal version
83#define HWY_COMPILER_CLANG (__clang_major__ * 100 + __clang_minor__)
84#endif
85#else // Not clang
86#define HWY_COMPILER_CLANG 0
87#endif
88
89// More than one may be nonzero, but we want at least one.
90#if !HWY_COMPILER_MSVC && !HWY_COMPILER_CLANGCL && !HWY_COMPILER_ICC && \
91 !HWY_COMPILER_GCC && !HWY_COMPILER_CLANG
92#error "Unsupported compiler"
93#endif
94
95#ifdef __has_builtin
96#define HWY_HAS_BUILTIN(name) __has_builtin(name)
97#else
98#define HWY_HAS_BUILTIN(name) 0
99#endif
100
101#ifdef __has_attribute
102#define HWY_HAS_ATTRIBUTE(name) __has_attribute(name)
103#else
104#define HWY_HAS_ATTRIBUTE(name) 0
105#endif
106
107#ifdef __has_feature
108#define HWY_HAS_FEATURE(name) __has_feature(name)
109#else
110#define HWY_HAS_FEATURE(name) 0
111#endif
112
113//------------------------------------------------------------------------------
114// Architecture
115
116#if defined(__i386__) || defined(_M_IX86)
117#define HWY_ARCH_X86_32 1
118#else
119#define HWY_ARCH_X86_32 0
120#endif
121
122#if defined(__x86_64__) || defined(_M_X64)
123#define HWY_ARCH_X86_64 1
124#else
125#define HWY_ARCH_X86_64 0
126#endif
127
128#if HWY_ARCH_X86_32 && HWY_ARCH_X86_64
129#error "Cannot have both x86-32 and x86-64"
130#endif
131
132#if HWY_ARCH_X86_32 || HWY_ARCH_X86_64
133#define HWY_ARCH_X86 1
134#else
135#define HWY_ARCH_X86 0
136#endif
137
138#if defined(__powerpc64__) || defined(_M_PPC)
139#define HWY_ARCH_PPC 1
140#else
141#define HWY_ARCH_PPC 0
142#endif
143
144#if defined(__ARM_ARCH_ISA_A64) || defined(__aarch64__) || defined(_M_ARM64)
145#define HWY_ARCH_ARM_A64 1
146#else
147#define HWY_ARCH_ARM_A64 0
148#endif
149
150#if defined(__arm__) || defined(_M_ARM)
151#define HWY_ARCH_ARM_V7 1
152#else
153#define HWY_ARCH_ARM_V7 0
154#endif
155
156#if HWY_ARCH_ARM_A64 && HWY_ARCH_ARM_V7
157#error "Cannot have both A64 and V7"
158#endif
159
160#if HWY_ARCH_ARM_A64 || HWY_ARCH_ARM_V7
161#define HWY_ARCH_ARM 1
162#else
163#define HWY_ARCH_ARM 0
164#endif
165
166#if defined(__EMSCRIPTEN__) || defined(__wasm__) || defined(__WASM__)
167#define HWY_ARCH_WASM 1
168#else
169#define HWY_ARCH_WASM 0
170#endif
171
172#ifdef __riscv
173#define HWY_ARCH_RVV 1
174#else
175#define HWY_ARCH_RVV 0
176#endif
177
178// It is an error to detect multiple architectures at the same time, but OK to
179// detect none of the above.
180#if (HWY_ARCH_X86 + HWY_ARCH_PPC + HWY_ARCH_ARM + HWY_ARCH_WASM + \
181 HWY_ARCH_RVV) > 1
182#error "Must not detect more than one architecture"
183#endif
184
185#endif // HIGHWAY_HWY_DETECT_COMPILER_ARCH_H_