1 // Copyright 2017 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 CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ 16 #define CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ 17 18 //////////////////////////////////////////////////////////////////////////////// 19 // Architectures 20 //////////////////////////////////////////////////////////////////////////////// 21 22 #if defined(__pnacl__) || defined(__CLR_VER) 23 #define CPU_FEATURES_ARCH_VM 24 #endif 25 26 #if (defined(_M_IX86) || defined(__i386__)) && !defined(CPU_FEATURES_ARCH_VM) 27 #define CPU_FEATURES_ARCH_X86_32 28 #endif 29 30 #if (defined(_M_X64) || defined(__x86_64__)) && !defined(CPU_FEATURES_ARCH_VM) 31 #define CPU_FEATURES_ARCH_X86_64 32 #endif 33 34 #if defined(CPU_FEATURES_ARCH_X86_32) || defined(CPU_FEATURES_ARCH_X86_64) 35 #define CPU_FEATURES_ARCH_X86 36 #endif 37 38 #if (defined(__arm__) || defined(_M_ARM)) 39 #define CPU_FEATURES_ARCH_ARM 40 #endif 41 42 #if (defined(__aarch64__) || defined(_M_ARM64)) 43 #define CPU_FEATURES_ARCH_AARCH64 44 #endif 45 46 #if (defined(CPU_FEATURES_ARCH_AARCH64) || defined(CPU_FEATURES_ARCH_ARM)) 47 #define CPU_FEATURES_ARCH_ANY_ARM 48 #endif 49 50 #if defined(__mips64) 51 #define CPU_FEATURES_ARCH_MIPS64 52 #endif 53 54 #if defined(__mips__) && !defined(__mips64) // mips64 also declares __mips__ 55 #define CPU_FEATURES_ARCH_MIPS32 56 #endif 57 58 #if defined(CPU_FEATURES_ARCH_MIPS32) || defined(CPU_FEATURES_ARCH_MIPS64) 59 #define CPU_FEATURES_ARCH_MIPS 60 #endif 61 62 #if defined(__powerpc__) 63 #define CPU_FEATURES_ARCH_PPC 64 #endif 65 66 #if defined(__s390x__) 67 #define CPU_FEATURES_ARCH_S390X 68 #endif 69 70 #if defined(__riscv) 71 #define CPU_FEATURES_ARCH_RISCV 72 #endif 73 74 #if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 32 75 #define CPU_FEATURES_ARCH_RISCV32 76 #endif 77 78 #if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64 79 #define CPU_FEATURES_ARCH_RISCV64 80 #endif 81 82 #if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 128 83 #define CPU_FEATURES_ARCH_RISCV128 84 #endif 85 86 //////////////////////////////////////////////////////////////////////////////// 87 // Os 88 //////////////////////////////////////////////////////////////////////////////// 89 90 #if (defined(__freebsd__) || defined(__FreeBSD__)) 91 #define CPU_FEATURES_OS_FREEBSD 92 #endif 93 94 #if defined(__ANDROID__) 95 #define CPU_FEATURES_OS_ANDROID 96 #endif 97 98 #if defined(__linux__) && !defined(CPU_FEATURES_OS_FREEBSD) && \ 99 !defined(CPU_FEATURES_OS_ANDROID) 100 #define CPU_FEATURES_OS_LINUX 101 #endif 102 103 #if (defined(_WIN64) || defined(_WIN32)) 104 #define CPU_FEATURES_OS_WINDOWS 105 #endif 106 107 #if (defined(__apple__) || defined(__APPLE__) || defined(__MACH__)) 108 // From https://stackoverflow.com/a/49560690 109 #include "TargetConditionals.h" 110 #if defined(TARGET_OS_OSX) 111 #define CPU_FEATURES_OS_MACOS 112 #endif 113 #if defined(TARGET_OS_IPHONE) 114 // This is set for any non-Mac Apple products (IOS, TV, WATCH) 115 #define CPU_FEATURES_OS_IPHONE 116 #endif 117 #endif 118 119 //////////////////////////////////////////////////////////////////////////////// 120 // Compilers 121 //////////////////////////////////////////////////////////////////////////////// 122 123 #if defined(__clang__) 124 #define CPU_FEATURES_COMPILER_CLANG 125 #endif 126 127 #if defined(__GNUC__) && !defined(__clang__) 128 #define CPU_FEATURES_COMPILER_GCC 129 #endif 130 131 #if defined(_MSC_VER) 132 #define CPU_FEATURES_COMPILER_MSC 133 #endif 134 135 //////////////////////////////////////////////////////////////////////////////// 136 // Cpp 137 //////////////////////////////////////////////////////////////////////////////// 138 139 #if defined(__cplusplus) 140 #define CPU_FEATURES_START_CPP_NAMESPACE \ 141 namespace cpu_features { \ 142 extern "C" { 143 #define CPU_FEATURES_END_CPP_NAMESPACE \ 144 } \ 145 } 146 #else 147 #define CPU_FEATURES_START_CPP_NAMESPACE 148 #define CPU_FEATURES_END_CPP_NAMESPACE 149 #endif 150 151 //////////////////////////////////////////////////////////////////////////////// 152 // Compiler flags 153 //////////////////////////////////////////////////////////////////////////////// 154 155 // Use the following to check if a feature is known to be available at 156 // compile time. See README.md for an example. 157 #if defined(CPU_FEATURES_ARCH_X86) 158 159 #if defined(__AES__) 160 #define CPU_FEATURES_COMPILED_X86_AES 1 161 #else 162 #define CPU_FEATURES_COMPILED_X86_AES 0 163 #endif // defined(__AES__) 164 165 #if defined(__F16C__) 166 #define CPU_FEATURES_COMPILED_X86_F16C 1 167 #else 168 #define CPU_FEATURES_COMPILED_X86_F16C 0 169 #endif // defined(__F16C__) 170 171 #if defined(__BMI__) 172 #define CPU_FEATURES_COMPILED_X86_BMI 1 173 #else 174 #define CPU_FEATURES_COMPILED_X86_BMI 0 175 #endif // defined(__BMI__) 176 177 #if defined(__BMI2__) 178 #define CPU_FEATURES_COMPILED_X86_BMI2 1 179 #else 180 #define CPU_FEATURES_COMPILED_X86_BMI2 0 181 #endif // defined(__BMI2__) 182 183 #if (defined(__SSE__) || (_M_IX86_FP >= 1)) 184 #define CPU_FEATURES_COMPILED_X86_SSE 1 185 #else 186 #define CPU_FEATURES_COMPILED_X86_SSE 0 187 #endif 188 189 #if (defined(__SSE2__) || (_M_IX86_FP >= 2)) 190 #define CPU_FEATURES_COMPILED_X86_SSE2 1 191 #else 192 #define CPU_FEATURES_COMPILED_X86_SSE2 0 193 #endif 194 195 #if defined(__SSE3__) 196 #define CPU_FEATURES_COMPILED_X86_SSE3 1 197 #else 198 #define CPU_FEATURES_COMPILED_X86_SSE3 0 199 #endif // defined(__SSE3__) 200 201 #if defined(__SSSE3__) 202 #define CPU_FEATURES_COMPILED_X86_SSSE3 1 203 #else 204 #define CPU_FEATURES_COMPILED_X86_SSSE3 0 205 #endif // defined(__SSSE3__) 206 207 #if defined(__SSE4_1__) 208 #define CPU_FEATURES_COMPILED_X86_SSE4_1 1 209 #else 210 #define CPU_FEATURES_COMPILED_X86_SSE4_1 0 211 #endif // defined(__SSE4_1__) 212 213 #if defined(__SSE4_2__) 214 #define CPU_FEATURES_COMPILED_X86_SSE4_2 1 215 #else 216 #define CPU_FEATURES_COMPILED_X86_SSE4_2 0 217 #endif // defined(__SSE4_2__) 218 219 #if defined(__AVX__) 220 #define CPU_FEATURES_COMPILED_X86_AVX 1 221 #else 222 #define CPU_FEATURES_COMPILED_X86_AVX 0 223 #endif // defined(__AVX__) 224 225 #if defined(__AVX2__) 226 #define CPU_FEATURES_COMPILED_X86_AVX2 1 227 #else 228 #define CPU_FEATURES_COMPILED_X86_AVX2 0 229 #endif // defined(__AVX2__) 230 231 #endif // defined(CPU_FEATURES_ARCH_X86) 232 233 #if defined(CPU_FEATURES_ARCH_ANY_ARM) 234 #if defined(__ARM_NEON__) 235 #define CPU_FEATURES_COMPILED_ANY_ARM_NEON 1 236 #else 237 #define CPU_FEATURES_COMPILED_ANY_ARM_NEON 0 238 #endif // defined(__ARM_NEON__) 239 #endif // defined(CPU_FEATURES_ARCH_ANY_ARM) 240 241 #if defined(CPU_FEATURES_ARCH_MIPS) 242 #if defined(__mips_msa) 243 #define CPU_FEATURES_COMPILED_MIPS_MSA 1 244 #else 245 #define CPU_FEATURES_COMPILED_MIPS_MSA 0 246 #endif // defined(__mips_msa) 247 #if defined(__mips3d) 248 #define CPU_FEATURES_COMPILED_MIPS_MIPS3D 1 249 #else 250 #define CPU_FEATURES_COMPILED_MIPS_MIPS3D 0 251 #endif 252 #endif // defined(CPU_FEATURES_ARCH_MIPS) 253 254 #if defined(CPU_FEATURES_ARCH_RISCV) 255 #if defined(__riscv_e) 256 #define CPU_FEATURES_COMPILED_RISCV_E 1 257 #else 258 #define CPU_FEATURES_COMPILED_RISCV_E 0 259 #endif 260 #if defined(__riscv_i) 261 #define CPU_FEATURES_COMPILED_RISCV_I 1 262 #else 263 #define CPU_FEATURES_COMPILED_RISCV_I 0 264 #endif 265 #if defined(__riscv_m) 266 #define CPU_FEATURES_COMPILED_RISCV_M 1 267 #else 268 #define CPU_FEATURES_COMPILED_RISCV_M 0 269 #endif 270 #if defined(__riscv_a) 271 #define CPU_FEATURES_COMPILED_RISCV_A 1 272 #else 273 #define CPU_FEATURES_COMPILED_RISCV_A 0 274 #endif 275 #if defined(__riscv_f) 276 #define CPU_FEATURES_COMPILED_RISCV_F 1 277 #else 278 #define CPU_FEATURES_COMPILED_RISCV_F 0 279 #endif 280 #if defined(__riscv_d) 281 #define CPU_FEATURES_COMPILED_RISCV_D 1 282 #else 283 #define CPU_FEATURES_COMPILED_RISCV_D 0 284 #endif 285 #if defined(__riscv_q) 286 #define CPU_FEATURES_COMPILED_RISCV_Q 1 287 #else 288 #define CPU_FEATURES_COMPILED_RISCV_Q 0 289 #endif 290 #if defined(__riscv_c) 291 #define CPU_FEATURES_COMPILED_RISCV_C 1 292 #else 293 #define CPU_FEATURES_COMPILED_RISCV_C 0 294 #endif 295 #if defined(__riscv_v) 296 #define CPU_FEATURES_COMPILED_RISCV_V 1 297 #else 298 #define CPU_FEATURES_COMPILED_RISCV_V 0 299 #endif 300 #if defined(__riscv_zba) 301 #define CPU_FEATURES_COMPILED_RISCV_ZBA 1 302 #else 303 #define CPU_FEATURES_COMPILED_RISCV_ZBA 0 304 #endif 305 #if defined(__riscv_zbb) 306 #define CPU_FEATURES_COMPILED_RISCV_ZBB 1 307 #else 308 #define CPU_FEATURES_COMPILED_RISCV_ZBB 0 309 #endif 310 #if defined(__riscv_zbc) 311 #define CPU_FEATURES_COMPILED_RISCV_ZBC 1 312 #else 313 #define CPU_FEATURES_COMPILED_RISCV_ZBC 0 314 #endif 315 #if defined(__riscv_zbs) 316 #define CPU_FEATURES_COMPILED_RISCV_ZBS 1 317 #else 318 #define CPU_FEATURES_COMPILED_RISCV_ZBS 0 319 #endif 320 #if defined(__riscv_zfh) 321 #define CPU_FEATURES_COMPILED_RISCV_ZFH 1 322 #else 323 #define CPU_FEATURES_COMPILED_RISCV_ZFH 0 324 #endif 325 #if defined(__riscv_zfhmin) 326 #define CPU_FEATURES_COMPILED_RISCV_ZFHMIN 1 327 #else 328 #define CPU_FEATURES_COMPILED_RISCV_ZFHMIN 0 329 #endif 330 #if defined(__riscv_zknd) 331 #define CPU_FEATURES_COMPILED_RISCV_ZKND 1 332 #else 333 #define CPU_FEATURES_COMPILED_RISCV_ZKND 0 334 #endif 335 #if defined(__riscv_zkne) 336 #define CPU_FEATURES_COMPILED_RISCV_ZKNE 1 337 #else 338 #define CPU_FEATURES_COMPILED_RISCV_ZKNE 0 339 #endif 340 #if defined(__riscv_zknh) 341 #define CPU_FEATURES_COMPILED_RISCV_ZKNH 1 342 #else 343 #define CPU_FEATURES_COMPILED_RISCV_ZKNH 0 344 #endif 345 #if defined(__riscv_zksed) 346 #define CPU_FEATURES_COMPILED_RISCV_ZKSED 1 347 #else 348 #define CPU_FEATURES_COMPILED_RISCV_ZKSED 0 349 #endif 350 #if defined(__riscv_zksh) 351 #define CPU_FEATURES_COMPILED_RISCV_ZKSH 1 352 #else 353 #define CPU_FEATURES_COMPILED_RISCV_ZKSH 0 354 #endif 355 #if defined(__riscv_zkr) 356 #define CPU_FEATURES_COMPILED_RISCV_ZKR 1 357 #else 358 #define CPU_FEATURES_COMPILED_RISCV_ZKR 0 359 #endif 360 #endif // defined(CPU_FEATURES_ARCH_RISCV) 361 362 //////////////////////////////////////////////////////////////////////////////// 363 // Utils 364 //////////////////////////////////////////////////////////////////////////////// 365 366 // Communicates to the compiler that the block is unreachable 367 #if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC) 368 #define CPU_FEATURES_UNREACHABLE() __builtin_unreachable() 369 #elif defined(CPU_FEATURES_COMPILER_MSC) 370 #define CPU_FEATURES_UNREACHABLE() __assume(0) 371 #else 372 #define CPU_FEATURES_UNREACHABLE() 373 #endif 374 375 // Communicates to the compiler that the function is now deprecated 376 #if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC) 377 #define CPU_FEATURES_DEPRECATED(message) __attribute__((deprecated(message))) 378 #elif defined(CPU_FEATURES_COMPILER_MSC) 379 #define CPU_FEATURES_DEPRECATED(message) __declspec(deprecated(message)) 380 #else 381 #define CPU_FEATURES_DEPRECATED(message) 382 #endif 383 384 #endif // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ 385