Grok  9.5.0
detect_compiler_arch.h
Go to the documentation of this file.
1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef HIGHWAY_HWY_DETECT_COMPILER_ARCH_H_
16 #define HIGHWAY_HWY_DETECT_COMPILER_ARCH_H_
17 
18 // Detects compiler and arch from predefined macros. Zero dependencies for
19 // inclusion by foreach_target.h.
20 
21 // Add to #if conditions to prevent IDE from graying out code.
22 #if (defined __CDT_PARSER__) || (defined __INTELLISENSE__) || \
23  (defined Q_CREATOR_RUN) || (defined(__CLANGD__))
24 #define HWY_IDE 1
25 #else
26 #define HWY_IDE 0
27 #endif
28 
29 //------------------------------------------------------------------------------
30 // Compiler
31 
32 // clang-cl defines _MSC_VER but doesn't behave like MSVC in other aspects like
33 // used in HWY_DIAGNOSTICS(). We include a check that we are not clang for that
34 // purpose.
35 #if defined(_MSC_VER) && !defined(__clang__)
36 #define HWY_COMPILER_MSVC _MSC_VER
37 #else
38 #define HWY_COMPILER_MSVC 0
39 #endif
40 
41 #ifdef __INTEL_COMPILER
42 #define HWY_COMPILER_ICC __INTEL_COMPILER
43 #else
44 #define HWY_COMPILER_ICC 0
45 #endif
46 
47 #ifdef __GNUC__
48 #define HWY_COMPILER_GCC (__GNUC__ * 100 + __GNUC_MINOR__)
49 #else
50 #define HWY_COMPILER_GCC 0
51 #endif
52 
53 // Clang can masquerade as MSVC/GCC, in which case both are set.
54 #ifdef __clang__
55 #ifdef __APPLE__
56 // Apple LLVM version is unrelated to the actual Clang version, which we need
57 // for enabling workarounds. Use the presence of warning flags to deduce it.
58 // Adapted from https://github.com/simd-everywhere/simde/ simde-detect-clang.h.
59 #if __has_warning("-Wformat-insufficient-args")
60 #define HWY_COMPILER_CLANG 1200
61 #elif __has_warning("-Wimplicit-const-int-float-conversion")
62 #define HWY_COMPILER_CLANG 1100
63 #elif __has_warning("-Wmisleading-indentation")
64 #define HWY_COMPILER_CLANG 1000
65 #elif defined(__FILE_NAME__)
66 #define HWY_COMPILER_CLANG 900
67 #elif __has_warning("-Wextra-semi-stmt") || \
68  __has_builtin(__builtin_rotateleft32)
69 #define HWY_COMPILER_CLANG 800
70 #elif __has_warning("-Wc++98-compat-extra-semi")
71 #define HWY_COMPILER_CLANG 700
72 #else // Anything older than 7.0 is not recommended for Highway.
73 #define HWY_COMPILER_CLANG 600
74 #endif // __has_warning chain
75 #else // Non-Apple: normal version
76 #define HWY_COMPILER_CLANG (__clang_major__ * 100 + __clang_minor__)
77 #endif
78 #else // Not clang
79 #define HWY_COMPILER_CLANG 0
80 #endif
81 
82 // More than one may be nonzero, but we want at least one.
83 #if !HWY_COMPILER_MSVC && !HWY_COMPILER_ICC && !HWY_COMPILER_GCC && \
84  !HWY_COMPILER_CLANG
85 #error "Unsupported compiler"
86 #endif
87 
88 #ifdef __has_builtin
89 #define HWY_HAS_BUILTIN(name) __has_builtin(name)
90 #else
91 #define HWY_HAS_BUILTIN(name) 0
92 #endif
93 
94 #ifdef __has_attribute
95 #define HWY_HAS_ATTRIBUTE(name) __has_attribute(name)
96 #else
97 #define HWY_HAS_ATTRIBUTE(name) 0
98 #endif
99 
100 //------------------------------------------------------------------------------
101 // Architecture
102 
103 #if defined(HWY_EMULATE_SVE)
104 
105 #define HWY_ARCH_X86_32 0
106 #define HWY_ARCH_X86_64 0
107 #define HWY_ARCH_X86 0
108 #define HWY_ARCH_PPC 0
109 #define HWY_ARCH_ARM_A64 1
110 #define HWY_ARCH_ARM_V7 0
111 #define HWY_ARCH_ARM 1
112 #define HWY_ARCH_WASM 0
113 #define HWY_ARCH_RVV 0
114 
115 #else
116 
117 #if defined(__i386__) || defined(_M_IX86)
118 #define HWY_ARCH_X86_32 1
119 #else
120 #define HWY_ARCH_X86_32 0
121 #endif
122 
123 #if defined(__x86_64__) || defined(_M_X64)
124 #define HWY_ARCH_X86_64 1
125 #else
126 #define HWY_ARCH_X86_64 0
127 #endif
128 
129 #if HWY_ARCH_X86_32 && HWY_ARCH_X86_64
130 #error "Cannot have both x86-32 and x86-64"
131 #endif
132 
133 #if HWY_ARCH_X86_32 || HWY_ARCH_X86_64
134 #define HWY_ARCH_X86 1
135 #else
136 #define HWY_ARCH_X86 0
137 #endif
138 
139 #if defined(__powerpc64__) || defined(_M_PPC)
140 #define HWY_ARCH_PPC 1
141 #else
142 #define HWY_ARCH_PPC 0
143 #endif
144 
145 #if defined(__ARM_ARCH_ISA_A64) || defined(__aarch64__) || defined(_M_ARM64)
146 #define HWY_ARCH_ARM_A64 1
147 #else
148 #define HWY_ARCH_ARM_A64 0
149 #endif
150 
151 #if defined(__arm__) || defined(_M_ARM)
152 #define HWY_ARCH_ARM_V7 1
153 #else
154 #define HWY_ARCH_ARM_V7 0
155 #endif
156 
157 #if HWY_ARCH_ARM_A64 && HWY_ARCH_ARM_V7
158 #error "Cannot have both A64 and V7"
159 #endif
160 
161 #if HWY_ARCH_ARM_A64 || HWY_ARCH_ARM_V7
162 #define HWY_ARCH_ARM 1
163 #else
164 #define HWY_ARCH_ARM 0
165 #endif
166 
167 #if defined(__EMSCRIPTEN__) || defined(__wasm__) || defined(__WASM__)
168 #define HWY_ARCH_WASM 1
169 #else
170 #define HWY_ARCH_WASM 0
171 #endif
172 
173 #ifdef __riscv
174 #define HWY_ARCH_RVV 1
175 #else
176 #define HWY_ARCH_RVV 0
177 #endif
178 
179 #endif // defined(HWY_EMULATE_SVE)
180 
181 // It is an error to detect multiple architectures at the same time, but OK to
182 // detect none of the above.
183 #if (HWY_ARCH_X86 + HWY_ARCH_PPC + HWY_ARCH_ARM + HWY_ARCH_WASM + \
184  HWY_ARCH_RVV) > 1
185 #error "Must not detect more than one architecture"
186 #endif
187 
188 #endif // HIGHWAY_HWY_DETECT_COMPILER_ARCH_H_