xref: /freebsd-src/contrib/libpcap/extract.h (revision afdbf109c6a661a729938f68211054a0a50d38ac)
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