simdutf
8.2.0
Unicode at GB/s.
Loading...
Searching...
No Matches
portability.h
1
#ifndef SIMDUTF_PORTABILITY_H
2
#define SIMDUTF_PORTABILITY_H
3
4
#include "simdutf/compiler_check.h"
5
6
#include <cfloat>
7
#include <cstddef>
8
#include <cstdint>
9
#include <cstdlib>
10
#ifndef _WIN32
11
// strcasecmp, strncasecmp
12
#include <strings.h>
13
#endif
14
15
#if defined(__apple_build_version__)
16
#if __apple_build_version__ < 14000000
17
#define SIMDUTF_SPAN_DISABLED \
18
1
// apple-clang/13 doesn't support std::convertible_to
19
#endif
20
#endif
21
22
#if SIMDUTF_CPLUSPLUS20
23
#include <version>
24
#if __cpp_concepts >= 201907L && __cpp_lib_span >= 202002L && \
25
!defined(SIMDUTF_SPAN_DISABLED)
26
#define SIMDUTF_SPAN 1
27
#endif
// __cpp_concepts >= 201907L && __cpp_lib_span >= 202002L
28
#if __cpp_lib_atomic_ref >= 201806L
29
#define SIMDUTF_ATOMIC_REF 1
30
#endif
// __cpp_lib_atomic_ref
31
#if __has_cpp_attribute(maybe_unused) >= 201603L
32
#define SIMDUTF_MAYBE_UNUSED_AVAILABLE 1
33
#endif
// __has_cpp_attribute(maybe_unused) >= 201603L
34
#endif
35
41
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
42
#define SIMDUTF_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
43
#elif defined(_WIN32)
44
#define SIMDUTF_IS_BIG_ENDIAN 0
45
#else
46
#if defined(__APPLE__) || \
47
defined(__FreeBSD__)
// defined __BYTE_ORDER__ && defined
48
// __ORDER_BIG_ENDIAN__
49
#include <machine/endian.h>
50
#elif defined(sun) || \
51
defined(__sun)
// defined(__APPLE__) || defined(__FreeBSD__)
52
#include <sys/byteorder.h>
53
#else
// defined(__APPLE__) || defined(__FreeBSD__)
54
55
#ifdef __has_include
56
#if __has_include(<endian.h>)
57
#include <endian.h>
58
#endif
//__has_include(<endian.h>)
59
#endif
//__has_include
60
61
#endif
// defined(__APPLE__) || defined(__FreeBSD__)
62
63
#ifndef !defined(__BYTE_ORDER__) || !defined(__ORDER_LITTLE_ENDIAN__)
64
#define SIMDUTF_IS_BIG_ENDIAN 0
65
#endif
66
67
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
68
#define SIMDUTF_IS_BIG_ENDIAN 0
69
#else
// __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
70
#define SIMDUTF_IS_BIG_ENDIAN 1
71
#endif
// __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
72
73
#endif
// defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__
74
79
#ifdef _MSC_VER
80
#define SIMDUTF_VISUAL_STUDIO 1
91
#ifdef __clang__
92
// clang under visual studio
93
#define SIMDUTF_CLANG_VISUAL_STUDIO 1
94
#else
95
// just regular visual studio (best guess)
96
#define SIMDUTF_REGULAR_VISUAL_STUDIO 1
97
#endif
// __clang__
98
#endif
// _MSC_VER
99
100
#ifdef SIMDUTF_REGULAR_VISUAL_STUDIO
101
// https://en.wikipedia.org/wiki/C_alternative_tokens
102
// This header should have no effect, except maybe
103
// under Visual Studio.
104
#include <iso646.h>
105
#endif
106
107
#if (defined(__x86_64__) || defined(_M_AMD64)) && !defined(_M_ARM64EC)
108
#define SIMDUTF_IS_X86_64 1
109
#elif defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
110
#define SIMDUTF_IS_ARM64 1
111
#elif defined(__PPC64__) || defined(_M_PPC64)
112
#if defined(__VEC__) && defined(__ALTIVEC__)
113
#define SIMDUTF_IS_PPC64 1
114
#endif
115
#elif defined(__s390__)
116
// s390 IBM system. Big endian.
117
#elif (defined(__riscv) || defined(__riscv__)) && __riscv_xlen == 64
118
// RISC-V 64-bit
119
#define SIMDUTF_IS_RISCV64 1
120
121
// #if __riscv_v_intrinsic >= 1000000
122
// #define SIMDUTF_HAS_RVV_INTRINSICS 1
123
// #define SIMDUTF_HAS_RVV_TARGET_REGION 1
124
// #elif ...
125
// Check for special compiler versions that implement pre v1.0 intrinsics
126
#if __riscv_v_intrinsic >= 11000
127
#define SIMDUTF_HAS_RVV_INTRINSICS 1
128
#endif
129
130
#define SIMDUTF_HAS_ZVBB_INTRINSICS \
131
0
// there is currently no way to detect this
132
133
#if SIMDUTF_HAS_RVV_INTRINSICS && __riscv_vector && \
134
__riscv_v_min_vlen >= 128 && __riscv_v_elen >= 64
135
// RISC-V V extension
136
#define SIMDUTF_IS_RVV 1
137
#if SIMDUTF_HAS_ZVBB_INTRINSICS && __riscv_zvbb >= 1000000
138
// RISC-V Vector Basic Bit-manipulation
139
#define SIMDUTF_IS_ZVBB 1
140
#endif
141
#endif
142
143
#elif defined(__loongarch_lp64)
144
#if defined(__loongarch_sx) && defined(__loongarch_asx)
145
#define SIMDUTF_IS_LSX 1
146
#define SIMDUTF_IS_LASX 1
// We can always run both
147
#elif defined(__loongarch_sx)
148
#define SIMDUTF_IS_LSX 1
149
// Adjust for runtime dispatching support.
150
#if defined(__GNUC__) && !defined(__clang__) && \
151
!defined(__INTEL_COMPILER) && !defined(__NVCOMPILER)
152
#if __GNUC__ > 15 || (__GNUC__ == 15 && __GNUC_MINOR__ >= 0)
153
// We are ok, we will support runtime dispatch for LASX.
154
#else
155
// We disable runtime dispatch for LASX, which means that we will not be
156
// able to use LASX even if it is supported by the hardware. Loongson
157
// users should update to GCC 15 or better.
158
#define SIMDUTF_IMPLEMENTATION_LASX 0
159
#endif
160
#else
161
// We are not using GCC, so we assume that we can support runtime dispatch
162
// for LASX. https://godbolt.org/z/jcMnrjYhs
163
#define SIMDUTF_IMPLEMENTATION_LASX 0
164
#endif
165
#endif
166
#else
167
// The simdutf library is designed
168
// for 64-bit processors and it seems that you are not
169
// compiling for a known 64-bit platform. Please
170
// use a 64-bit target such as x64 or 64-bit ARM for best performance.
171
#define SIMDUTF_IS_32BITS 1
172
173
// We do not support 32-bit platforms, but it can be
174
// handy to identify them.
175
#if defined(_M_IX86) || defined(__i386__)
176
#define SIMDUTF_IS_X86_32BITS 1
177
#elif defined(__arm__) || defined(_M_ARM)
178
#define SIMDUTF_IS_ARM_32BITS 1
179
#elif defined(__PPC__) || defined(_M_PPC)
180
#define SIMDUTF_IS_PPC_32BITS 1
181
#endif
182
183
#endif
// defined(__x86_64__) || defined(_M_AMD64)
184
185
#ifdef SIMDUTF_IS_32BITS
186
#ifndef SIMDUTF_NO_PORTABILITY_WARNING
187
// In the future, we may want to warn users of 32-bit systems that
188
// the simdutf does not support accelerated kernels for such systems.
189
#endif
// SIMDUTF_NO_PORTABILITY_WARNING
190
#endif
// SIMDUTF_IS_32BITS
191
192
// this is almost standard?
193
#define SIMDUTF_STRINGIFY_IMPLEMENTATION_(a) #a
194
#define SIMDUTF_STRINGIFY(a) SIMDUTF_STRINGIFY_IMPLEMENTATION_(a)
195
196
// Our fast kernels require 64-bit systems.
197
//
198
// On 32-bit x86, we lack 64-bit popcnt, lzcnt, blsr instructions.
199
// Furthermore, the number of SIMD registers is reduced.
200
//
201
// On 32-bit ARM, we would have smaller registers.
202
//
203
// The simdutf users should still have the fallback kernel. It is
204
// slower, but it should run everywhere.
205
206
//
207
// Enable valid runtime implementations, and select
208
// SIMDUTF_BUILTIN_IMPLEMENTATION
209
//
210
211
// We are going to use runtime dispatch.
212
#if defined(SIMDUTF_IS_X86_64) || defined(SIMDUTF_IS_LSX)
213
#ifdef __clang__
214
// clang does not have GCC push pop
215
// warning: clang attribute push can't be used within a namespace in clang
216
// up til 8.0 so SIMDUTF_TARGET_REGION and SIMDUTF_UNTARGET_REGION must be
217
// *outside* of a namespace.
218
#define SIMDUTF_TARGET_REGION(T) \
219
_Pragma(SIMDUTF_STRINGIFY(clang attribute push( \
220
__attribute__((target(T))), apply_to = function)))
221
#define SIMDUTF_UNTARGET_REGION _Pragma("clang attribute pop")
222
#elif defined(__GNUC__)
223
// GCC is easier
224
#define SIMDUTF_TARGET_REGION(T) \
225
_Pragma("GCC push_options") _Pragma(SIMDUTF_STRINGIFY(GCC target(T)))
226
#define SIMDUTF_UNTARGET_REGION _Pragma("GCC pop_options")
227
#endif
// clang then gcc
228
229
#endif
// defined(SIMDUTF_IS_X86_64) || defined(SIMDUTF_IS_LSX)
230
231
// Default target region macros don't do anything.
232
#ifndef SIMDUTF_TARGET_REGION
233
#define SIMDUTF_TARGET_REGION(T)
234
#define SIMDUTF_UNTARGET_REGION
235
#endif
236
237
// Is threading enabled?
238
#if defined(_REENTRANT) || defined(_MT)
239
#ifndef SIMDUTF_THREADS_ENABLED
240
#define SIMDUTF_THREADS_ENABLED
241
#endif
242
#endif
243
244
// workaround for large stack sizes under -O0.
245
// https://github.com/simdutf/simdutf/issues/691
246
#ifdef __APPLE__
247
#ifndef __OPTIMIZE__
248
// Apple systems have small stack sizes in secondary threads.
249
// Lack of compiler optimization may generate high stack usage.
250
// Users may want to disable threads for safety, but only when
251
// in debug mode which we detect by the fact that the __OPTIMIZE__
252
// macro is not defined.
253
#undef SIMDUTF_THREADS_ENABLED
254
#endif
255
#endif
256
257
#ifdef SIMDUTF_VISUAL_STUDIO
258
// This is one case where we do not distinguish between
259
// regular visual studio and clang under visual studio.
260
// clang under Windows has _stricmp (like visual studio) but not strcasecmp
261
// (as clang normally has)
262
#define simdutf_strcasecmp _stricmp
263
#define simdutf_strncasecmp _strnicmp
264
#else
265
// The strcasecmp, strncasecmp, and strcasestr functions do not work with
266
// multibyte strings (e.g. UTF-8). So they are only useful for ASCII in our
267
// context.
268
// https://www.gnu.org/software/libunistring/manual/libunistring.html#char-_002a-strings
269
#define simdutf_strcasecmp strcasecmp
270
#define simdutf_strncasecmp strncasecmp
271
#endif
272
273
#if defined(__GNUC__) && !defined(__clang__)
274
#if __GNUC__ >= 11
275
#define SIMDUTF_GCC11ORMORE 1
276
#endif
// __GNUC__ >= 11
277
#if __GNUC__ == 10
278
#define SIMDUTF_GCC10 1
279
#endif
// __GNUC__ == 10
280
#if __GNUC__ < 10
281
#define SIMDUTF_GCC9OROLDER 1
282
#endif
// __GNUC__ == 10
283
#endif
// defined(__GNUC__) && !defined(__clang__)
284
285
#endif
// SIMDUTF_PORTABILITY_H
include
simdutf
portability.h
Generated by
1.9.8