1ada6f083SXin LI /* 2ada6f083SXin LI * Copyright (c) 1992, 1993, 1994, 1995, 1996 3ada6f083SXin LI * The Regents of the University of California. All rights reserved. 4ada6f083SXin LI * 5ada6f083SXin LI * Redistribution and use in source and binary forms, with or without 6ada6f083SXin LI * modification, are permitted provided that: (1) source code distributions 7ada6f083SXin LI * retain the above copyright notice and this paragraph in its entirety, (2) 8ada6f083SXin LI * distributions including binary code include the above copyright notice and 9ada6f083SXin LI * this paragraph in its entirety in the documentation or other materials 10ada6f083SXin LI * provided with the distribution, and (3) all advertising materials mentioning 11ada6f083SXin LI * features or use of this software display the following acknowledgement: 12ada6f083SXin LI * ``This product includes software developed by the University of California, 13ada6f083SXin LI * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14ada6f083SXin LI * the University nor the names of its contributors may be used to endorse 15ada6f083SXin LI * or promote products derived from this software without specific prior 16ada6f083SXin LI * written permission. 17ada6f083SXin LI * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18ada6f083SXin LI * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19ada6f083SXin LI * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20ada6f083SXin LI */ 21ada6f083SXin LI 22ada6f083SXin LI #ifndef _WIN32 23ada6f083SXin LI #include <arpa/inet.h> 24ada6f083SXin LI #endif 25ada6f083SXin LI 26b00ab754SHans Petter Selasky #include <pcap/pcap-inttypes.h> 27b00ab754SHans Petter Selasky #include <pcap/compiler-tests.h> 286f9cba8fSJoseph Mingrone #include "portability.h" 29b00ab754SHans Petter Selasky 30ada6f083SXin LI /* 316f9cba8fSJoseph Mingrone * If we have versions of GCC or Clang that support an __attribute__ 326f9cba8fSJoseph Mingrone * to say "if we're building with unsigned behavior sanitization, 336f9cba8fSJoseph Mingrone * don't complain about undefined behavior in this function", we 346f9cba8fSJoseph Mingrone * label these functions with that attribute - we *know* it's undefined 356f9cba8fSJoseph Mingrone * in the C standard, but we *also* know it does what we want with 366f9cba8fSJoseph Mingrone * the ISA we're targeting and the compiler we're using. 376f9cba8fSJoseph Mingrone * 386f9cba8fSJoseph Mingrone * For GCC 4.9.0 and later, we use __attribute__((no_sanitize_undefined)); 396f9cba8fSJoseph Mingrone * pre-5.0 GCC doesn't have __has_attribute, and I'm not sure whether 406f9cba8fSJoseph Mingrone * GCC or Clang first had __attribute__((no_sanitize(XXX)). 416f9cba8fSJoseph Mingrone * 426f9cba8fSJoseph Mingrone * For Clang, we check for __attribute__((no_sanitize(XXX)) with 436f9cba8fSJoseph Mingrone * __has_attribute, as there are versions of Clang that support 446f9cba8fSJoseph Mingrone * __attribute__((no_sanitize("undefined")) but don't support 456f9cba8fSJoseph Mingrone * __attribute__((no_sanitize_undefined)). 466f9cba8fSJoseph Mingrone * 476f9cba8fSJoseph Mingrone * We define this here, rather than in funcattrs.h, because we 486f9cba8fSJoseph Mingrone * only want it used here, we don't want it to be broadly used. 496f9cba8fSJoseph Mingrone * (Any printer will get this defined, but this should at least 506f9cba8fSJoseph Mingrone * make it harder for people to find.) 51ada6f083SXin LI */ 526f9cba8fSJoseph Mingrone #if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 409) 536f9cba8fSJoseph Mingrone #define UNALIGNED_OK __attribute__((no_sanitize_undefined)) 546f9cba8fSJoseph Mingrone #elif __has_attribute(no_sanitize) 556f9cba8fSJoseph Mingrone #define UNALIGNED_OK __attribute__((no_sanitize("undefined"))) 566f9cba8fSJoseph Mingrone #else 576f9cba8fSJoseph Mingrone #define UNALIGNED_OK 586f9cba8fSJoseph Mingrone #endif 596f9cba8fSJoseph Mingrone 606f9cba8fSJoseph Mingrone #if (defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(__x86_64__) || defined(_M_X64)) || \ 616f9cba8fSJoseph Mingrone (defined(__m68k__) && (!defined(__mc68000__) && !defined(__mc68010__))) || \ 626f9cba8fSJoseph Mingrone (defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)) || \ 636f9cba8fSJoseph Mingrone (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) 64ada6f083SXin LI /* 656f9cba8fSJoseph Mingrone * The processor natively handles unaligned loads, so we can just 666f9cba8fSJoseph Mingrone * cast the pointer and fetch through it. 676f9cba8fSJoseph Mingrone * 686f9cba8fSJoseph Mingrone * XXX - are those all the x86 tests we need? 696f9cba8fSJoseph Mingrone * XXX - are those the only 68k tests we need not to generated 706f9cba8fSJoseph Mingrone * unaligned accesses if the target is the 68000 or 68010? 716f9cba8fSJoseph Mingrone * XXX - are there any tests we don't need, because some definitions are for 726f9cba8fSJoseph Mingrone * compilers that also predefine the GCC symbols? 736f9cba8fSJoseph Mingrone * XXX - do we need to test for both 32-bit and 64-bit versions of those 746f9cba8fSJoseph Mingrone * architectures in all cases? 75ada6f083SXin LI */ 766f9cba8fSJoseph Mingrone UNALIGNED_OK static inline uint16_t 776f9cba8fSJoseph Mingrone EXTRACT_BE_U_2(const void *p) 786f9cba8fSJoseph Mingrone { 796f9cba8fSJoseph Mingrone return ((uint16_t)ntohs(*(const uint16_t *)(p))); 806f9cba8fSJoseph Mingrone } 816f9cba8fSJoseph Mingrone 826f9cba8fSJoseph Mingrone UNALIGNED_OK static inline int16_t 836f9cba8fSJoseph Mingrone EXTRACT_BE_S_2(const void *p) 846f9cba8fSJoseph Mingrone { 856f9cba8fSJoseph Mingrone return ((int16_t)ntohs(*(const int16_t *)(p))); 866f9cba8fSJoseph Mingrone } 876f9cba8fSJoseph Mingrone 886f9cba8fSJoseph Mingrone UNALIGNED_OK static inline uint32_t 896f9cba8fSJoseph Mingrone EXTRACT_BE_U_4(const void *p) 906f9cba8fSJoseph Mingrone { 916f9cba8fSJoseph Mingrone return ((uint32_t)ntohl(*(const uint32_t *)(p))); 926f9cba8fSJoseph Mingrone } 936f9cba8fSJoseph Mingrone 946f9cba8fSJoseph Mingrone UNALIGNED_OK static inline int32_t 956f9cba8fSJoseph Mingrone EXTRACT_BE_S_4(const void *p) 966f9cba8fSJoseph Mingrone { 976f9cba8fSJoseph Mingrone return ((int32_t)ntohl(*(const int32_t *)(p))); 986f9cba8fSJoseph Mingrone } 996f9cba8fSJoseph Mingrone 1006f9cba8fSJoseph Mingrone UNALIGNED_OK static inline uint64_t 1016f9cba8fSJoseph Mingrone EXTRACT_BE_U_8(const void *p) 1026f9cba8fSJoseph Mingrone { 1036f9cba8fSJoseph Mingrone return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | 1046f9cba8fSJoseph Mingrone ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0)); 1056f9cba8fSJoseph Mingrone 1066f9cba8fSJoseph Mingrone } 1076f9cba8fSJoseph Mingrone 1086f9cba8fSJoseph Mingrone UNALIGNED_OK static inline int64_t 1096f9cba8fSJoseph Mingrone EXTRACT_BE_S_8(const void *p) 1106f9cba8fSJoseph Mingrone { 1116f9cba8fSJoseph Mingrone return ((int64_t)(((int64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | 1126f9cba8fSJoseph Mingrone ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0)); 1136f9cba8fSJoseph Mingrone 1146f9cba8fSJoseph Mingrone } 1156f9cba8fSJoseph Mingrone #elif PCAP_IS_AT_LEAST_GNUC_VERSION(2,0) && \ 116ada6f083SXin LI (defined(__alpha) || defined(__alpha__) || \ 117ada6f083SXin LI defined(__mips) || defined(__mips__)) 118ada6f083SXin LI /* 119b00ab754SHans Petter Selasky * This is MIPS or Alpha, which don't natively handle unaligned loads, 120b00ab754SHans Petter Selasky * but which have instructions that can help when doing unaligned 121b00ab754SHans Petter Selasky * loads, and this is GCC 2.0 or later or a compiler that claims to 122b00ab754SHans Petter Selasky * be GCC 2.0 or later, which we assume that mean we have 123b00ab754SHans Petter Selasky * __attribute__((packed)), which we can use to convince the compiler 124b00ab754SHans Petter Selasky * to generate those instructions. 125ada6f083SXin LI * 126ada6f083SXin LI * Declare packed structures containing a uint16_t and a uint32_t, 127ada6f083SXin LI * cast the pointer to point to one of those, and fetch through it; 128ada6f083SXin LI * the GCC manual doesn't appear to explicitly say that 129ada6f083SXin LI * __attribute__((packed)) causes the compiler to generate unaligned-safe 1306f9cba8fSJoseph Mingrone * code, but it appears to do so. 131ada6f083SXin LI * 132ada6f083SXin LI * We do this in case the compiler can generate code using those 133ada6f083SXin LI * instructions to do an unaligned load and pass stuff to "ntohs()" or 1346f9cba8fSJoseph Mingrone * "ntohl()", which might be better than the code to fetch the 135ada6f083SXin LI * bytes one at a time and assemble them. (That might not be the 136ada6f083SXin LI * case on a little-endian platform, such as DEC's MIPS machines and 137ada6f083SXin LI * Alpha machines, where "ntohs()" and "ntohl()" might not be done 138ada6f083SXin LI * inline.) 139ada6f083SXin LI * 140ada6f083SXin LI * We do this only for specific architectures because, for example, 141ada6f083SXin LI * at least some versions of GCC, when compiling for 64-bit SPARC, 142ada6f083SXin LI * generate code that assumes alignment if we do this. 143ada6f083SXin LI * 144ada6f083SXin LI * XXX - add other architectures and compilers as possible and 145ada6f083SXin LI * appropriate. 146ada6f083SXin LI * 147ada6f083SXin LI * HP's C compiler, indicated by __HP_cc being defined, supports 148ada6f083SXin LI * "#pragma unaligned N" in version A.05.50 and later, where "N" 149ada6f083SXin LI * specifies a number of bytes at which the typedef on the next 150ada6f083SXin LI * line is aligned, e.g. 151ada6f083SXin LI * 152ada6f083SXin LI * #pragma unalign 1 153ada6f083SXin LI * typedef uint16_t unaligned_uint16_t; 154ada6f083SXin LI * 155ada6f083SXin LI * to define unaligned_uint16_t as a 16-bit unaligned data type. 156ada6f083SXin LI * This could be presumably used, in sufficiently recent versions of 157ada6f083SXin LI * the compiler, with macros similar to those below. This would be 158ada6f083SXin LI * useful only if that compiler could generate better code for PA-RISC 159ada6f083SXin LI * or Itanium than would be generated by a bunch of shifts-and-ORs. 160ada6f083SXin LI * 161ada6f083SXin LI * DEC C, indicated by __DECC being defined, has, at least on Alpha, 162ada6f083SXin LI * an __unaligned qualifier that can be applied to pointers to get the 163ada6f083SXin LI * compiler to generate code that does unaligned loads and stores when 164ada6f083SXin LI * dereferencing the pointer in question. 165ada6f083SXin LI * 166ada6f083SXin LI * XXX - what if the native C compiler doesn't support 167ada6f083SXin LI * __attribute__((packed))? How can we get it to generate unaligned 168ada6f083SXin LI * accesses for *specific* items? 169ada6f083SXin LI */ 170ada6f083SXin LI typedef struct { 171ada6f083SXin LI uint16_t val; 172ada6f083SXin LI } __attribute__((packed)) unaligned_uint16_t; 173ada6f083SXin LI 174ada6f083SXin LI typedef struct { 1756f9cba8fSJoseph Mingrone int16_t val; 1766f9cba8fSJoseph Mingrone } __attribute__((packed)) unaligned_int16_t; 1776f9cba8fSJoseph Mingrone 1786f9cba8fSJoseph Mingrone typedef struct { 179ada6f083SXin LI uint32_t val; 180ada6f083SXin LI } __attribute__((packed)) unaligned_uint32_t; 181ada6f083SXin LI 1826f9cba8fSJoseph Mingrone typedef struct { 1836f9cba8fSJoseph Mingrone int32_t val; 1846f9cba8fSJoseph Mingrone } __attribute__((packed)) unaligned_int32_t; 1856f9cba8fSJoseph Mingrone 1866f9cba8fSJoseph Mingrone UNALIGNED_OK static inline uint16_t 1876f9cba8fSJoseph Mingrone EXTRACT_BE_U_2(const void *p) 188ada6f083SXin LI { 189ada6f083SXin LI return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val)); 190ada6f083SXin LI } 191ada6f083SXin LI 1926f9cba8fSJoseph Mingrone UNALIGNED_OK static inline int16_t 1936f9cba8fSJoseph Mingrone EXTRACT_BE_S_2(const void *p) 1946f9cba8fSJoseph Mingrone { 1956f9cba8fSJoseph Mingrone return ((int16_t)ntohs(((const unaligned_int16_t *)(p))->val)); 1966f9cba8fSJoseph Mingrone } 1976f9cba8fSJoseph Mingrone 1986f9cba8fSJoseph Mingrone UNALIGNED_OK static inline uint32_t 1996f9cba8fSJoseph Mingrone EXTRACT_BE_U_4(const void *p) 200ada6f083SXin LI { 201ada6f083SXin LI return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val)); 202ada6f083SXin LI } 203ada6f083SXin LI 2046f9cba8fSJoseph Mingrone UNALIGNED_OK static inline int32_t 2056f9cba8fSJoseph Mingrone EXTRACT_BE_S_4(const void *p) 206ada6f083SXin LI { 2076f9cba8fSJoseph Mingrone return ((int32_t)ntohl(((const unaligned_int32_t *)(p))->val)); 2086f9cba8fSJoseph Mingrone } 2096f9cba8fSJoseph Mingrone 2106f9cba8fSJoseph Mingrone UNALIGNED_OK static inline uint64_t 2116f9cba8fSJoseph Mingrone EXTRACT_BE_U_8(const void *p) 2126f9cba8fSJoseph Mingrone { 2136f9cba8fSJoseph Mingrone return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | 214ada6f083SXin LI ((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0)); 215ada6f083SXin LI } 216ada6f083SXin LI 2176f9cba8fSJoseph Mingrone UNALIGNED_OK static inline int64_t 2186f9cba8fSJoseph Mingrone EXTRACT_BE_S_8(const void *p) 2196f9cba8fSJoseph Mingrone { 2206f9cba8fSJoseph Mingrone return ((int64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | 2216f9cba8fSJoseph Mingrone ((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0)); 2226f9cba8fSJoseph Mingrone } 2236f9cba8fSJoseph Mingrone #else 224ada6f083SXin LI /* 2256f9cba8fSJoseph Mingrone * This architecture doesn't natively support unaligned loads, and either 2266f9cba8fSJoseph Mingrone * this isn't a GCC-compatible compiler, we don't have __attribute__, 227ada6f083SXin LI * or we do but we don't know of any better way with this instruction 228ada6f083SXin LI * set to do unaligned loads, so do unaligned loads of big-endian 229ada6f083SXin LI * quantities the hard way - fetch the bytes one at a time and 230ada6f083SXin LI * assemble them. 2316f9cba8fSJoseph Mingrone * 232*afdbf109SJoseph Mingrone * XXX - ARM is a special case. ARMv1 through ARMv5 didn't support 2336f9cba8fSJoseph Mingrone * unaligned loads; ARMv6 and later support it *but* have a bit in 2346f9cba8fSJoseph Mingrone * the system control register that the OS can set and that causes 2356f9cba8fSJoseph Mingrone * unaligned loads to fault rather than succeeding. 2366f9cba8fSJoseph Mingrone * 2376f9cba8fSJoseph Mingrone * At least some OSes may set that flag, so we do *not* treat ARM 2386f9cba8fSJoseph Mingrone * as supporting unaligned loads. If your OS supports them on ARM, 2396f9cba8fSJoseph Mingrone * and you want to use them, please update the tests in the #if above 2406f9cba8fSJoseph Mingrone * to check for ARM *and* for your OS. 241ada6f083SXin LI */ 2426f9cba8fSJoseph Mingrone #define EXTRACT_BE_U_2(p) \ 243ada6f083SXin LI ((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \ 244ada6f083SXin LI ((uint16_t)(*((const uint8_t *)(p) + 1)) << 0))) 2456f9cba8fSJoseph Mingrone #define EXTRACT_BE_S_2(p) \ 2466f9cba8fSJoseph Mingrone ((int16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \ 2476f9cba8fSJoseph Mingrone ((uint16_t)(*((const uint8_t *)(p) + 1)) << 0))) 2486f9cba8fSJoseph Mingrone #define EXTRACT_BE_U_4(p) \ 249ada6f083SXin LI ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \ 250ada6f083SXin LI ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \ 251ada6f083SXin LI ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \ 252ada6f083SXin LI ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0))) 2536f9cba8fSJoseph Mingrone #define EXTRACT_BE_S_4(p) \ 2546f9cba8fSJoseph Mingrone ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \ 2556f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \ 2566f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \ 2576f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0))) 2586f9cba8fSJoseph Mingrone #define EXTRACT_BE_U_8(p) \ 259ada6f083SXin LI ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \ 260ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \ 261ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \ 262ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 3)) << 32) | \ 263ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 4)) << 24) | \ 264ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \ 265ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \ 266ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 7)) << 0))) 2676f9cba8fSJoseph Mingrone #define EXTRACT_BE_S_8(p) \ 2686f9cba8fSJoseph Mingrone ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \ 2696f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \ 2706f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \ 2716f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 3)) << 32) | \ 2726f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 4)) << 24) | \ 2736f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \ 2746f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \ 2756f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 7)) << 0))) 2766f9cba8fSJoseph Mingrone 277ada6f083SXin LI /* 2786f9cba8fSJoseph Mingrone * Extract an IPv4 address, which is in network byte order, and not 2796f9cba8fSJoseph Mingrone * necessarily aligned, and provide the result in host byte order. 280ada6f083SXin LI */ 2816f9cba8fSJoseph Mingrone #define EXTRACT_IPV4_TO_HOST_ORDER(p) \ 2826f9cba8fSJoseph Mingrone ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \ 2836f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \ 2846f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \ 2856f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0))) 2866f9cba8fSJoseph Mingrone #endif /* unaligned access checks */ 287ada6f083SXin LI 2886f9cba8fSJoseph Mingrone /* 2896f9cba8fSJoseph Mingrone * Non-power-of-2 sizes. 2906f9cba8fSJoseph Mingrone */ 2916f9cba8fSJoseph Mingrone #define EXTRACT_BE_U_3(p) \ 292ada6f083SXin LI ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \ 293ada6f083SXin LI ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 294ada6f083SXin LI ((uint32_t)(*((const uint8_t *)(p) + 2)) << 0))) 295ada6f083SXin LI 2966f9cba8fSJoseph Mingrone #define EXTRACT_BE_S_3(p) \ 2976f9cba8fSJoseph Mingrone (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ 2986f9cba8fSJoseph Mingrone ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \ 2996f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 3006f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 2)) << 0))) : \ 3016f9cba8fSJoseph Mingrone ((int32_t)(0xFF000000U | \ 3026f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \ 3036f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 3046f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 2)) << 0)))) 3056f9cba8fSJoseph Mingrone 3066f9cba8fSJoseph Mingrone #define EXTRACT_BE_U_5(p) \ 307ada6f083SXin LI ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \ 308ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \ 309ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 310ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \ 311ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 4)) << 0))) 312ada6f083SXin LI 3136f9cba8fSJoseph Mingrone #define EXTRACT_BE_S_5(p) \ 3146f9cba8fSJoseph Mingrone (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ 3156f9cba8fSJoseph Mingrone ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \ 3166f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \ 3176f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 3186f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \ 3196f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 4)) << 0))) : \ 3206f9cba8fSJoseph Mingrone ((int64_t)(INT64_T_CONSTANT(0xFFFFFF0000000000U) | \ 3216f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \ 3226f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \ 3236f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 3246f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \ 3256f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 4)) << 0)))) 3266f9cba8fSJoseph Mingrone 3276f9cba8fSJoseph Mingrone #define EXTRACT_BE_U_6(p) \ 328ada6f083SXin LI ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \ 329ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \ 330ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \ 331ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \ 332ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \ 333ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 5)) << 0))) 334ada6f083SXin LI 3356f9cba8fSJoseph Mingrone #define EXTRACT_BE_S_6(p) \ 3366f9cba8fSJoseph Mingrone (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ 3376f9cba8fSJoseph Mingrone ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \ 3386f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \ 3396f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \ 3406f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \ 3416f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \ 3426f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 5)) << 0))) : \ 3436f9cba8fSJoseph Mingrone ((int64_t)(INT64_T_CONSTANT(0xFFFFFFFF00000000U) | \ 3446f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \ 3456f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \ 3466f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \ 3476f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \ 3486f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \ 3496f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 5)) << 0)))) 3506f9cba8fSJoseph Mingrone 3516f9cba8fSJoseph Mingrone #define EXTRACT_BE_U_7(p) \ 352ada6f083SXin LI ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \ 353ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \ 354ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \ 355ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 356ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \ 357ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \ 358ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 6)) << 0))) 359ada6f083SXin LI 3606f9cba8fSJoseph Mingrone #define EXTRACT_BE_S_7(p) \ 3616f9cba8fSJoseph Mingrone (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ 3626f9cba8fSJoseph Mingrone ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \ 3636f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \ 3646f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \ 3656f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 3666f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \ 3676f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \ 3686f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 6)) << 0))) : \ 3696f9cba8fSJoseph Mingrone ((int64_t)(INT64_T_CONSTANT(0xFFFFFFFFFF000000U) | \ 3706f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \ 3716f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \ 3726f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \ 3736f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 3746f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \ 3756f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \ 3766f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 6)) << 0)))) 3776f9cba8fSJoseph Mingrone 378ada6f083SXin LI /* 379ada6f083SXin LI * Macros to extract possibly-unaligned little-endian integral values. 380ada6f083SXin LI * XXX - do loads on little-endian machines that support unaligned loads? 381ada6f083SXin LI */ 3826f9cba8fSJoseph Mingrone #define EXTRACT_LE_U_2(p) \ 383ada6f083SXin LI ((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 384ada6f083SXin LI ((uint16_t)(*((const uint8_t *)(p) + 0)) << 0))) 3856f9cba8fSJoseph Mingrone #define EXTRACT_LE_S_2(p) \ 3866f9cba8fSJoseph Mingrone ((int16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 3876f9cba8fSJoseph Mingrone ((uint16_t)(*((const uint8_t *)(p) + 0)) << 0))) 3886f9cba8fSJoseph Mingrone #define EXTRACT_LE_U_4(p) \ 389ada6f083SXin LI ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 390ada6f083SXin LI ((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 391ada6f083SXin LI ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 392ada6f083SXin LI ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) 3936f9cba8fSJoseph Mingrone #define EXTRACT_LE_S_4(p) \ 3946f9cba8fSJoseph Mingrone ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 3956f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 3966f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 3976f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) 3986f9cba8fSJoseph Mingrone #define EXTRACT_LE_U_3(p) \ 399ada6f083SXin LI ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 400ada6f083SXin LI ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 401ada6f083SXin LI ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) 4026f9cba8fSJoseph Mingrone #define EXTRACT_LE_S_3(p) \ 4036f9cba8fSJoseph Mingrone ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 4046f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 4056f9cba8fSJoseph Mingrone ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) 4066f9cba8fSJoseph Mingrone #define EXTRACT_LE_U_8(p) \ 407ada6f083SXin LI ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \ 408ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \ 409ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \ 410ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \ 411ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 412ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 413ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 414ada6f083SXin LI ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) 4156f9cba8fSJoseph Mingrone #define EXTRACT_LE_S_8(p) \ 4166f9cba8fSJoseph Mingrone ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \ 4176f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \ 4186f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \ 4196f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \ 4206f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 4216f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 4226f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 4236f9cba8fSJoseph Mingrone ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) 424