2 * Common code for checksum implementations
4 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 * See https://llvm.org/LICENSE.txt for license information.
6 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
9 #ifndef CHKSUM_COMMON_H
10 #define CHKSUM_COMMON_H
12 #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
13 #error Only little endian supported
21 /* Assertions must be explicitly enabled */
25 #define Assert(exp) assert(exp)
27 #define Assert(exp) (void) (exp)
31 #define likely(x) __builtin_expect(!!(x), 1)
32 #define unlikely(x) __builtin_expect(!!(x), 0)
33 #define may_alias __attribute__((__may_alias__))
34 #define always_inline __attribute__((always_inline))
36 #define no_unroll_loops
38 #define no_unroll_loops __attribute__((optimize("no-unroll-loops")))
40 #define bswap16(x) __builtin_bswap16((x))
43 #define unlikely(x) (x)
46 #define no_unroll_loops
47 #define bswap16(x) ((uint8_t)((x) >> 8) | ((uint8_t)(x) << 8))
50 #define ALL_ONES ~UINT64_C(0)
53 uint64_t load64(const void *ptr
)
55 /* GCC will optimise this to a normal load instruction */
57 memcpy(&v
, ptr
, sizeof v
);
62 uint32_t load32(const void *ptr
)
64 /* GCC will optimise this to a normal load instruction */
66 memcpy(&v
, ptr
, sizeof v
);
71 uint16_t load16(const void *ptr
)
73 /* GCC will optimise this to a normal load instruction */
75 memcpy(&v
, ptr
, sizeof v
);
79 /* slurp_small() is for small buffers, don't waste cycles on alignment */
82 static inline uint64_t
83 slurp_small(const void *ptr
, uint32_t nbytes
)
85 const unsigned char *cptr
= ptr
;
100 sum
+= (uint8_t) *cptr
;
105 static inline const void *
106 align_ptr(const void *ptr
, size_t bytes
)
108 return (void *) ((uintptr_t) ptr
& -(uintptr_t) bytes
);
112 static inline uint16_t
113 fold_and_swap(uint64_t sum
, bool swap
)
115 /* Fold 64-bit sum to 32 bits */
116 sum
= (sum
& 0xffffffff) + (sum
>> 32);
117 sum
= (sum
& 0xffffffff) + (sum
>> 32);
118 Assert(sum
== (uint32_t) sum
);
120 /* Fold 32-bit sum to 16 bits */
121 sum
= (sum
& 0xffff) + (sum
>> 16);
122 sum
= (sum
& 0xffff) + (sum
>> 16);
123 Assert(sum
== (uint16_t) sum
);
125 if (unlikely(swap
)) /* Odd base pointer is unexpected */
130 return (uint16_t) sum
;