/src/libdeflate/common_defs.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * common_defs.h |
3 | | * |
4 | | * Copyright 2016 Eric Biggers |
5 | | * |
6 | | * Permission is hereby granted, free of charge, to any person |
7 | | * obtaining a copy of this software and associated documentation |
8 | | * files (the "Software"), to deal in the Software without |
9 | | * restriction, including without limitation the rights to use, |
10 | | * copy, modify, merge, publish, distribute, sublicense, and/or sell |
11 | | * copies of the Software, and to permit persons to whom the |
12 | | * Software is furnished to do so, subject to the following |
13 | | * conditions: |
14 | | * |
15 | | * The above copyright notice and this permission notice shall be |
16 | | * included in all copies or substantial portions of the Software. |
17 | | * |
18 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
19 | | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
20 | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
21 | | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
22 | | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
23 | | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
24 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
25 | | * OTHER DEALINGS IN THE SOFTWARE. |
26 | | */ |
27 | | |
28 | | #ifndef COMMON_DEFS_H |
29 | | #define COMMON_DEFS_H |
30 | | |
31 | | #include "libdeflate.h" |
32 | | |
33 | | #include <stdbool.h> |
34 | | #include <stddef.h> /* for size_t */ |
35 | | #include <stdint.h> |
36 | | #ifdef _MSC_VER |
37 | | # include <intrin.h> /* for _BitScan*() and other intrinsics */ |
38 | | # include <stdlib.h> /* for _byteswap_*() */ |
39 | | /* Disable MSVC warnings that are expected. */ |
40 | | /* /W2 */ |
41 | | # pragma warning(disable : 4146) /* unary minus on unsigned type */ |
42 | | /* /W3 */ |
43 | | # pragma warning(disable : 4018) /* signed/unsigned mismatch */ |
44 | | # pragma warning(disable : 4244) /* possible loss of data */ |
45 | | # pragma warning(disable : 4267) /* possible loss of precision */ |
46 | | # pragma warning(disable : 4310) /* cast truncates constant value */ |
47 | | /* /W4 */ |
48 | | # pragma warning(disable : 4100) /* unreferenced formal parameter */ |
49 | | # pragma warning(disable : 4127) /* conditional expression is constant */ |
50 | | # pragma warning(disable : 4189) /* local variable initialized but not referenced */ |
51 | | # pragma warning(disable : 4232) /* nonstandard extension used */ |
52 | | # pragma warning(disable : 4245) /* conversion from 'int' to 'unsigned int' */ |
53 | | # pragma warning(disable : 4295) /* array too small to include terminating null */ |
54 | | #endif |
55 | | #ifndef FREESTANDING |
56 | | # include <string.h> /* for memcpy() */ |
57 | | #endif |
58 | | |
59 | | /* ========================================================================== */ |
60 | | /* Target architecture */ |
61 | | /* ========================================================================== */ |
62 | | |
63 | | /* If possible, define a compiler-independent ARCH_* macro. */ |
64 | | #undef ARCH_X86_64 |
65 | | #undef ARCH_X86_32 |
66 | | #undef ARCH_ARM64 |
67 | | #undef ARCH_ARM32 |
68 | | #undef ARCH_RISCV |
69 | | #ifdef _MSC_VER |
70 | | /* Way too many things are broken in ARM64EC to pretend that it is x86_64. */ |
71 | | # if defined(_M_X64) && !defined(_M_ARM64EC) |
72 | | # define ARCH_X86_64 |
73 | | # elif defined(_M_IX86) |
74 | | # define ARCH_X86_32 |
75 | | # elif defined(_M_ARM64) |
76 | | # define ARCH_ARM64 |
77 | | # elif defined(_M_ARM) |
78 | | # define ARCH_ARM32 |
79 | | # endif |
80 | | #else |
81 | | # if defined(__x86_64__) |
82 | | # define ARCH_X86_64 |
83 | | # elif defined(__i386__) |
84 | | # define ARCH_X86_32 |
85 | | # elif defined(__aarch64__) |
86 | | # define ARCH_ARM64 |
87 | | # elif defined(__arm__) |
88 | | # define ARCH_ARM32 |
89 | | # elif defined(__riscv) |
90 | | # define ARCH_RISCV |
91 | | # endif |
92 | | #endif |
93 | | |
94 | | /* ========================================================================== */ |
95 | | /* Type definitions */ |
96 | | /* ========================================================================== */ |
97 | | |
98 | | /* Fixed-width integer types */ |
99 | | typedef uint8_t u8; |
100 | | typedef uint16_t u16; |
101 | | typedef uint32_t u32; |
102 | | typedef uint64_t u64; |
103 | | typedef int8_t s8; |
104 | | typedef int16_t s16; |
105 | | typedef int32_t s32; |
106 | | typedef int64_t s64; |
107 | | |
108 | | /* ssize_t, if not available in <sys/types.h> */ |
109 | | #ifdef _MSC_VER |
110 | | # ifdef _WIN64 |
111 | | typedef long long ssize_t; |
112 | | # else |
113 | | typedef long ssize_t; |
114 | | # endif |
115 | | #endif |
116 | | |
117 | | /* |
118 | | * Word type of the target architecture. Use 'size_t' instead of |
119 | | * 'unsigned long' to account for platforms such as Windows that use 32-bit |
120 | | * 'unsigned long' on 64-bit architectures. |
121 | | */ |
122 | | typedef size_t machine_word_t; |
123 | | |
124 | | /* Number of bytes in a word */ |
125 | 1.28M | #define WORDBYTES ((int)sizeof(machine_word_t)) |
126 | | |
127 | | /* Number of bits in a word */ |
128 | 319k | #define WORDBITS (8 * WORDBYTES) |
129 | | |
130 | | /* ========================================================================== */ |
131 | | /* Optional compiler features */ |
132 | | /* ========================================================================== */ |
133 | | |
134 | | /* Compiler version checks. Only use when absolutely necessary. */ |
135 | | #if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) |
136 | | # define GCC_PREREQ(major, minor) \ |
137 | | (__GNUC__ > (major) || \ |
138 | | (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) |
139 | | # if !GCC_PREREQ(4, 9) |
140 | | # error "gcc versions older than 4.9 are no longer supported" |
141 | | # endif |
142 | | #else |
143 | | # define GCC_PREREQ(major, minor) 0 |
144 | | #endif |
145 | | #ifdef __clang__ |
146 | | # ifdef __apple_build_version__ |
147 | | # define CLANG_PREREQ(major, minor, apple_version) \ |
148 | | (__apple_build_version__ >= (apple_version)) |
149 | | # else |
150 | | # define CLANG_PREREQ(major, minor, apple_version) \ |
151 | | (__clang_major__ > (major) || \ |
152 | | (__clang_major__ == (major) && __clang_minor__ >= (minor))) |
153 | | # endif |
154 | | # if !CLANG_PREREQ(3, 9, 8000000) |
155 | | # error "clang versions older than 3.9 are no longer supported" |
156 | | # endif |
157 | | #else |
158 | | # define CLANG_PREREQ(major, minor, apple_version) 0 |
159 | | #endif |
160 | | #ifdef _MSC_VER |
161 | | # define MSVC_PREREQ(version) (_MSC_VER >= (version)) |
162 | | # if !MSVC_PREREQ(1900) |
163 | | # error "MSVC versions older than Visual Studio 2015 are no longer supported" |
164 | | # endif |
165 | | #else |
166 | | # define MSVC_PREREQ(version) 0 |
167 | | #endif |
168 | | |
169 | | /* |
170 | | * __has_attribute(attribute) - check whether the compiler supports the given |
171 | | * attribute (and also supports doing the check in the first place). Mostly |
172 | | * useful just for clang, since gcc didn't add this macro until gcc 5. |
173 | | */ |
174 | | #ifndef __has_attribute |
175 | | # define __has_attribute(attribute) 0 |
176 | | #endif |
177 | | |
178 | | /* |
179 | | * __has_builtin(builtin) - check whether the compiler supports the given |
180 | | * builtin (and also supports doing the check in the first place). Mostly |
181 | | * useful just for clang, since gcc didn't add this macro until gcc 10. |
182 | | */ |
183 | | #ifndef __has_builtin |
184 | | # define __has_builtin(builtin) 0 |
185 | | #endif |
186 | | |
187 | | /* inline - suggest that a function be inlined */ |
188 | | #ifdef _MSC_VER |
189 | | # define inline __inline |
190 | | #endif /* else assume 'inline' is usable as-is */ |
191 | | |
192 | | /* forceinline - force a function to be inlined, if possible */ |
193 | | #if defined(__GNUC__) || __has_attribute(always_inline) |
194 | | # define forceinline inline __attribute__((always_inline)) |
195 | | #elif defined(_MSC_VER) |
196 | | # define forceinline __forceinline |
197 | | #else |
198 | | # define forceinline inline |
199 | | #endif |
200 | | |
201 | | /* MAYBE_UNUSED - mark a function or variable as maybe unused */ |
202 | | #if defined(__GNUC__) || __has_attribute(unused) |
203 | | # define MAYBE_UNUSED __attribute__((unused)) |
204 | | #else |
205 | | # define MAYBE_UNUSED |
206 | | #endif |
207 | | |
208 | | /* NORETURN - mark a function as never returning, e.g. due to calling abort() */ |
209 | | #if defined(__GNUC__) || __has_attribute(noreturn) |
210 | | # define NORETURN __attribute__((noreturn)) |
211 | | #else |
212 | | # define NORETURN |
213 | | #endif |
214 | | |
215 | | /* |
216 | | * restrict - hint that writes only occur through the given pointer. |
217 | | * |
218 | | * Don't use MSVC's __restrict, since it has nonstandard behavior. |
219 | | * Standard restrict is okay, if it is supported. |
220 | | */ |
221 | | #if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 201112L) |
222 | | # if defined(__GNUC__) || defined(__clang__) |
223 | | # define restrict __restrict__ |
224 | | # else |
225 | | # define restrict |
226 | | # endif |
227 | | #endif /* else assume 'restrict' is usable as-is */ |
228 | | |
229 | | /* likely(expr) - hint that an expression is usually true */ |
230 | | #if defined(__GNUC__) || __has_builtin(__builtin_expect) |
231 | 295k | # define likely(expr) __builtin_expect(!!(expr), 1) |
232 | | #else |
233 | | # define likely(expr) (expr) |
234 | | #endif |
235 | | |
236 | | /* unlikely(expr) - hint that an expression is usually false */ |
237 | | #if defined(__GNUC__) || __has_builtin(__builtin_expect) |
238 | 1.09M | # define unlikely(expr) __builtin_expect(!!(expr), 0) |
239 | | #else |
240 | | # define unlikely(expr) (expr) |
241 | | #endif |
242 | | |
243 | | /* prefetchr(addr) - prefetch into L1 cache for read */ |
244 | | #undef prefetchr |
245 | | #if defined(__GNUC__) || __has_builtin(__builtin_prefetch) |
246 | | # define prefetchr(addr) __builtin_prefetch((addr), 0) |
247 | | #elif defined(_MSC_VER) |
248 | | # if defined(ARCH_X86_32) || defined(ARCH_X86_64) |
249 | | # define prefetchr(addr) _mm_prefetch((addr), _MM_HINT_T0) |
250 | | # elif defined(ARCH_ARM64) |
251 | | # define prefetchr(addr) __prefetch2((addr), 0x00 /* prfop=PLDL1KEEP */) |
252 | | # elif defined(ARCH_ARM32) |
253 | | # define prefetchr(addr) __prefetch(addr) |
254 | | # endif |
255 | | #endif |
256 | | #ifndef prefetchr |
257 | | # define prefetchr(addr) |
258 | | #endif |
259 | | |
260 | | /* prefetchw(addr) - prefetch into L1 cache for write */ |
261 | | #undef prefetchw |
262 | | #if defined(__GNUC__) || __has_builtin(__builtin_prefetch) |
263 | 0 | # define prefetchw(addr) __builtin_prefetch((addr), 1) |
264 | | #elif defined(_MSC_VER) |
265 | | # if defined(ARCH_X86_32) || defined(ARCH_X86_64) |
266 | | # define prefetchw(addr) _m_prefetchw(addr) |
267 | | # elif defined(ARCH_ARM64) |
268 | | # define prefetchw(addr) __prefetch2((addr), 0x10 /* prfop=PSTL1KEEP */) |
269 | | # elif defined(ARCH_ARM32) |
270 | | # define prefetchw(addr) __prefetchw(addr) |
271 | | # endif |
272 | | #endif |
273 | | #ifndef prefetchw |
274 | | # define prefetchw(addr) |
275 | | #endif |
276 | | |
277 | | /* |
278 | | * _aligned_attribute(n) - declare that the annotated variable, or variables of |
279 | | * the annotated type, must be aligned on n-byte boundaries. |
280 | | */ |
281 | | #undef _aligned_attribute |
282 | | #if defined(__GNUC__) || __has_attribute(aligned) |
283 | | # define _aligned_attribute(n) __attribute__((aligned(n))) |
284 | | #elif defined(_MSC_VER) |
285 | | # define _aligned_attribute(n) __declspec(align(n)) |
286 | | #endif |
287 | | |
288 | | /* |
289 | | * _target_attribute(attrs) - override the compilation target for a function. |
290 | | * |
291 | | * This accepts one or more comma-separated suffixes to the -m prefix jointly |
292 | | * forming the name of a machine-dependent option. On gcc-like compilers, this |
293 | | * enables codegen for the given targets, including arbitrary compiler-generated |
294 | | * code as well as the corresponding intrinsics. On other compilers this macro |
295 | | * expands to nothing, though MSVC allows intrinsics to be used anywhere anyway. |
296 | | */ |
297 | | #if defined(__GNUC__) || __has_attribute(target) |
298 | | # define _target_attribute(attrs) __attribute__((target(attrs))) |
299 | | #else |
300 | | # define _target_attribute(attrs) |
301 | | #endif |
302 | | |
303 | | /* ========================================================================== */ |
304 | | /* Miscellaneous macros */ |
305 | | /* ========================================================================== */ |
306 | | |
307 | 6 | #define ARRAY_LEN(A) (sizeof(A) / sizeof((A)[0])) |
308 | 22.7k | #define MIN(a, b) ((a) <= (b) ? (a) : (b)) |
309 | 0 | #define MAX(a, b) ((a) >= (b) ? (a) : (b)) |
310 | 0 | #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) |
311 | 1.19M | #define STATIC_ASSERT(expr) ((void)sizeof(char[1 - 2 * !(expr)])) |
312 | 0 | #define ALIGN(n, a) (((n) + (a) - 1) & ~((a) - 1)) |
313 | | #define ROUND_UP(n, d) ((d) * DIV_ROUND_UP((n), (d))) |
314 | | |
315 | | /* ========================================================================== */ |
316 | | /* Endianness handling */ |
317 | | /* ========================================================================== */ |
318 | | |
319 | | /* |
320 | | * CPU_IS_LITTLE_ENDIAN() - 1 if the CPU is little endian, or 0 if it is big |
321 | | * endian. When possible this is a compile-time macro that can be used in |
322 | | * preprocessor conditionals. As a fallback, a generic method is used that |
323 | | * can't be used in preprocessor conditionals but should still be optimized out. |
324 | | */ |
325 | | #if defined(__BYTE_ORDER__) /* gcc v4.6+ and clang */ |
326 | 329k | # define CPU_IS_LITTLE_ENDIAN() (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) |
327 | | #elif defined(_MSC_VER) |
328 | | # define CPU_IS_LITTLE_ENDIAN() true |
329 | | #else |
330 | | static forceinline bool CPU_IS_LITTLE_ENDIAN(void) |
331 | | { |
332 | | union { |
333 | | u32 w; |
334 | | u8 b; |
335 | | } u; |
336 | | |
337 | | u.w = 1; |
338 | | return u.b; |
339 | | } |
340 | | #endif |
341 | | |
342 | | /* bswap16(v) - swap the bytes of a 16-bit integer */ |
343 | | static forceinline u16 bswap16(u16 v) |
344 | 6.65k | { |
345 | 6.65k | #if defined(__GNUC__) || __has_builtin(__builtin_bswap16) |
346 | 6.65k | return __builtin_bswap16(v); |
347 | | #elif defined(_MSC_VER) |
348 | | return _byteswap_ushort(v); |
349 | | #else |
350 | | return (v << 8) | (v >> 8); |
351 | | #endif |
352 | 6.65k | } Unexecuted instantiation: deflate_compress.c:bswap16 Unexecuted instantiation: utils.c:bswap16 Unexecuted instantiation: deflate_decompress.c:bswap16 Unexecuted instantiation: cpu_features.c:bswap16 Unexecuted instantiation: zlib_compress.c:bswap16 Unexecuted instantiation: adler32.c:bswap16 zlib_decompress.c:bswap16 Line | Count | Source | 344 | 6.65k | { | 345 | 6.65k | #if defined(__GNUC__) || __has_builtin(__builtin_bswap16) | 346 | 6.65k | return __builtin_bswap16(v); | 347 | | #elif defined(_MSC_VER) | 348 | | return _byteswap_ushort(v); | 349 | | #else | 350 | | return (v << 8) | (v >> 8); | 351 | | #endif | 352 | 6.65k | } |
|
353 | | |
354 | | /* bswap32(v) - swap the bytes of a 32-bit integer */ |
355 | | static forceinline u32 bswap32(u32 v) |
356 | 1.04k | { |
357 | 1.04k | #if defined(__GNUC__) || __has_builtin(__builtin_bswap32) |
358 | 1.04k | return __builtin_bswap32(v); |
359 | | #elif defined(_MSC_VER) |
360 | | return _byteswap_ulong(v); |
361 | | #else |
362 | | return ((v & 0x000000FF) << 24) | |
363 | | ((v & 0x0000FF00) << 8) | |
364 | | ((v & 0x00FF0000) >> 8) | |
365 | | ((v & 0xFF000000) >> 24); |
366 | | #endif |
367 | 1.04k | } Unexecuted instantiation: deflate_compress.c:bswap32 Unexecuted instantiation: utils.c:bswap32 Unexecuted instantiation: deflate_decompress.c:bswap32 Unexecuted instantiation: cpu_features.c:bswap32 Unexecuted instantiation: zlib_compress.c:bswap32 Unexecuted instantiation: adler32.c:bswap32 zlib_decompress.c:bswap32 Line | Count | Source | 356 | 1.04k | { | 357 | 1.04k | #if defined(__GNUC__) || __has_builtin(__builtin_bswap32) | 358 | 1.04k | return __builtin_bswap32(v); | 359 | | #elif defined(_MSC_VER) | 360 | | return _byteswap_ulong(v); | 361 | | #else | 362 | | return ((v & 0x000000FF) << 24) | | 363 | | ((v & 0x0000FF00) << 8) | | 364 | | ((v & 0x00FF0000) >> 8) | | 365 | | ((v & 0xFF000000) >> 24); | 366 | | #endif | 367 | 1.04k | } |
|
368 | | |
369 | | /* bswap64(v) - swap the bytes of a 64-bit integer */ |
370 | | static forceinline u64 bswap64(u64 v) |
371 | 0 | { |
372 | 0 | #if defined(__GNUC__) || __has_builtin(__builtin_bswap64) |
373 | 0 | return __builtin_bswap64(v); |
374 | 0 | #elif defined(_MSC_VER) |
375 | 0 | return _byteswap_uint64(v); |
376 | 0 | #else |
377 | 0 | return ((v & 0x00000000000000FF) << 56) | |
378 | 0 | ((v & 0x000000000000FF00) << 40) | |
379 | 0 | ((v & 0x0000000000FF0000) << 24) | |
380 | 0 | ((v & 0x00000000FF000000) << 8) | |
381 | 0 | ((v & 0x000000FF00000000) >> 8) | |
382 | 0 | ((v & 0x0000FF0000000000) >> 24) | |
383 | 0 | ((v & 0x00FF000000000000) >> 40) | |
384 | 0 | ((v & 0xFF00000000000000) >> 56); |
385 | 0 | #endif |
386 | 0 | } Unexecuted instantiation: deflate_compress.c:bswap64 Unexecuted instantiation: utils.c:bswap64 Unexecuted instantiation: deflate_decompress.c:bswap64 Unexecuted instantiation: cpu_features.c:bswap64 Unexecuted instantiation: zlib_compress.c:bswap64 Unexecuted instantiation: adler32.c:bswap64 Unexecuted instantiation: zlib_decompress.c:bswap64 |
387 | | |
388 | 2.10k | #define le16_bswap(v) (CPU_IS_LITTLE_ENDIAN() ? (v) : bswap16(v)) |
389 | 0 | #define le32_bswap(v) (CPU_IS_LITTLE_ENDIAN() ? (v) : bswap32(v)) |
390 | 319k | #define le64_bswap(v) (CPU_IS_LITTLE_ENDIAN() ? (v) : bswap64(v)) |
391 | 6.65k | #define be16_bswap(v) (CPU_IS_LITTLE_ENDIAN() ? bswap16(v) : (v)) |
392 | 1.04k | #define be32_bswap(v) (CPU_IS_LITTLE_ENDIAN() ? bswap32(v) : (v)) |
393 | | #define be64_bswap(v) (CPU_IS_LITTLE_ENDIAN() ? bswap64(v) : (v)) |
394 | | |
395 | | /* ========================================================================== */ |
396 | | /* Unaligned memory accesses */ |
397 | | /* ========================================================================== */ |
398 | | |
399 | | /* |
400 | | * UNALIGNED_ACCESS_IS_FAST() - 1 if unaligned memory accesses can be performed |
401 | | * efficiently on the target platform, otherwise 0. |
402 | | */ |
403 | | #if (defined(__GNUC__) || defined(__clang__)) && \ |
404 | | (defined(ARCH_X86_64) || defined(ARCH_X86_32) || \ |
405 | | defined(__ARM_FEATURE_UNALIGNED) || defined(__powerpc64__) || \ |
406 | | defined(__riscv_misaligned_fast) || \ |
407 | | /* |
408 | | * For all compilation purposes, WebAssembly behaves like any other CPU |
409 | | * instruction set. Even though WebAssembly engine might be running on |
410 | | * top of different actual CPU architectures, the WebAssembly spec |
411 | | * itself permits unaligned access and it will be fast on most of those |
412 | | * platforms, and simulated at the engine level on others, so it's |
413 | | * worth treating it as a CPU architecture with fast unaligned access. |
414 | | */ defined(__wasm__)) |
415 | 2.14M | # define UNALIGNED_ACCESS_IS_FAST 1 |
416 | | #elif defined(_MSC_VER) |
417 | | # define UNALIGNED_ACCESS_IS_FAST 1 |
418 | | #else |
419 | | # define UNALIGNED_ACCESS_IS_FAST 0 |
420 | | #endif |
421 | | |
422 | | /* |
423 | | * Implementing unaligned memory accesses using memcpy() is portable, and it |
424 | | * usually gets optimized appropriately by modern compilers. I.e., each |
425 | | * memcpy() of 1, 2, 4, or WORDBYTES bytes gets compiled to a load or store |
426 | | * instruction, not to an actual function call. |
427 | | * |
428 | | * We no longer use the "packed struct" approach to unaligned accesses, as that |
429 | | * is nonstandard, has unclear semantics, and doesn't receive enough testing |
430 | | * (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94994). |
431 | | * |
432 | | * arm32 with __ARM_FEATURE_UNALIGNED in gcc 5 and earlier is a known exception |
433 | | * where memcpy() generates inefficient code |
434 | | * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67366). However, we no longer |
435 | | * consider that one case important enough to maintain different code for. |
436 | | * If you run into it, please just use a newer version of gcc (or use clang). |
437 | | */ |
438 | | |
439 | | #ifdef FREESTANDING |
440 | | # define MEMCOPY __builtin_memcpy |
441 | | #else |
442 | 8.60M | # define MEMCOPY memcpy |
443 | | #endif |
444 | | |
445 | | /* Unaligned loads and stores without endianness conversion */ |
446 | | |
447 | | #define DEFINE_UNALIGNED_TYPE(type) \ |
448 | | static forceinline type \ |
449 | 4.16M | load_##type##_unaligned(const void *p) \ |
450 | 4.16M | { \ |
451 | 4.16M | type v; \ |
452 | 4.16M | \ |
453 | 4.16M | MEMCOPY(&v, p, sizeof(v)); \ |
454 | 4.16M | return v; \ |
455 | 4.16M | } \ Unexecuted instantiation: deflate_compress.c:load_u32_unaligned Unexecuted instantiation: deflate_compress.c:load_machine_word_t_unaligned Unexecuted instantiation: deflate_compress.c:load_u16_unaligned Unexecuted instantiation: deflate_compress.c:load_u64_unaligned Unexecuted instantiation: utils.c:load_u16_unaligned Unexecuted instantiation: utils.c:load_u32_unaligned Unexecuted instantiation: utils.c:load_u64_unaligned Unexecuted instantiation: utils.c:load_machine_word_t_unaligned deflate_decompress.c:load_u64_unaligned Line | Count | Source | 449 | 319k | load_##type##_unaligned(const void *p) \ | 450 | 319k | { \ | 451 | 319k | type v; \ | 452 | 319k | \ | 453 | 319k | MEMCOPY(&v, p, sizeof(v)); \ | 454 | 319k | return v; \ | 455 | 319k | } \ |
deflate_decompress.c:load_u16_unaligned Line | Count | Source | 449 | 2.10k | load_##type##_unaligned(const void *p) \ | 450 | 2.10k | { \ | 451 | 2.10k | type v; \ | 452 | 2.10k | \ | 453 | 2.10k | MEMCOPY(&v, p, sizeof(v)); \ | 454 | 2.10k | return v; \ | 455 | 2.10k | } \ |
deflate_decompress.c:load_machine_word_t_unaligned Line | Count | Source | 449 | 3.83M | load_##type##_unaligned(const void *p) \ | 450 | 3.83M | { \ | 451 | 3.83M | type v; \ | 452 | 3.83M | \ | 453 | 3.83M | MEMCOPY(&v, p, sizeof(v)); \ | 454 | 3.83M | return v; \ | 455 | 3.83M | } \ |
Unexecuted instantiation: deflate_decompress.c:load_u32_unaligned Unexecuted instantiation: cpu_features.c:load_u16_unaligned Unexecuted instantiation: cpu_features.c:load_u32_unaligned Unexecuted instantiation: cpu_features.c:load_u64_unaligned Unexecuted instantiation: cpu_features.c:load_machine_word_t_unaligned Unexecuted instantiation: zlib_compress.c:load_u16_unaligned Unexecuted instantiation: zlib_compress.c:load_u32_unaligned Unexecuted instantiation: zlib_compress.c:load_u64_unaligned Unexecuted instantiation: zlib_compress.c:load_machine_word_t_unaligned Unexecuted instantiation: adler32.c:load_u16_unaligned Unexecuted instantiation: adler32.c:load_u32_unaligned Unexecuted instantiation: adler32.c:load_u64_unaligned Unexecuted instantiation: adler32.c:load_machine_word_t_unaligned zlib_decompress.c:load_u16_unaligned Line | Count | Source | 449 | 6.65k | load_##type##_unaligned(const void *p) \ | 450 | 6.65k | { \ | 451 | 6.65k | type v; \ | 452 | 6.65k | \ | 453 | 6.65k | MEMCOPY(&v, p, sizeof(v)); \ | 454 | 6.65k | return v; \ | 455 | 6.65k | } \ |
zlib_decompress.c:load_u32_unaligned Line | Count | Source | 449 | 1.04k | load_##type##_unaligned(const void *p) \ | 450 | 1.04k | { \ | 451 | 1.04k | type v; \ | 452 | 1.04k | \ | 453 | 1.04k | MEMCOPY(&v, p, sizeof(v)); \ | 454 | 1.04k | return v; \ | 455 | 1.04k | } \ |
Unexecuted instantiation: zlib_decompress.c:load_u64_unaligned Unexecuted instantiation: zlib_decompress.c:load_machine_word_t_unaligned |
456 | | \ |
457 | | static forceinline void \ |
458 | 4.43M | store_##type##_unaligned(type v, void *p) \ |
459 | 4.43M | { \ |
460 | 4.43M | MEMCOPY(p, &v, sizeof(v)); \ |
461 | 4.43M | } Unexecuted instantiation: deflate_compress.c:store_u16_unaligned Unexecuted instantiation: deflate_compress.c:store_u64_unaligned Unexecuted instantiation: deflate_compress.c:store_u32_unaligned Unexecuted instantiation: deflate_compress.c:store_machine_word_t_unaligned Unexecuted instantiation: utils.c:store_u16_unaligned Unexecuted instantiation: utils.c:store_u32_unaligned Unexecuted instantiation: utils.c:store_u64_unaligned Unexecuted instantiation: utils.c:store_machine_word_t_unaligned deflate_decompress.c:store_machine_word_t_unaligned Line | Count | Source | 458 | 4.43M | store_##type##_unaligned(type v, void *p) \ | 459 | 4.43M | { \ | 460 | 4.43M | MEMCOPY(p, &v, sizeof(v)); \ | 461 | 4.43M | } |
Unexecuted instantiation: deflate_decompress.c:store_u16_unaligned Unexecuted instantiation: deflate_decompress.c:store_u32_unaligned Unexecuted instantiation: deflate_decompress.c:store_u64_unaligned Unexecuted instantiation: cpu_features.c:store_u16_unaligned Unexecuted instantiation: cpu_features.c:store_u32_unaligned Unexecuted instantiation: cpu_features.c:store_u64_unaligned Unexecuted instantiation: cpu_features.c:store_machine_word_t_unaligned Unexecuted instantiation: zlib_compress.c:store_u16_unaligned Unexecuted instantiation: zlib_compress.c:store_u32_unaligned Unexecuted instantiation: zlib_compress.c:store_u64_unaligned Unexecuted instantiation: zlib_compress.c:store_machine_word_t_unaligned Unexecuted instantiation: adler32.c:store_u16_unaligned Unexecuted instantiation: adler32.c:store_u32_unaligned Unexecuted instantiation: adler32.c:store_u64_unaligned Unexecuted instantiation: adler32.c:store_machine_word_t_unaligned Unexecuted instantiation: zlib_decompress.c:store_u16_unaligned Unexecuted instantiation: zlib_decompress.c:store_u32_unaligned Unexecuted instantiation: zlib_decompress.c:store_u64_unaligned Unexecuted instantiation: zlib_decompress.c:store_machine_word_t_unaligned |
462 | | |
463 | | DEFINE_UNALIGNED_TYPE(u16) |
464 | | DEFINE_UNALIGNED_TYPE(u32) |
465 | | DEFINE_UNALIGNED_TYPE(u64) |
466 | | DEFINE_UNALIGNED_TYPE(machine_word_t) |
467 | | |
468 | | #undef MEMCOPY |
469 | | |
470 | 3.83M | #define load_word_unaligned load_machine_word_t_unaligned |
471 | 4.43M | #define store_word_unaligned store_machine_word_t_unaligned |
472 | | |
473 | | /* Unaligned loads with endianness conversion */ |
474 | | |
475 | | static forceinline u16 |
476 | | get_unaligned_le16(const u8 *p) |
477 | 2.10k | { |
478 | 2.10k | if (UNALIGNED_ACCESS_IS_FAST) |
479 | 2.10k | return le16_bswap(load_u16_unaligned(p)); |
480 | 0 | else |
481 | 0 | return ((u16)p[1] << 8) | p[0]; |
482 | 2.10k | } Unexecuted instantiation: deflate_compress.c:get_unaligned_le16 Unexecuted instantiation: utils.c:get_unaligned_le16 deflate_decompress.c:get_unaligned_le16 Line | Count | Source | 477 | 2.10k | { | 478 | 2.10k | if (UNALIGNED_ACCESS_IS_FAST) | 479 | 2.10k | return le16_bswap(load_u16_unaligned(p)); | 480 | 0 | else | 481 | 0 | return ((u16)p[1] << 8) | p[0]; | 482 | 2.10k | } |
Unexecuted instantiation: cpu_features.c:get_unaligned_le16 Unexecuted instantiation: zlib_compress.c:get_unaligned_le16 Unexecuted instantiation: adler32.c:get_unaligned_le16 Unexecuted instantiation: zlib_decompress.c:get_unaligned_le16 |
483 | | |
484 | | static forceinline u16 |
485 | | get_unaligned_be16(const u8 *p) |
486 | 6.65k | { |
487 | 6.65k | if (UNALIGNED_ACCESS_IS_FAST) |
488 | 6.65k | return be16_bswap(load_u16_unaligned(p)); |
489 | 0 | else |
490 | 0 | return ((u16)p[0] << 8) | p[1]; |
491 | 6.65k | } Unexecuted instantiation: deflate_compress.c:get_unaligned_be16 Unexecuted instantiation: utils.c:get_unaligned_be16 Unexecuted instantiation: deflate_decompress.c:get_unaligned_be16 Unexecuted instantiation: cpu_features.c:get_unaligned_be16 Unexecuted instantiation: zlib_compress.c:get_unaligned_be16 Unexecuted instantiation: adler32.c:get_unaligned_be16 zlib_decompress.c:get_unaligned_be16 Line | Count | Source | 486 | 6.65k | { | 487 | 6.65k | if (UNALIGNED_ACCESS_IS_FAST) | 488 | 6.65k | return be16_bswap(load_u16_unaligned(p)); | 489 | 0 | else | 490 | 0 | return ((u16)p[0] << 8) | p[1]; | 491 | 6.65k | } |
|
492 | | |
493 | | static forceinline u32 |
494 | | get_unaligned_le32(const u8 *p) |
495 | 0 | { |
496 | 0 | if (UNALIGNED_ACCESS_IS_FAST) |
497 | 0 | return le32_bswap(load_u32_unaligned(p)); |
498 | 0 | else |
499 | 0 | return ((u32)p[3] << 24) | ((u32)p[2] << 16) | |
500 | 0 | ((u32)p[1] << 8) | p[0]; |
501 | 0 | } Unexecuted instantiation: deflate_compress.c:get_unaligned_le32 Unexecuted instantiation: utils.c:get_unaligned_le32 Unexecuted instantiation: deflate_decompress.c:get_unaligned_le32 Unexecuted instantiation: cpu_features.c:get_unaligned_le32 Unexecuted instantiation: zlib_compress.c:get_unaligned_le32 Unexecuted instantiation: adler32.c:get_unaligned_le32 Unexecuted instantiation: zlib_decompress.c:get_unaligned_le32 |
502 | | |
503 | | static forceinline u32 |
504 | | get_unaligned_be32(const u8 *p) |
505 | 1.04k | { |
506 | 1.04k | if (UNALIGNED_ACCESS_IS_FAST) |
507 | 1.04k | return be32_bswap(load_u32_unaligned(p)); |
508 | 0 | else |
509 | 0 | return ((u32)p[0] << 24) | ((u32)p[1] << 16) | |
510 | 0 | ((u32)p[2] << 8) | p[3]; |
511 | 1.04k | } Unexecuted instantiation: deflate_compress.c:get_unaligned_be32 Unexecuted instantiation: utils.c:get_unaligned_be32 Unexecuted instantiation: deflate_decompress.c:get_unaligned_be32 Unexecuted instantiation: cpu_features.c:get_unaligned_be32 Unexecuted instantiation: zlib_compress.c:get_unaligned_be32 Unexecuted instantiation: adler32.c:get_unaligned_be32 zlib_decompress.c:get_unaligned_be32 Line | Count | Source | 505 | 1.04k | { | 506 | 1.04k | if (UNALIGNED_ACCESS_IS_FAST) | 507 | 1.04k | return be32_bswap(load_u32_unaligned(p)); | 508 | 0 | else | 509 | 0 | return ((u32)p[0] << 24) | ((u32)p[1] << 16) | | 510 | 0 | ((u32)p[2] << 8) | p[3]; | 511 | 1.04k | } |
|
512 | | |
513 | | static forceinline u64 |
514 | | get_unaligned_le64(const u8 *p) |
515 | 319k | { |
516 | 319k | if (UNALIGNED_ACCESS_IS_FAST) |
517 | 319k | return le64_bswap(load_u64_unaligned(p)); |
518 | 0 | else |
519 | 0 | return ((u64)p[7] << 56) | ((u64)p[6] << 48) | |
520 | 0 | ((u64)p[5] << 40) | ((u64)p[4] << 32) | |
521 | 0 | ((u64)p[3] << 24) | ((u64)p[2] << 16) | |
522 | 0 | ((u64)p[1] << 8) | p[0]; |
523 | 319k | } Unexecuted instantiation: deflate_compress.c:get_unaligned_le64 Unexecuted instantiation: utils.c:get_unaligned_le64 deflate_decompress.c:get_unaligned_le64 Line | Count | Source | 515 | 319k | { | 516 | 319k | if (UNALIGNED_ACCESS_IS_FAST) | 517 | 319k | return le64_bswap(load_u64_unaligned(p)); | 518 | 0 | else | 519 | 0 | return ((u64)p[7] << 56) | ((u64)p[6] << 48) | | 520 | 0 | ((u64)p[5] << 40) | ((u64)p[4] << 32) | | 521 | 0 | ((u64)p[3] << 24) | ((u64)p[2] << 16) | | 522 | 0 | ((u64)p[1] << 8) | p[0]; | 523 | 319k | } |
Unexecuted instantiation: cpu_features.c:get_unaligned_le64 Unexecuted instantiation: zlib_compress.c:get_unaligned_le64 Unexecuted instantiation: adler32.c:get_unaligned_le64 Unexecuted instantiation: zlib_decompress.c:get_unaligned_le64 |
524 | | |
525 | | static forceinline machine_word_t |
526 | | get_unaligned_leword(const u8 *p) |
527 | 319k | { |
528 | 319k | STATIC_ASSERT(WORDBITS == 32 || WORDBITS == 64); |
529 | 319k | if (WORDBITS == 32) |
530 | 0 | return get_unaligned_le32(p); |
531 | 319k | else |
532 | 319k | return get_unaligned_le64(p); |
533 | 319k | } Unexecuted instantiation: deflate_compress.c:get_unaligned_leword Unexecuted instantiation: utils.c:get_unaligned_leword deflate_decompress.c:get_unaligned_leword Line | Count | Source | 527 | 319k | { | 528 | 319k | STATIC_ASSERT(WORDBITS == 32 || WORDBITS == 64); | 529 | 319k | if (WORDBITS == 32) | 530 | 0 | return get_unaligned_le32(p); | 531 | 319k | else | 532 | 319k | return get_unaligned_le64(p); | 533 | 319k | } |
Unexecuted instantiation: cpu_features.c:get_unaligned_leword Unexecuted instantiation: zlib_compress.c:get_unaligned_leword Unexecuted instantiation: adler32.c:get_unaligned_leword Unexecuted instantiation: zlib_decompress.c:get_unaligned_leword |
534 | | |
535 | | /* Unaligned stores with endianness conversion */ |
536 | | |
537 | | static forceinline void |
538 | | put_unaligned_le16(u16 v, u8 *p) |
539 | 0 | { |
540 | 0 | if (UNALIGNED_ACCESS_IS_FAST) { |
541 | 0 | store_u16_unaligned(le16_bswap(v), p); |
542 | 0 | } else { |
543 | 0 | p[0] = (u8)(v >> 0); |
544 | 0 | p[1] = (u8)(v >> 8); |
545 | 0 | } |
546 | 0 | } Unexecuted instantiation: deflate_compress.c:put_unaligned_le16 Unexecuted instantiation: utils.c:put_unaligned_le16 Unexecuted instantiation: deflate_decompress.c:put_unaligned_le16 Unexecuted instantiation: cpu_features.c:put_unaligned_le16 Unexecuted instantiation: zlib_compress.c:put_unaligned_le16 Unexecuted instantiation: adler32.c:put_unaligned_le16 Unexecuted instantiation: zlib_decompress.c:put_unaligned_le16 |
547 | | |
548 | | static forceinline void |
549 | | put_unaligned_be16(u16 v, u8 *p) |
550 | 0 | { |
551 | 0 | if (UNALIGNED_ACCESS_IS_FAST) { |
552 | 0 | store_u16_unaligned(be16_bswap(v), p); |
553 | 0 | } else { |
554 | 0 | p[0] = (u8)(v >> 8); |
555 | 0 | p[1] = (u8)(v >> 0); |
556 | 0 | } |
557 | 0 | } Unexecuted instantiation: deflate_compress.c:put_unaligned_be16 Unexecuted instantiation: utils.c:put_unaligned_be16 Unexecuted instantiation: deflate_decompress.c:put_unaligned_be16 Unexecuted instantiation: cpu_features.c:put_unaligned_be16 Unexecuted instantiation: zlib_compress.c:put_unaligned_be16 Unexecuted instantiation: adler32.c:put_unaligned_be16 Unexecuted instantiation: zlib_decompress.c:put_unaligned_be16 |
558 | | |
559 | | static forceinline void |
560 | | put_unaligned_le32(u32 v, u8 *p) |
561 | 0 | { |
562 | 0 | if (UNALIGNED_ACCESS_IS_FAST) { |
563 | 0 | store_u32_unaligned(le32_bswap(v), p); |
564 | 0 | } else { |
565 | 0 | p[0] = (u8)(v >> 0); |
566 | 0 | p[1] = (u8)(v >> 8); |
567 | 0 | p[2] = (u8)(v >> 16); |
568 | 0 | p[3] = (u8)(v >> 24); |
569 | 0 | } |
570 | 0 | } Unexecuted instantiation: deflate_compress.c:put_unaligned_le32 Unexecuted instantiation: utils.c:put_unaligned_le32 Unexecuted instantiation: deflate_decompress.c:put_unaligned_le32 Unexecuted instantiation: cpu_features.c:put_unaligned_le32 Unexecuted instantiation: zlib_compress.c:put_unaligned_le32 Unexecuted instantiation: adler32.c:put_unaligned_le32 Unexecuted instantiation: zlib_decompress.c:put_unaligned_le32 |
571 | | |
572 | | static forceinline void |
573 | | put_unaligned_be32(u32 v, u8 *p) |
574 | 0 | { |
575 | 0 | if (UNALIGNED_ACCESS_IS_FAST) { |
576 | 0 | store_u32_unaligned(be32_bswap(v), p); |
577 | 0 | } else { |
578 | 0 | p[0] = (u8)(v >> 24); |
579 | 0 | p[1] = (u8)(v >> 16); |
580 | 0 | p[2] = (u8)(v >> 8); |
581 | 0 | p[3] = (u8)(v >> 0); |
582 | 0 | } |
583 | 0 | } Unexecuted instantiation: deflate_compress.c:put_unaligned_be32 Unexecuted instantiation: utils.c:put_unaligned_be32 Unexecuted instantiation: deflate_decompress.c:put_unaligned_be32 Unexecuted instantiation: cpu_features.c:put_unaligned_be32 Unexecuted instantiation: zlib_compress.c:put_unaligned_be32 Unexecuted instantiation: adler32.c:put_unaligned_be32 Unexecuted instantiation: zlib_decompress.c:put_unaligned_be32 |
584 | | |
585 | | static forceinline void |
586 | | put_unaligned_le64(u64 v, u8 *p) |
587 | 0 | { |
588 | 0 | if (UNALIGNED_ACCESS_IS_FAST) { |
589 | 0 | store_u64_unaligned(le64_bswap(v), p); |
590 | 0 | } else { |
591 | 0 | p[0] = (u8)(v >> 0); |
592 | 0 | p[1] = (u8)(v >> 8); |
593 | 0 | p[2] = (u8)(v >> 16); |
594 | 0 | p[3] = (u8)(v >> 24); |
595 | 0 | p[4] = (u8)(v >> 32); |
596 | 0 | p[5] = (u8)(v >> 40); |
597 | 0 | p[6] = (u8)(v >> 48); |
598 | 0 | p[7] = (u8)(v >> 56); |
599 | 0 | } |
600 | 0 | } Unexecuted instantiation: deflate_compress.c:put_unaligned_le64 Unexecuted instantiation: utils.c:put_unaligned_le64 Unexecuted instantiation: deflate_decompress.c:put_unaligned_le64 Unexecuted instantiation: cpu_features.c:put_unaligned_le64 Unexecuted instantiation: zlib_compress.c:put_unaligned_le64 Unexecuted instantiation: adler32.c:put_unaligned_le64 Unexecuted instantiation: zlib_decompress.c:put_unaligned_le64 |
601 | | |
602 | | static forceinline void |
603 | | put_unaligned_leword(machine_word_t v, u8 *p) |
604 | 0 | { |
605 | 0 | STATIC_ASSERT(WORDBITS == 32 || WORDBITS == 64); |
606 | 0 | if (WORDBITS == 32) |
607 | 0 | put_unaligned_le32(v, p); |
608 | 0 | else |
609 | 0 | put_unaligned_le64(v, p); |
610 | 0 | } Unexecuted instantiation: deflate_compress.c:put_unaligned_leword Unexecuted instantiation: utils.c:put_unaligned_leword Unexecuted instantiation: deflate_decompress.c:put_unaligned_leword Unexecuted instantiation: cpu_features.c:put_unaligned_leword Unexecuted instantiation: zlib_compress.c:put_unaligned_leword Unexecuted instantiation: adler32.c:put_unaligned_leword Unexecuted instantiation: zlib_decompress.c:put_unaligned_leword |
611 | | |
612 | | /* ========================================================================== */ |
613 | | /* Bit manipulation functions */ |
614 | | /* ========================================================================== */ |
615 | | |
616 | | /* |
617 | | * Bit Scan Reverse (BSR) - find the 0-based index (relative to the least |
618 | | * significant end) of the *most* significant 1 bit in the input value. The |
619 | | * input value must be nonzero! |
620 | | */ |
621 | | |
622 | | static forceinline unsigned |
623 | | bsr32(u32 v) |
624 | 676k | { |
625 | 676k | #if defined(__GNUC__) || __has_builtin(__builtin_clz) |
626 | 676k | return 31 - __builtin_clz(v); |
627 | | #elif defined(_MSC_VER) |
628 | | unsigned long i; |
629 | | |
630 | | _BitScanReverse(&i, v); |
631 | | return i; |
632 | | #else |
633 | | unsigned i = 0; |
634 | | |
635 | | while ((v >>= 1) != 0) |
636 | | i++; |
637 | | return i; |
638 | | #endif |
639 | 676k | } Unexecuted instantiation: deflate_compress.c:bsr32 Unexecuted instantiation: utils.c:bsr32 deflate_decompress.c:bsr32 Line | Count | Source | 624 | 676k | { | 625 | 676k | #if defined(__GNUC__) || __has_builtin(__builtin_clz) | 626 | 676k | return 31 - __builtin_clz(v); | 627 | | #elif defined(_MSC_VER) | 628 | | unsigned long i; | 629 | | | 630 | | _BitScanReverse(&i, v); | 631 | | return i; | 632 | | #else | 633 | | unsigned i = 0; | 634 | | | 635 | | while ((v >>= 1) != 0) | 636 | | i++; | 637 | | return i; | 638 | | #endif | 639 | 676k | } |
Unexecuted instantiation: cpu_features.c:bsr32 Unexecuted instantiation: zlib_compress.c:bsr32 Unexecuted instantiation: adler32.c:bsr32 Unexecuted instantiation: zlib_decompress.c:bsr32 |
640 | | |
641 | | static forceinline unsigned |
642 | | bsr64(u64 v) |
643 | 0 | { |
644 | 0 | #if defined(__GNUC__) || __has_builtin(__builtin_clzll) |
645 | 0 | return 63 - __builtin_clzll(v); |
646 | 0 | #elif defined(_MSC_VER) && defined(_WIN64) |
647 | 0 | unsigned long i; |
648 | 0 |
|
649 | 0 | _BitScanReverse64(&i, v); |
650 | 0 | return i; |
651 | 0 | #else |
652 | 0 | unsigned i = 0; |
653 | 0 |
|
654 | 0 | while ((v >>= 1) != 0) |
655 | 0 | i++; |
656 | 0 | return i; |
657 | 0 | #endif |
658 | 0 | } Unexecuted instantiation: deflate_compress.c:bsr64 Unexecuted instantiation: utils.c:bsr64 Unexecuted instantiation: deflate_decompress.c:bsr64 Unexecuted instantiation: cpu_features.c:bsr64 Unexecuted instantiation: zlib_compress.c:bsr64 Unexecuted instantiation: adler32.c:bsr64 Unexecuted instantiation: zlib_decompress.c:bsr64 |
659 | | |
660 | | static forceinline unsigned |
661 | | bsrw(machine_word_t v) |
662 | 0 | { |
663 | 0 | STATIC_ASSERT(WORDBITS == 32 || WORDBITS == 64); |
664 | 0 | if (WORDBITS == 32) |
665 | 0 | return bsr32(v); |
666 | 0 | else |
667 | 0 | return bsr64(v); |
668 | 0 | } Unexecuted instantiation: deflate_compress.c:bsrw Unexecuted instantiation: utils.c:bsrw Unexecuted instantiation: deflate_decompress.c:bsrw Unexecuted instantiation: cpu_features.c:bsrw Unexecuted instantiation: zlib_compress.c:bsrw Unexecuted instantiation: adler32.c:bsrw Unexecuted instantiation: zlib_decompress.c:bsrw |
669 | | |
670 | | /* |
671 | | * Bit Scan Forward (BSF) - find the 0-based index (relative to the least |
672 | | * significant end) of the *least* significant 1 bit in the input value. The |
673 | | * input value must be nonzero! |
674 | | */ |
675 | | |
676 | | static forceinline unsigned |
677 | | bsf32(u32 v) |
678 | 0 | { |
679 | 0 | #if defined(__GNUC__) || __has_builtin(__builtin_ctz) |
680 | 0 | return __builtin_ctz(v); |
681 | 0 | #elif defined(_MSC_VER) |
682 | 0 | unsigned long i; |
683 | 0 |
|
684 | 0 | _BitScanForward(&i, v); |
685 | 0 | return i; |
686 | 0 | #else |
687 | 0 | unsigned i = 0; |
688 | 0 |
|
689 | 0 | for (; (v & 1) == 0; v >>= 1) |
690 | 0 | i++; |
691 | 0 | return i; |
692 | 0 | #endif |
693 | 0 | } Unexecuted instantiation: deflate_compress.c:bsf32 Unexecuted instantiation: utils.c:bsf32 Unexecuted instantiation: deflate_decompress.c:bsf32 Unexecuted instantiation: cpu_features.c:bsf32 Unexecuted instantiation: zlib_compress.c:bsf32 Unexecuted instantiation: adler32.c:bsf32 Unexecuted instantiation: zlib_decompress.c:bsf32 |
694 | | |
695 | | static forceinline unsigned |
696 | | bsf64(u64 v) |
697 | 0 | { |
698 | 0 | #if defined(__GNUC__) || __has_builtin(__builtin_ctzll) |
699 | 0 | return __builtin_ctzll(v); |
700 | | #elif defined(_MSC_VER) && defined(_WIN64) |
701 | | unsigned long i; |
702 | | |
703 | | _BitScanForward64(&i, v); |
704 | | return i; |
705 | | #else |
706 | | unsigned i = 0; |
707 | | |
708 | | for (; (v & 1) == 0; v >>= 1) |
709 | | i++; |
710 | | return i; |
711 | | #endif |
712 | 0 | } Unexecuted instantiation: deflate_compress.c:bsf64 Unexecuted instantiation: utils.c:bsf64 Unexecuted instantiation: deflate_decompress.c:bsf64 Unexecuted instantiation: cpu_features.c:bsf64 Unexecuted instantiation: zlib_compress.c:bsf64 Unexecuted instantiation: adler32.c:bsf64 Unexecuted instantiation: zlib_decompress.c:bsf64 |
713 | | |
714 | | static forceinline unsigned |
715 | | bsfw(machine_word_t v) |
716 | 0 | { |
717 | 0 | STATIC_ASSERT(WORDBITS == 32 || WORDBITS == 64); |
718 | 0 | if (WORDBITS == 32) |
719 | 0 | return bsf32(v); |
720 | 0 | else |
721 | 0 | return bsf64(v); |
722 | 0 | } Unexecuted instantiation: deflate_compress.c:bsfw Unexecuted instantiation: utils.c:bsfw Unexecuted instantiation: deflate_decompress.c:bsfw Unexecuted instantiation: cpu_features.c:bsfw Unexecuted instantiation: zlib_compress.c:bsfw Unexecuted instantiation: adler32.c:bsfw Unexecuted instantiation: zlib_decompress.c:bsfw |
723 | | |
724 | | /* |
725 | | * rbit32(v): reverse the bits in a 32-bit integer. This doesn't have a |
726 | | * fallback implementation; use '#ifdef rbit32' to check if this is available. |
727 | | */ |
728 | | #undef rbit32 |
729 | | #if (defined(__GNUC__) || defined(__clang__)) && defined(ARCH_ARM32) && \ |
730 | | (__ARM_ARCH >= 7 || (__ARM_ARCH == 6 && defined(__ARM_ARCH_6T2__))) |
731 | | static forceinline u32 |
732 | | rbit32(u32 v) |
733 | | { |
734 | | __asm__("rbit %0, %1" : "=r" (v) : "r" (v)); |
735 | | return v; |
736 | | } |
737 | | #define rbit32 rbit32 |
738 | | #elif (defined(__GNUC__) || defined(__clang__)) && defined(ARCH_ARM64) |
739 | | static forceinline u32 |
740 | | rbit32(u32 v) |
741 | | { |
742 | | __asm__("rbit %w0, %w1" : "=r" (v) : "r" (v)); |
743 | | return v; |
744 | | } |
745 | | #define rbit32 rbit32 |
746 | | #endif |
747 | | |
748 | | #endif /* COMMON_DEFS_H */ |