simdjson
4.2.1
Ridiculously Fast JSON
Loading...
Searching...
No Matches
portability.h
1
#ifndef SIMDJSON_PORTABILITY_H
2
#define SIMDJSON_PORTABILITY_H
3
4
#include <cstddef>
5
#include <cstdint>
6
#include <cstdlib>
7
#include <cfloat>
8
#include <cassert>
9
#include <climits>
10
#ifndef _WIN32
11
// strcasecmp, strncasecmp
12
#include <strings.h>
13
#endif
14
15
static_assert
(CHAR_BIT == 8,
"simdjson requires 8-bit bytes"
);
16
17
18
// We are using size_t without namespace std:: throughout the project
19
using
std::size_t;
20
21
#ifdef _MSC_VER
22
#define SIMDJSON_VISUAL_STUDIO 1
33
#ifdef __clang__
34
// clang under visual studio
35
#define SIMDJSON_CLANG_VISUAL_STUDIO 1
36
#else
37
// just regular visual studio (best guess)
38
#define SIMDJSON_REGULAR_VISUAL_STUDIO 1
39
#endif
// __clang__
40
#endif
// _MSC_VER
41
42
#if (defined(__x86_64__) || defined(_M_AMD64)) && !defined(_M_ARM64EC)
43
#define SIMDJSON_IS_X86_64 1
44
#elif defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
45
#define SIMDJSON_IS_ARM64 1
46
#elif defined(__riscv) && __riscv_xlen == 64
47
#define SIMDJSON_IS_RISCV64 1
48
#if __riscv_v_intrinsic >= 11000
49
#define SIMDJSON_HAS_RVV_INTRINSICS 1
50
#endif
51
52
#define SIMDJSON_HAS_ZVBB_INTRINSICS \
53
0
// there is currently no way to detect this
54
55
#if SIMDJSON_HAS_RVV_INTRINSICS && __riscv_vector && \
56
__riscv_v_min_vlen >= 128 && __riscv_v_elen >= 64
57
// RISC-V V extension
58
#define SIMDJSON_IS_RVV 1
59
#if SIMDJSON_HAS_ZVBB_INTRINSICS && __riscv_zvbb >= 1000000
60
// RISC-V Vector Basic Bit-manipulation
61
#define SIMDJSON_IS_ZVBB 1
62
#endif
63
#endif
64
#elif defined(__loongarch_lp64)
65
#define SIMDJSON_IS_LOONGARCH64 1
66
#elif defined(__PPC64__) || defined(_M_PPC64)
67
#define SIMDJSON_IS_PPC64 1
68
#if defined(__ALTIVEC__)
69
#define SIMDJSON_IS_PPC64_VMX 1
70
#endif
// defined(__ALTIVEC__)
71
#else
72
#define SIMDJSON_IS_32BITS 1
73
74
#if defined(_M_IX86) || defined(__i386__)
75
#define SIMDJSON_IS_X86_32BITS 1
76
#elif defined(__arm__) || defined(_M_ARM)
77
#define SIMDJSON_IS_ARM_32BITS 1
78
#elif defined(__PPC__) || defined(_M_PPC)
79
#define SIMDJSON_IS_PPC_32BITS 1
80
#endif
81
82
#endif
// defined(__x86_64__) || defined(_M_AMD64)
83
#ifndef SIMDJSON_IS_32BITS
84
#define SIMDJSON_IS_32BITS 0
85
#endif
86
87
#if SIMDJSON_IS_32BITS
88
#ifndef SIMDJSON_NO_PORTABILITY_WARNING
89
// In the future, we should allow programmers
90
// to get warning.
91
#endif
// SIMDJSON_NO_PORTABILITY_WARNING
92
#endif
// SIMDJSON_IS_32BITS
93
94
#define SIMDJSON_CAT_IMPLEMENTATION_(a,...) a ## __VA_ARGS__
95
#define SIMDJSON_CAT(a,...) SIMDJSON_CAT_IMPLEMENTATION_(a, __VA_ARGS__)
96
97
#define SIMDJSON_STRINGIFY_IMPLEMENTATION_(a,...) #a SIMDJSON_STRINGIFY(__VA_ARGS__)
98
#define SIMDJSON_STRINGIFY(a,...) SIMDJSON_CAT_IMPLEMENTATION_(a, __VA_ARGS__)
99
100
// this is almost standard?
101
#undef SIMDJSON_STRINGIFY_IMPLEMENTATION_
102
#undef SIMDJSON_STRINGIFY
103
#define SIMDJSON_STRINGIFY_IMPLEMENTATION_(a) #a
104
#define SIMDJSON_STRINGIFY(a) SIMDJSON_STRINGIFY_IMPLEMENTATION_(a)
105
106
// Our fast kernels require 64-bit systems.
107
//
108
// On 32-bit x86, we lack 64-bit popcnt, lzcnt, blsr instructions.
109
// Furthermore, the number of SIMD registers is reduced.
110
//
111
// On 32-bit ARM, we would have smaller registers.
112
//
113
// The simdjson users should still have the fallback kernel. It is
114
// slower, but it should run everywhere.
115
116
//
117
// Enable valid runtime implementations, and select SIMDJSON_BUILTIN_IMPLEMENTATION
118
//
119
120
// We are going to use runtime dispatch.
121
#if SIMDJSON_IS_X86_64
122
#ifdef __clang__
123
// clang does not have GCC push pop
124
// warning: clang attribute push can't be used within a namespace in clang up
125
// til 8.0 so SIMDJSON_TARGET_REGION and SIMDJSON_UNTARGET_REGION must be *outside* of a
126
// namespace.
127
#define SIMDJSON_TARGET_REGION(T) \
128
_Pragma(SIMDJSON_STRINGIFY( \
129
clang attribute push(__attribute__((target(T))), apply_to = function)))
130
#define SIMDJSON_UNTARGET_REGION _Pragma("clang attribute pop")
131
#elif defined(__GNUC__)
132
// GCC is easier
133
#define SIMDJSON_TARGET_REGION(T) \
134
_Pragma("GCC push_options") _Pragma(SIMDJSON_STRINGIFY(GCC target(T)))
135
#define SIMDJSON_UNTARGET_REGION _Pragma("GCC pop_options")
136
#endif
// clang then gcc
137
138
#endif
// x86
139
140
// Default target region macros don't do anything.
141
#ifndef SIMDJSON_TARGET_REGION
142
#define SIMDJSON_TARGET_REGION(T)
143
#define SIMDJSON_UNTARGET_REGION
144
#endif
145
146
// Is threading enabled?
147
#if defined(_REENTRANT) || defined(_MT)
148
#ifndef SIMDJSON_THREADS_ENABLED
149
#define SIMDJSON_THREADS_ENABLED
150
#endif
151
#endif
152
153
// workaround for large stack sizes under -O0.
154
// https://github.com/simdjson/simdjson/issues/691
155
#ifdef __APPLE__
156
#ifndef __OPTIMIZE__
157
// Apple systems have small stack sizes in secondary threads.
158
// Lack of compiler optimization may generate high stack usage.
159
// Users may want to disable threads for safety, but only when
160
// in debug mode which we detect by the fact that the __OPTIMIZE__
161
// macro is not defined.
162
#undef SIMDJSON_THREADS_ENABLED
163
#endif
164
#endif
165
166
167
#if defined(__clang__)
168
#define SIMDJSON_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined")))
169
#elif defined(__GNUC__)
170
#define SIMDJSON_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined))
171
#else
172
#define SIMDJSON_NO_SANITIZE_UNDEFINED
173
#endif
174
175
#if defined(__clang__) || defined(__GNUC__)
176
#define simdjson_pure [[gnu::pure]]
177
#else
178
#define simdjson_pure
179
#endif
180
181
#if defined(__clang__) || defined(__GNUC__)
182
#if defined(__has_feature)
183
# if __has_feature(memory_sanitizer)
184
#define SIMDJSON_NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory")))
185
# endif
// if __has_feature(memory_sanitizer)
186
#endif
// defined(__has_feature)
187
#endif
188
// make sure it is defined as 'nothing' if it is unapplicable.
189
#ifndef SIMDJSON_NO_SANITIZE_MEMORY
190
#define SIMDJSON_NO_SANITIZE_MEMORY
191
#endif
192
193
#if SIMDJSON_VISUAL_STUDIO
194
// This is one case where we do not distinguish between
195
// regular visual studio and clang under visual studio.
196
// clang under Windows has _stricmp (like visual studio) but not strcasecmp (as clang normally has)
197
#define simdjson_strcasecmp _stricmp
198
#define simdjson_strncasecmp _strnicmp
199
#else
200
// The strcasecmp, strncasecmp, and strcasestr functions do not work with multibyte strings (e.g. UTF-8).
201
// So they are only useful for ASCII in our context.
202
// https://www.gnu.org/software/libunistring/manual/libunistring.html#char-_002a-strings
203
#define simdjson_strcasecmp strcasecmp
204
#define simdjson_strncasecmp strncasecmp
205
#endif
206
207
#if defined(NDEBUG) || defined(__OPTIMIZE__) || (defined(_MSC_VER) && !defined(_DEBUG))
208
// If NDEBUG is set, or __OPTIMIZE__ is set, or we are under MSVC in release mode,
209
// then do away with asserts and use __assume.
210
// We still recommend that our users set NDEBUG in release mode.
211
#if SIMDJSON_VISUAL_STUDIO
212
#define SIMDJSON_UNREACHABLE() __assume(0)
213
#define SIMDJSON_ASSUME(COND) __assume(COND)
214
#else
215
#define SIMDJSON_UNREACHABLE() __builtin_unreachable();
216
#define SIMDJSON_ASSUME(COND) do { if (!(COND)) __builtin_unreachable(); } while (0)
217
#endif
218
219
#else
// defined(NDEBUG) || defined(__OPTIMIZE__) || (defined(_MSC_VER) && !defined(_DEBUG))
220
// This should only ever be enabled in debug mode.
221
#define SIMDJSON_UNREACHABLE() assert(0);
222
#define SIMDJSON_ASSUME(COND) assert(COND)
223
224
#endif
225
226
227
228
#if defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__
229
#define SIMDJSON_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
230
#elif defined _WIN32
231
#define SIMDJSON_IS_BIG_ENDIAN 0
232
#else
233
#if defined(__APPLE__) || defined(__FreeBSD__)
234
#include <machine/endian.h>
235
#elif defined(sun) || defined(__sun)
236
#include <sys/byteorder.h>
237
#elif defined(__MVS__)
238
#include <sys/endian.h>
239
#else
240
#ifdef __has_include
241
#if __has_include(<endian.h>)
242
#include <endian.h>
243
#endif
//__has_include(<endian.h>)
244
#endif
//__has_include
245
#endif
246
#
247
#ifndef __BYTE_ORDER__
248
// safe choice
249
#define SIMDJSON_IS_BIG_ENDIAN 0
250
#endif
251
#
252
#ifndef __ORDER_LITTLE_ENDIAN__
253
// safe choice
254
#define SIMDJSON_IS_BIG_ENDIAN 0
255
#endif
256
#
257
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
258
#define SIMDJSON_IS_BIG_ENDIAN 0
259
#else
260
#define SIMDJSON_IS_BIG_ENDIAN 1
261
#endif
262
#endif
263
264
265
#endif
// SIMDJSON_PORTABILITY_H
include
simdjson
portability.h
Generated by
1.9.8