simdjson  3.11.0
Ridiculously Fast JSON
implementation_detection.h
1 #ifndef SIMDJSON_IMPLEMENTATION_DETECTION_H
2 #define SIMDJSON_IMPLEMENTATION_DETECTION_H
3 
4 #include "simdjson/base.h"
5 
6 // 0 is reserved, because undefined SIMDJSON_IMPLEMENTATION equals 0 in preprocessor macros.
7 #define SIMDJSON_IMPLEMENTATION_ID_arm64 1
8 #define SIMDJSON_IMPLEMENTATION_ID_fallback 2
9 #define SIMDJSON_IMPLEMENTATION_ID_haswell 3
10 #define SIMDJSON_IMPLEMENTATION_ID_icelake 4
11 #define SIMDJSON_IMPLEMENTATION_ID_ppc64 5
12 #define SIMDJSON_IMPLEMENTATION_ID_westmere 6
13 #define SIMDJSON_IMPLEMENTATION_ID_lsx 7
14 #define SIMDJSON_IMPLEMENTATION_ID_lasx 8
15 
16 #define SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL) SIMDJSON_CAT(SIMDJSON_IMPLEMENTATION_ID_, IMPL)
17 #define SIMDJSON_IMPLEMENTATION_ID SIMDJSON_IMPLEMENTATION_ID_FOR(SIMDJSON_IMPLEMENTATION)
18 
19 #define SIMDJSON_IMPLEMENTATION_IS(IMPL) SIMDJSON_IMPLEMENTATION_ID == SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL)
20 
21 //
22 // First, figure out which implementations can be run. Doing it here makes it so we don't have to worry about the order
23 // in which we include them.
24 //
25 
26 #ifndef SIMDJSON_IMPLEMENTATION_ARM64
27 #define SIMDJSON_IMPLEMENTATION_ARM64 (SIMDJSON_IS_ARM64)
28 #endif
29 #if SIMDJSON_IMPLEMENTATION_ARM64 && SIMDJSON_IS_ARM64
30 #define SIMDJSON_CAN_ALWAYS_RUN_ARM64 1
31 #else
32 #define SIMDJSON_CAN_ALWAYS_RUN_ARM64 0
33 #endif
34 
35 // Default Icelake to on if this is x86-64. Even if we're not compiled for it, it could be selected
36 // at runtime.
37 #ifndef SIMDJSON_IMPLEMENTATION_ICELAKE
38 #define SIMDJSON_IMPLEMENTATION_ICELAKE ((SIMDJSON_IS_X86_64) && (SIMDJSON_AVX512_ALLOWED) && (SIMDJSON_COMPILER_SUPPORTS_VBMI2))
39 #endif
40 
41 #ifdef _MSC_VER
42 // To see why (__BMI__) && (__PCLMUL__) && (__LZCNT__) are not part of this next line, see
43 // https://github.com/simdjson/simdjson/issues/1247
44 #if ((SIMDJSON_IMPLEMENTATION_ICELAKE) && (__AVX2__) && (__AVX512F__) && (__AVX512DQ__) && (__AVX512CD__) && (__AVX512BW__) && (__AVX512VL__) && (__AVX512VBMI2__))
45 #define SIMDJSON_CAN_ALWAYS_RUN_ICELAKE 1
46 #else
47 #define SIMDJSON_CAN_ALWAYS_RUN_ICELAKE 0
48 #endif
49 
50 #else
51 
52 #if ((SIMDJSON_IMPLEMENTATION_ICELAKE) && (__AVX2__) && (__BMI__) && (__PCLMUL__) && (__LZCNT__) && (__AVX512F__) && (__AVX512DQ__) && (__AVX512CD__) && (__AVX512BW__) && (__AVX512VL__) && (__AVX512VBMI2__))
53 #define SIMDJSON_CAN_ALWAYS_RUN_ICELAKE 1
54 #else
55 #define SIMDJSON_CAN_ALWAYS_RUN_ICELAKE 0
56 #endif
57 
58 #endif
59 
60 // Default Haswell to on if this is x86-64. Even if we're not compiled for it, it could be selected
61 // at runtime.
62 #ifndef SIMDJSON_IMPLEMENTATION_HASWELL
63 #if SIMDJSON_CAN_ALWAYS_RUN_ICELAKE
64 // if icelake is always available, never enable haswell.
65 #define SIMDJSON_IMPLEMENTATION_HASWELL 0
66 #else
67 #define SIMDJSON_IMPLEMENTATION_HASWELL SIMDJSON_IS_X86_64
68 #endif
69 #endif
70 #ifdef _MSC_VER
71 // To see why (__BMI__) && (__PCLMUL__) && (__LZCNT__) are not part of this next line, see
72 // https://github.com/simdjson/simdjson/issues/1247
73 #if ((SIMDJSON_IMPLEMENTATION_HASWELL) && (SIMDJSON_IS_X86_64) && (__AVX2__))
74 #define SIMDJSON_CAN_ALWAYS_RUN_HASWELL 1
75 #else
76 #define SIMDJSON_CAN_ALWAYS_RUN_HASWELL 0
77 #endif
78 
79 #else
80 
81 #if ((SIMDJSON_IMPLEMENTATION_HASWELL) && (SIMDJSON_IS_X86_64) && (__AVX2__) && (__BMI__) && (__PCLMUL__) && (__LZCNT__))
82 #define SIMDJSON_CAN_ALWAYS_RUN_HASWELL 1
83 #else
84 #define SIMDJSON_CAN_ALWAYS_RUN_HASWELL 0
85 #endif
86 
87 #endif
88 
89 // Default Westmere to on if this is x86-64.
90 #ifndef SIMDJSON_IMPLEMENTATION_WESTMERE
91 #if SIMDJSON_CAN_ALWAYS_RUN_ICELAKE || SIMDJSON_CAN_ALWAYS_RUN_HASWELL
92 // if icelake or haswell are always available, never enable westmere.
93 #define SIMDJSON_IMPLEMENTATION_WESTMERE 0
94 #else
95 #define SIMDJSON_IMPLEMENTATION_WESTMERE SIMDJSON_IS_X86_64
96 #endif
97 #endif
98 
99 #if (SIMDJSON_IMPLEMENTATION_WESTMERE && SIMDJSON_IS_X86_64 && __SSE4_2__ && __PCLMUL__)
100 #define SIMDJSON_CAN_ALWAYS_RUN_WESTMERE 1
101 #else
102 #define SIMDJSON_CAN_ALWAYS_RUN_WESTMERE 0
103 #endif
104 
105 
106 #ifndef SIMDJSON_IMPLEMENTATION_PPC64
107 #define SIMDJSON_IMPLEMENTATION_PPC64 (SIMDJSON_IS_PPC64 && SIMDJSON_IS_PPC64_VMX)
108 #endif
109 #if SIMDJSON_IMPLEMENTATION_PPC64 && SIMDJSON_IS_PPC64 && SIMDJSON_IS_PPC64_VMX
110 #define SIMDJSON_CAN_ALWAYS_RUN_PPC64 1
111 #else
112 #define SIMDJSON_CAN_ALWAYS_RUN_PPC64 0
113 #endif
114 
115 #ifndef SIMDJSON_IMPLEMENTATION_LASX
116 #define SIMDJSON_IMPLEMENTATION_LASX (SIMDJSON_IS_LOONGARCH64 && __loongarch_asx)
117 #endif
118 #define SIMDJSON_CAN_ALWAYS_RUN_LASX (SIMDJSON_IMPLEMENTATION_LASX)
119 
120 #ifndef SIMDJSON_IMPLEMENTATION_LSX
121 #if SIMDJSON_CAN_ALWAYS_RUN_LASX
122 #define SIMDJSON_IMPLEMENTATION_LSX 0
123 #else
124 #define SIMDJSON_IMPLEMENTATION_LSX (SIMDJSON_IS_LOONGARCH64 && __loongarch_sx)
125 #endif
126 #endif
127 #define SIMDJSON_CAN_ALWAYS_RUN_LSX (SIMDJSON_IMPLEMENTATION_LSX)
128 
129 // Default Fallback to on unless a builtin implementation has already been selected.
130 #ifndef SIMDJSON_IMPLEMENTATION_FALLBACK
131 #if SIMDJSON_CAN_ALWAYS_RUN_ARM64 || SIMDJSON_CAN_ALWAYS_RUN_ICELAKE || SIMDJSON_CAN_ALWAYS_RUN_HASWELL || SIMDJSON_CAN_ALWAYS_RUN_WESTMERE || SIMDJSON_CAN_ALWAYS_RUN_PPC64 || SIMDJSON_CAN_ALWAYS_RUN_LSX || SIMDJSON_CAN_ALWAYS_RUN_LASX
132 // if anything at all except fallback can always run, then disable fallback.
133 #define SIMDJSON_IMPLEMENTATION_FALLBACK 0
134 #else
135 #define SIMDJSON_IMPLEMENTATION_FALLBACK 1
136 #endif
137 #endif
138 #define SIMDJSON_CAN_ALWAYS_RUN_FALLBACK SIMDJSON_IMPLEMENTATION_FALLBACK
139 
140 // Determine the best builtin implementation
141 #ifndef SIMDJSON_BUILTIN_IMPLEMENTATION
142 
143 #if SIMDJSON_CAN_ALWAYS_RUN_ICELAKE
144 #define SIMDJSON_BUILTIN_IMPLEMENTATION icelake
145 #elif SIMDJSON_CAN_ALWAYS_RUN_HASWELL
146 #define SIMDJSON_BUILTIN_IMPLEMENTATION haswell
147 #elif SIMDJSON_CAN_ALWAYS_RUN_WESTMERE
148 #define SIMDJSON_BUILTIN_IMPLEMENTATION westmere
149 #elif SIMDJSON_CAN_ALWAYS_RUN_ARM64
150 #define SIMDJSON_BUILTIN_IMPLEMENTATION arm64
151 #elif SIMDJSON_CAN_ALWAYS_RUN_PPC64
152 #define SIMDJSON_BUILTIN_IMPLEMENTATION ppc64
153 #elif SIMDJSON_CAN_ALWAYS_RUN_LSX
154 #define SIMDJSON_BUILTIN_IMPLEMENTATION lsx
155 #elif SIMDJSON_CAN_ALWAYS_RUN_LASX
156 #define SIMDJSON_BUILTIN_IMPLEMENTATION lasx
157 #elif SIMDJSON_CAN_ALWAYS_RUN_FALLBACK
158 #define SIMDJSON_BUILTIN_IMPLEMENTATION fallback
159 #else
160 #error "All possible implementations (including fallback) have been disabled! simdjson will not run."
161 #endif
162 
163 #endif // SIMDJSON_BUILTIN_IMPLEMENTATION
164 
165 #define SIMDJSON_BUILTIN_IMPLEMENTATION_ID SIMDJSON_IMPLEMENTATION_ID_FOR(SIMDJSON_BUILTIN_IMPLEMENTATION)
166 #define SIMDJSON_BUILTIN_IMPLEMENTATION_IS(IMPL) SIMDJSON_BUILTIN_IMPLEMENTATION_ID == SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL)
167 
168 #endif // SIMDJSON_IMPLEMENTATION_DETECTION_H