1 /* Copyright 2019 Google LLC. All Rights Reserved. 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 16 // Preprocessor platform check macros. 17 // Note that ruy_copts contains '-Wundef', which ensures that we get a compile 18 // error if these macros are mistyped or if they are used without having 19 // #included this header. 20 21 #ifndef RUY_RUY_PLATFORM_H_ 22 #define RUY_RUY_PLATFORM_H_ 23 24 #ifdef __ANDROID_NDK__ 25 #include <android/ndk-version.h> 26 #endif 27 28 // Detect APPLE. 29 #ifdef __APPLE__ 30 #define RUY_PLATFORM_APPLE 1 31 #include <TargetConditionals.h> 32 #define RUY_PLATFORM_APPLE_IPHONE_SIMULATOR TARGET_IPHONE_SIMULATOR 33 #else 34 #define RUY_PLATFORM_APPLE 0 35 #define RUY_PLATFORM_APPLE_IPHONE_SIMULATOR 0 36 #endif 37 38 // Detect APPLE. 39 #if defined(__ppc__) || defined(__powerpc__) 40 #define RUY_PLATFORM_PPC 1 41 #else 42 #define RUY_PLATFORM_PPC 0 43 #endif 44 45 // Detect Fuchsia 46 #ifdef __Fuchsia__ 47 #define RUY_PLATFORM_FUCHSIA 1 48 #else 49 #define RUY_PLATFORM_FUCHSIA 0 50 #endif 51 52 // Architecture-level platform detection. 53 // 54 // Ruy requires these to be mutually exclusive. 55 56 // Detect x86. 57 #if defined(__x86_64__) || defined(__i386__) || defined(__i386) || \ 58 defined(__x86__) || defined(__X86__) || defined(_X86_) || \ 59 defined(_M_IX86) || defined(_M_X64) 60 #define RUY_PLATFORM_X86 1 61 #else 62 #define RUY_PLATFORM_X86 0 63 #endif 64 65 // Detect ARM 32-bit. 66 #ifdef __arm__ 67 #define RUY_PLATFORM_ARM_32 1 68 #else 69 #define RUY_PLATFORM_ARM_32 0 70 #endif 71 72 // Detect ARM 64-bit. 73 #ifdef __aarch64__ 74 #define RUY_PLATFORM_ARM_64 1 75 #else 76 #define RUY_PLATFORM_ARM_64 0 77 #endif 78 79 // Combined ARM. 80 #define RUY_PLATFORM_ARM (RUY_PLATFORM_ARM_64 || RUY_PLATFORM_ARM_32) 81 82 // Feature and capability platform detection. 83 // 84 // These are mostly sub-selections of architectures. 85 86 // Detect NEON. Explicitly avoid emulation, or anything like it, on x86. 87 #if (defined(__ARM_NEON) || defined(__ARM_NEON__)) && !RUY_PLATFORM_X86 88 #define RUY_PLATFORM_NEON 1 89 #else 90 #define RUY_PLATFORM_NEON 0 91 #endif 92 93 // Define ARM 32-bit NEON. 94 #define RUY_PLATFORM_NEON_32 (RUY_PLATFORM_NEON && RUY_PLATFORM_ARM_32) 95 96 // Define ARM 64-bit NEON. 97 // Note: NEON is implied by ARM64, so this define is redundant. 98 // It still allows some conveyance of intent. 99 #define RUY_PLATFORM_NEON_64 (RUY_PLATFORM_NEON && RUY_PLATFORM_ARM_64) 100 101 // Determine whether to enable X86 non-portable performance improvements, 102 // typically x86 SIMD paths (AVX, etc). 103 #if defined(RUY_FORCE_ENABLE_X86_ENHANCEMENTS) 104 #define RUY_PLATFORM_X86_ENHANCEMENTS 1 105 #elif defined(__EMSCRIPTEN__) 106 // We use some x86 asm e.g. in runtime CPU detection and to implement missing 107 // intrinsics. This can't build to Emscripten. 108 #define RUY_PLATFORM_X86_ENHANCEMENTS 0 109 #elif defined(__ANDROID_NDK__) && defined(__NDK_MAJOR__) && \ 110 (__NDK_MAJOR__ >= 20) 111 // Enable on sufficiently recent Android NDK. Earlier versions had broken 112 // intrinsics headers. 113 #define RUY_PLATFORM_X86_ENHANCEMENTS 1 114 #elif ((RUY_PLATFORM_APPLE && !RUY_PLATFORM_APPLE_IPHONE_SIMULATOR) || \ 115 defined(__linux__)) && \ 116 defined(__clang__) && (__clang_major__ >= 8) 117 // Enable on recent versions of Clang. Might be possible 118 // to relax this version requirement. 119 #define RUY_PLATFORM_X86_ENHANCEMENTS 1 120 #elif defined(__GNUC__) && (__GNUC__ >= 9) 121 // Enable on recent versions of GCC. Might be possible 122 // to relax this version requirement. 123 #define RUY_PLATFORM_X86_ENHANCEMENTS 1 124 // Things are working on MSVC 2019. This should also enable on sufficiently 125 // recent Clang-CL. 126 #elif defined(_MSC_VER) && (_MSC_VER >= 1920) 127 #define RUY_PLATFORM_X86_ENHANCEMENTS 1 128 #else 129 #define RUY_PLATFORM_X86_ENHANCEMENTS 0 130 #endif 131 132 // These CPU capabilities will all be true when Skylake, etc, are enabled during 133 // compilation. 134 #if RUY_PLATFORM_X86_ENHANCEMENTS && RUY_PLATFORM_X86 && \ 135 defined(__AVX512F__) && defined(__AVX512DQ__) && defined(__AVX512CD__) && \ 136 defined(__AVX512BW__) && defined(__AVX512VL__) 137 #define RUY_PLATFORM_AVX512 1 138 #else 139 #define RUY_PLATFORM_AVX512 0 140 #endif 141 142 #if RUY_PLATFORM_X86_ENHANCEMENTS && RUY_PLATFORM_X86 && defined(__AVX2__) && \ 143 (defined(__FMA__) || defined(_MSC_VER)) 144 #define RUY_PLATFORM_AVX2_FMA 1 145 #else 146 #define RUY_PLATFORM_AVX2_FMA 0 147 #endif 148 149 #if RUY_PLATFORM_X86_ENHANCEMENTS && RUY_PLATFORM_X86 && defined(__AVX__) 150 #define RUY_PLATFORM_AVX 1 151 #else 152 #define RUY_PLATFORM_AVX 0 153 #endif 154 155 // Detect Emscripten, typically Wasm. 156 #ifdef __EMSCRIPTEN__ 157 #define RUY_PLATFORM_EMSCRIPTEN 1 158 #else 159 #define RUY_PLATFORM_EMSCRIPTEN 0 160 #endif 161 162 #endif // RUY_RUY_PLATFORM_H_ 163