45#ifndef TUKLIB_INTEGER_H
46#define TUKLIB_INTEGER_H
53#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)
54# include <immintrin.h>
62#if defined(HAVE___BUILTIN_BSWAPXX)
64# define bswap16(n) __builtin_bswap16(n)
65# define bswap32(n) __builtin_bswap32(n)
66# define bswap64(n) __builtin_bswap64(n)
68#elif defined(HAVE_BYTESWAP_H)
72# define bswap16(num) bswap_16(num)
75# define bswap32(num) bswap_32(num)
78# define bswap64(num) bswap_64(num)
81#elif defined(HAVE_SYS_ENDIAN_H)
83# include <sys/endian.h>
85#elif defined(HAVE_SYS_BYTEORDER_H)
87# include <sys/byteorder.h>
89# define bswap16(num) BSWAP_16(num)
92# define bswap32(num) BSWAP_32(num)
95# define bswap64(num) BSWAP_64(num)
98# define conv16be(num) BE_16(num)
101# define conv32be(num) BE_32(num)
104# define conv64be(num) BE_64(num)
107# define conv16le(num) LE_16(num)
110# define conv32le(num) LE_32(num)
113# define conv64le(num) LE_64(num)
118# define bswap16(n) (uint16_t)( \
119 (((n) & 0x00FFU) << 8) \
120 | (((n) & 0xFF00U) >> 8) \
125# define bswap32(n) (uint32_t)( \
126 (((n) & UINT32_C(0x000000FF)) << 24) \
127 | (((n) & UINT32_C(0x0000FF00)) << 8) \
128 | (((n) & UINT32_C(0x00FF0000)) >> 8) \
129 | (((n) & UINT32_C(0xFF000000)) >> 24) \
134# define bswap64(n) (uint64_t)( \
135 (((n) & UINT64_C(0x00000000000000FF)) << 56) \
136 | (((n) & UINT64_C(0x000000000000FF00)) << 40) \
137 | (((n) & UINT64_C(0x0000000000FF0000)) << 24) \
138 | (((n) & UINT64_C(0x00000000FF000000)) << 8) \
139 | (((n) & UINT64_C(0x000000FF00000000)) >> 8) \
140 | (((n) & UINT64_C(0x0000FF0000000000)) >> 24) \
141 | (((n) & UINT64_C(0x00FF000000000000)) >> 40) \
142 | (((n) & UINT64_C(0xFF00000000000000)) >> 56) \
147#ifdef WORDS_BIGENDIAN
149# define conv16be(num) ((uint16_t)(num))
152# define conv32be(num) ((uint32_t)(num))
155# define conv64be(num) ((uint64_t)(num))
158# define conv16le(num) bswap16(num)
161# define conv32le(num) bswap32(num)
164# define conv64le(num) bswap64(num)
168# define conv16be(num) bswap16(num)
171# define conv32be(num) bswap32(num)
174# define conv64be(num) bswap64(num)
177# define conv16le(num) ((uint16_t)(num))
180# define conv32le(num) ((uint32_t)(num))
183# define conv64le(num) ((uint64_t)(num))
207static inline uint16_t
210#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \
211 && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING)
212 return *(
const uint16_t *)
buf;
215 memcpy(&num,
buf,
sizeof(num));
221static inline uint32_t
224#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \
225 && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING)
226 return *(
const uint32_t *)
buf;
229 memcpy(&num,
buf,
sizeof(num));
235static inline uint64_t
238#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \
239 && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING)
240 return *(
const uint64_t *)
buf;
243 memcpy(&num,
buf,
sizeof(num));
252#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \
253 && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING)
254 *(uint16_t *)
buf = num;
256 memcpy(
buf, &num,
sizeof(num));
265#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \
266 && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING)
267 *(uint32_t *)
buf = num;
269 memcpy(
buf, &num,
sizeof(num));
278#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \
279 && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING)
280 *(uint64_t *)
buf = num;
282 memcpy(
buf, &num,
sizeof(num));
288static inline uint16_t
289read16be(
const uint8_t *
buf)
291#if defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)
295 uint16_t num = ((uint16_t)
buf[0] << 8) | (uint16_t)
buf[1];
301static inline uint16_t
302read16le(
const uint8_t *
buf)
304#if !defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)
308 uint16_t num = ((uint16_t)
buf[0]) | ((uint16_t)
buf[1] << 8);
314static inline uint32_t
315read32be(
const uint8_t *
buf)
317#if defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)
321 uint32_t num = (uint32_t)
buf[0] << 24;
322 num |= (uint32_t)
buf[1] << 16;
323 num |= (uint32_t)
buf[2] << 8;
324 num |= (uint32_t)
buf[3];
330static inline uint32_t
331read32le(
const uint8_t *
buf)
333#if !defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)
337 uint32_t num = (uint32_t)
buf[0];
338 num |= (uint32_t)
buf[1] << 8;
339 num |= (uint32_t)
buf[2] << 16;
340 num |= (uint32_t)
buf[3] << 24;
346static inline uint64_t
347read64be(
const uint8_t *
buf)
349#if defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)
353 uint64_t num = (uint64_t)
buf[0] << 56;
354 num |= (uint64_t)
buf[1] << 48;
355 num |= (uint64_t)
buf[2] << 40;
356 num |= (uint64_t)
buf[3] << 32;
357 num |= (uint64_t)
buf[4] << 24;
358 num |= (uint64_t)
buf[5] << 16;
359 num |= (uint64_t)
buf[6] << 8;
360 num |= (uint64_t)
buf[7];
366static inline uint64_t
367read64le(
const uint8_t *
buf)
369#if !defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)
373 uint64_t num = (uint64_t)
buf[0];
374 num |= (uint64_t)
buf[1] << 8;
375 num |= (uint64_t)
buf[2] << 16;
376 num |= (uint64_t)
buf[3] << 24;
377 num |= (uint64_t)
buf[4] << 32;
378 num |= (uint64_t)
buf[5] << 40;
379 num |= (uint64_t)
buf[6] << 48;
380 num |= (uint64_t)
buf[7] << 56;
390#if defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)
391# define write16be(buf, num) write16ne(buf, conv16be(num))
392# define write32be(buf, num) write32ne(buf, conv32be(num))
393# define write64be(buf, num) write64ne(buf, conv64be(num))
396#if !defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)
397# define write16le(buf, num) write16ne(buf, conv16le(num))
398# define write32le(buf, num) write32ne(buf, conv32le(num))
399# define write64le(buf, num) write64ne(buf, conv64le(num))
405write16be(uint8_t *
buf, uint16_t num)
407 buf[0] = (uint8_t)(num >> 8);
408 buf[1] = (uint8_t)num;
418 buf[0] = (uint8_t)num;
419 buf[1] = (uint8_t)(num >> 8);
427write32be(uint8_t *
buf, uint32_t num)
429 buf[0] = (uint8_t)(num >> 24);
430 buf[1] = (uint8_t)(num >> 16);
431 buf[2] = (uint8_t)(num >> 8);
432 buf[3] = (uint8_t)num;
442 buf[0] = (uint8_t)num;
443 buf[1] = (uint8_t)(num >> 8);
444 buf[2] = (uint8_t)(num >> 16);
445 buf[3] = (uint8_t)(num >> 24);
475#ifdef HAVE___BUILTIN_ASSUME_ALIGNED
476# define tuklib_memcpy_aligned(dest, src, size) \
477 memcpy(dest, __builtin_assume_aligned(src, size), size)
479# define tuklib_memcpy_aligned(dest, src, size) \
480 memcpy(dest, src, size)
481# ifndef TUKLIB_FAST_UNALIGNED_ACCESS
482# define TUKLIB_USE_UNSAFE_ALIGNED_READS 1
487static inline uint16_t
488aligned_read16ne(
const uint8_t *
buf)
490#if defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) \
491 || defined(TUKLIB_USE_UNSAFE_ALIGNED_READS)
492 return *(
const uint16_t *)
buf;
501static inline uint32_t
502aligned_read32ne(
const uint8_t *
buf)
504#if defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) \
505 || defined(TUKLIB_USE_UNSAFE_ALIGNED_READS)
506 return *(
const uint32_t *)
buf;
515static inline uint64_t
516aligned_read64ne(
const uint8_t *
buf)
518#if defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) \
519 || defined(TUKLIB_USE_UNSAFE_ALIGNED_READS)
520 return *(
const uint64_t *)
buf;
530aligned_write16ne(uint8_t *
buf, uint16_t num)
532#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING
533 *(uint16_t *)
buf = num;
542aligned_write32ne(uint8_t *
buf, uint32_t num)
544#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING
545 *(uint32_t *)
buf = num;
554aligned_write64ne(uint8_t *
buf, uint64_t num)
556#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING
557 *(uint64_t *)
buf = num;
565static inline uint16_t
566aligned_read16be(
const uint8_t *
buf)
568 uint16_t num = aligned_read16ne(
buf);
573static inline uint16_t
574aligned_read16le(
const uint8_t *
buf)
576 uint16_t num = aligned_read16ne(
buf);
581static inline uint32_t
582aligned_read32be(
const uint8_t *
buf)
584 uint32_t num = aligned_read32ne(
buf);
589static inline uint32_t
590aligned_read32le(
const uint8_t *
buf)
592 uint32_t num = aligned_read32ne(
buf);
597static inline uint64_t
598aligned_read64be(
const uint8_t *
buf)
600 uint64_t num = aligned_read64ne(
buf);
605static inline uint64_t
606aligned_read64le(
const uint8_t *
buf)
608 uint64_t num = aligned_read64ne(
buf);
614#define aligned_write16be(buf, num) aligned_write16ne((buf), conv16be(num))
615#define aligned_write16le(buf, num) aligned_write16ne((buf), conv16le(num))
616#define aligned_write32be(buf, num) aligned_write32ne((buf), conv32be(num))
617#define aligned_write32le(buf, num) aligned_write32ne((buf), conv32le(num))
618#define aligned_write64be(buf, num) aligned_write64ne((buf), conv64be(num))
619#define aligned_write64le(buf, num) aligned_write64ne((buf), conv64le(num))
626static inline uint32_t
630#if defined(__INTEL_COMPILER)
631 return _bit_scan_reverse(n);
633#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX == UINT32_MAX
638 return (uint32_t)__builtin_clz(n) ^ 31U;
640#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
642 __asm__(
"bsrl %1, %0" :
"=r" (
i) :
"rm" (n));
645#elif defined(_MSC_VER)
647 _BitScanReverse(&
i, n);
653 if ((n & 0xFFFF0000) == 0) {
658 if ((n & 0xFF000000) == 0) {
663 if ((n & 0xF0000000) == 0) {
668 if ((n & 0xC0000000) == 0) {
673 if ((n & 0x80000000) == 0)
681static inline uint32_t
684#if defined(__INTEL_COMPILER)
685 return _bit_scan_reverse(n) ^ 31U;
687#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX == UINT32_MAX
688 return (uint32_t)__builtin_clz(n);
690#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
692 __asm__(
"bsrl %1, %0\n\t"
694 :
"=r" (
i) :
"rm" (n));
697#elif defined(_MSC_VER)
699 _BitScanReverse(&
i, n);
705 if ((n & 0xFFFF0000) == 0) {
710 if ((n & 0xFF000000) == 0) {
715 if ((n & 0xF0000000) == 0) {
720 if ((n & 0xC0000000) == 0) {
725 if ((n & 0x80000000) == 0)
733static inline uint32_t
736#if defined(__INTEL_COMPILER)
737 return _bit_scan_forward(n);
739#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX >= UINT32_MAX
740 return (uint32_t)__builtin_ctz(n);
742#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
744 __asm__(
"bsfl %1, %0" :
"=r" (
i) :
"rm" (n));
747#elif defined(_MSC_VER)
749 _BitScanForward(&
i, n);
755 if ((n & 0x0000FFFF) == 0) {
760 if ((n & 0x000000FF) == 0) {
765 if ((n & 0x0000000F) == 0) {
770 if ((n & 0x00000003) == 0) {
775 if ((n & 0x00000001) == 0)
char buf[N_BUF]
Definition spewG.c:36
lzma_index ** i
Definition index.h:629
Common definitions for tuklib modules.
#define conv64le(num)
Definition tuklib_integer.h:183
#define conv16le(num)
Definition tuklib_integer.h:177
#define conv16be(num)
Definition tuklib_integer.h:168
#define conv32be(num)
Definition tuklib_integer.h:171
#define conv64be(num)
Definition tuklib_integer.h:174
#define conv32le(num)
Definition tuklib_integer.h:180
#define tuklib_memcpy_aligned(dest, src, size)
Definition tuklib_integer.h:479
#define write16le(buf, num)
Definition tuklib_integer.h:397
#define write32le(buf, num)
Definition tuklib_integer.h:398
#define read32ne
Definition tuklib_integer.h:467
#define write32ne
Definition tuklib_integer.h:470
#define write64ne
Definition tuklib_integer.h:471
#define read16ne
Definition tuklib_integer.h:466
#define read64ne
Definition tuklib_integer.h:468
#define write16ne
Definition tuklib_integer.h:469