Initial import of libdpf.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
commit
e4e666f459
4563 changed files with 1690372 additions and 0 deletions
107
thirdparty/portable-snippets/unaligned/README.md
vendored
Normal file
107
thirdparty/portable-snippets/unaligned/README.md
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
# Unaligned Loads and Stores
|
||||
|
||||
**WARNING**: This module is work-in-progress, and not yet ready for
|
||||
widespread adoption. Testing, however, would be greatly appreciated.
|
||||
|
||||
This header provides fast load/store operations.
|
||||
|
||||
## Rationale
|
||||
|
||||
Yann Collet wrote a [great blog
|
||||
post](https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html)
|
||||
about accessing unaligned memory a while back which is well worth a
|
||||
read. Basically, there are a few different methods to access
|
||||
unaligned memory, with different performance implications. `memcpy`
|
||||
is safe, but slow on some compilers. Other methods rely on undefined
|
||||
behavior which may or may not be safe depending on the compiler and
|
||||
platform, and/or compiler-specific constructs.
|
||||
|
||||
It's important to note that, if you rely on undefined behavior,
|
||||
compilers which currently work may stop working in the future when
|
||||
optimizations are added. For example, unaligned accesses are usually
|
||||
allowed on x86, but not for some SIMD instructions. GCC 4.9 added an
|
||||
optimization which automatically vectorized some code in LZ4, and
|
||||
since LZ4 (at the time) relied on unaligned accesses that change broke
|
||||
LZ4.
|
||||
|
||||
The biggest value of this module is the logic to determine which
|
||||
method to use on different combinations of compilers, compiler
|
||||
versions, and architectures.
|
||||
|
||||
## Usage
|
||||
|
||||
`unaligned.h` defines macros which can be used to generate inline
|
||||
functions for whatever types you want. For example, to generate
|
||||
functions for `int`:
|
||||
|
||||
```c
|
||||
PSNIP_UNALIGNED_LOAD_DEFINE(foo_load, int)
|
||||
PSNIP_UNALIGNED_STORE_DEFINE(foo_store, int)
|
||||
```
|
||||
|
||||
Would yield functions which look something like:
|
||||
|
||||
```c
|
||||
int foo_load(const void* src);
|
||||
void foo_store(void* dest, int src);
|
||||
```
|
||||
|
||||
By default, we will use `memcpy` as it's the only completely safe
|
||||
option. However, if you define `PSNIP_UNALIGNED_ALLOW_UNDEFINED`
|
||||
prior to including `unaligned.h` it will check for platforms where
|
||||
unaligned accesses are safe and faster than `memcpy()`. On such
|
||||
platforms, access may be done through either a cast & dereference or
|
||||
through a packed union.
|
||||
|
||||
If you include `exact-int.h` before including `unaligned.h` (or define
|
||||
the exact-width types yourself), we will also define functions to
|
||||
load/store to/from those types:
|
||||
|
||||
```c
|
||||
psnip_int16_t psnip_unaligned_load_int16 (const void* src);
|
||||
psnip_int32_t psnip_unaligned_load_int32 (const void* src);
|
||||
psnip_int64_t psnip_unaligned_load_int64 (const void* src);
|
||||
psnip_uint16_t psnip_unaligned_load_uint16 (const void* src);
|
||||
psnip_uint32_t psnip_unaligned_load_uint32 (const void* src);
|
||||
psnip_uint64_t psnip_unaligned_load_uint64 (const void* src);
|
||||
void psnip_unaligned_store_int16 (void* dest, int16_t src);
|
||||
void psnip_unaligned_store_int32 (void* dest, int32_t src);
|
||||
void psnip_unaligned_store_int64 (void* dest, int64_t src);
|
||||
void psnip_unaligned_store_uint16(void* dest, uint16_t src);
|
||||
void psnip_unaligned_store_uint32(void* dest, uint32_t src);
|
||||
void psnip_unaligned_store_uint64(void* dest, uint64_t src);
|
||||
```
|
||||
|
||||
If you also include `endian.h` before including `unaligned.h`, we will
|
||||
also define macros to load/store different-endian values to/from
|
||||
the exact-width types:
|
||||
|
||||
```c
|
||||
psnip_int16_t psnip_unaligned_load_int16le (const void* src);
|
||||
psnip_int32_t psnip_unaligned_load_int32le (const void* src);
|
||||
psnip_int64_t psnip_unaligned_load_int64le (const void* src);
|
||||
psnip_int16_t psnip_unaligned_load_int16be (const void* src);
|
||||
psnip_int32_t psnip_unaligned_load_int32be (const void* src);
|
||||
psnip_int64_t psnip_unaligned_load_int64be (const void* src);
|
||||
psnip_uint16_t psnip_unaligned_load_uint16le (const void* src);
|
||||
psnip_uint32_t psnip_unaligned_load_uint32le (const void* src);
|
||||
psnip_uint64_t psnip_unaligned_load_uint64le (const void* src);
|
||||
psnip_uint16_t psnip_unaligned_load_uint16be (const void* src);
|
||||
psnip_uint32_t psnip_unaligned_load_uint32be (const void* src);
|
||||
psnip_uint64_t psnip_unaligned_load_uint64be (const void* src);
|
||||
void psnip_unaligned_store_int16le (void* dest, psnip_int16_t src);
|
||||
void psnip_unaligned_store_int32le (void* dest, psnip_int32_t src);
|
||||
void psnip_unaligned_store_int64le (void* dest, psnip_int64_t src);
|
||||
void psnip_unaligned_store_int16be (void* dest, psnip_int16_t src);
|
||||
void psnip_unaligned_store_int32be (void* dest, psnip_int32_t src);
|
||||
void psnip_unaligned_store_int64be (void* dest, psnip_int64_t src);
|
||||
void psnip_unaligned_store_uint16le(void* dest, psnip_int16_t src);
|
||||
void psnip_unaligned_store_uint32le(void* dest, psnip_int32_t src);
|
||||
void psnip_unaligned_store_uint64le(void* dest, psnip_int64_t src);
|
||||
void psnip_unaligned_store_uint16be(void* dest, psnip_int16_t src);
|
||||
void psnip_unaligned_store_uint32be(void* dest, psnip_int32_t src);
|
||||
void psnip_unaligned_store_uint64be(void* dest, psnip_int64_t src);
|
||||
```
|
||||
|
||||
These are implemented as macros, the prototypes above are purely for
|
||||
documentation.
|
||||
230
thirdparty/portable-snippets/unaligned/unaligned.h
vendored
Normal file
230
thirdparty/portable-snippets/unaligned/unaligned.h
vendored
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
/* Unaligned operations (v1)
|
||||
* Portable Snippets - https://github.com/nemequ/portable-snippets
|
||||
* Created by Evan Nemerson <evan@nemerson.com>
|
||||
*
|
||||
* To the extent possible under law, the authors have waived all
|
||||
* copyright and related or neighboring rights to this code. For
|
||||
* details, see the Creative Commons Zero 1.0 Universal license at
|
||||
* https://creativecommons.org/publicdomain/zero/1.0/
|
||||
*
|
||||
* Most architectures allow unaligned access to some degree, but
|
||||
* according to the C specification unaligned accesses are undefined
|
||||
* behavior. The portable thing to do is use memcpy(), but depending
|
||||
* on the architecture and compiler that may be slower than either
|
||||
* dereferencing a pointer or using a union.
|
||||
*
|
||||
* If you define PSNIP_UNALIGNED_ALLOW_UNDEFINED prior to including
|
||||
* this header, it will try to implement the fastest method which is
|
||||
* known to work given the architecture and compiler.
|
||||
*
|
||||
* Some of the tests are taken from zstd; Yann Collet has done some
|
||||
* great work benchmarking different methods on different
|
||||
* architectures.
|
||||
*/
|
||||
|
||||
#if !defined(PSNIP_UNALIGNED_H)
|
||||
#define PSNIP_UNALIGNED_H
|
||||
|
||||
#define PSNIP_UNALIGNED_IMPL_MEMCPY 1
|
||||
#define PSNIP_UNALIGNED_IMPL_DEREF 2
|
||||
#define PSNIP_UNALIGNED_IMPL_UNION 3
|
||||
|
||||
#if defined(PSNIP_UNALIGNED_IMPL)
|
||||
# if (PSNIP_UNALIGNED_IMPL < 1) || (PSNIP_UNALIGNED_IMPL > 3)
|
||||
# error Unsupported unaligned access method requested.
|
||||
# endif
|
||||
#elif !defined(PSNIP_UNALIGNED_ALLOW_UNDEFINED)
|
||||
# define PSNIP_UNALIGNED_IMPL PSNIP_UNALIGNED_IMPL_MEMCPY
|
||||
#elif defined(__INTEL_COMPILER)
|
||||
# define PSNIP_UNALIGNED_IMPL PSNIP_UNALIGNED_IMPL_UNION
|
||||
#elif defined(__GNUC__)
|
||||
# if (__GNUC__ >= 6)
|
||||
# define PSNIP_UNALIGNED_IMPL PSNIP_UNALIGNED_IMPL_MEMCPY
|
||||
# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
|
||||
# define PSNIP_UNALIGNED_IMPL PSNIP_UNALIGNED_IMPL_UNION
|
||||
# elif (defined(__amd64) || defined(__i386))
|
||||
# if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
|
||||
# define PSNIP_UNALIGNED_IMPL PSNIP_UNALIGNED_IMPL_MEMCPY
|
||||
# else
|
||||
# define PSNIP_UNALIGNED_IMPL PSNIP_UNALIGNED_IMPL_DEREF
|
||||
# endif
|
||||
# elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
|
||||
# define PSNIP_UNALIGNED_IMPL PSNIP_UNALIGNED_IMPL_DEREF
|
||||
# else
|
||||
# define PSNIP_UNALIGNED_IMPL PSNIP_UNALIGNED_IMPL_MEMCPY
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(PSNIP_UNALIGNED_IMPL)
|
||||
# define PSNIP_UNALIGNED_IMPL PSNIP_UNALIGNED_IMPL_MEMCPY
|
||||
#endif
|
||||
|
||||
#if !defined(PSNIP_UNALIGNED_STATIC_INLINE)
|
||||
# if defined(__GNUC__)
|
||||
# define PSNIP_UNALIGNED__COMPILER_ATTRIBUTES __attribute__((__unused__))
|
||||
# else
|
||||
# define PSNIP_UNALIGNED__COMPILER_ATTRIBUTES
|
||||
# endif
|
||||
|
||||
# if defined(HEDLEY_ALWAYS_INLINE)
|
||||
# define PSNIP_UNALIGNED__INLINE HEDLEY_ALWAYS_INLINE
|
||||
# elif defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
# define PSNIP_UNALIGNED__INLINE __attribute__((__always_inline__,__gnu_inline__)) inline
|
||||
# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
# define PSNIP_UNALIGNED__INLINE inline
|
||||
# elif defined(__GNUC_STDC_INLINE__)
|
||||
# define PSNIP_UNALIGNED__INLINE __inline__
|
||||
# elif defined(_MSC_VER) && _MSC_VER >= 1200
|
||||
# define PSNIP_UNALIGNED__INLINE __inline
|
||||
# else
|
||||
# define PSNIP_UNALIGNED__INLINE
|
||||
# endif
|
||||
|
||||
# define PSNIP_UNALIGNED__FUNCTION PSNIP_UNALIGNED__COMPILER_ATTRIBUTES static PSNIP_UNALIGNED__INLINE
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(PSNIP_UNALIGNED_ALLOW_UBSAN)
|
||||
# if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
|
||||
# define PSNIP_UNALIGNED__NO_UBSAN __attribute__((__no_sanitize_undefined__))
|
||||
# elif defined(__clang__) && defined(__has_attribute)
|
||||
# if __has_attribute(no_sanitize)
|
||||
# define PSNIP_UNALIGNED__NO_UBSAN __attribute__((no_sanitize("undefined")))
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(PSNIP_UNALIGNED__NO_UBSAN)
|
||||
# define PSNIP_UNALIGNED__NO_UBSAN
|
||||
#endif
|
||||
|
||||
/* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/4972.html */
|
||||
#if defined(__CC_ARM)
|
||||
# define PSNIP_UNALIGNED__PACKED __packed
|
||||
#else
|
||||
# define PSNIP_UNALIGNED__PACKED
|
||||
#endif
|
||||
|
||||
#if PSNIP_UNALIGNED_IMPL == PSNIP_UNALIGNED_IMPL_MEMCPY
|
||||
# include <string.h>
|
||||
# define PSNIP_UNALIGNED_LOAD_DEFINE(name, T) \
|
||||
PSNIP_UNALIGNED__FUNCTION \
|
||||
T name(const void* src) { \
|
||||
T r; \
|
||||
memcpy(&r, (PSNIP_UNALIGNED__PACKED const void*) src, sizeof(T)); \
|
||||
return r; \
|
||||
}
|
||||
# define PSNIP_UNALIGNED_STORE_DEFINE(name, T) \
|
||||
PSNIP_UNALIGNED__FUNCTION \
|
||||
void name(void* dest, T src) { \
|
||||
memcpy((PSNIP_UNALIGNED__PACKED void*) &dest, &src, sizeof(T)); \
|
||||
}
|
||||
#elif PSNIP_UNALIGNED_IMPL == PSNIP_UNALIGNED_IMPL_DEREF
|
||||
# if defined(__cplusplus)
|
||||
# define PSNIP_UNALIGNED_LOAD_DEFINE(name, T) \
|
||||
PSNIP_UNALIGNED__FUNCTION \
|
||||
PSNIP_UNALIGNED__NO_UBSAN \
|
||||
T name(const void* src) { \
|
||||
return *static_cast<PSNIP_UNALIGNED__PACKED const T*>(src); \
|
||||
}
|
||||
# define PSNIP_UNALIGNED_STORE_DEFINE(name, T) \
|
||||
PSNIP_UNALIGNED__FUNCTION \
|
||||
PSNIP_UNALIGNED__NO_UBSAN \
|
||||
void name(void* dest, T src) { \
|
||||
*(static_cast<PSNIP_UNALIGNED__PACKED T*>(dest)) = src; \
|
||||
}
|
||||
# else
|
||||
# define PSNIP_UNALIGNED_LOAD_DEFINE(name, T) \
|
||||
PSNIP_UNALIGNED__FUNCTION \
|
||||
PSNIP_UNALIGNED__NO_UBSAN \
|
||||
T name(const void* src) { \
|
||||
return *((PSNIP_UNALIGNED__PACKED T*) src); \
|
||||
}
|
||||
# define PSNIP_UNALIGNED_STORE_DEFINE(name, T) \
|
||||
PSNIP_UNALIGNED__FUNCTION \
|
||||
PSNIP_UNALIGNED__NO_UBSAN \
|
||||
void name(void* dest, T src) { \
|
||||
*((PSNIP_UNALIGNED__PACKED T*) dest) = src; \
|
||||
}
|
||||
# endif
|
||||
#elif PSNIP_UNALIGNED_IMPL == PSNIP_UNALIGNED_IMPL_UNION
|
||||
# if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32))
|
||||
# define PSNIP_UNALIGNED__UNION_T(T) \
|
||||
__pragma(pack(push, 1)) \
|
||||
union { psnip_int64_t v; char a[sizeof(psnip_int64_t)]; } \
|
||||
__pragma(pack(pop))
|
||||
# else
|
||||
# define PSNIP_UNALIGNED__UNION_T(T) \
|
||||
union { psnip_int64_t v; char a[sizeof(psnip_int64_t)]; } \
|
||||
__attribute__((packed))
|
||||
# endif
|
||||
# define PSNIP_UNALIGNED_LOAD_DEFINE(name, T) \
|
||||
PSNIP_UNALIGNED__FUNCTION \
|
||||
T name(const void* src) { \
|
||||
return ((PSNIP_UNALIGNED__UNION_T(T) *) src)->v; \
|
||||
}
|
||||
# define PSNIP_UNALIGNED_STORE_DEFINE(name, T) \
|
||||
PSNIP_UNALIGNED__FUNCTION \
|
||||
void name(void* dest, T src) { \
|
||||
((PSNIP_UNALIGNED__UNION_T(T) *) dest)->v = src; \
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If we've already included exact-int.h (or defined the relevant
|
||||
types), we'll set up functions for those types */
|
||||
|
||||
#if defined(psnip_int16_t)
|
||||
PSNIP_UNALIGNED_LOAD_DEFINE(psnip_unaligned_load_int16, psnip_int16_t)
|
||||
PSNIP_UNALIGNED_STORE_DEFINE(psnip_unaligned_store_int16, psnip_int16_t)
|
||||
#endif
|
||||
#if defined(psnip_uint16_t)
|
||||
PSNIP_UNALIGNED_LOAD_DEFINE(psnip_unaligned_load_uint16, psnip_uint16_t)
|
||||
PSNIP_UNALIGNED_STORE_DEFINE(psnip_unaligned_store_uint16, psnip_uint16_t)
|
||||
#endif
|
||||
#if defined(psnip_int32_t)
|
||||
PSNIP_UNALIGNED_LOAD_DEFINE(psnip_unaligned_load_int32, psnip_int32_t)
|
||||
PSNIP_UNALIGNED_STORE_DEFINE(psnip_unaligned_store_int32, psnip_int32_t)
|
||||
#endif
|
||||
#if defined(psnip_uint32_t)
|
||||
PSNIP_UNALIGNED_LOAD_DEFINE(psnip_unaligned_load_uint32, psnip_uint32_t)
|
||||
PSNIP_UNALIGNED_STORE_DEFINE(psnip_unaligned_store_uint32, psnip_uint32_t)
|
||||
#endif
|
||||
#if defined(psnip_int64_t)
|
||||
PSNIP_UNALIGNED_LOAD_DEFINE(psnip_unaligned_load_int64, psnip_int64_t)
|
||||
PSNIP_UNALIGNED_STORE_DEFINE(psnip_unaligned_store_int64, psnip_int64_t)
|
||||
#endif
|
||||
#if defined(psnip_uint64_t)
|
||||
PSNIP_UNALIGNED_LOAD_DEFINE(psnip_unaligned_load_uint64, psnip_uint64_t)
|
||||
PSNIP_UNALIGNED_STORE_DEFINE(psnip_unaligned_store_uint64, psnip_uint64_t)
|
||||
#endif
|
||||
|
||||
/* And, if endian.h has been included, we can also define functions to
|
||||
load different-endian data from unaligned addresses… */
|
||||
|
||||
#if defined(PSNIP_ENDIAN_H)
|
||||
# psnip_unaligned_load_int16le(src) psnip_endian_le16(psnip_unaligned_load_int16(src))
|
||||
# psnip_unaligned_load_int32le(src) psnip_endian_le32(psnip_unaligned_load_int32(src))
|
||||
# psnip_unaligned_load_int64le(src) psnip_endian_le64(psnip_unaligned_load_int64(src))
|
||||
# psnip_unaligned_load_int16be(src) psnip_endian_be16(psnip_unaligned_load_int16(src))
|
||||
# psnip_unaligned_load_int32be(src) psnip_endian_be32(psnip_unaligned_load_int32(src))
|
||||
# psnip_unaligned_load_int64be(src) psnip_endian_be64(psnip_unaligned_load_int64(src))
|
||||
# psnip_unaligned_load_uint16le(src) psnip_endian_le16(psnip_unaligned_load_uint16(src))
|
||||
# psnip_unaligned_load_uint32le(src) psnip_endian_le32(psnip_unaligned_load_uint32(src))
|
||||
# psnip_unaligned_load_uint64le(src) psnip_endian_le64(psnip_unaligned_load_uint64(src))
|
||||
# psnip_unaligned_load_uint16be(src) psnip_endian_be16(psnip_unaligned_load_uint16(src))
|
||||
# psnip_unaligned_load_uint32be(src) psnip_endian_be32(psnip_unaligned_load_uint32(src))
|
||||
# psnip_unaligned_load_uint64be(src) psnip_endian_be64(psnip_unaligned_load_uint64(src))
|
||||
# psnip_unaligned_store_int16le(dest, src) psnip_unaligned_store_int16(dest, (psnip_int16_t) psnip_endian_le16(src))
|
||||
# psnip_unaligned_store_int32le(dest, src) psnip_unaligned_store_int32(dest, (psnip_int32_t) psnip_endian_le32(src))
|
||||
# psnip_unaligned_store_int64le(dest, src) psnip_unaligned_store_int64(dest, (psnip_int64_t) psnip_endian_le64(src))
|
||||
# psnip_unaligned_store_int16be(dest, src) psnip_unaligned_store_int16(dest, (psnip_int16_t) psnip_endian_be16(src))
|
||||
# psnip_unaligned_store_int32be(dest, src) psnip_unaligned_store_int32(dest, (psnip_int32_t) psnip_endian_be32(src))
|
||||
# psnip_unaligned_store_int64be(dest, src) psnip_unaligned_store_int64(dest, (psnip_int64_t) psnip_endian_be64(src))
|
||||
# psnip_unaligned_store_uint16le(dest, src) psnip_unaligned_store_uint16(dest, (psnip_uint16_t) psnip_endian_le16(src))
|
||||
# psnip_unaligned_store_uint32le(dest, src) psnip_unaligned_store_uint32(dest, (psnip_uint32_t) psnip_endian_le32(src))
|
||||
# psnip_unaligned_store_uint64le(dest, src) psnip_unaligned_store_uint64(dest, (psnip_uint64_t) psnip_endian_le64(src))
|
||||
# psnip_unaligned_store_uint16be(dest, src) psnip_unaligned_store_uint16(dest, (psnip_uint16_t) psnip_endian_be16(src))
|
||||
# psnip_unaligned_store_uint32be(dest, src) psnip_unaligned_store_uint32(dest, (psnip_uint32_t) psnip_endian_be32(src))
|
||||
# psnip_unaligned_store_uint64be(dest, src) psnip_unaligned_store_uint64(dest, (psnip_uint64_t) psnip_endian_be64(src))
|
||||
#endif
|
||||
|
||||
#endif /* PSNIP_UNALIGNED_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue