comparison mupdf-source/thirdparty/brotli/c/common/platform.h @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 /* Copyright 2016 Google Inc. All Rights Reserved.
2
3 Distributed under MIT license.
4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 */
6
7 /* Macros for compiler / platform specific features and build options.
8
9 Build options are:
10 * BROTLI_BUILD_32_BIT disables 64-bit optimizations
11 * BROTLI_BUILD_64_BIT forces to use 64-bit optimizations
12 * BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations
13 * BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations
14 * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations
15 * BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs
16 * BROTLI_BUILD_NO_UNALIGNED_READ_FAST forces off the fast-unaligned-read
17 optimizations (mainly for testing purposes)
18 * BROTLI_DEBUG dumps file name and line number when decoder detects stream
19 or memory error
20 * BROTLI_ENABLE_LOG enables asserts and dumps various state information
21 * BROTLI_ENABLE_DUMP overrides default "dump" behaviour
22 */
23
24 #ifndef BROTLI_COMMON_PLATFORM_H_
25 #define BROTLI_COMMON_PLATFORM_H_
26
27 #include <string.h> /* memcpy */
28
29 #include <brotli/port.h>
30 #include <brotli/types.h>
31
32 #include <sys/types.h> /* should include endian.h for us */
33
34 #if BROTLI_MSVC_VERSION_CHECK(18, 0, 0)
35 #include <intrin.h>
36 #endif
37
38 #if defined(BROTLI_ENABLE_LOG) || defined(BROTLI_DEBUG)
39 #include <assert.h>
40 #include <stdio.h>
41 #endif
42
43 /* The following macros were borrowed from https://github.com/nemequ/hedley
44 * with permission of original author - Evan Nemerson <evan@nemerson.com> */
45
46 /* >>> >>> >>> hedley macros */
47
48 /* Define "BROTLI_PREDICT_TRUE" and "BROTLI_PREDICT_FALSE" macros for capable
49 compilers.
50
51 To apply compiler hint, enclose the branching condition into macros, like this:
52
53 if (BROTLI_PREDICT_TRUE(zero == 0)) {
54 // main execution path
55 } else {
56 // compiler should place this code outside of main execution path
57 }
58
59 OR:
60
61 if (BROTLI_PREDICT_FALSE(something_rare_or_unexpected_happens)) {
62 // compiler should place this code outside of main execution path
63 }
64
65 */
66 #if BROTLI_GNUC_HAS_BUILTIN(__builtin_expect, 3, 0, 0) || \
67 BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \
68 BROTLI_SUNPRO_VERSION_CHECK(5, 15, 0) || \
69 BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \
70 BROTLI_IBM_VERSION_CHECK(10, 1, 0) || \
71 BROTLI_TI_VERSION_CHECK(7, 3, 0) || \
72 BROTLI_TINYC_VERSION_CHECK(0, 9, 27)
73 #define BROTLI_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
74 #define BROTLI_PREDICT_FALSE(x) (__builtin_expect(x, 0))
75 #else
76 #define BROTLI_PREDICT_FALSE(x) (x)
77 #define BROTLI_PREDICT_TRUE(x) (x)
78 #endif
79
80 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
81 !defined(__cplusplus)
82 #define BROTLI_RESTRICT restrict
83 #elif BROTLI_GNUC_VERSION_CHECK(3, 1, 0) || \
84 BROTLI_MSVC_VERSION_CHECK(14, 0, 0) || \
85 BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \
86 BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \
87 BROTLI_IBM_VERSION_CHECK(10, 1, 0) || \
88 BROTLI_PGI_VERSION_CHECK(17, 10, 0) || \
89 BROTLI_TI_VERSION_CHECK(8, 0, 0) || \
90 BROTLI_IAR_VERSION_CHECK(8, 0, 0) || \
91 (BROTLI_SUNPRO_VERSION_CHECK(5, 14, 0) && defined(__cplusplus))
92 #define BROTLI_RESTRICT __restrict
93 #elif BROTLI_SUNPRO_VERSION_CHECK(5, 3, 0) && !defined(__cplusplus)
94 #define BROTLI_RESTRICT _Restrict
95 #else
96 #define BROTLI_RESTRICT
97 #endif
98
99 #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
100 (defined(__cplusplus) && (__cplusplus >= 199711L))
101 #define BROTLI_MAYBE_INLINE inline
102 #elif defined(__GNUC_STDC_INLINE__) || defined(__GNUC_GNU_INLINE__) || \
103 BROTLI_ARM_VERSION_CHECK(6, 2, 0)
104 #define BROTLI_MAYBE_INLINE __inline__
105 #elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0) || \
106 BROTLI_ARM_VERSION_CHECK(4, 1, 0) || BROTLI_TI_VERSION_CHECK(8, 0, 0)
107 #define BROTLI_MAYBE_INLINE __inline
108 #else
109 #define BROTLI_MAYBE_INLINE
110 #endif
111
112 #if BROTLI_GNUC_HAS_ATTRIBUTE(always_inline, 4, 0, 0) || \
113 BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \
114 BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) || \
115 BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \
116 BROTLI_IBM_VERSION_CHECK(10, 1, 0) || \
117 BROTLI_TI_VERSION_CHECK(8, 0, 0) || \
118 (BROTLI_TI_VERSION_CHECK(7, 3, 0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
119 #define BROTLI_INLINE BROTLI_MAYBE_INLINE __attribute__((__always_inline__))
120 #elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0)
121 #define BROTLI_INLINE BROTLI_MAYBE_INLINE __forceinline
122 #elif BROTLI_TI_VERSION_CHECK(7, 0, 0) && defined(__cplusplus)
123 #define BROTLI_INLINE BROTLI_MAYBE_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
124 #elif BROTLI_IAR_VERSION_CHECK(8, 0, 0)
125 #define BROTLI_INLINE BROTLI_MAYBE_INLINE _Pragma("inline=forced")
126 #else
127 #define BROTLI_INLINE BROTLI_MAYBE_INLINE
128 #endif
129
130 #if BROTLI_GNUC_HAS_ATTRIBUTE(noinline, 4, 0, 0) || \
131 BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \
132 BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) || \
133 BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \
134 BROTLI_IBM_VERSION_CHECK(10, 1, 0) || \
135 BROTLI_TI_VERSION_CHECK(8, 0, 0) || \
136 (BROTLI_TI_VERSION_CHECK(7, 3, 0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
137 #define BROTLI_NOINLINE __attribute__((__noinline__))
138 #elif BROTLI_MSVC_VERSION_CHECK(13, 10, 0)
139 #define BROTLI_NOINLINE __declspec(noinline)
140 #elif BROTLI_PGI_VERSION_CHECK(10, 2, 0)
141 #define BROTLI_NOINLINE _Pragma("noinline")
142 #elif BROTLI_TI_VERSION_CHECK(6, 0, 0) && defined(__cplusplus)
143 #define BROTLI_NOINLINE _Pragma("FUNC_CANNOT_INLINE;")
144 #elif BROTLI_IAR_VERSION_CHECK(8, 0, 0)
145 #define BROTLI_NOINLINE _Pragma("inline=never")
146 #else
147 #define BROTLI_NOINLINE
148 #endif
149
150 /* <<< <<< <<< end of hedley macros. */
151
152 #if BROTLI_GNUC_HAS_ATTRIBUTE(unused, 2, 7, 0) || \
153 BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
154 #define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE __attribute__ ((unused))
155 #else
156 #define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE
157 #endif
158
159 #if BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0)
160 #define BROTLI_ALIGNED(N) __attribute__((aligned(N)))
161 #else
162 #define BROTLI_ALIGNED(N)
163 #endif
164
165 #if (defined(__ARM_ARCH) && (__ARM_ARCH == 7)) || \
166 (defined(M_ARM) && (M_ARM == 7))
167 #define BROTLI_TARGET_ARMV7
168 #endif /* ARMv7 */
169
170 #if (defined(__ARM_ARCH) && (__ARM_ARCH == 8)) || \
171 defined(__aarch64__) || defined(__ARM64_ARCH_8__)
172 #define BROTLI_TARGET_ARMV8_ANY
173
174 #if defined(__ARM_32BIT_STATE)
175 #define BROTLI_TARGET_ARMV8_32
176 #elif defined(__ARM_64BIT_STATE)
177 #define BROTLI_TARGET_ARMV8_64
178 #endif
179
180 #endif /* ARMv8 */
181
182 #if defined(__ARM_NEON__) || defined(__ARM_NEON)
183 #define BROTLI_TARGET_NEON
184 #endif
185
186 #if defined(__i386) || defined(_M_IX86)
187 #define BROTLI_TARGET_X86
188 #endif
189
190 #if defined(__x86_64__) || defined(_M_X64)
191 #define BROTLI_TARGET_X64
192 #endif
193
194 #if defined(__PPC64__)
195 #define BROTLI_TARGET_POWERPC64
196 #endif
197
198 #if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64
199 #define BROTLI_TARGET_RISCV64
200 #endif
201
202 #if defined(__loongarch_lp64)
203 #define BROTLI_TARGET_LOONGARCH64
204 #endif
205
206 #if defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \
207 defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64) || \
208 defined(BROTLI_TARGET_LOONGARCH64)
209 #define BROTLI_TARGET_64_BITS 1
210 #else
211 #define BROTLI_TARGET_64_BITS 0
212 #endif
213
214 #if defined(BROTLI_BUILD_64_BIT)
215 #define BROTLI_64_BITS 1
216 #elif defined(BROTLI_BUILD_32_BIT)
217 #define BROTLI_64_BITS 0
218 #else
219 #define BROTLI_64_BITS BROTLI_TARGET_64_BITS
220 #endif
221
222 #if (BROTLI_64_BITS)
223 #define brotli_reg_t uint64_t
224 #else
225 #define brotli_reg_t uint32_t
226 #endif
227
228 #if defined(BROTLI_BUILD_BIG_ENDIAN)
229 #define BROTLI_BIG_ENDIAN 1
230 #elif defined(BROTLI_BUILD_LITTLE_ENDIAN)
231 #define BROTLI_LITTLE_ENDIAN 1
232 #elif defined(BROTLI_BUILD_ENDIAN_NEUTRAL)
233 /* Just break elif chain. */
234 #elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
235 #define BROTLI_LITTLE_ENDIAN 1
236 #elif defined(_WIN32) || defined(BROTLI_TARGET_X64)
237 /* Win32 & x64 can currently always be assumed to be little endian */
238 #define BROTLI_LITTLE_ENDIAN 1
239 #elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
240 #define BROTLI_BIG_ENDIAN 1
241 /* Likely target platform is iOS / OSX. */
242 #elif defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
243 #define BROTLI_LITTLE_ENDIAN 1
244 #elif defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
245 #define BROTLI_BIG_ENDIAN 1
246 #endif
247
248 #if !defined(BROTLI_LITTLE_ENDIAN)
249 #define BROTLI_LITTLE_ENDIAN 0
250 #endif
251
252 #if !defined(BROTLI_BIG_ENDIAN)
253 #define BROTLI_BIG_ENDIAN 0
254 #endif
255
256 #if defined(BROTLI_BUILD_NO_UNALIGNED_READ_FAST)
257 #define BROTLI_UNALIGNED_READ_FAST (!!0)
258 #elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
259 defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) || \
260 defined(BROTLI_TARGET_RISCV64) || defined(BROTLI_TARGET_LOONGARCH64)
261 /* These targets are known to generate efficient code for unaligned reads
262 * (e.g. a single instruction, not multiple 1-byte loads, shifted and or'd
263 * together). */
264 #define BROTLI_UNALIGNED_READ_FAST (!!1)
265 #else
266 #define BROTLI_UNALIGNED_READ_FAST (!!0)
267 #endif
268
269 /* Portable unaligned memory access: read / write values via memcpy. */
270 static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) {
271 uint16_t t;
272 memcpy(&t, p, sizeof t);
273 return t;
274 }
275 static BROTLI_INLINE uint32_t BrotliUnalignedRead32(const void* p) {
276 uint32_t t;
277 memcpy(&t, p, sizeof t);
278 return t;
279 }
280 static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
281 uint64_t t;
282 memcpy(&t, p, sizeof t);
283 return t;
284 }
285 static BROTLI_INLINE size_t BrotliUnalignedReadSizeT(const void* p) {
286 size_t t;
287 memcpy(&t, p, sizeof t);
288 return t;
289 }
290 static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
291 memcpy(p, &v, sizeof v);
292 }
293
294 #if BROTLI_LITTLE_ENDIAN
295 /* Straight endianness. Just read / write values. */
296 #define BROTLI_UNALIGNED_LOAD16LE BrotliUnalignedRead16
297 #define BROTLI_UNALIGNED_LOAD32LE BrotliUnalignedRead32
298 #define BROTLI_UNALIGNED_LOAD64LE BrotliUnalignedRead64
299 #define BROTLI_UNALIGNED_STORE64LE BrotliUnalignedWrite64
300 #elif BROTLI_BIG_ENDIAN /* BROTLI_LITTLE_ENDIAN */
301 /* Explain compiler to byte-swap values. */
302 #define BROTLI_BSWAP16_(V) ((uint16_t)( \
303 (((V) & 0xFFU) << 8) | \
304 (((V) >> 8) & 0xFFU)))
305 static BROTLI_INLINE uint16_t BROTLI_UNALIGNED_LOAD16LE(const void* p) {
306 uint16_t value = BrotliUnalignedRead16(p);
307 return BROTLI_BSWAP16_(value);
308 }
309 #define BROTLI_BSWAP32_(V) ( \
310 (((V) & 0xFFU) << 24) | (((V) & 0xFF00U) << 8) | \
311 (((V) >> 8) & 0xFF00U) | (((V) >> 24) & 0xFFU))
312 static BROTLI_INLINE uint32_t BROTLI_UNALIGNED_LOAD32LE(const void* p) {
313 uint32_t value = BrotliUnalignedRead32(p);
314 return BROTLI_BSWAP32_(value);
315 }
316 #define BROTLI_BSWAP64_(V) ( \
317 (((V) & 0xFFU) << 56) | (((V) & 0xFF00U) << 40) | \
318 (((V) & 0xFF0000U) << 24) | (((V) & 0xFF000000U) << 8) | \
319 (((V) >> 8) & 0xFF000000U) | (((V) >> 24) & 0xFF0000U) | \
320 (((V) >> 40) & 0xFF00U) | (((V) >> 56) & 0xFFU))
321 static BROTLI_INLINE uint64_t BROTLI_UNALIGNED_LOAD64LE(const void* p) {
322 uint64_t value = BrotliUnalignedRead64(p);
323 return BROTLI_BSWAP64_(value);
324 }
325 static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
326 uint64_t value = BROTLI_BSWAP64_(v);
327 BrotliUnalignedWrite64(p, value);
328 }
329 #else /* BROTLI_LITTLE_ENDIAN */
330 /* Read / store values byte-wise; hopefully compiler will understand. */
331 static BROTLI_INLINE uint16_t BROTLI_UNALIGNED_LOAD16LE(const void* p) {
332 const uint8_t* in = (const uint8_t*)p;
333 return (uint16_t)(in[0] | (in[1] << 8));
334 }
335 static BROTLI_INLINE uint32_t BROTLI_UNALIGNED_LOAD32LE(const void* p) {
336 const uint8_t* in = (const uint8_t*)p;
337 uint32_t value = (uint32_t)(in[0]);
338 value |= (uint32_t)(in[1]) << 8;
339 value |= (uint32_t)(in[2]) << 16;
340 value |= (uint32_t)(in[3]) << 24;
341 return value;
342 }
343 static BROTLI_INLINE uint64_t BROTLI_UNALIGNED_LOAD64LE(const void* p) {
344 const uint8_t* in = (const uint8_t*)p;
345 uint64_t value = (uint64_t)(in[0]);
346 value |= (uint64_t)(in[1]) << 8;
347 value |= (uint64_t)(in[2]) << 16;
348 value |= (uint64_t)(in[3]) << 24;
349 value |= (uint64_t)(in[4]) << 32;
350 value |= (uint64_t)(in[5]) << 40;
351 value |= (uint64_t)(in[6]) << 48;
352 value |= (uint64_t)(in[7]) << 56;
353 return value;
354 }
355 static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
356 uint8_t* out = (uint8_t*)p;
357 out[0] = (uint8_t)v;
358 out[1] = (uint8_t)(v >> 8);
359 out[2] = (uint8_t)(v >> 16);
360 out[3] = (uint8_t)(v >> 24);
361 out[4] = (uint8_t)(v >> 32);
362 out[5] = (uint8_t)(v >> 40);
363 out[6] = (uint8_t)(v >> 48);
364 out[7] = (uint8_t)(v >> 56);
365 }
366 #endif /* BROTLI_LITTLE_ENDIAN */
367
368 static BROTLI_INLINE void* BROTLI_UNALIGNED_LOAD_PTR(const void* p) {
369 void* v;
370 memcpy(&v, p, sizeof(void*));
371 return v;
372 }
373
374 static BROTLI_INLINE void BROTLI_UNALIGNED_STORE_PTR(void* p, const void* v) {
375 memcpy(p, &v, sizeof(void*));
376 }
377
378 /* BROTLI_IS_CONSTANT macros returns true for compile-time constants. */
379 #if BROTLI_GNUC_HAS_BUILTIN(__builtin_constant_p, 3, 0, 1) || \
380 BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
381 #define BROTLI_IS_CONSTANT(x) (!!__builtin_constant_p(x))
382 #else
383 #define BROTLI_IS_CONSTANT(x) (!!0)
384 #endif
385
386 #if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY)
387 #define BROTLI_HAS_UBFX (!!1)
388 #else
389 #define BROTLI_HAS_UBFX (!!0)
390 #endif
391
392 #if defined(BROTLI_ENABLE_LOG)
393 #define BROTLI_LOG(x) printf x
394 #else
395 #define BROTLI_LOG(x)
396 #endif
397
398 #if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG)
399 #define BROTLI_ENABLE_DUMP_DEFAULT 1
400 #define BROTLI_DCHECK(x) assert(x)
401 #else
402 #define BROTLI_ENABLE_DUMP_DEFAULT 0
403 #define BROTLI_DCHECK(x)
404 #endif
405
406 #if !defined(BROTLI_ENABLE_DUMP)
407 #define BROTLI_ENABLE_DUMP BROTLI_ENABLE_DUMP_DEFAULT
408 #endif
409
410 #if BROTLI_ENABLE_DUMP
411 static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) {
412 fprintf(stderr, "%s:%d (%s)\n", f, l, fn);
413 fflush(stderr);
414 }
415 #define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__)
416 #else
417 #define BROTLI_DUMP() (void)(0)
418 #endif
419
420 /* BrotliRBit assumes brotli_reg_t fits native CPU register type. */
421 #if (BROTLI_64_BITS == BROTLI_TARGET_64_BITS)
422 /* TODO(eustas): add appropriate icc/sunpro/arm/ibm/ti checks. */
423 #if (BROTLI_GNUC_VERSION_CHECK(3, 0, 0) || defined(__llvm__)) && \
424 !defined(BROTLI_BUILD_NO_RBIT)
425 #if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY)
426 /* TODO(eustas): detect ARMv6T2 and enable this code for it. */
427 static BROTLI_INLINE brotli_reg_t BrotliRBit(brotli_reg_t input) {
428 brotli_reg_t output;
429 __asm__("rbit %0, %1\n" : "=r"(output) : "r"(input));
430 return output;
431 }
432 #define BROTLI_RBIT(x) BrotliRBit(x)
433 #endif /* armv7 / armv8 */
434 #endif /* gcc || clang */
435 #endif /* brotli_reg_t is native */
436 #if !defined(BROTLI_RBIT)
437 static BROTLI_INLINE void BrotliRBit(void) { /* Should break build if used. */ }
438 #endif /* BROTLI_RBIT */
439
440 #define BROTLI_REPEAT_4(X) {X; X; X; X;}
441 #define BROTLI_REPEAT_5(X) {X; X; X; X; X;}
442 #define BROTLI_REPEAT_6(X) {X; X; X; X; X; X;}
443
444 #define BROTLI_UNUSED(X) (void)(X)
445
446 #define BROTLI_MIN_MAX(T) \
447 static BROTLI_INLINE T brotli_min_ ## T (T a, T b) { return a < b ? a : b; } \
448 static BROTLI_INLINE T brotli_max_ ## T (T a, T b) { return a > b ? a : b; }
449 BROTLI_MIN_MAX(double) BROTLI_MIN_MAX(float) BROTLI_MIN_MAX(int)
450 BROTLI_MIN_MAX(size_t) BROTLI_MIN_MAX(uint32_t) BROTLI_MIN_MAX(uint8_t)
451 #undef BROTLI_MIN_MAX
452 #define BROTLI_MIN(T, A, B) (brotli_min_ ## T((A), (B)))
453 #define BROTLI_MAX(T, A, B) (brotli_max_ ## T((A), (B)))
454
455 #define BROTLI_SWAP(T, A, I, J) { \
456 T __brotli_swap_tmp = (A)[(I)]; \
457 (A)[(I)] = (A)[(J)]; \
458 (A)[(J)] = __brotli_swap_tmp; \
459 }
460
461 #if BROTLI_64_BITS
462 #if BROTLI_GNUC_HAS_BUILTIN(__builtin_ctzll, 3, 4, 0) || \
463 BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
464 #define BROTLI_TZCNT64 __builtin_ctzll
465 #elif BROTLI_MSVC_VERSION_CHECK(18, 0, 0)
466 #if defined(BROTLI_TARGET_X64) && !defined(_M_ARM64EC)
467 #define BROTLI_TZCNT64 _tzcnt_u64
468 #else /* BROTLI_TARGET_X64 */
469 static BROTLI_INLINE uint32_t BrotliBsf64Msvc(uint64_t x) {
470 uint32_t lsb;
471 _BitScanForward64(&lsb, x);
472 return lsb;
473 }
474 #define BROTLI_TZCNT64 BrotliBsf64Msvc
475 #endif /* BROTLI_TARGET_X64 */
476 #endif /* __builtin_ctzll */
477 #endif /* BROTLI_64_BITS */
478
479 #if BROTLI_GNUC_HAS_BUILTIN(__builtin_clz, 3, 4, 0) || \
480 BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
481 #define BROTLI_BSR32(x) (31u ^ (uint32_t)__builtin_clz(x))
482 #elif BROTLI_MSVC_VERSION_CHECK(18, 0, 0)
483 static BROTLI_INLINE uint32_t BrotliBsr32Msvc(uint32_t x) {
484 unsigned long msb;
485 _BitScanReverse(&msb, x);
486 return (uint32_t)msb;
487 }
488 #define BROTLI_BSR32 BrotliBsr32Msvc
489 #endif /* __builtin_clz */
490
491 /* Default brotli_alloc_func */
492 BROTLI_COMMON_API void* BrotliDefaultAllocFunc(void* opaque, size_t size);
493
494 /* Default brotli_free_func */
495 BROTLI_COMMON_API void BrotliDefaultFreeFunc(void* opaque, void* address);
496
497 /* Circular logical rotates. */
498 static BROTLI_INLINE uint16_t BrotliRotateRight16(uint16_t const value,
499 size_t count) {
500 count &= 0x0F; /* for fickle pattern recognition */
501 return (value >> count) | (uint16_t)(value << ((0U - count) & 0x0F));
502 }
503 static BROTLI_INLINE uint32_t BrotliRotateRight32(uint32_t const value,
504 size_t count) {
505 count &= 0x1F; /* for fickle pattern recognition */
506 return (value >> count) | (uint32_t)(value << ((0U - count) & 0x1F));
507 }
508 static BROTLI_INLINE uint64_t BrotliRotateRight64(uint64_t const value,
509 size_t count) {
510 count &= 0x3F; /* for fickle pattern recognition */
511 return (value >> count) | (uint64_t)(value << ((0U - count) & 0x3F));
512 }
513
514 BROTLI_UNUSED_FUNCTION void BrotliSuppressUnusedFunctions(void) {
515 BROTLI_UNUSED(&BrotliSuppressUnusedFunctions);
516 BROTLI_UNUSED(&BrotliUnalignedRead16);
517 BROTLI_UNUSED(&BrotliUnalignedRead32);
518 BROTLI_UNUSED(&BrotliUnalignedRead64);
519 BROTLI_UNUSED(&BrotliUnalignedReadSizeT);
520 BROTLI_UNUSED(&BrotliUnalignedWrite64);
521 BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD16LE);
522 BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD32LE);
523 BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD64LE);
524 BROTLI_UNUSED(&BROTLI_UNALIGNED_STORE64LE);
525 BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD_PTR);
526 BROTLI_UNUSED(&BROTLI_UNALIGNED_STORE_PTR);
527 BROTLI_UNUSED(&BrotliRBit);
528 BROTLI_UNUSED(&brotli_min_double);
529 BROTLI_UNUSED(&brotli_max_double);
530 BROTLI_UNUSED(&brotli_min_float);
531 BROTLI_UNUSED(&brotli_max_float);
532 BROTLI_UNUSED(&brotli_min_int);
533 BROTLI_UNUSED(&brotli_max_int);
534 BROTLI_UNUSED(&brotli_min_size_t);
535 BROTLI_UNUSED(&brotli_max_size_t);
536 BROTLI_UNUSED(&brotli_min_uint32_t);
537 BROTLI_UNUSED(&brotli_max_uint32_t);
538 BROTLI_UNUSED(&brotli_min_uint8_t);
539 BROTLI_UNUSED(&brotli_max_uint8_t);
540 BROTLI_UNUSED(&BrotliDefaultAllocFunc);
541 BROTLI_UNUSED(&BrotliDefaultFreeFunc);
542 BROTLI_UNUSED(&BrotliRotateRight16);
543 BROTLI_UNUSED(&BrotliRotateRight32);
544 BROTLI_UNUSED(&BrotliRotateRight64);
545 #if BROTLI_ENABLE_DUMP
546 BROTLI_UNUSED(&BrotliDump);
547 #endif
548
549 #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) && !defined(_M_ARM64EC) /* _mm_prefetch() is not defined outside of x86/x64 */
550 # include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
551 # define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
552 # define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
553 #elif BROTLI_GNUC_HAS_BUILTIN(__builtin_prefetch, 3, 1, 0)
554 # define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
555 # define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)
556 #elif defined(__aarch64__)
557 # define PREFETCH_L1(ptr) do { __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))); } while (0)
558 # define PREFETCH_L2(ptr) do { __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))); } while (0)
559 #else
560 # define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */
561 # define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */
562 #endif
563
564 /* The SIMD matchers are only faster at certain quality levels. */
565 #if defined(_M_X64) && defined(BROTLI_TZCNT64)
566 #define BROTLI_MAX_SIMD_QUALITY 7
567 #elif defined(BROTLI_TZCNT64)
568 #define BROTLI_MAX_SIMD_QUALITY 6
569 #endif
570 }
571
572 #endif /* BROTLI_COMMON_PLATFORM_H_ */