github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/compress/libdeflate/common_defs.h (about) 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_COMMON_DEFS_H 29 #define COMMON_COMMON_DEFS_H 30 31 #ifdef __GNUC__ 32 # include "compiler_gcc.h" 33 #elif defined(_MSC_VER) 34 # include "compiler_msc.h" 35 #else 36 # pragma message("Unrecognized compiler. Please add a header file for your compiler. Compilation will proceed, but performance may suffer!") 37 #endif 38 39 /* ========================================================================== */ 40 /* Type definitions */ 41 /* ========================================================================== */ 42 43 #include <stddef.h> /* size_t */ 44 45 #ifndef __bool_true_false_are_defined 46 # include <stdbool.h> /* bool */ 47 #endif 48 49 /* Fixed-width integer types */ 50 #ifndef PRIu32 51 # include <inttypes.h> 52 #endif 53 typedef uint8_t u8; 54 typedef uint16_t u16; 55 typedef uint32_t u32; 56 typedef uint64_t u64; 57 typedef int8_t s8; 58 typedef int16_t s16; 59 typedef int32_t s32; 60 typedef int64_t s64; 61 62 /* 63 * Word type of the target architecture. Use 'size_t' instead of 'unsigned 64 * long' to account for platforms such as Windows that use 32-bit 'unsigned 65 * long' on 64-bit architectures. 66 */ 67 typedef size_t machine_word_t; 68 69 /* Number of bytes in a word */ 70 #define WORDBYTES ((int)sizeof(machine_word_t)) 71 72 /* Number of bits in a word */ 73 #define WORDBITS (8 * WORDBYTES) 74 75 /* ========================================================================== */ 76 /* Optional compiler features */ 77 /* ========================================================================== */ 78 79 /* LIBEXPORT - export a function from a shared library */ 80 #ifndef LIBEXPORT 81 # define LIBEXPORT 82 #endif 83 84 /* inline - suggest that a function be inlined */ 85 #ifndef inline 86 # define inline 87 #endif 88 89 /* forceinline - force a function to be inlined, if possible */ 90 #ifndef forceinline 91 # define forceinline inline 92 #endif 93 94 /* restrict - annotate a non-aliased pointer */ 95 #ifndef restrict 96 # define restrict 97 #endif 98 99 /* likely(expr) - hint that an expression is usually true */ 100 #ifndef likely 101 # define likely(expr) (expr) 102 #endif 103 104 /* unlikely(expr) - hint that an expression is usually false */ 105 #ifndef unlikely 106 # define unlikely(expr) (expr) 107 #endif 108 109 /* prefetchr(addr) - prefetch into L1 cache for read */ 110 #ifndef prefetchr 111 # define prefetchr(addr) 112 #endif 113 114 /* prefetchw(addr) - prefetch into L1 cache for write */ 115 #ifndef prefetchw 116 # define prefetchw(addr) 117 #endif 118 119 /* Does the compiler support the 'target' function attribute? */ 120 #ifndef COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE 121 # define COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE 0 122 #endif 123 124 /* Which targets are supported with the 'target' function attribute? */ 125 #ifndef COMPILER_SUPPORTS_BMI2_TARGET 126 # define COMPILER_SUPPORTS_BMI2_TARGET 0 127 #endif 128 #ifndef COMPILER_SUPPORTS_AVX_TARGET 129 # define COMPILER_SUPPORTS_AVX_TARGET 0 130 #endif 131 132 /* 133 * Which targets are supported with the 'target' function attribute and have 134 * intrinsics that work within 'target'-ed functions? 135 */ 136 #ifndef COMPILER_SUPPORTS_SSE2_TARGET_INTRINSICS 137 # define COMPILER_SUPPORTS_SSE2_TARGET_INTRINSICS 0 138 #endif 139 #ifndef COMPILER_SUPPORTS_PCLMUL_TARGET_INTRINSICS 140 # define COMPILER_SUPPORTS_PCLMUL_TARGET_INTRINSICS 0 141 #endif 142 #ifndef COMPILER_SUPPORTS_AVX2_TARGET_INTRINSICS 143 # define COMPILER_SUPPORTS_AVX2_TARGET_INTRINSICS 0 144 #endif 145 #ifndef COMPILER_SUPPORTS_NEON_TARGET_INTRINSICS 146 # define COMPILER_SUPPORTS_NEON_TARGET_INTRINSICS 0 147 #endif 148 #ifndef COMPILER_SUPPORTS_PMULL_TARGET_INTRINSICS 149 # define COMPILER_SUPPORTS_PMULL_TARGET_INTRINSICS 0 150 #endif 151 152 /* _aligned_attribute(n) - declare that the annotated variable, or variables of 153 * the annotated type, are to be aligned on n-byte boundaries */ 154 #ifndef _aligned_attribute 155 #endif 156 157 /* ========================================================================== */ 158 /* Miscellaneous macros */ 159 /* ========================================================================== */ 160 161 #define ARRAY_LEN(A) (sizeof(A) / sizeof((A)[0])) 162 #define MIN(a, b) ((a) <= (b) ? (a) : (b)) 163 #define MAX(a, b) ((a) >= (b) ? (a) : (b)) 164 #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) 165 #define STATIC_ASSERT(expr) ((void)sizeof(char[1 - 2 * !(expr)])) 166 #define ALIGN(n, a) (((n) + (a) - 1) & ~((a) - 1)) 167 168 /* ========================================================================== */ 169 /* Endianness handling */ 170 /* ========================================================================== */ 171 172 /* 173 * CPU_IS_LITTLE_ENDIAN() - a macro which evaluates to 1 if the CPU is little 174 * endian or 0 if it is big endian. The macro should be defined in a way such 175 * that the compiler can evaluate it at compilation time. If not defined, a 176 * fallback is used. 177 */ 178 #ifndef CPU_IS_LITTLE_ENDIAN 179 static forceinline int CPU_IS_LITTLE_ENDIAN(void) 180 { 181 union { 182 unsigned int v; 183 unsigned char b; 184 } u; 185 u.v = 1; 186 return u.b; 187 } 188 #endif 189 190 /* bswap16(n) - swap the bytes of a 16-bit integer */ 191 #ifndef bswap16 192 static forceinline u16 bswap16(u16 n) 193 { 194 return (n << 8) | (n >> 8); 195 } 196 #endif 197 198 /* bswap32(n) - swap the bytes of a 32-bit integer */ 199 #ifndef bswap32 200 static forceinline u32 bswap32(u32 n) 201 { 202 return ((n & 0x000000FF) << 24) | 203 ((n & 0x0000FF00) << 8) | 204 ((n & 0x00FF0000) >> 8) | 205 ((n & 0xFF000000) >> 24); 206 } 207 #endif 208 209 /* bswap64(n) - swap the bytes of a 64-bit integer */ 210 #ifndef bswap64 211 static forceinline u64 bswap64(u64 n) 212 { 213 return ((n & 0x00000000000000FF) << 56) | 214 ((n & 0x000000000000FF00) << 40) | 215 ((n & 0x0000000000FF0000) << 24) | 216 ((n & 0x00000000FF000000) << 8) | 217 ((n & 0x000000FF00000000) >> 8) | 218 ((n & 0x0000FF0000000000) >> 24) | 219 ((n & 0x00FF000000000000) >> 40) | 220 ((n & 0xFF00000000000000) >> 56); 221 } 222 #endif 223 224 #define le16_bswap(n) (CPU_IS_LITTLE_ENDIAN() ? (n) : bswap16(n)) 225 #define le32_bswap(n) (CPU_IS_LITTLE_ENDIAN() ? (n) : bswap32(n)) 226 #define le64_bswap(n) (CPU_IS_LITTLE_ENDIAN() ? (n) : bswap64(n)) 227 #define be16_bswap(n) (CPU_IS_LITTLE_ENDIAN() ? bswap16(n) : (n)) 228 #define be32_bswap(n) (CPU_IS_LITTLE_ENDIAN() ? bswap32(n) : (n)) 229 #define be64_bswap(n) (CPU_IS_LITTLE_ENDIAN() ? bswap64(n) : (n)) 230 231 /* ========================================================================== */ 232 /* Unaligned memory accesses */ 233 /* ========================================================================== */ 234 235 /* 236 * UNALIGNED_ACCESS_IS_FAST should be defined to 1 if unaligned memory accesses 237 * can be performed efficiently on the target platform. 238 */ 239 #ifndef UNALIGNED_ACCESS_IS_FAST 240 # define UNALIGNED_ACCESS_IS_FAST 0 241 #endif 242 243 /* 244 * DEFINE_UNALIGNED_TYPE(type) - a macro that, given an integer type 'type', 245 * defines load_type_unaligned(addr) and store_type_unaligned(v, addr) functions 246 * which load and store variables of type 'type' from/to unaligned memory 247 * addresses. If not defined, a fallback is used. 248 */ 249 #ifndef DEFINE_UNALIGNED_TYPE 250 251 /* 252 * Although memcpy() may seem inefficient, it *usually* gets optimized 253 * appropriately by modern compilers. It's portable and may be the best we can 254 * do for a fallback... 255 */ 256 #include <string.h> 257 258 #define DEFINE_UNALIGNED_TYPE(type) \ 259 \ 260 static forceinline type \ 261 load_##type##_unaligned(const void *p) \ 262 { \ 263 type v; \ 264 memcpy(&v, p, sizeof(v)); \ 265 return v; \ 266 } \ 267 \ 268 static forceinline void \ 269 store_##type##_unaligned(type v, void *p) \ 270 { \ 271 memcpy(p, &v, sizeof(v)); \ 272 } 273 274 #endif /* !DEFINE_UNALIGNED_TYPE */ 275 276 /* ========================================================================== */ 277 /* Bit scan functions */ 278 /* ========================================================================== */ 279 280 /* 281 * Bit Scan Reverse (BSR) - find the 0-based index (relative to the least 282 * significant end) of the *most* significant 1 bit in the input value. The 283 * input value must be nonzero! 284 */ 285 286 #ifndef bsr32 287 static forceinline unsigned 288 bsr32(u32 n) 289 { 290 unsigned i = 0; 291 while ((n >>= 1) != 0) 292 i++; 293 return i; 294 } 295 #endif 296 297 #ifndef bsr64 298 static forceinline unsigned 299 bsr64(u64 n) 300 { 301 unsigned i = 0; 302 while ((n >>= 1) != 0) 303 i++; 304 return i; 305 } 306 #endif 307 308 static forceinline unsigned 309 bsrw(machine_word_t n) 310 { 311 STATIC_ASSERT(WORDBITS == 32 || WORDBITS == 64); 312 if (WORDBITS == 32) 313 return bsr32(n); 314 else 315 return bsr64(n); 316 } 317 318 /* 319 * Bit Scan Forward (BSF) - find the 0-based index (relative to the least 320 * significant end) of the *least* significant 1 bit in the input value. The 321 * input value must be nonzero! 322 */ 323 324 #ifndef bsf32 325 static forceinline unsigned 326 bsf32(u32 n) 327 { 328 unsigned i = 0; 329 while ((n & 1) == 0) { 330 i++; 331 n >>= 1; 332 } 333 return i; 334 } 335 #endif 336 337 #ifndef bsf64 338 static forceinline unsigned 339 bsf64(u64 n) 340 { 341 unsigned i = 0; 342 while ((n & 1) == 0) { 343 i++; 344 n >>= 1; 345 } 346 return i; 347 } 348 #endif 349 350 static forceinline unsigned 351 bsfw(machine_word_t n) 352 { 353 STATIC_ASSERT(WORDBITS == 32 || WORDBITS == 64); 354 if (WORDBITS == 32) 355 return bsf32(n); 356 else 357 return bsf64(n); 358 } 359 360 #endif /* COMMON_COMMON_DEFS_H */