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__) 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 //////////////////////////////////////////////////////////////////////////////// 67 // Os 68 //////////////////////////////////////////////////////////////////////////////// 69 70 #if (defined(__freebsd__) || defined(__FreeBSD__)) 71 #define CPU_FEATURES_OS_FREEBSD 72 #endif 73 74 #if defined(__ANDROID__) 75 #define CPU_FEATURES_OS_ANDROID 76 #endif 77 78 #if defined(__linux__) && !defined(CPU_FEATURES_OS_FREEBSD) && \ 79 !defined(CPU_FEATURES_OS_ANDROID) 80 #define CPU_FEATURES_OS_LINUX 81 #endif 82 83 #if (defined(_WIN64) || defined(_WIN32)) 84 #define CPU_FEATURES_OS_WINDOWS 85 #endif 86 87 #if (defined(__apple__) || defined(__APPLE__) || defined(__MACH__)) 88 // From https://stackoverflow.com/a/49560690 89 #include "TargetConditionals.h" 90 #if defined(TARGET_OS_OSX) 91 #define CPU_FEATURES_OS_MACOS 92 #endif 93 #if defined(TARGET_OS_IPHONE) 94 // This is set for any non-Mac Apple products (IOS, TV, WATCH) 95 #define CPU_FEATURES_OS_IPHONE 96 #endif 97 #endif 98 99 //////////////////////////////////////////////////////////////////////////////// 100 // Compilers 101 //////////////////////////////////////////////////////////////////////////////// 102 103 #if defined(__clang__) 104 #define CPU_FEATURES_COMPILER_CLANG 105 #endif 106 107 #if defined(__GNUC__) && !defined(__clang__) 108 #define CPU_FEATURES_COMPILER_GCC 109 #endif 110 111 #if defined(_MSC_VER) 112 #define CPU_FEATURES_COMPILER_MSC 113 #endif 114 115 //////////////////////////////////////////////////////////////////////////////// 116 // Cpp 117 //////////////////////////////////////////////////////////////////////////////// 118 119 #if defined(__cplusplus) 120 #define CPU_FEATURES_START_CPP_NAMESPACE \ 121 namespace cpu_features { \ 122 extern "C" { 123 #define CPU_FEATURES_END_CPP_NAMESPACE \ 124 } \ 125 } 126 #else 127 #define CPU_FEATURES_START_CPP_NAMESPACE 128 #define CPU_FEATURES_END_CPP_NAMESPACE 129 #endif 130 131 //////////////////////////////////////////////////////////////////////////////// 132 // Compiler flags 133 //////////////////////////////////////////////////////////////////////////////// 134 135 // Use the following to check if a feature is known to be available at 136 // compile time. See README.md for an example. 137 #if defined(CPU_FEATURES_ARCH_X86) 138 139 #if defined(__AES__) 140 #define CPU_FEATURES_COMPILED_X86_AES 1 141 #else 142 #define CPU_FEATURES_COMPILED_X86_AES 0 143 #endif // defined(__AES__) 144 145 #if defined(__F16C__) 146 #define CPU_FEATURES_COMPILED_X86_F16C 1 147 #else 148 #define CPU_FEATURES_COMPILED_X86_F16C 0 149 #endif // defined(__F16C__) 150 151 #if defined(__BMI__) 152 #define CPU_FEATURES_COMPILED_X86_BMI 1 153 #else 154 #define CPU_FEATURES_COMPILED_X86_BMI 0 155 #endif // defined(__BMI__) 156 157 #if defined(__BMI2__) 158 #define CPU_FEATURES_COMPILED_X86_BMI2 1 159 #else 160 #define CPU_FEATURES_COMPILED_X86_BMI2 0 161 #endif // defined(__BMI2__) 162 163 #if (defined(__SSE__) || (_M_IX86_FP >= 1)) 164 #define CPU_FEATURES_COMPILED_X86_SSE 1 165 #else 166 #define CPU_FEATURES_COMPILED_X86_SSE 0 167 #endif 168 169 #if (defined(__SSE2__) || (_M_IX86_FP >= 2)) 170 #define CPU_FEATURES_COMPILED_X86_SSE2 1 171 #else 172 #define CPU_FEATURES_COMPILED_X86_SSE2 0 173 #endif 174 175 #if defined(__SSE3__) 176 #define CPU_FEATURES_COMPILED_X86_SSE3 1 177 #else 178 #define CPU_FEATURES_COMPILED_X86_SSE3 0 179 #endif // defined(__SSE3__) 180 181 #if defined(__SSSE3__) 182 #define CPU_FEATURES_COMPILED_X86_SSSE3 1 183 #else 184 #define CPU_FEATURES_COMPILED_X86_SSSE3 0 185 #endif // defined(__SSSE3__) 186 187 #if defined(__SSE4_1__) 188 #define CPU_FEATURES_COMPILED_X86_SSE4_1 1 189 #else 190 #define CPU_FEATURES_COMPILED_X86_SSE4_1 0 191 #endif // defined(__SSE4_1__) 192 193 #if defined(__SSE4_2__) 194 #define CPU_FEATURES_COMPILED_X86_SSE4_2 1 195 #else 196 #define CPU_FEATURES_COMPILED_X86_SSE4_2 0 197 #endif // defined(__SSE4_2__) 198 199 #if defined(__AVX__) 200 #define CPU_FEATURES_COMPILED_X86_AVX 1 201 #else 202 #define CPU_FEATURES_COMPILED_X86_AVX 0 203 #endif // defined(__AVX__) 204 205 #if defined(__AVX2__) 206 #define CPU_FEATURES_COMPILED_X86_AVX2 1 207 #else 208 #define CPU_FEATURES_COMPILED_X86_AVX2 0 209 #endif // defined(__AVX2__) 210 211 #endif // defined(CPU_FEATURES_ARCH_X86) 212 213 #if defined(CPU_FEATURES_ARCH_ANY_ARM) 214 #if defined(__ARM_NEON__) 215 #define CPU_FEATURES_COMPILED_ANY_ARM_NEON 1 216 #else 217 #define CPU_FEATURES_COMPILED_ANY_ARM_NEON 0 218 #endif // defined(__ARM_NEON__) 219 #endif // defined(CPU_FEATURES_ARCH_ANY_ARM) 220 221 #if defined(CPU_FEATURES_ARCH_MIPS) 222 #if defined(__mips_msa) 223 #define CPU_FEATURES_COMPILED_MIPS_MSA 1 224 #else 225 #define CPU_FEATURES_COMPILED_MIPS_MSA 0 226 #endif // defined(__mips_msa) 227 #endif // defined(CPU_FEATURES_ARCH_MIPS) 228 229 //////////////////////////////////////////////////////////////////////////////// 230 // Utils 231 //////////////////////////////////////////////////////////////////////////////// 232 233 // Communicates to the compiler that the block is unreachable 234 #if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC) 235 #define CPU_FEATURES_UNREACHABLE() __builtin_unreachable() 236 #elif defined(CPU_FEATURES_COMPILER_MSC) 237 #define CPU_FEATURES_UNREACHABLE() __assume(0) 238 #else 239 #define CPU_FEATURES_UNREACHABLE() 240 #endif 241 242 // Communicates to the compiler that the function is now deprecated 243 #if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC) 244 #define CPU_FEATURES_DEPRECATED(message) __attribute__((deprecated(message))) 245 #else 246 #define CPU_FEATURES_DEPRECATED(message) 247 #endif 248 249 #endif // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ 250