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