44#ifndef TUKLIB_INTEGER_H
45#define TUKLIB_INTEGER_H
52#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)
53# include <immintrin.h>
58#elif defined(_MSC_VER) && !TUKLIB_GNUC_REQ(3, 4) && !defined(__clang__)
67#if defined(HAVE___BUILTIN_BSWAPXX)
69# define byteswap16(num) __builtin_bswap16(num)
70# define byteswap32(num) __builtin_bswap32(num)
71# define byteswap64(num) __builtin_bswap64(num)
73#elif defined(HAVE_BYTESWAP_H)
77# define byteswap16(num) bswap_16(num)
80# define byteswap32(num) bswap_32(num)
83# define byteswap64(num) bswap_64(num)
86#elif defined(HAVE_SYS_ENDIAN_H)
88# include <sys/endian.h>
89# define byteswap16(num) bswap16(num)
90# define byteswap32(num) bswap32(num)
91# define byteswap64(num) bswap64(num)
93#elif defined(HAVE_SYS_BYTEORDER_H)
95# include <sys/byteorder.h>
97# define byteswap16(num) BSWAP_16(num)
100# define byteswap32(num) BSWAP_32(num)
103# define byteswap64(num) BSWAP_64(num)
106# define conv16be(num) BE_16(num)
109# define conv32be(num) BE_32(num)
112# define conv64be(num) BE_64(num)
115# define conv16le(num) LE_16(num)
118# define conv32le(num) LE_32(num)
121# define conv64le(num) LE_64(num)
126# define byteswap16(n) (uint16_t)( \
127 (((n) & 0x00FFU) << 8) \
128 | (((n) & 0xFF00U) >> 8) \
133# define byteswap32(n) (uint32_t)( \
134 (((n) & UINT32_C(0x000000FF)) << 24) \
135 | (((n) & UINT32_C(0x0000FF00)) << 8) \
136 | (((n) & UINT32_C(0x00FF0000)) >> 8) \
137 | (((n) & UINT32_C(0xFF000000)) >> 24) \
142# define byteswap64(n) (uint64_t)( \
143 (((n) & UINT64_C(0x00000000000000FF)) << 56) \
144 | (((n) & UINT64_C(0x000000000000FF00)) << 40) \
145 | (((n) & UINT64_C(0x0000000000FF0000)) << 24) \
146 | (((n) & UINT64_C(0x00000000FF000000)) << 8) \
147 | (((n) & UINT64_C(0x000000FF00000000)) >> 8) \
148 | (((n) & UINT64_C(0x0000FF0000000000)) >> 24) \
149 | (((n) & UINT64_C(0x00FF000000000000)) >> 40) \
150 | (((n) & UINT64_C(0xFF00000000000000)) >> 56) \
155#ifdef WORDS_BIGENDIAN
157# define conv16be(num) ((uint16_t)(num))
160# define conv32be(num) ((uint32_t)(num))
163# define conv64be(num) ((uint64_t)(num))
166# define conv16le(num) byteswap16(num)
169# define conv32le(num) byteswap32(num)
172# define conv64le(num) byteswap64(num)
176# define conv16be(num) byteswap16(num)
179# define conv32be(num) byteswap32(num)
182# define conv64be(num) byteswap64(num)
185# define conv16le(num) ((uint16_t)(num))
188# define conv32le(num) ((uint32_t)(num))
191# define conv64le(num) ((uint64_t)(num))
320#ifdef TUKLIB_FAST_UNALIGNED_ACCESS
322static inline uint16_t
325#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING
326 return *(
const uint16_t *)
buf;
329 memcpy(&num,
buf,
sizeof(num));
335static inline uint32_t
338#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING
339 return *(
const uint32_t *)
buf;
342 memcpy(&num,
buf,
sizeof(num));
348static inline uint64_t
351#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING
352 return *(
const uint64_t *)
buf;
355 memcpy(&num,
buf,
sizeof(num));
364#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING
365 *(uint16_t *)
buf = num;
367 memcpy(
buf, &num,
sizeof(num));
376#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING
377 *(uint32_t *)
buf = num;
379 memcpy(
buf, &num,
sizeof(num));
388#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING
389 *(uint64_t *)
buf = num;
391 memcpy(
buf, &num,
sizeof(num));
397static inline uint16_t
398read16be(
const uint8_t *
buf)
405static inline uint16_t
406read16le(
const uint8_t *
buf)
413static inline uint32_t
414read32be(
const uint8_t *
buf)
421static inline uint32_t
422read32le(
const uint8_t *
buf)
429static inline uint64_t
430read64be(
const uint8_t *
buf)
437static inline uint64_t
438read64le(
const uint8_t *
buf)
449#define write16be(buf, num) write16ne(buf, conv16be(num))
450#define write32be(buf, num) write32ne(buf, conv32be(num))
451#define write64be(buf, num) write64ne(buf, conv64be(num))
452#define write16le(buf, num) write16ne(buf, conv16le(num))
453#define write32le(buf, num) write32ne(buf, conv32le(num))
454#define write64le(buf, num) write64ne(buf, conv64le(num))
458#ifdef WORDS_BIGENDIAN
459# define read16ne read16be
460# define read32ne read32be
461# define read64ne read64be
462# define write16ne write16be
463# define write32ne write32be
464# define write64ne write64be
466# define read16ne read16le
467# define read32ne read32le
468# define read64ne read64le
469# define write16ne write16le
470# define write32ne write32le
471# define write64ne write64le
475static inline uint16_t
476read16be(
const uint8_t *
buf)
478 uint16_t num = ((uint16_t)
buf[0] << 8) | (uint16_t)
buf[1];
483static inline uint16_t
484read16le(
const uint8_t *
buf)
486 uint16_t num = ((uint16_t)
buf[0]) | ((uint16_t)
buf[1] << 8);
491static inline uint32_t
492read32be(
const uint8_t *
buf)
494 uint32_t num = (uint32_t)
buf[0] << 24;
495 num |= (uint32_t)
buf[1] << 16;
496 num |= (uint32_t)
buf[2] << 8;
497 num |= (uint32_t)
buf[3];
502static inline uint32_t
503read32le(
const uint8_t *
buf)
505 uint32_t num = (uint32_t)
buf[0];
506 num |= (uint32_t)
buf[1] << 8;
507 num |= (uint32_t)
buf[2] << 16;
508 num |= (uint32_t)
buf[3] << 24;
513static inline uint64_t
514read64be(
const uint8_t *
buf)
516 uint64_t num = (uint64_t)
buf[0] << 56;
517 num |= (uint64_t)
buf[1] << 48;
518 num |= (uint64_t)
buf[2] << 40;
519 num |= (uint64_t)
buf[3] << 32;
520 num |= (uint64_t)
buf[4] << 24;
521 num |= (uint64_t)
buf[5] << 16;
522 num |= (uint64_t)
buf[6] << 8;
523 num |= (uint64_t)
buf[7];
528static inline uint64_t
529read64le(
const uint8_t *
buf)
531 uint64_t num = (uint64_t)
buf[0];
532 num |= (uint64_t)
buf[1] << 8;
533 num |= (uint64_t)
buf[2] << 16;
534 num |= (uint64_t)
buf[3] << 24;
535 num |= (uint64_t)
buf[4] << 32;
536 num |= (uint64_t)
buf[5] << 40;
537 num |= (uint64_t)
buf[6] << 48;
538 num |= (uint64_t)
buf[7] << 56;
544write16be(uint8_t *
buf, uint16_t num)
546 buf[0] = (uint8_t)(num >> 8);
547 buf[1] = (uint8_t)num;
555 buf[0] = (uint8_t)num;
556 buf[1] = (uint8_t)(num >> 8);
562write32be(uint8_t *
buf, uint32_t num)
564 buf[0] = (uint8_t)(num >> 24);
565 buf[1] = (uint8_t)(num >> 16);
566 buf[2] = (uint8_t)(num >> 8);
567 buf[3] = (uint8_t)num;
575 buf[0] = (uint8_t)num;
576 buf[1] = (uint8_t)(num >> 8);
577 buf[2] = (uint8_t)(num >> 16);
578 buf[3] = (uint8_t)(num >> 24);
584write64be(uint8_t *
buf, uint64_t num)
586 buf[0] = (uint8_t)(num >> 56);
587 buf[1] = (uint8_t)(num >> 48);
588 buf[2] = (uint8_t)(num >> 40);
589 buf[3] = (uint8_t)(num >> 32);
590 buf[4] = (uint8_t)(num >> 24);
591 buf[5] = (uint8_t)(num >> 16);
592 buf[6] = (uint8_t)(num >> 8);
593 buf[7] = (uint8_t)num;
601 buf[0] = (uint8_t)num;
602 buf[1] = (uint8_t)(num >> 8);
603 buf[2] = (uint8_t)(num >> 16);
604 buf[3] = (uint8_t)(num >> 24);
605 buf[4] = (uint8_t)(num >> 32);
606 buf[5] = (uint8_t)(num >> 40);
607 buf[6] = (uint8_t)(num >> 48);
608 buf[7] = (uint8_t)(num >> 56);
639#ifdef HAVE___BUILTIN_ASSUME_ALIGNED
640# define tuklib_memcpy_aligned(dest, src, size) \
641 memcpy(dest, __builtin_assume_aligned(src, size), size)
643# define tuklib_memcpy_aligned(dest, src, size) \
644 memcpy(dest, src, size)
645# ifndef TUKLIB_FAST_UNALIGNED_ACCESS
646# define TUKLIB_USE_UNSAFE_ALIGNED_READS 1
651static inline uint16_t
652aligned_read16ne(
const uint8_t *
buf)
654#if defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) \
655 || defined(TUKLIB_USE_UNSAFE_ALIGNED_READS)
656 return *(
const uint16_t *)
buf;
665static inline uint32_t
666aligned_read32ne(
const uint8_t *
buf)
668#if defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) \
669 || defined(TUKLIB_USE_UNSAFE_ALIGNED_READS)
670 return *(
const uint32_t *)
buf;
679static inline uint64_t
680aligned_read64ne(
const uint8_t *
buf)
682#if defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) \
683 || defined(TUKLIB_USE_UNSAFE_ALIGNED_READS)
684 return *(
const uint64_t *)
buf;
694aligned_write16ne(uint8_t *
buf, uint16_t num)
696#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING
697 *(uint16_t *)
buf = num;
706aligned_write32ne(uint8_t *
buf, uint32_t num)
708#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING
709 *(uint32_t *)
buf = num;
718aligned_write64ne(uint8_t *
buf, uint64_t num)
720#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING
721 *(uint64_t *)
buf = num;
729static inline uint16_t
730aligned_read16be(
const uint8_t *
buf)
732 uint16_t num = aligned_read16ne(
buf);
737static inline uint16_t
738aligned_read16le(
const uint8_t *
buf)
740 uint16_t num = aligned_read16ne(
buf);
745static inline uint32_t
746aligned_read32be(
const uint8_t *
buf)
748 uint32_t num = aligned_read32ne(
buf);
753static inline uint32_t
754aligned_read32le(
const uint8_t *
buf)
756 uint32_t num = aligned_read32ne(
buf);
761static inline uint64_t
762aligned_read64be(
const uint8_t *
buf)
764 uint64_t num = aligned_read64ne(
buf);
769static inline uint64_t
770aligned_read64le(
const uint8_t *
buf)
772 uint64_t num = aligned_read64ne(
buf);
778#define aligned_write16be(buf, num) aligned_write16ne((buf), conv16be(num))
779#define aligned_write16le(buf, num) aligned_write16ne((buf), conv16le(num))
780#define aligned_write32be(buf, num) aligned_write32ne((buf), conv32be(num))
781#define aligned_write32le(buf, num) aligned_write32ne((buf), conv32le(num))
782#define aligned_write64be(buf, num) aligned_write64ne((buf), conv64be(num))
783#define aligned_write64le(buf, num) aligned_write64ne((buf), conv64le(num))
790static inline uint32_t
794#if defined(__INTEL_COMPILER)
795 return _bit_scan_reverse(n);
797#elif (TUKLIB_GNUC_REQ(3, 4) || defined(__clang__)) && UINT_MAX == UINT32_MAX
802 return (uint32_t)__builtin_clz(n) ^ 31U;
804#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
806 __asm__(
"bsrl %1, %0" :
"=r" (
i) :
"rm" (n));
809#elif defined(_MSC_VER)
811 _BitScanReverse(&
i, n);
817 if ((n & 0xFFFF0000) == 0) {
822 if ((n & 0xFF000000) == 0) {
827 if ((n & 0xF0000000) == 0) {
832 if ((n & 0xC0000000) == 0) {
837 if ((n & 0x80000000) == 0)
845static inline uint32_t
848#if defined(__INTEL_COMPILER)
849 return _bit_scan_reverse(n) ^ 31U;
851#elif (TUKLIB_GNUC_REQ(3, 4) || defined(__clang__)) && UINT_MAX == UINT32_MAX
852 return (uint32_t)__builtin_clz(n);
854#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
856 __asm__(
"bsrl %1, %0\n\t"
858 :
"=r" (
i) :
"rm" (n));
861#elif defined(_MSC_VER)
863 _BitScanReverse(&
i, n);
869 if ((n & 0xFFFF0000) == 0) {
874 if ((n & 0xFF000000) == 0) {
879 if ((n & 0xF0000000) == 0) {
884 if ((n & 0xC0000000) == 0) {
889 if ((n & 0x80000000) == 0)
897static inline uint32_t
900#if defined(__INTEL_COMPILER)
901 return _bit_scan_forward(n);
903#elif (TUKLIB_GNUC_REQ(3, 4) || defined(__clang__)) && UINT_MAX >= UINT32_MAX
904 return (uint32_t)__builtin_ctz(n);
906#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
908 __asm__(
"bsfl %1, %0" :
"=r" (
i) :
"rm" (n));
911#elif defined(_MSC_VER)
913 _BitScanForward(&
i, n);
919 if ((n & 0x0000FFFF) == 0) {
924 if ((n & 0x000000FF) == 0) {
929 if ((n & 0x0000000F) == 0) {
934 if ((n & 0x00000003) == 0) {
939 if ((n & 0x00000001) == 0)
char buf[N_BUF]
Definition spewG.c:36
lzma_index ** i
Definition index.h:629
#define write64le(buf, num)
Definition tuklib_integer.h:399
#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
Common definitions for tuklib modules.
#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