Flutter Engine
The Flutter Engine
SkOpts_SetTarget.h
Go to the documentation of this file.
1/*
2 * Copyright 2023 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8// Include guards are intentionally omitted
9
11
12#if !defined(SK_OPTS_TARGET)
13 #error Define SK_OPTS_TARGET before including SkOpts_SetTarget
14#endif
15
16#if defined(SK_OPTS_NS)
17 // For testing define SK_OPTS_NS before including.
18#elif SK_OPTS_TARGET == SK_OPTS_TARGET_DEFAULT
19
20 #if defined(SK_ARM_HAS_NEON)
21 #define SK_OPTS_NS neon
22 #elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SKX
23 #define SK_OPTS_NS skx
24 #elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_AVX2
25 #define SK_OPTS_NS avx2
26 #elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_AVX
27 #define SK_OPTS_NS avx
28 #elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE42
29 #define SK_OPTS_NS sse42
30 #elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE41
31 #define SK_OPTS_NS sse41
32 #elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
33 #define SK_OPTS_NS ssse3
34 #elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE3
35 #define SK_OPTS_NS sse3
36 #elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
37 #define SK_OPTS_NS sse2
38 #elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1
39 #define SK_OPTS_NS sse
40 #elif SK_CPU_LSX_LEVEL >= SK_CPU_LSX_LEVEL_LASX
41 #define SK_OPTS_NS lasx
42 #elif SK_CPU_LSX_LEVEL >= SK_CPU_LSX_LEVEL_LSX
43 #define SK_OPTS_NS lsx
44 #else
45 #define SK_OPTS_NS portable
46 #endif
47
48 #define DEFINE_DEFAULT(name) decltype(name) name = SK_OPTS_NS::name
49
50#else // SK_OPTS_TARGET != SK_OPTS_TARGET_DEFAULT
51
52 #if defined(SK_OLD_CPU_SSE_LEVEL)
53 #error Include SkOpts_RestoreTarget before re-including SkOpts_SetTarget
54 #endif
55
56 #define SK_OLD_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL
57 #undef SK_CPU_SSE_LEVEL
58
59 // NOTE: Below, we automatically include arch-specific intrinsic headers when we've detected
60 // that the compiler is clang-cl. Clang's headers skip including "unsupported" intrinsics (via
61 // defines like __AVX__ etc.), but only when _MSC_VER is also defined. To get around that, we
62 // directly include the headers for any intrinsics that ought to be present in each opts target.
63 //
64 // Each of the specific intrinsic headers also checks to ensure that immintrin.h has been
65 // included, so do that here, first.
66 #if defined(__clang__) && defined(_MSC_VER)
67 #include <immintrin.h>
68 #endif
69
70 // Why not put the target string in a #define, and remove the boilerplate? Because GCC doesn't
71 // allow the target() option to be expanded by the preprocessor - it must be a literal string.
72 #if SK_OPTS_TARGET == SK_OPTS_TARGET_SSSE3
73
74 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSSE3
75 #define SK_OPTS_NS ssse3
76
77 #if defined(__clang__)
78 #pragma clang attribute push(__attribute__((target("sse2,ssse3"))), apply_to=function)
79 #elif defined(__GNUC__)
80 #pragma GCC push_options
81 #pragma GCC target("sse2,ssse3")
82 #endif
83
84 #if defined(__clang__) && defined(_MSC_VER)
85 #include <pmmintrin.h>
86 #include <tmmintrin.h>
87 #endif
88
89 #elif SK_OPTS_TARGET == SK_OPTS_TARGET_AVX
90
91 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX
92 #define SK_OPTS_NS avx
93
94 #if defined(__clang__)
95 #pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1,sse4.2,avx"))), apply_to=function)
96 #elif defined(__GNUC__)
97 #pragma GCC push_options
98 #pragma GCC target("sse2,ssse3,sse4.1,sse4.2,avx")
99 #endif
100
101 #if defined(__clang__) && defined(_MSC_VER)
102 #include <pmmintrin.h>
103 #include <tmmintrin.h>
104 #include <smmintrin.h>
105 #include <avxintrin.h>
106 #endif
107
108 #elif SK_OPTS_TARGET == SK_OPTS_TARGET_HSW
109
110 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX2
111 #define SK_OPTS_NS hsw
112
113 #if defined(__clang__)
114 #pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1,sse4.2,avx,avx2,bmi,bmi2,f16c,fma"))), apply_to=function)
115 #elif defined(__GNUC__)
116 #pragma GCC push_options
117 #pragma GCC target("sse2,ssse3,sse4.1,sse4.2,avx,avx2,bmi,bmi2,f16c,fma")
118 #endif
119
120 #if defined(__clang__) && defined(_MSC_VER)
121 #include <pmmintrin.h>
122 #include <tmmintrin.h>
123 #include <smmintrin.h>
124 #include <avxintrin.h>
125 #include <avx2intrin.h>
126 #include <f16cintrin.h>
127 #include <bmi2intrin.h>
128 #include <fmaintrin.h>
129 #endif
130
131 #else
132 #error Unexpected value of SK_OPTS_TARGET
133
134 #endif
135
136#endif // !SK_OPTS_TARGET_DEFAULT