44 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
55*/
66
7- /* Macros for compiler / platform specific features and build options. */
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_PORTABLE disables dangerous optimizations, like unaligned
16+ read and overlapping memcpy; this reduces decompression speed by 5%
17+ * BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs
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+ */
822
923#ifndef BROTLI_COMMON_PLATFORM_H_
1024#define BROTLI_COMMON_PLATFORM_H_
1529#include < brotli/port.h>
1630#include < brotli/types.h>
1731
18- #if defined OS_LINUX || defined OS_CYGWIN
32+ #if defined( OS_LINUX) || defined( OS_CYGWIN)
1933#include < endian.h>
20- #elif defined OS_FREEBSD
34+ #elif defined( OS_FREEBSD)
2135#include < machine/endian.h>
22- #elif defined OS_MACOSX
36+ #elif defined( OS_MACOSX)
2337#include < machine/endian.h>
2438/* Let's try and follow the Linux convention */
2539#define BROTLI_X_BYTE_ORDER BYTE_ORDER
3246#include < stdio.h>
3347#endif
3448
35- /* Macros for compiler / platform specific features and build options.
49+ /* The following macros were borrowed from https://github.com/nemequ/hedley
50+ * with permission of original author - Evan Nemerson <[email protected] > */ 3651
37- Build options are:
38- * BROTLI_BUILD_32_BIT disables 64-bit optimizations
39- * BROTLI_BUILD_64_BIT forces to use 64-bit optimizations
40- * BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations
41- * BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations
42- * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations
43- * BROTLI_BUILD_PORTABLE disables dangerous optimizations, like unaligned
44- read and overlapping memcpy; this reduces decompression speed by 5%
45- * BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs
46- * BROTLI_DEBUG dumps file name and line number when decoder detects stream
47- or memory error
48- * BROTLI_ENABLE_LOG enables asserts and dumps various state information
49- */
52+ /* >>> >>> >>> hedley macros */
53+
54+ /* Define "BROTLI_PREDICT_TRUE" and "BROTLI_PREDICT_FALSE" macros for capable
55+ compilers.
56+
57+ To apply compiler hint, enclose the branching condition into macros, like this:
58+
59+ if (BROTLI_PREDICT_TRUE(zero == 0)) {
60+ // main execution path
61+ } else {
62+ // compiler should place this code outside of main execution path
63+ }
64+
65+ OR:
5066
51- #if BROTLI_MODERN_COMPILER || __has_attribute (always_inline )
52- #define BROTLI_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline))
67+ if (BROTLI_PREDICT_FALSE(something_rare_or_unexpected_happens)) {
68+ // compiler should place this code outside of main execution path
69+ }
70+
71+ */
72+ #if BROTLI_GNUC_HAS_BUILTIN(__builtin_expect, 3, 0, 0) || \
73+ BROTLI_INTEL_VERSION_CHECK (16 , 0 , 0 ) || \
74+ BROTLI_SUNPRO_VERSION_CHECK(5 , 12 , 0 ) || \
75+ BROTLI_ARM_VERSION_CHECK(4 , 1 , 0 ) || \
76+ BROTLI_IBM_VERSION_CHECK(10 , 1 , 0 ) || \
77+ BROTLI_TI_VERSION_CHECK(7 , 3 , 0 ) || \
78+ BROTLI_TINYC_VERSION_CHECK(0 , 9 , 27 )
79+ #define BROTLI_PREDICT_TRUE (x ) (__builtin_expect(!!(x), 1 ))
80+ #define BROTLI_PREDICT_FALSE (x ) (__builtin_expect(x, 0 ))
5381#else
54- #define BROTLI_ATTRIBUTE_ALWAYS_INLINE
82+ #define BROTLI_PREDICT_FALSE (x ) (x)
83+ #define BROTLI_PREDICT_TRUE (x ) (x)
5584#endif
5685
57- #if defined(_WIN32 ) || defined(__CYGWIN__ )
58- #define BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN
59- #elif BROTLI_MODERN_COMPILER || __has_attribute (visibility )
60- #define BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN \
61- __attribute__ ((visibility ("hidden")))
86+ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
87+ !defined (__cplusplus)
88+ #define BROTLI_RESTRICT restrict
89+ #elif BROTLI_GNUC_VERSION_CHECK(3, 1, 0) || \
90+ BROTLI_MSVC_VERSION_CHECK (14 , 0 , 0 ) || \
91+ BROTLI_INTEL_VERSION_CHECK(16 , 0 , 0 ) || \
92+ BROTLI_ARM_VERSION_CHECK(4 , 1 , 0 ) || \
93+ BROTLI_IBM_VERSION_CHECK(10 , 1 , 0 ) || \
94+ BROTLI_PGI_VERSION_CHECK(17 , 10 , 0 ) || \
95+ BROTLI_TI_VERSION_CHECK(8 , 0 , 0 ) || \
96+ BROTLI_IAR_VERSION_CHECK(8 , 0 , 0 ) || \
97+ (BROTLI_SUNPRO_VERSION_CHECK(5 , 14 , 0 ) && defined(__cplusplus))
98+ #define BROTLI_RESTRICT __restrict
99+ #elif BROTLI_SUNPRO_VERSION_CHECK(5, 3, 0) && !defined(__cplusplus)
100+ #define BROTLI_RESTRICT _Restrict
62101#else
63- #define BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN
102+ #define BROTLI_RESTRICT
64103#endif
65104
66- #ifndef BROTLI_INTERNAL
67- #define BROTLI_INTERNAL BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN
105+ #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
106+ (defined (__cplusplus) && (__cplusplus >= 199711L ))
107+ #define BROTLI_MAYBE_INLINE inline
108+ #elif defined(__GNUC_STDC_INLINE__) || defined(__GNUC_GNU_INLINE__) || \
109+ BROTLI_ARM_VERSION_CHECK (6 , 2 , 0 )
110+ #define BROTLI_MAYBE_INLINE __inline__
111+ #elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0) || \
112+ BROTLI_ARM_VERSION_CHECK (4 , 1 , 0 ) || BROTLI_TI_VERSION_CHECK(8 , 0 , 0 )
113+ #define BROTLI_MAYBE_INLINE __inline
114+ #else
115+ #define BROTLI_MAYBE_INLINE
68116#endif
69117
70- #ifndef _MSC_VER
71- #if defined(__cplusplus ) || !defined(__STRICT_ANSI__ ) || \
72- (defined(__STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L )
73- #define BROTLI_INLINE inline BROTLI_ATTRIBUTE_ALWAYS_INLINE
118+ #if BROTLI_GNUC_HAS_ATTRIBUTE(always_inline, 4, 0, 0) || \
119+ BROTLI_INTEL_VERSION_CHECK (16 , 0 , 0 ) || \
120+ BROTLI_SUNPRO_VERSION_CHECK(5 , 11 , 0 ) || \
121+ BROTLI_ARM_VERSION_CHECK(4 , 1 , 0 ) || \
122+ BROTLI_IBM_VERSION_CHECK(10 , 1 , 0 ) || \
123+ BROTLI_TI_VERSION_CHECK(8 , 0 , 0 ) || \
124+ (BROTLI_TI_VERSION_CHECK(7 , 3 , 0 ) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
125+ #define BROTLI_INLINE BROTLI_MAYBE_INLINE __attribute__ ((__always_inline__))
126+ #elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0)
127+ #define BROTLI_INLINE BROTLI_MAYBE_INLINE __forceinline
128+ #elif BROTLI_TI_VERSION_CHECK(7, 0, 0) && defined(__cplusplus)
129+ #define BROTLI_INLINE BROTLI_MAYBE_INLINE _Pragma (" FUNC_ALWAYS_INLINE;" )
130+ #elif BROTLI_IAR_VERSION_CHECK(8, 0, 0)
131+ #define BROTLI_INLINE BROTLI_MAYBE_INLINE _Pragma (" inline=forced" )
74132#else
75- #define BROTLI_INLINE
133+ #define BROTLI_INLINE BROTLI_MAYBE_INLINE
76134#endif
77- #else /* _MSC_VER */
78- #define BROTLI_INLINE __forceinline
79- #endif /* _MSC_VER */
80135
81- #if BROTLI_MODERN_COMPILER || __has_attribute (unused )
82- #define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE __attribute__ ((unused))
136+ #if BROTLI_GNUC_HAS_ATTRIBUTE(noinline, 4, 0, 0) || \
137+ BROTLI_INTEL_VERSION_CHECK (16 , 0 , 0 ) || \
138+ BROTLI_SUNPRO_VERSION_CHECK(5 , 11 , 0 ) || \
139+ BROTLI_ARM_VERSION_CHECK(4 , 1 , 0 ) || \
140+ BROTLI_IBM_VERSION_CHECK(10 , 1 , 0 ) || \
141+ BROTLI_TI_VERSION_CHECK(8 , 0 , 0 ) || \
142+ (BROTLI_TI_VERSION_CHECK(7 , 3 , 0 ) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
143+ #define BROTLI_NOINLINE __attribute__ ((__noinline__))
144+ #elif BROTLI_MSVC_VERSION_CHECK(13, 10, 0)
145+ #define BROTLI_NOINLINE __declspec (noinline)
146+ #elif BROTLI_PGI_VERSION_CHECK(10, 2, 0)
147+ #define BROTLI_NOINLINE _Pragma (" noinline" )
148+ #elif BROTLI_TI_VERSION_CHECK(6, 0, 0) && defined(__cplusplus)
149+ #define BROTLI_NOINLINE _Pragma (" FUNC_CANNOT_INLINE;" )
150+ #elif BROTLI_IAR_VERSION_CHECK(8, 0, 0)
151+ #define BROTLI_NOINLINE _Pragma (" inline=never" )
83152#else
84- #define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE
153+ #define BROTLI_NOINLINE
85154#endif
86155
87- #if !defined(__cplusplus ) && !defined(c_plusplus ) && \
88- (defined(__STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L )
89- #define BROTLI_RESTRICT restrict
90- #elif BROTLI_GCC_VERSION > 295 || defined(__llvm__ )
91- #define BROTLI_RESTRICT __restrict
156+ /* BROTLI_INTERNAL could be defined to override visibility, e.g. for tests. */
157+ #if !defined(BROTLI_INTERNAL)
158+ #if defined(_WIN32) || defined(__CYGWIN__)
159+ #define BROTLI_INTERNAL
160+ #elif BROTLI_GNUC_VERSION_CHECK(3, 3, 0) || \
161+ BROTLI_TI_VERSION_CHECK (8 , 0 , 0 ) || \
162+ BROTLI_INTEL_VERSION_CHECK(16 , 0 , 0 ) || \
163+ BROTLI_ARM_VERSION_CHECK(4 , 1 , 0 ) || \
164+ BROTLI_IBM_VERSION_CHECK(13 , 1 , 0 ) || \
165+ BROTLI_SUNPRO_VERSION_CHECK(5 , 11 , 0 ) || \
166+ (BROTLI_TI_VERSION_CHECK(7 , 3 , 0 ) && \
167+ defined(__TI_GNU_ATTRIBUTE_SUPPORT__) && defined(__TI_EABI__))
168+ #define BROTLI_INTERNAL __attribute__ ((visibility (" hidden" )))
92169#else
93- #define BROTLI_RESTRICT
170+ #define BROTLI_INTERNAL
94171#endif
172+ #endif
173+
174+ /* <<< <<< <<< end of hedley macros. */
95175
96- #if BROTLI_MODERN_COMPILER || __has_attribute (noinline )
97- #define BROTLI_NOINLINE __attribute__((noinline))
176+ #if BROTLI_GNUC_HAS_ATTRIBUTE(unused, 2, 7, 0) || \
177+ BROTLI_INTEL_VERSION_CHECK (16 , 0 , 0 )
178+ #define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE __attribute__ ((unused))
98179#else
99- #define BROTLI_NOINLINE
180+ #define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE
100181#endif
101182
102183#if (defined(__ARM_ARCH) && (__ARM_ARCH == 7)) || \
121202#define BROTLI_TARGET_POWERPC64
122203#endif
123204
205+ #if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64
206+ #define BROTLI_TARGET_RISCV64
207+ #endif
208+
124209#if defined(BROTLI_BUILD_64_BIT)
125210#define BROTLI_64_BITS 1
126211#elif defined(BROTLI_BUILD_32_BIT)
127212#define BROTLI_64_BITS 0
128213#elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8) || \
129- defined(BROTLI_TARGET_POWERPC64 )
214+ defined (BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64)
130215#define BROTLI_64_BITS 1
131216#else
132217#define BROTLI_64_BITS 0
167252#define BROTLI_BIG_ENDIAN 0
168253#endif
169254
170- #ifdef BROTLI_X_BYTE_ORDER
255+ #if defined( BROTLI_X_BYTE_ORDER)
171256#undef BROTLI_X_BYTE_ORDER
172257#undef BROTLI_X_LITTLE_ENDIAN
173258#undef BROTLI_X_BIG_ENDIAN
174259#endif
175260
176- #ifdef BROTLI_BUILD_PORTABLE
261+ #if defined( BROTLI_BUILD_PORTABLE)
177262#define BROTLI_ALIGNED_READ (!!1 )
178263#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
179- defined(BROTLI_TARGET_ARMV7 ) || defined(BROTLI_TARGET_ARMV8 )
264+ defined (BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8) || \
265+ defined(BROTLI_TARGET_RISCV64)
180266/* Allow unaligned read only for white-listed CPUs. */
181267#define BROTLI_ALIGNED_READ (!!0 )
182268#else
@@ -306,34 +392,9 @@ static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
306392}
307393#endif /* BROTLI_LITTLE_ENDIAN */
308394
309- /* Define "BROTLI_PREDICT_TRUE" and "BROTLI_PREDICT_FALSE" macros for capable
310- compilers.
311-
312- To apply compiler hint, enclose the branching condition into macros, like this:
313-
314- if (BROTLI_PREDICT_TRUE(zero == 0)) {
315- // main execution path
316- } else {
317- // compiler should place this code outside of main execution path
318- }
319-
320- OR:
321-
322- if (BROTLI_PREDICT_FALSE(something_rare_or_unexpected_happens)) {
323- // compiler should place this code outside of main execution path
324- }
325-
326- */
327- #if BROTLI_MODERN_COMPILER || __has_builtin (__builtin_expect )
328- #define BROTLI_PREDICT_TRUE (x ) (__builtin_expect(!!(x), 1))
329- #define BROTLI_PREDICT_FALSE (x ) (__builtin_expect(x, 0))
330- #else
331- #define BROTLI_PREDICT_FALSE (x ) (x)
332- #define BROTLI_PREDICT_TRUE (x ) (x)
333- #endif
334-
335395/* BROTLI_IS_CONSTANT macros returns true for compile-time constants. */
336- #if BROTLI_MODERN_COMPILER || __has_builtin (__builtin_constant_p )
396+ #if BROTLI_GNUC_HAS_BUILTIN(__builtin_constant_p, 3, 0, 1) || \
397+ BROTLI_INTEL_VERSION_CHECK (16 , 0 , 0 )
337398#define BROTLI_IS_CONSTANT (x ) (!!__builtin_constant_p(x))
338399#else
339400#define BROTLI_IS_CONSTANT (x ) (!!0 )
@@ -345,7 +406,7 @@ To apply compiler hint, enclose the branching condition into macros, like this:
345406#define BROTLI_HAS_UBFX (!!0 )
346407#endif
347408
348- #ifdef BROTLI_ENABLE_LOG
409+ #if defined( BROTLI_ENABLE_LOG)
349410#define BROTLI_DCHECK (x ) assert (x)
350411#define BROTLI_LOG (x ) printf x
351412#else
@@ -363,7 +424,8 @@ static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) {
363424#define BROTLI_DUMP () (void )(0 )
364425#endif
365426
366- #if (BROTLI_MODERN_COMPILER || defined(__llvm__ )) && \
427+ /* TODO: add appropriate icc/sunpro/arm/ibm/ti checks. */
428+ #if (BROTLI_GNUC_VERSION_CHECK(3, 0, 0) || defined(__llvm__)) && \
367429 !defined (BROTLI_BUILD_NO_RBIT)
368430#if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8)
369431/* TODO: detect ARMv6T2 and enable this code for it. */
@@ -415,32 +477,32 @@ static void BrotliDefaultFreeFunc(void* opaque, void* address) {
415477}
416478
417479BROTLI_UNUSED_FUNCTION void BrotliSuppressUnusedFunctions (void ) {
418- BROTLI_UNUSED (BrotliSuppressUnusedFunctions );
419- BROTLI_UNUSED (BrotliUnalignedRead16 );
420- BROTLI_UNUSED (BrotliUnalignedRead32 );
421- BROTLI_UNUSED (BrotliUnalignedRead64 );
422- BROTLI_UNUSED (BrotliUnalignedWrite64 );
423- BROTLI_UNUSED (BROTLI_UNALIGNED_LOAD16LE );
424- BROTLI_UNUSED (BROTLI_UNALIGNED_LOAD32LE );
425- BROTLI_UNUSED (BROTLI_UNALIGNED_LOAD64LE );
426- BROTLI_UNUSED (BROTLI_UNALIGNED_STORE64LE );
427- BROTLI_UNUSED (BrotliRBit );
428- BROTLI_UNUSED (brotli_min_double );
429- BROTLI_UNUSED (brotli_max_double );
430- BROTLI_UNUSED (brotli_min_float );
431- BROTLI_UNUSED (brotli_max_float );
432- BROTLI_UNUSED (brotli_min_int );
433- BROTLI_UNUSED (brotli_max_int );
434- BROTLI_UNUSED (brotli_min_size_t );
435- BROTLI_UNUSED (brotli_max_size_t );
436- BROTLI_UNUSED (brotli_min_uint32_t );
437- BROTLI_UNUSED (brotli_max_uint32_t );
438- BROTLI_UNUSED (brotli_min_uint8_t );
439- BROTLI_UNUSED (brotli_max_uint8_t );
440- BROTLI_UNUSED (BrotliDefaultAllocFunc );
441- BROTLI_UNUSED (BrotliDefaultFreeFunc );
480+ BROTLI_UNUSED (& BrotliSuppressUnusedFunctions);
481+ BROTLI_UNUSED (& BrotliUnalignedRead16);
482+ BROTLI_UNUSED (& BrotliUnalignedRead32);
483+ BROTLI_UNUSED (& BrotliUnalignedRead64);
484+ BROTLI_UNUSED (& BrotliUnalignedWrite64);
485+ BROTLI_UNUSED (& BROTLI_UNALIGNED_LOAD16LE);
486+ BROTLI_UNUSED (& BROTLI_UNALIGNED_LOAD32LE);
487+ BROTLI_UNUSED (& BROTLI_UNALIGNED_LOAD64LE);
488+ BROTLI_UNUSED (& BROTLI_UNALIGNED_STORE64LE);
489+ BROTLI_UNUSED (& BrotliRBit);
490+ BROTLI_UNUSED (& brotli_min_double);
491+ BROTLI_UNUSED (& brotli_max_double);
492+ BROTLI_UNUSED (& brotli_min_float);
493+ BROTLI_UNUSED (& brotli_max_float);
494+ BROTLI_UNUSED (& brotli_min_int);
495+ BROTLI_UNUSED (& brotli_max_int);
496+ BROTLI_UNUSED (& brotli_min_size_t );
497+ BROTLI_UNUSED (& brotli_max_size_t );
498+ BROTLI_UNUSED (& brotli_min_uint32_t );
499+ BROTLI_UNUSED (& brotli_max_uint32_t );
500+ BROTLI_UNUSED (& brotli_min_uint8_t );
501+ BROTLI_UNUSED (& brotli_max_uint8_t );
502+ BROTLI_UNUSED (& BrotliDefaultAllocFunc);
503+ BROTLI_UNUSED (& BrotliDefaultFreeFunc);
442504#if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG)
443- BROTLI_UNUSED (BrotliDump );
505+ BROTLI_UNUSED (& BrotliDump);
444506#endif
445507}
446508
0 commit comments