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