| OLD | NEW |
| 1 /* Copyright 2015 Google Inc. All Rights Reserved. | 1 /* Copyright 2015 Google Inc. All Rights Reserved. |
| 2 | 2 |
| 3 Distributed under MIT license. | 3 Distributed under MIT license. |
| 4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT | 4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 /* Macros for compiler / platform specific features and build options. | 7 /* Macros for compiler / platform specific features and build options. |
| 8 | 8 |
| 9 Build options are: | 9 Build options are: |
| 10 * BROTLI_BUILD_32_BIT disables 64-bit optimizations | 10 * BROTLI_BUILD_32_BIT disables 64-bit optimizations |
| 11 * BROTLI_BUILD_64_BIT forces to use 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 | 12 * BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations |
| 13 * BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations | 13 * BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations |
| 14 * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations | 14 * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations |
| 15 * BROTLI_BUILD_MODERN_COMPILER forces to use modern compilers built-ins, | 15 * BROTLI_BUILD_MODERN_COMPILER forces to use modern compilers built-ins, |
| 16 features and attributes | 16 features and attributes |
| 17 * BROTLI_BUILD_PORTABLE disables dangerous optimizations, like unaligned | 17 * BROTLI_BUILD_PORTABLE disables dangerous optimizations, like unaligned |
| 18 read and overlapping memcpy; this reduces decompression speed by 5% | 18 read and overlapping memcpy; this reduces decompression speed by 5% |
| 19 * BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs |
| 19 * BROTLI_DEBUG dumps file name and line number when decoder detects stream | 20 * BROTLI_DEBUG dumps file name and line number when decoder detects stream |
| 20 or memory error | 21 or memory error |
| 21 * BROTLI_ENABLE_LOG enables asserts and dumps various state information | 22 * BROTLI_ENABLE_LOG enables asserts and dumps various state information |
| 22 */ | 23 */ |
| 23 | 24 |
| 24 #ifndef BROTLI_DEC_PORT_H_ | 25 #ifndef BROTLI_DEC_PORT_H_ |
| 25 #define BROTLI_DEC_PORT_H_ | 26 #define BROTLI_DEC_PORT_H_ |
| 26 | 27 |
| 27 #if defined(BROTLI_ENABLE_LOG) || defined(BROTLI_DEBUG) | 28 #if defined(BROTLI_ENABLE_LOG) || defined(BROTLI_DEBUG) |
| 28 #include <assert.h> | 29 #include <assert.h> |
| 29 #include <stdio.h> | 30 #include <stdio.h> |
| 30 #endif | 31 #endif |
| 31 | 32 |
| 32 /* Compatibility with non-clang compilers. */ | 33 #include <brotli/port.h> |
| 33 #ifndef __has_builtin | |
| 34 #define __has_builtin(x) 0 | |
| 35 #endif | |
| 36 | |
| 37 #ifndef __has_attribute | |
| 38 #define __has_attribute(x) 0 | |
| 39 #endif | |
| 40 | |
| 41 #ifndef __has_feature | |
| 42 #define __has_feature(x) 0 | |
| 43 #endif | |
| 44 | 34 |
| 45 #if defined(__arm__) || defined(__thumb__) || \ | 35 #if defined(__arm__) || defined(__thumb__) || \ |
| 46 defined(_M_ARM) || defined(_M_ARMT) | 36 defined(_M_ARM) || defined(_M_ARMT) || defined(__ARM64_ARCH_8__) |
| 47 #define BROTLI_TARGET_ARM | 37 #define BROTLI_TARGET_ARM |
| 48 #if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) || \ | 38 #if (defined(__ARM_ARCH) && (__ARM_ARCH == 7)) || \ |
| 49 (defined(M_ARM) && (M_ARM >= 7)) | 39 (defined(M_ARM) && (M_ARM == 7)) |
| 50 #define BROTLI_TARGET_ARMV7 | 40 #define BROTLI_TARGET_ARMV7 |
| 51 #endif /* ARMv7 */ | 41 #endif /* ARMv7 */ |
| 52 #if defined(__aarch64__) | 42 #if defined(__aarch64__) || defined(__ARM64_ARCH_8__) |
| 53 #define BROTLI_TARGET_ARMV8 | 43 #define BROTLI_TARGET_ARMV8 |
| 54 #endif /* ARMv8 */ | 44 #endif /* ARMv8 */ |
| 55 #endif /* ARM */ | 45 #endif /* ARM */ |
| 56 | 46 |
| 57 #if defined(__i386) || defined(_M_IX86) | 47 #if defined(__i386) || defined(_M_IX86) |
| 58 #define BROTLI_TARGET_X86 | 48 #define BROTLI_TARGET_X86 |
| 59 #endif | 49 #endif |
| 60 | 50 |
| 61 #if defined(__x86_64__) || defined(_M_X64) | 51 #if defined(__x86_64__) || defined(_M_X64) |
| 62 #define BROTLI_TARGET_X64 | 52 #define BROTLI_TARGET_X64 |
| 63 #endif | 53 #endif |
| 64 | 54 |
| 65 #if defined(__PPC64__) | 55 #if defined(__PPC64__) |
| 66 #define BROTLI_TARGET_POWERPC64 | 56 #define BROTLI_TARGET_POWERPC64 |
| 67 #endif | 57 #endif |
| 68 | 58 |
| 69 #if defined(__GNUC__) && defined(__GNUC_MINOR__) | |
| 70 #define BROTLI_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) | |
| 71 #else | |
| 72 #define BROTLI_GCC_VERSION 0 | |
| 73 #endif | |
| 74 | |
| 75 #if defined(__ICC) | |
| 76 #define BROTLI_ICC_VERSION __ICC | |
| 77 #else | |
| 78 #define BROTLI_ICC_VERSION 0 | |
| 79 #endif | |
| 80 | |
| 81 #if defined(BROTLI_BUILD_MODERN_COMPILER) | |
| 82 #define BROTLI_MODERN_COMPILER 1 | |
| 83 #elif (BROTLI_GCC_VERSION > 300) || (BROTLI_ICC_VERSION >= 1600) | |
| 84 #define BROTLI_MODERN_COMPILER 1 | |
| 85 #else | |
| 86 #define BROTLI_MODERN_COMPILER 0 | |
| 87 #endif | |
| 88 | |
| 89 #ifdef BROTLI_BUILD_PORTABLE | 59 #ifdef BROTLI_BUILD_PORTABLE |
| 90 #define BROTLI_ALIGNED_READ (!!1) | 60 #define BROTLI_ALIGNED_READ (!!1) |
| 91 #elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \ | 61 #elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \ |
| 92 defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8) | 62 defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8) |
| 93 /* Allow unaligned read only for whitelisted CPUs. */ | 63 /* Allow unaligned read only for white-listed CPUs. */ |
| 94 #define BROTLI_ALIGNED_READ (!!0) | 64 #define BROTLI_ALIGNED_READ (!!0) |
| 95 #else | 65 #else |
| 96 #define BROTLI_ALIGNED_READ (!!1) | 66 #define BROTLI_ALIGNED_READ (!!1) |
| 97 #endif | 67 #endif |
| 98 | 68 |
| 99 /* Define "PREDICT_TRUE" and "PREDICT_FALSE" macros for capable compilers. | |
| 100 | |
| 101 To apply compiler hint, enclose the branching condition into macros, like this: | |
| 102 | |
| 103 if (PREDICT_TRUE(zero == 0)) { | |
| 104 // main execution path | |
| 105 } else { | |
| 106 // compiler should place this code outside of main execution path | |
| 107 } | |
| 108 | |
| 109 OR: | |
| 110 | |
| 111 if (PREDICT_FALSE(something_rare_or_unexpected_happens)) { | |
| 112 // compiler should place this code outside of main execution path | |
| 113 } | |
| 114 | |
| 115 */ | |
| 116 #if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_expect) | |
| 117 #define PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) | |
| 118 #define PREDICT_FALSE(x) (__builtin_expect(x, 0)) | |
| 119 #else | |
| 120 #define PREDICT_FALSE(x) (x) | |
| 121 #define PREDICT_TRUE(x) (x) | |
| 122 #endif | |
| 123 | |
| 124 /* IS_CONSTANT macros returns true for compile-time constant expressions. */ | 69 /* IS_CONSTANT macros returns true for compile-time constant expressions. */ |
| 125 #if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_constant_p) | 70 #if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_constant_p) |
| 126 #define IS_CONSTANT(x) (!!__builtin_constant_p(x)) | 71 #define IS_CONSTANT(x) (!!__builtin_constant_p(x)) |
| 127 #else | 72 #else |
| 128 #define IS_CONSTANT(x) (!!0) | 73 #define IS_CONSTANT(x) (!!0) |
| 129 #endif | 74 #endif |
| 130 | 75 |
| 131 #if BROTLI_MODERN_COMPILER || __has_attribute(always_inline) | |
| 132 #define ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) | |
| 133 #else | |
| 134 #define ATTRIBUTE_ALWAYS_INLINE | |
| 135 #endif | |
| 136 | |
| 137 #if BROTLI_MODERN_COMPILER || __has_attribute(visibility) | |
| 138 #define ATTRIBUTE_VISIBILITY_HIDDEN __attribute__ ((visibility ("hidden"))) | |
| 139 #else | |
| 140 #define ATTRIBUTE_VISIBILITY_HIDDEN | |
| 141 #endif | |
| 142 | |
| 143 #ifndef BROTLI_INTERNAL | |
| 144 #define BROTLI_INTERNAL ATTRIBUTE_VISIBILITY_HIDDEN | |
| 145 #endif | |
| 146 | |
| 147 #ifndef _MSC_VER | |
| 148 #if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \ | |
| 149 __STDC_VERSION__ >= 199901L | |
| 150 #define BROTLI_INLINE inline ATTRIBUTE_ALWAYS_INLINE | |
| 151 #else | |
| 152 #define BROTLI_INLINE | |
| 153 #endif | |
| 154 #else /* _MSC_VER */ | |
| 155 #define BROTLI_INLINE __forceinline | |
| 156 #endif /* _MSC_VER */ | |
| 157 | |
| 158 #ifdef BROTLI_ENABLE_LOG | 76 #ifdef BROTLI_ENABLE_LOG |
| 159 #define BROTLI_DCHECK(x) assert(x) | 77 #define BROTLI_DCHECK(x) assert(x) |
| 160 #define BROTLI_LOG(x) printf x | 78 #define BROTLI_LOG(x) printf x |
| 161 #else | 79 #else |
| 162 #define BROTLI_DCHECK(x) | 80 #define BROTLI_DCHECK(x) |
| 163 #define BROTLI_LOG(x) | 81 #define BROTLI_LOG(x) |
| 164 #endif | 82 #endif |
| 165 | 83 |
| 166 #if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG) | 84 #if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG) |
| 167 static inline void BrotliDump(const char* f, int l, const char* fn) { | 85 static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) { |
| 168 fprintf(stderr, "%s:%d (%s)\n", f, l, fn); | 86 fprintf(stderr, "%s:%d (%s)\n", f, l, fn); |
| 169 fflush(stderr); | 87 fflush(stderr); |
| 170 } | 88 } |
| 171 #define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__) | 89 #define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__) |
| 172 #else | 90 #else |
| 173 #define BROTLI_DUMP() (void)(0) | 91 #define BROTLI_DUMP() (void)(0) |
| 174 #endif | 92 #endif |
| 175 | 93 |
| 176 #if defined(BROTLI_BUILD_64_BIT) | 94 #if defined(BROTLI_BUILD_64_BIT) |
| 177 #define BROTLI_64_BITS 1 | 95 #define BROTLI_64_BITS 1 |
| 178 #elif defined(BROTLI_BUILD_32_BIT) | 96 #elif defined(BROTLI_BUILD_32_BIT) |
| 179 #define BROTLI_64_BITS 0 | 97 #define BROTLI_64_BITS 0 |
| 180 #elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8) || \ | 98 #elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8) || \ |
| 181 defined(BROTLI_TARGET_POWERPC64) | 99 defined(BROTLI_TARGET_POWERPC64) |
| 182 #define BROTLI_64_BITS 1 | 100 #define BROTLI_64_BITS 1 |
| 183 #else | 101 #else |
| 184 #define BROTLI_64_BITS 0 | 102 #define BROTLI_64_BITS 0 |
| 185 #endif | 103 #endif |
| 186 | 104 |
| 105 #if (BROTLI_64_BITS) |
| 106 #define reg_t uint64_t |
| 107 #else |
| 108 #define reg_t uint32_t |
| 109 #endif |
| 110 |
| 187 #if defined(BROTLI_BUILD_BIG_ENDIAN) | 111 #if defined(BROTLI_BUILD_BIG_ENDIAN) |
| 188 #define BROTLI_LITTLE_ENDIAN 0 | 112 #define BROTLI_LITTLE_ENDIAN 0 |
| 189 #define BROTLI_BIG_ENDIAN 1 | 113 #define BROTLI_BIG_ENDIAN 1 |
| 190 #elif defined(BROTLI_BUILD_LITTLE_ENDIAN) | 114 #elif defined(BROTLI_BUILD_LITTLE_ENDIAN) |
| 191 #define BROTLI_LITTLE_ENDIAN 1 | 115 #define BROTLI_LITTLE_ENDIAN 1 |
| 192 #define BROTLI_BIG_ENDIAN 0 | 116 #define BROTLI_BIG_ENDIAN 0 |
| 193 #elif defined(BROTLI_BUILD_ENDIAN_NEUTRAL) | 117 #elif defined(BROTLI_BUILD_ENDIAN_NEUTRAL) |
| 194 #define BROTLI_LITTLE_ENDIAN 0 | 118 #define BROTLI_LITTLE_ENDIAN 0 |
| 195 #define BROTLI_BIG_ENDIAN 0 | 119 #define BROTLI_BIG_ENDIAN 0 |
| 196 #elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) | 120 #elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) |
| 197 #define BROTLI_LITTLE_ENDIAN 1 | 121 #define BROTLI_LITTLE_ENDIAN 1 |
| 198 #define BROTLI_BIG_ENDIAN 0 | 122 #define BROTLI_BIG_ENDIAN 0 |
| 199 #elif defined(_WIN32) | 123 #elif defined(_WIN32) |
| 200 /* Win32 can currently always be assumed to be little endian */ | 124 /* Win32 can currently always be assumed to be little endian */ |
| 201 #define BROTLI_LITTLE_ENDIAN 1 | 125 #define BROTLI_LITTLE_ENDIAN 1 |
| 202 #define BROTLI_BIG_ENDIAN 0 | 126 #define BROTLI_BIG_ENDIAN 0 |
| 203 #else | 127 #else |
| 204 #if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) | 128 #if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) |
| 205 #define BROTLI_BIG_ENDIAN 1 | 129 #define BROTLI_BIG_ENDIAN 1 |
| 206 #else | 130 #else |
| 207 #define BROTLI_BIG_ENDIAN 0 | 131 #define BROTLI_BIG_ENDIAN 0 |
| 208 #endif | 132 #endif |
| 209 #define BROTLI_LITTLE_ENDIAN 0 | 133 #define BROTLI_LITTLE_ENDIAN 0 |
| 210 #endif | 134 #endif |
| 211 | 135 |
| 212 #if BROTLI_MODERN_COMPILER || __has_attribute(noinline) | |
| 213 #define BROTLI_NOINLINE __attribute__((noinline)) | |
| 214 #else | |
| 215 #define BROTLI_NOINLINE | |
| 216 #endif | |
| 217 | |
| 218 #define BROTLI_REPEAT(N, X) { \ | 136 #define BROTLI_REPEAT(N, X) { \ |
| 219 if ((N & 1) != 0) {X;} \ | 137 if ((N & 1) != 0) {X;} \ |
| 220 if ((N & 2) != 0) {X; X;} \ | 138 if ((N & 2) != 0) {X; X;} \ |
| 221 if ((N & 4) != 0) {X; X; X; X;} \ | 139 if ((N & 4) != 0) {X; X; X; X;} \ |
| 222 } | 140 } |
| 223 | 141 |
| 224 #if BROTLI_MODERN_COMPILER || defined(__llvm__) | 142 #if (BROTLI_MODERN_COMPILER || defined(__llvm__)) && \ |
| 225 #if defined(BROTLI_TARGET_ARMV7) | 143 !defined(BROTLI_BUILD_NO_RBIT) |
| 226 static BROTLI_INLINE unsigned BrotliRBit(unsigned input) { | 144 #if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8) |
| 227 unsigned output; | 145 /* TODO: detect ARMv6T2 and enable this code for it. */ |
| 146 static BROTLI_INLINE reg_t BrotliRBit(reg_t input) { |
| 147 reg_t output; |
| 228 __asm__("rbit %0, %1\n" : "=r"(output) : "r"(input)); | 148 __asm__("rbit %0, %1\n" : "=r"(output) : "r"(input)); |
| 229 return output; | 149 return output; |
| 230 } | 150 } |
| 231 #define BROTLI_RBIT(x) BrotliRBit(x) | 151 #define BROTLI_RBIT(x) BrotliRBit(x) |
| 232 #endif /* armv7 */ | 152 #endif /* armv7 */ |
| 233 #endif /* gcc || clang */ | 153 #endif /* gcc || clang */ |
| 234 | 154 |
| 235 #if defined(BROTLI_TARGET_ARM) | 155 #if defined(BROTLI_TARGET_ARM) |
| 236 #define BROTLI_HAS_UBFX (!!1) | 156 #define BROTLI_HAS_UBFX (!!1) |
| 237 #else | 157 #else |
| 238 #define BROTLI_HAS_UBFX (!!0) | 158 #define BROTLI_HAS_UBFX (!!0) |
| 239 #endif | 159 #endif |
| 240 | 160 |
| 241 #define BROTLI_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L) | 161 #define BROTLI_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L) |
| 242 | 162 |
| 243 #define BROTLI_FREE(S, X) { \ | 163 #define BROTLI_FREE(S, X) { \ |
| 244 S->free_func(S->memory_manager_opaque, X); \ | 164 S->free_func(S->memory_manager_opaque, X); \ |
| 245 X = NULL; \ | 165 X = NULL; \ |
| 246 } | 166 } |
| 247 | 167 |
| 248 #define BROTLI_UNUSED(X) (void)(X) | |
| 249 | |
| 250 #endif /* BROTLI_DEC_PORT_H_ */ | 168 #endif /* BROTLI_DEC_PORT_H_ */ |
| OLD | NEW |