src: add support for constexpr bele.h
This commit is contained in:
parent
43f9b90c92
commit
c3341ce4dc
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
@ -53,6 +53,7 @@ jobs:
|
||||
git config --global --add safe.directory '*' # needed when running in a container
|
||||
git clone --branch "$GITHUB_REF_NAME" --depth 1 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" .
|
||||
git submodule update --init -- vendor/lzma-sdk
|
||||
git fsck --strict --no-progress
|
||||
- name: Rebuild and verify stubs
|
||||
run: |
|
||||
export PATH="$(readlink -en ../deps/bin-upx-20221212):$PATH"
|
||||
|
||||
535
src/bele.h
535
src/bele.h
@ -32,14 +32,12 @@
|
||||
// NE - Native Endianness (aka Host Endianness aka CPU Endianness)
|
||||
// TE - Target Endianness (not used here, see various packers)
|
||||
|
||||
#if 1
|
||||
// some platforms may provide their own system bswapXX() functions, so rename to avoid conflicts
|
||||
#undef bswap16
|
||||
#undef bswap32
|
||||
#undef bswap64
|
||||
#define bswap16 upx_bswap16
|
||||
#define bswap32 upx_bswap32
|
||||
#define bswap64 upx_bswap64
|
||||
static_assert(std::is_same_v<unsigned, upx_uint32_t>);
|
||||
|
||||
#if defined(upx_is_constant_evaluated)
|
||||
#define bele_constexpr constexpr
|
||||
#else
|
||||
#define bele_constexpr /*empty*/
|
||||
#endif
|
||||
|
||||
// forward declarations
|
||||
@ -55,7 +53,7 @@ struct LE64;
|
||||
// try to detect XX16 vs XX32 vs XX64 size mismatches
|
||||
**************************************************************************/
|
||||
|
||||
#if !(DEBUG)
|
||||
#if !defined(upx_is_constant_evaluated) && !(DEBUG)
|
||||
|
||||
// permissive version using "void *"
|
||||
#define REQUIRE_XE16 /*empty*/
|
||||
@ -109,67 +107,196 @@ using enable_if_xe64 = std::enable_if_t<is_xe64_type<T>, T>;
|
||||
// core - NE
|
||||
**************************************************************************/
|
||||
|
||||
forceinline bele_constexpr unsigned get_ne16(const byte *p) noexcept {
|
||||
#if defined(upx_is_constant_evaluated)
|
||||
if (upx_is_constant_evaluated()) {
|
||||
typedef unsigned U;
|
||||
#if (ACC_ABI_BIG_ENDIAN)
|
||||
return (U(p[0]) << 8) | (U(p[1]) << 0);
|
||||
#else
|
||||
return (U(p[0]) << 0) | (U(p[1]) << 8);
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
upx_uint16_t v = 0;
|
||||
upx_memcpy_inline(&v, p, sizeof(v));
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
forceinline bele_constexpr unsigned get_ne32(const byte *p) noexcept {
|
||||
#if defined(upx_is_constant_evaluated)
|
||||
if (upx_is_constant_evaluated()) {
|
||||
typedef unsigned U;
|
||||
#if (ACC_ABI_BIG_ENDIAN)
|
||||
return (U(p[0]) << 24) | (U(p[1]) << 16) | (U(p[2]) << 8) | (U(p[3]) << 0);
|
||||
#else
|
||||
return (U(p[0]) << 0) | (U(p[1]) << 8) | (U(p[2]) << 16) | (U(p[3]) << 24);
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
upx_uint32_t v = 0;
|
||||
upx_memcpy_inline(&v, p, sizeof(v));
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
forceinline bele_constexpr upx_uint64_t get_ne64(const byte *p) noexcept {
|
||||
#if defined(upx_is_constant_evaluated)
|
||||
if (upx_is_constant_evaluated()) {
|
||||
typedef upx_uint64_t U;
|
||||
#if (ACC_ABI_BIG_ENDIAN)
|
||||
return (U(p[0]) << 56) | (U(p[1]) << 48) | (U(p[2]) << 40) | (U(p[3]) << 32) |
|
||||
(U(p[4]) << 24) | (U(p[5]) << 16) | (U(p[6]) << 8) | (U(p[7]) << 0);
|
||||
#else
|
||||
return (U(p[0]) << 0) | (U(p[1]) << 8) | (U(p[2]) << 16) | (U(p[3]) << 24) |
|
||||
(U(p[4]) << 32) | (U(p[5]) << 40) | (U(p[6]) << 48) | (U(p[7]) << 56);
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
upx_uint64_t v = 0;
|
||||
upx_memcpy_inline(&v, p, sizeof(v));
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
forceinline bele_constexpr void set_ne16(byte *p, unsigned v) noexcept {
|
||||
#if defined(upx_is_constant_evaluated)
|
||||
if (upx_is_constant_evaluated()) {
|
||||
#if (ACC_ABI_BIG_ENDIAN)
|
||||
p[0] = byte((v >> 8) & 0xff);
|
||||
p[1] = byte((v >> 0) & 0xff);
|
||||
#else
|
||||
p[0] = byte((v >> 0) & 0xff);
|
||||
p[1] = byte((v >> 8) & 0xff);
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
upx_uint16_t vv = (upx_uint16_t) (v & 0xffff);
|
||||
upx_memcpy_inline(p, &vv, sizeof(vv));
|
||||
}
|
||||
}
|
||||
|
||||
forceinline bele_constexpr void set_ne32(byte *p, unsigned v) noexcept {
|
||||
#if defined(upx_is_constant_evaluated)
|
||||
if (upx_is_constant_evaluated()) {
|
||||
#if (ACC_ABI_BIG_ENDIAN)
|
||||
p[0] = byte((v >> 24) & 0xff);
|
||||
p[1] = byte((v >> 16) & 0xff);
|
||||
p[2] = byte((v >> 8) & 0xff);
|
||||
p[3] = byte((v >> 0) & 0xff);
|
||||
#else
|
||||
p[0] = byte((v >> 0) & 0xff);
|
||||
p[1] = byte((v >> 8) & 0xff);
|
||||
p[2] = byte((v >> 16) & 0xff);
|
||||
p[3] = byte((v >> 24) & 0xff);
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
upx_uint32_t vv = v;
|
||||
upx_memcpy_inline(p, &vv, sizeof(vv));
|
||||
}
|
||||
}
|
||||
|
||||
forceinline bele_constexpr void set_ne64(byte *p, upx_uint64_t v) noexcept {
|
||||
#if defined(upx_is_constant_evaluated)
|
||||
if (upx_is_constant_evaluated()) {
|
||||
#if (ACC_ABI_BIG_ENDIAN)
|
||||
p[0] = byte((v >> 56) & 0xff);
|
||||
p[1] = byte((v >> 48) & 0xff);
|
||||
p[2] = byte((v >> 40) & 0xff);
|
||||
p[3] = byte((v >> 32) & 0xff);
|
||||
p[4] = byte((v >> 24) & 0xff);
|
||||
p[5] = byte((v >> 16) & 0xff);
|
||||
p[6] = byte((v >> 8) & 0xff);
|
||||
p[7] = byte((v >> 0) & 0xff);
|
||||
#else
|
||||
p[0] = byte((v >> 0) & 0xff);
|
||||
p[1] = byte((v >> 8) & 0xff);
|
||||
p[2] = byte((v >> 16) & 0xff);
|
||||
p[3] = byte((v >> 24) & 0xff);
|
||||
p[4] = byte((v >> 32) & 0xff);
|
||||
p[5] = byte((v >> 40) & 0xff);
|
||||
p[6] = byte((v >> 48) & 0xff);
|
||||
p[7] = byte((v >> 56) & 0xff);
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
upx_uint64_t vv = v;
|
||||
upx_memcpy_inline(p, &vv, sizeof(vv));
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// core - NE
|
||||
**************************************************************************/
|
||||
|
||||
REQUIRE_XE16
|
||||
static forceinline unsigned get_ne16(const XE16 *p) noexcept {
|
||||
upx_uint16_t v = 0;
|
||||
upx_memcpy_inline(&v, p, sizeof(v));
|
||||
return v;
|
||||
forceinline bele_constexpr unsigned get_ne16(const XE16 *p) noexcept {
|
||||
return get_ne16(upx::ptr_static_cast<const byte *>(p));
|
||||
}
|
||||
|
||||
REQUIRE_XE32
|
||||
static forceinline unsigned get_ne32(const XE32 *p) noexcept {
|
||||
upx_uint32_t v = 0;
|
||||
upx_memcpy_inline(&v, p, sizeof(v));
|
||||
return v;
|
||||
forceinline bele_constexpr unsigned get_ne32(const XE32 *p) noexcept {
|
||||
return get_ne32(upx::ptr_static_cast<const byte *>(p));
|
||||
}
|
||||
|
||||
REQUIRE_XE64
|
||||
static forceinline upx_uint64_t get_ne64(const XE64 *p) noexcept {
|
||||
upx_uint64_t v = 0;
|
||||
upx_memcpy_inline(&v, p, sizeof(v));
|
||||
return v;
|
||||
forceinline bele_constexpr upx_uint64_t get_ne64(const XE64 *p) noexcept {
|
||||
return get_ne64(upx::ptr_static_cast<const byte *>(p));
|
||||
}
|
||||
|
||||
REQUIRE_XE16
|
||||
static forceinline void set_ne16(XE16 *p, unsigned vv) noexcept {
|
||||
upx_uint16_t v = (upx_uint16_t) (vv & 0xffff);
|
||||
upx_memcpy_inline(p, &v, sizeof(v));
|
||||
forceinline bele_constexpr void set_ne16(XE16 *p, unsigned v) noexcept {
|
||||
set_ne16(upx::ptr_static_cast<byte *>(p), v);
|
||||
}
|
||||
|
||||
REQUIRE_XE32
|
||||
static forceinline void set_ne32(XE32 *p, unsigned vv) noexcept {
|
||||
upx_uint32_t v = vv;
|
||||
upx_memcpy_inline(p, &v, sizeof(v));
|
||||
forceinline bele_constexpr void set_ne32(XE32 *p, unsigned v) noexcept {
|
||||
set_ne32(upx::ptr_static_cast<byte *>(p), v);
|
||||
}
|
||||
|
||||
REQUIRE_XE64
|
||||
static forceinline void set_ne64(XE64 *p, upx_uint64_t vv) noexcept {
|
||||
upx_uint64_t v = vv;
|
||||
upx_memcpy_inline(p, &v, sizeof(v));
|
||||
forceinline bele_constexpr void set_ne64(XE64 *p, upx_uint64_t v) noexcept {
|
||||
set_ne64(upx::ptr_static_cast<byte *>(p), v);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// core - bswap
|
||||
**************************************************************************/
|
||||
|
||||
#if (ACC_CC_MSC)
|
||||
#if __cpp_lib_byteswap >= 202110L
|
||||
|
||||
forceinline constexpr unsigned bswap16(unsigned v) noexcept {
|
||||
return std::byteswap((upx_uint16_t) (v & 0xffff));
|
||||
}
|
||||
forceinline constexpr unsigned bswap32(unsigned v) noexcept { return std::byteswap(v); }
|
||||
forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) noexcept { return std::byteswap(v); }
|
||||
|
||||
#elif (ACC_CC_MSC)
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4)
|
||||
|
||||
// unfortunately *not* constexpr with current MSVC
|
||||
static forceinline /*constexpr*/ unsigned bswap16(unsigned v) noexcept {
|
||||
forceinline /*constexpr*/ unsigned bswap16(unsigned v) noexcept {
|
||||
return (unsigned) _byteswap_ulong(v << 16);
|
||||
}
|
||||
static forceinline /*constexpr*/ unsigned bswap32(unsigned v) noexcept {
|
||||
forceinline /*constexpr*/ unsigned bswap32(unsigned v) noexcept {
|
||||
return (unsigned) _byteswap_ulong(v);
|
||||
}
|
||||
static forceinline /*constexpr*/ upx_uint64_t bswap64(upx_uint64_t v) noexcept {
|
||||
forceinline /*constexpr*/ upx_uint64_t bswap64(upx_uint64_t v) noexcept {
|
||||
return _byteswap_uint64(v);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static forceinline constexpr unsigned bswap16(unsigned v) noexcept {
|
||||
forceinline constexpr unsigned bswap16(unsigned v) noexcept {
|
||||
#if defined(__riscv) && __riscv_xlen == 64
|
||||
return (unsigned) __builtin_bswap64((upx_uint64_t) v << 48);
|
||||
#else
|
||||
@ -177,25 +304,23 @@ static forceinline constexpr unsigned bswap16(unsigned v) noexcept {
|
||||
return __builtin_bswap32(v << 16);
|
||||
#endif
|
||||
}
|
||||
static forceinline constexpr unsigned bswap32(unsigned v) noexcept {
|
||||
forceinline constexpr unsigned bswap32(unsigned v) noexcept {
|
||||
#if defined(__riscv) && __riscv_xlen == 64
|
||||
return (unsigned) __builtin_bswap64((upx_uint64_t) v << 32);
|
||||
#else
|
||||
return __builtin_bswap32(v);
|
||||
#endif
|
||||
}
|
||||
static forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) noexcept {
|
||||
return __builtin_bswap64(v);
|
||||
}
|
||||
forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) noexcept { return __builtin_bswap64(v); }
|
||||
|
||||
#endif
|
||||
|
||||
static forceinline constexpr unsigned no_bswap16(unsigned v) noexcept {
|
||||
forceinline constexpr unsigned no_bswap16(unsigned v) noexcept {
|
||||
// mask is needed so that for all v: bswap16(bswap16(v)) == no_bswap16(v)
|
||||
return v & 0xffff;
|
||||
}
|
||||
static forceinline constexpr unsigned no_bswap32(unsigned v) noexcept { return v; }
|
||||
static forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) noexcept { return v; }
|
||||
forceinline constexpr unsigned no_bswap32(unsigned v) noexcept { return v; }
|
||||
forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) noexcept { return v; }
|
||||
|
||||
#if (ACC_ABI_BIG_ENDIAN)
|
||||
#define ne16_to_be16(v) no_bswap16(v)
|
||||
@ -218,72 +343,106 @@ static forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) noexcept {
|
||||
**************************************************************************/
|
||||
|
||||
REQUIRE_XE16
|
||||
inline unsigned get_be16(const XE16 *p) noexcept { return ne16_to_be16(get_ne16(p)); }
|
||||
inline bele_constexpr unsigned get_be16(const XE16 *p) noexcept {
|
||||
return ne16_to_be16(get_ne16(p));
|
||||
}
|
||||
REQUIRE_XE32
|
||||
inline unsigned get_be32(const XE32 *p) noexcept { return ne32_to_be32(get_ne32(p)); }
|
||||
inline bele_constexpr unsigned get_be32(const XE32 *p) noexcept {
|
||||
return ne32_to_be32(get_ne32(p));
|
||||
}
|
||||
REQUIRE_XE64
|
||||
inline upx_uint64_t get_be64(const XE64 *p) noexcept { return ne64_to_be64(get_ne64(p)); }
|
||||
inline bele_constexpr upx_uint64_t get_be64(const XE64 *p) noexcept {
|
||||
return ne64_to_be64(get_ne64(p));
|
||||
}
|
||||
REQUIRE_XE16
|
||||
inline unsigned get_le16(const XE16 *p) noexcept { return ne16_to_le16(get_ne16(p)); }
|
||||
inline bele_constexpr unsigned get_le16(const XE16 *p) noexcept {
|
||||
return ne16_to_le16(get_ne16(p));
|
||||
}
|
||||
REQUIRE_XE32
|
||||
inline unsigned get_le32(const XE32 *p) noexcept { return ne32_to_le32(get_ne32(p)); }
|
||||
inline bele_constexpr unsigned get_le32(const XE32 *p) noexcept {
|
||||
return ne32_to_le32(get_ne32(p));
|
||||
}
|
||||
REQUIRE_XE64
|
||||
inline upx_uint64_t get_le64(const XE64 *p) noexcept { return ne64_to_le64(get_ne64(p)); }
|
||||
inline bele_constexpr upx_uint64_t get_le64(const XE64 *p) noexcept {
|
||||
return ne64_to_le64(get_ne64(p));
|
||||
}
|
||||
|
||||
REQUIRE_XE16
|
||||
inline void set_be16(XE16 *p, unsigned v) noexcept { set_ne16(p, ne16_to_be16(v)); }
|
||||
inline bele_constexpr void set_be16(XE16 *p, unsigned v) noexcept { set_ne16(p, ne16_to_be16(v)); }
|
||||
REQUIRE_XE32
|
||||
inline void set_be32(XE32 *p, unsigned v) noexcept { set_ne32(p, ne32_to_be32(v)); }
|
||||
inline bele_constexpr void set_be32(XE32 *p, unsigned v) noexcept { set_ne32(p, ne32_to_be32(v)); }
|
||||
REQUIRE_XE64
|
||||
inline void set_be64(XE64 *p, upx_uint64_t v) noexcept { set_ne64(p, ne64_to_be64(v)); }
|
||||
inline bele_constexpr void set_be64(XE64 *p, upx_uint64_t v) noexcept {
|
||||
set_ne64(p, ne64_to_be64(v));
|
||||
}
|
||||
REQUIRE_XE16
|
||||
inline void set_le16(XE16 *p, unsigned v) noexcept { set_ne16(p, ne16_to_le16(v)); }
|
||||
inline bele_constexpr void set_le16(XE16 *p, unsigned v) noexcept { set_ne16(p, ne16_to_le16(v)); }
|
||||
REQUIRE_XE32
|
||||
inline void set_le32(XE32 *p, unsigned v) noexcept { set_ne32(p, ne32_to_le32(v)); }
|
||||
inline bele_constexpr void set_le32(XE32 *p, unsigned v) noexcept { set_ne32(p, ne32_to_le32(v)); }
|
||||
REQUIRE_XE64
|
||||
inline void set_le64(XE64 *p, upx_uint64_t v) noexcept { set_ne64(p, ne64_to_le64(v)); }
|
||||
inline bele_constexpr void set_le64(XE64 *p, upx_uint64_t v) noexcept {
|
||||
set_ne64(p, ne64_to_le64(v));
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// get/set 24/26
|
||||
**************************************************************************/
|
||||
|
||||
REQUIRE_XE24
|
||||
inline unsigned get_be24(const XE24 *p) noexcept {
|
||||
const byte *b = ACC_CCAST(const byte *, p);
|
||||
return (b[0] << 16) | (b[1] << 8) | (b[2] << 0);
|
||||
inline constexpr unsigned get_be24(const byte *p) noexcept {
|
||||
typedef unsigned U;
|
||||
return (U(p[0]) << 16) | (U(p[1]) << 8) | (U(p[2]) << 0);
|
||||
}
|
||||
|
||||
inline constexpr unsigned get_le24(const byte *p) noexcept {
|
||||
typedef unsigned U;
|
||||
return (U(p[0]) << 0) | (U(p[1]) << 8) | (U(p[2]) << 16);
|
||||
}
|
||||
|
||||
inline constexpr void set_be24(byte *p, unsigned v) noexcept {
|
||||
p[0] = byte((v >> 16) & 0xff);
|
||||
p[1] = byte((v >> 8) & 0xff);
|
||||
p[2] = byte((v >> 0) & 0xff);
|
||||
}
|
||||
|
||||
inline constexpr void set_le24(byte *p, unsigned v) noexcept {
|
||||
p[0] = byte((v >> 0) & 0xff);
|
||||
p[1] = byte((v >> 8) & 0xff);
|
||||
p[2] = byte((v >> 16) & 0xff);
|
||||
}
|
||||
|
||||
REQUIRE_XE24
|
||||
inline unsigned get_le24(const XE24 *p) noexcept {
|
||||
const byte *b = ACC_CCAST(const byte *, p);
|
||||
return (b[0] << 0) | (b[1] << 8) | (b[2] << 16);
|
||||
forceinline bele_constexpr unsigned get_be24(const XE24 *p) noexcept {
|
||||
return get_be24(upx::ptr_static_cast<const byte *>(p));
|
||||
}
|
||||
|
||||
REQUIRE_XE24
|
||||
inline void set_be24(XE24 *p, unsigned v) noexcept {
|
||||
byte *b = ACC_PCAST(byte *, p);
|
||||
b[0] = ACC_ICONV(byte, (v >> 16) & 0xff);
|
||||
b[1] = ACC_ICONV(byte, (v >> 8) & 0xff);
|
||||
b[2] = ACC_ICONV(byte, (v >> 0) & 0xff);
|
||||
forceinline bele_constexpr unsigned get_le24(const XE24 *p) noexcept {
|
||||
return get_le24(upx::ptr_static_cast<const byte *>(p));
|
||||
}
|
||||
|
||||
REQUIRE_XE24
|
||||
inline void set_le24(XE24 *p, unsigned v) noexcept {
|
||||
byte *b = ACC_PCAST(byte *, p);
|
||||
b[0] = ACC_ICONV(byte, (v >> 0) & 0xff);
|
||||
b[1] = ACC_ICONV(byte, (v >> 8) & 0xff);
|
||||
b[2] = ACC_ICONV(byte, (v >> 16) & 0xff);
|
||||
forceinline bele_constexpr void set_be24(XE24 *p, unsigned v) noexcept {
|
||||
set_be24(upx::ptr_static_cast<byte *>(p), v);
|
||||
}
|
||||
|
||||
REQUIRE_XE24
|
||||
forceinline bele_constexpr void set_le24(XE24 *p, unsigned v) noexcept {
|
||||
set_le24(upx::ptr_static_cast<byte *>(p), v);
|
||||
}
|
||||
|
||||
REQUIRE_XE32
|
||||
inline unsigned get_le26(const XE32 *p) noexcept { return get_le32(p) & 0x03ffffff; }
|
||||
inline bele_constexpr unsigned get_le26(const XE32 *p) noexcept { return get_le32(p) & 0x03ffffff; }
|
||||
REQUIRE_XE32
|
||||
inline unsigned get_le19_5(const XE32 *p) noexcept { return (get_le32(p) >> 5) & 0x0007ffff; }
|
||||
inline bele_constexpr unsigned get_le19_5(const XE32 *p) noexcept {
|
||||
return (get_le32(p) >> 5) & 0x0007ffff;
|
||||
}
|
||||
REQUIRE_XE32
|
||||
inline unsigned get_le14_5(const XE32 *p) noexcept { return (get_le32(p) >> 5) & 0x00003fff; }
|
||||
inline bele_constexpr unsigned get_le14_5(const XE32 *p) noexcept {
|
||||
return (get_le32(p) >> 5) & 0x00003fff;
|
||||
}
|
||||
|
||||
REQUIRE_XE32
|
||||
inline void set_le26(XE32 *p, unsigned v) noexcept {
|
||||
inline bele_constexpr void set_le26(XE32 *p, unsigned v) noexcept {
|
||||
// preserve the top 6 bits
|
||||
// set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff));
|
||||
// optimized version, saving a runtime bswap32
|
||||
@ -291,11 +450,11 @@ inline void set_le26(XE32 *p, unsigned v) noexcept {
|
||||
(ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
|
||||
}
|
||||
REQUIRE_XE32
|
||||
inline void set_le19_5(XE32 *p, unsigned v) noexcept {
|
||||
inline bele_constexpr void set_le19_5(XE32 *p, unsigned v) noexcept {
|
||||
set_le32(p, (get_le32(p) & 0xff00001f) | ((v & 0x0007ffff) << 5));
|
||||
}
|
||||
REQUIRE_XE32
|
||||
inline void set_le14_5(XE32 *p, unsigned v) noexcept {
|
||||
inline bele_constexpr void set_le14_5(XE32 *p, unsigned v) noexcept {
|
||||
set_le32(p, (get_le32(p) & 0xfff8001f) | ((v & 0x00003fff) << 5));
|
||||
}
|
||||
|
||||
@ -303,7 +462,7 @@ inline void set_le14_5(XE32 *p, unsigned v) noexcept {
|
||||
// get signed values
|
||||
**************************************************************************/
|
||||
|
||||
static forceinline constexpr int sign_extend(unsigned v, unsigned bits) noexcept {
|
||||
forceinline constexpr int sign_extend(unsigned v, unsigned bits) noexcept {
|
||||
#if (ACC_ARCH_M68K) // no barrel shifter
|
||||
const unsigned sign_bit = 1u << (bits - 1);
|
||||
return ACC_ICAST(int, (v & (sign_bit - 1)) - (v & sign_bit));
|
||||
@ -312,7 +471,7 @@ static forceinline constexpr int sign_extend(unsigned v, unsigned bits) noexcept
|
||||
#endif
|
||||
}
|
||||
|
||||
static forceinline constexpr upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) noexcept {
|
||||
forceinline constexpr upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) noexcept {
|
||||
#if (ACC_ARCH_M68K) // no barrel shifter
|
||||
const upx_uint64_t sign_bit = 1ull << (bits - 1);
|
||||
return ACC_ICAST(upx_int64_t, (v & (sign_bit - 1)) - (v & sign_bit));
|
||||
@ -322,49 +481,49 @@ static forceinline constexpr upx_int64_t sign_extend(upx_uint64_t v, unsigned bi
|
||||
}
|
||||
|
||||
REQUIRE_XE16
|
||||
inline int get_be16_signed(const XE16 *p) noexcept {
|
||||
inline bele_constexpr int get_be16_signed(const XE16 *p) noexcept {
|
||||
unsigned v = get_be16(p);
|
||||
return sign_extend(v, 16);
|
||||
}
|
||||
|
||||
REQUIRE_XE24
|
||||
inline int get_be24_signed(const XE24 *p) noexcept {
|
||||
inline bele_constexpr int get_be24_signed(const XE24 *p) noexcept {
|
||||
unsigned v = get_be24(p);
|
||||
return sign_extend(v, 24);
|
||||
}
|
||||
|
||||
REQUIRE_XE32
|
||||
inline int get_be32_signed(const XE32 *p) noexcept {
|
||||
inline bele_constexpr int get_be32_signed(const XE32 *p) noexcept {
|
||||
unsigned v = get_be32(p);
|
||||
return sign_extend(v, 32);
|
||||
}
|
||||
|
||||
REQUIRE_XE64
|
||||
inline upx_int64_t get_be64_signed(const XE64 *p) noexcept {
|
||||
inline bele_constexpr upx_int64_t get_be64_signed(const XE64 *p) noexcept {
|
||||
upx_uint64_t v = get_be64(p);
|
||||
return sign_extend(v, 64);
|
||||
}
|
||||
|
||||
REQUIRE_XE16
|
||||
inline int get_le16_signed(const XE16 *p) noexcept {
|
||||
inline bele_constexpr int get_le16_signed(const XE16 *p) noexcept {
|
||||
unsigned v = get_le16(p);
|
||||
return sign_extend(v, 16);
|
||||
}
|
||||
|
||||
REQUIRE_XE24
|
||||
inline int get_le24_signed(const XE24 *p) noexcept {
|
||||
inline bele_constexpr int get_le24_signed(const XE24 *p) noexcept {
|
||||
unsigned v = get_le24(p);
|
||||
return sign_extend(v, 24);
|
||||
}
|
||||
|
||||
REQUIRE_XE32
|
||||
inline int get_le32_signed(const XE32 *p) noexcept {
|
||||
inline bele_constexpr int get_le32_signed(const XE32 *p) noexcept {
|
||||
unsigned v = get_le32(p);
|
||||
return sign_extend(v, 32);
|
||||
}
|
||||
|
||||
REQUIRE_XE64
|
||||
inline upx_int64_t get_le64_signed(const XE64 *p) noexcept {
|
||||
inline bele_constexpr upx_int64_t get_le64_signed(const XE64 *p) noexcept {
|
||||
upx_uint64_t v = get_le64(p);
|
||||
return sign_extend(v, 64);
|
||||
}
|
||||
@ -384,9 +543,16 @@ struct alignas(1) BE16 final {
|
||||
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||
byte d[2];
|
||||
|
||||
forceinline operator unsigned() const noexcept { return get_be16(d); }
|
||||
static forceinline constexpr BE16 make(const BE16 &x) noexcept { return x; }
|
||||
static forceinline bele_constexpr BE16 make(unsigned v) noexcept {
|
||||
BE16 x = {};
|
||||
set_be16(x.d, v);
|
||||
return x;
|
||||
}
|
||||
|
||||
forceinline BE16 &operator=(unsigned v) noexcept {
|
||||
forceinline bele_constexpr operator unsigned() const noexcept { return get_be16(d); }
|
||||
|
||||
forceinline bele_constexpr BE16 &operator=(unsigned v) noexcept {
|
||||
set_be16(d, v);
|
||||
return *this;
|
||||
}
|
||||
@ -427,17 +593,28 @@ struct alignas(1) BE16 final {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const BE16 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
|
||||
bool operator<(const BE16 &x) const noexcept { return unsigned(*this) < unsigned(x); }
|
||||
bele_constexpr bool operator==(const BE16 &x) const noexcept {
|
||||
return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
|
||||
}
|
||||
bele_constexpr bool operator<(const BE16 &x) const noexcept {
|
||||
return unsigned(*this) < unsigned(x);
|
||||
}
|
||||
};
|
||||
|
||||
struct alignas(1) BE32 final {
|
||||
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||
byte d[4];
|
||||
|
||||
forceinline operator unsigned() const noexcept { return get_be32(d); }
|
||||
static forceinline constexpr BE32 make(const BE32 &x) noexcept { return x; }
|
||||
static forceinline bele_constexpr BE32 make(unsigned v) noexcept {
|
||||
BE32 x = {};
|
||||
set_be32(x.d, v);
|
||||
return x;
|
||||
}
|
||||
|
||||
forceinline BE32 &operator=(unsigned v) noexcept {
|
||||
forceinline bele_constexpr operator unsigned() const noexcept { return get_be32(d); }
|
||||
|
||||
forceinline bele_constexpr BE32 &operator=(unsigned v) noexcept {
|
||||
set_be32(d, v);
|
||||
return *this;
|
||||
}
|
||||
@ -478,17 +655,28 @@ struct alignas(1) BE32 final {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const BE32 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
|
||||
bool operator<(const BE32 &x) const noexcept { return unsigned(*this) < unsigned(x); }
|
||||
bele_constexpr bool operator==(const BE32 &x) const noexcept {
|
||||
return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
|
||||
}
|
||||
bele_constexpr bool operator<(const BE32 &x) const noexcept {
|
||||
return unsigned(*this) < unsigned(x);
|
||||
}
|
||||
};
|
||||
|
||||
struct alignas(1) BE64 final {
|
||||
typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
|
||||
byte d[8];
|
||||
|
||||
forceinline operator upx_uint64_t() const noexcept { return get_be64(d); }
|
||||
static forceinline constexpr BE64 make(const BE64 &x) noexcept { return x; }
|
||||
static forceinline bele_constexpr BE64 make(upx_uint64_t v) noexcept {
|
||||
BE64 x = {};
|
||||
set_be64(x.d, v);
|
||||
return x;
|
||||
}
|
||||
|
||||
forceinline BE64 &operator=(upx_uint64_t v) noexcept {
|
||||
forceinline bele_constexpr operator upx_uint64_t() const noexcept { return get_be64(d); }
|
||||
|
||||
forceinline bele_constexpr BE64 &operator=(upx_uint64_t v) noexcept {
|
||||
set_be64(d, v);
|
||||
return *this;
|
||||
}
|
||||
@ -529,17 +717,28 @@ struct alignas(1) BE64 final {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const BE64 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
|
||||
bool operator<(const BE64 &x) const noexcept { return upx_uint64_t(*this) < upx_uint64_t(x); }
|
||||
bele_constexpr bool operator==(const BE64 &x) const noexcept {
|
||||
return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
|
||||
}
|
||||
bele_constexpr bool operator<(const BE64 &x) const noexcept {
|
||||
return upx_uint64_t(*this) < upx_uint64_t(x);
|
||||
}
|
||||
};
|
||||
|
||||
struct alignas(1) LE16 final {
|
||||
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||
byte d[2];
|
||||
|
||||
forceinline operator unsigned() const noexcept { return get_le16(d); }
|
||||
static forceinline constexpr LE16 make(const LE16 &x) noexcept { return x; }
|
||||
static forceinline bele_constexpr LE16 make(unsigned v) noexcept {
|
||||
LE16 x = {};
|
||||
set_le16(x.d, v);
|
||||
return x;
|
||||
}
|
||||
|
||||
forceinline LE16 &operator=(unsigned v) noexcept {
|
||||
forceinline bele_constexpr operator unsigned() const noexcept { return get_le16(d); }
|
||||
|
||||
forceinline bele_constexpr LE16 &operator=(unsigned v) noexcept {
|
||||
set_le16(d, v);
|
||||
return *this;
|
||||
}
|
||||
@ -580,17 +779,28 @@ struct alignas(1) LE16 final {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const LE16 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
|
||||
bool operator<(const LE16 &x) const noexcept { return unsigned(*this) < unsigned(x); }
|
||||
bele_constexpr bool operator==(const LE16 &x) const noexcept {
|
||||
return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
|
||||
}
|
||||
bele_constexpr bool operator<(const LE16 &x) const noexcept {
|
||||
return unsigned(*this) < unsigned(x);
|
||||
}
|
||||
};
|
||||
|
||||
struct alignas(1) LE32 final {
|
||||
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||
byte d[4];
|
||||
|
||||
forceinline operator unsigned() const noexcept { return get_le32(d); }
|
||||
static forceinline constexpr LE32 make(const LE32 &x) noexcept { return x; }
|
||||
static forceinline bele_constexpr LE32 make(unsigned v) noexcept {
|
||||
LE32 x = {};
|
||||
set_le32(x.d, v);
|
||||
return x;
|
||||
}
|
||||
|
||||
forceinline LE32 &operator=(unsigned v) noexcept {
|
||||
forceinline bele_constexpr operator unsigned() const noexcept { return get_le32(d); }
|
||||
|
||||
forceinline bele_constexpr LE32 &operator=(unsigned v) noexcept {
|
||||
set_le32(d, v);
|
||||
return *this;
|
||||
}
|
||||
@ -631,17 +841,28 @@ struct alignas(1) LE32 final {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const LE32 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
|
||||
bool operator<(const LE32 &x) const noexcept { return unsigned(*this) < unsigned(x); }
|
||||
bele_constexpr bool operator==(const LE32 &x) const noexcept {
|
||||
return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
|
||||
}
|
||||
bele_constexpr bool operator<(const LE32 &x) const noexcept {
|
||||
return unsigned(*this) < unsigned(x);
|
||||
}
|
||||
};
|
||||
|
||||
struct alignas(1) LE64 final {
|
||||
typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
|
||||
byte d[8];
|
||||
|
||||
forceinline operator upx_uint64_t() const noexcept { return get_le64(d); }
|
||||
static forceinline constexpr LE64 make(const LE64 &x) noexcept { return x; }
|
||||
static forceinline bele_constexpr LE64 make(upx_uint64_t v) noexcept {
|
||||
LE64 x = {};
|
||||
set_le64(x.d, v);
|
||||
return x;
|
||||
}
|
||||
|
||||
forceinline LE64 &operator=(upx_uint64_t v) noexcept {
|
||||
forceinline bele_constexpr operator upx_uint64_t() const noexcept { return get_le64(d); }
|
||||
|
||||
forceinline bele_constexpr LE64 &operator=(upx_uint64_t v) noexcept {
|
||||
set_le64(d, v);
|
||||
return *this;
|
||||
}
|
||||
@ -682,8 +903,12 @@ struct alignas(1) LE64 final {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const LE64 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
|
||||
bool operator<(const LE64 &x) const noexcept { return upx_uint64_t(*this) < upx_uint64_t(x); }
|
||||
bele_constexpr bool operator==(const LE64 &x) const noexcept {
|
||||
return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
|
||||
}
|
||||
bele_constexpr bool operator<(const LE64 &x) const noexcept {
|
||||
return upx_uint64_t(*this) < upx_uint64_t(x);
|
||||
}
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
@ -691,35 +916,35 @@ struct alignas(1) LE64 final {
|
||||
**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
inline T *operator+(T *ptr, const BE16 &v) noexcept {
|
||||
inline bele_constexpr T *operator+(T *ptr, const BE16 &v) noexcept {
|
||||
return ptr + unsigned(v);
|
||||
}
|
||||
template <class T>
|
||||
inline T *operator-(T *ptr, const BE16 &v) noexcept {
|
||||
inline bele_constexpr T *operator-(T *ptr, const BE16 &v) noexcept {
|
||||
return ptr - unsigned(v);
|
||||
}
|
||||
template <class T>
|
||||
inline T *operator+(T *ptr, const BE32 &v) noexcept {
|
||||
inline bele_constexpr T *operator+(T *ptr, const BE32 &v) noexcept {
|
||||
return ptr + unsigned(v);
|
||||
}
|
||||
template <class T>
|
||||
inline T *operator-(T *ptr, const BE32 &v) noexcept {
|
||||
inline bele_constexpr T *operator-(T *ptr, const BE32 &v) noexcept {
|
||||
return ptr - unsigned(v);
|
||||
}
|
||||
template <class T>
|
||||
inline T *operator+(T *ptr, const LE16 &v) noexcept {
|
||||
inline bele_constexpr T *operator+(T *ptr, const LE16 &v) noexcept {
|
||||
return ptr + unsigned(v);
|
||||
}
|
||||
template <class T>
|
||||
inline T *operator-(T *ptr, const LE16 &v) noexcept {
|
||||
inline bele_constexpr T *operator-(T *ptr, const LE16 &v) noexcept {
|
||||
return ptr - unsigned(v);
|
||||
}
|
||||
template <class T>
|
||||
inline T *operator+(T *ptr, const LE32 &v) noexcept {
|
||||
inline bele_constexpr T *operator+(T *ptr, const LE32 &v) noexcept {
|
||||
return ptr + unsigned(v);
|
||||
}
|
||||
template <class T>
|
||||
inline T *operator-(T *ptr, const LE32 &v) noexcept {
|
||||
inline bele_constexpr T *operator-(T *ptr, const LE32 &v) noexcept {
|
||||
return ptr - unsigned(v);
|
||||
}
|
||||
|
||||
@ -761,72 +986,80 @@ namespace upx {
|
||||
template <class T, class = std::enable_if_t<std::is_same_v<T, upx_uint64_t>, T> >
|
||||
|
||||
REQUIRE_UINT32
|
||||
inline T align_down(const T &a, const BE32 &b) noexcept { return align_down(a, T(b)); }
|
||||
inline bele_constexpr T align_down(const T &a, const BE32 &b) noexcept {
|
||||
return align_down(a, T(b));
|
||||
}
|
||||
REQUIRE_UINT32
|
||||
inline T align_down(const BE32 &a, const T &b) noexcept { return align_down(T(a), b); }
|
||||
inline bele_constexpr T align_down(const BE32 &a, const T &b) noexcept {
|
||||
return align_down(T(a), b);
|
||||
}
|
||||
REQUIRE_UINT32
|
||||
inline T align_down(const T &a, const LE32 &b) noexcept { return align_down(a, T(b)); }
|
||||
inline bele_constexpr T align_down(const T &a, const LE32 &b) noexcept {
|
||||
return align_down(a, T(b));
|
||||
}
|
||||
REQUIRE_UINT32
|
||||
inline T align_down(const LE32 &a, const T &b) noexcept { return align_down(T(a), b); }
|
||||
inline bele_constexpr T align_down(const LE32 &a, const T &b) noexcept {
|
||||
return align_down(T(a), b);
|
||||
}
|
||||
|
||||
REQUIRE_UINT32
|
||||
inline T align_up(const T &a, const LE32 &b) noexcept { return align_up(a, T(b)); }
|
||||
inline bele_constexpr T align_up(const T &a, const LE32 &b) noexcept { return align_up(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T align_up(const LE32 &a, const T &b) noexcept { return align_up(T(a), b); }
|
||||
inline bele_constexpr T align_up(const LE32 &a, const T &b) noexcept { return align_up(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T align_up(const T &a, const BE32 &b) noexcept { return align_up(a, T(b)); }
|
||||
inline bele_constexpr T align_up(const T &a, const BE32 &b) noexcept { return align_up(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T align_up(const BE32 &a, const T &b) noexcept { return align_up(T(a), b); }
|
||||
inline bele_constexpr T align_up(const BE32 &a, const T &b) noexcept { return align_up(T(a), b); }
|
||||
|
||||
REQUIRE_UINT32
|
||||
inline T min(const T &a, const BE16 &b) noexcept { return min(a, T(b)); }
|
||||
inline bele_constexpr T min(const T &a, const BE16 &b) noexcept { return min(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const BE16 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
inline bele_constexpr T min(const BE16 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const T &a, const BE32 &b) noexcept { return min(a, T(b)); }
|
||||
inline bele_constexpr T min(const T &a, const BE32 &b) noexcept { return min(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const BE32 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
inline bele_constexpr T min(const BE32 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
REQUIRE_UINT64
|
||||
inline T min(const T &a, const BE64 &b) noexcept { return min(a, T(b)); }
|
||||
inline bele_constexpr T min(const T &a, const BE64 &b) noexcept { return min(a, T(b)); }
|
||||
REQUIRE_UINT64
|
||||
inline T min(const BE64 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
inline bele_constexpr T min(const BE64 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const T &a, const LE16 &b) noexcept { return min(a, T(b)); }
|
||||
inline bele_constexpr T min(const T &a, const LE16 &b) noexcept { return min(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const LE16 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
inline bele_constexpr T min(const LE16 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const T &a, const LE32 &b) noexcept { return min(a, T(b)); }
|
||||
inline bele_constexpr T min(const T &a, const LE32 &b) noexcept { return min(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const LE32 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
inline bele_constexpr T min(const LE32 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
REQUIRE_UINT64
|
||||
inline T min(const T &a, const LE64 &b) noexcept { return min(a, T(b)); }
|
||||
inline bele_constexpr T min(const T &a, const LE64 &b) noexcept { return min(a, T(b)); }
|
||||
REQUIRE_UINT64
|
||||
inline T min(const LE64 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
inline bele_constexpr T min(const LE64 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
|
||||
REQUIRE_UINT32
|
||||
inline T max(const T &a, const BE16 &b) noexcept { return max(a, T(b)); }
|
||||
inline bele_constexpr T max(const T &a, const BE16 &b) noexcept { return max(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const BE16 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
inline bele_constexpr T max(const BE16 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const T &a, const BE32 &b) noexcept { return max(a, T(b)); }
|
||||
inline bele_constexpr T max(const T &a, const BE32 &b) noexcept { return max(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const BE32 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
inline bele_constexpr T max(const BE32 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
REQUIRE_UINT64
|
||||
inline T max(const T &a, const BE64 &b) noexcept { return max(a, T(b)); }
|
||||
inline bele_constexpr T max(const T &a, const BE64 &b) noexcept { return max(a, T(b)); }
|
||||
REQUIRE_UINT64
|
||||
inline T max(const BE64 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
inline bele_constexpr T max(const BE64 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const T &a, const LE16 &b) noexcept { return max(a, T(b)); }
|
||||
inline bele_constexpr T max(const T &a, const LE16 &b) noexcept { return max(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const LE16 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
inline bele_constexpr T max(const LE16 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const T &a, const LE32 &b) noexcept { return max(a, T(b)); }
|
||||
inline bele_constexpr T max(const T &a, const LE32 &b) noexcept { return max(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const LE32 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
inline bele_constexpr T max(const LE32 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
REQUIRE_UINT64
|
||||
inline T max(const T &a, const LE64 &b) noexcept { return max(a, T(b)); }
|
||||
inline bele_constexpr T max(const T &a, const LE64 &b) noexcept { return max(a, T(b)); }
|
||||
REQUIRE_UINT64
|
||||
inline T max(const LE64 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
inline bele_constexpr T max(const LE64 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
|
||||
#undef REQUIRE_UINT32
|
||||
#undef REQUIRE_UINT64
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
|
||||
#if defined(BELE_CTP)
|
||||
// CTP - Compile-Time Polymorphism (templates)
|
||||
#define V static inline
|
||||
#define V static inline bele_constexpr
|
||||
#define VV static forceinline_constexpr
|
||||
#define S static int __acc_cdecl_qsort
|
||||
#define C noexcept
|
||||
|
||||
@ -236,6 +236,8 @@ struct CheckIntegral {
|
||||
one = 1;
|
||||
three = 3;
|
||||
four = 4;
|
||||
assert_noexcept(one == 1);
|
||||
assert_noexcept(four == 4);
|
||||
// min / max
|
||||
assert_noexcept(upx::min(one, four) == 1);
|
||||
assert_noexcept(upx::min(one, four) == one);
|
||||
@ -411,6 +413,44 @@ struct TestBELE {
|
||||
assert_noexcept(upx::max(minus_one_t, minus_two_u) == minus_one_t);
|
||||
assert_noexcept(upx::max(minus_one_t, minus_two_u) == minus_one_u);
|
||||
}
|
||||
// constexpr
|
||||
{
|
||||
constexpr T zero = {};
|
||||
constexpr T zero_copy = T::make(zero);
|
||||
assert_noexcept(zero_copy == 0);
|
||||
}
|
||||
#if defined(upx_is_constant_evaluated)
|
||||
{
|
||||
typedef typename T::integral_conversion_type U;
|
||||
constexpr T one = T::make(1);
|
||||
static_assert(one == 1);
|
||||
constexpr T four = T::make(one + 3);
|
||||
static_assert(four == 4);
|
||||
constexpr U all_bits_u = (U) T::make(U(0) - U(1));
|
||||
constexpr T all_bits = T::make(all_bits_u);
|
||||
static_assert(all_bits == all_bits_u);
|
||||
static_assert(all_bits == T::make(one - 2));
|
||||
static_assert(one == one);
|
||||
static_assert(!(one == four));
|
||||
static_assert(!(one == all_bits));
|
||||
static_assert(one < four);
|
||||
static_assert(one < all_bits);
|
||||
static_assert(upx::min(one, four) == 1);
|
||||
static_assert(upx::min(one, four) == one);
|
||||
static_assert(upx::min(U(1), four) == 1);
|
||||
static_assert(upx::min(one, U(4)) == 1);
|
||||
static_assert(upx::max(one, four) == 4);
|
||||
static_assert(upx::max(one, four) == four);
|
||||
static_assert(upx::max(U(1), four) == 4);
|
||||
static_assert(upx::max(one, U(4)) == 4);
|
||||
static_assert(upx::align_down(one, four) == 0);
|
||||
static_assert(upx::align_up(one, four) == 4);
|
||||
static_assert(upx::align_gap(one, four) == 3);
|
||||
constexpr T one_copy = T::make(one);
|
||||
static_assert(one_copy == one);
|
||||
static_assert(one_copy == 1);
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -690,12 +730,11 @@ void upx_compiler_sanity_check(void) noexcept {
|
||||
assert_noexcept(TestBELE<BE32>::test());
|
||||
assert_noexcept(TestBELE<BE64>::test());
|
||||
{
|
||||
alignas(16) static const byte dd[32] = {
|
||||
alignas(16) static constexpr byte dd[32] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0,
|
||||
0, 0, 0, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0, 0, 0, 0, 0};
|
||||
const byte *d;
|
||||
constexpr const byte *d = dd + 7;
|
||||
const N_BELE_RTP::AbstractPolicy *bele;
|
||||
d = dd + 7;
|
||||
assert_noexcept(upx_adler32(d, 4) == 0x09f003f7);
|
||||
assert_noexcept(upx_adler32(d, 4, 0) == 0x09ec03f6);
|
||||
assert_noexcept(upx_adler32(d, 4, 1) == 0x09f003f7);
|
||||
@ -709,6 +748,8 @@ void upx_compiler_sanity_check(void) noexcept {
|
||||
assert_noexcept(get_be32(d) == 0xfffefdfc);
|
||||
assert_noexcept(bele->get32(d) == 0xfffefdfc);
|
||||
assert_noexcept(get_be32_signed(d) == -66052);
|
||||
assert_noexcept(get_be64(d) == 0xfffefdfcfbfaf9f8ULL);
|
||||
assert_noexcept(get_be64_signed(d) == -283686952306184LL);
|
||||
bele = &N_BELE_RTP::le_policy;
|
||||
assert_noexcept(get_le16(d) == 0xfeff);
|
||||
assert_noexcept(bele->get16(d) == 0xfeff);
|
||||
@ -719,16 +760,41 @@ void upx_compiler_sanity_check(void) noexcept {
|
||||
assert_noexcept(get_le32(d) == 0xfcfdfeff);
|
||||
assert_noexcept(bele->get32(d) == 0xfcfdfeff);
|
||||
assert_noexcept(get_le32_signed(d) == -50462977);
|
||||
assert_noexcept(get_le64(d) == 0xf8f9fafbfcfdfeffULL);
|
||||
assert_noexcept(get_le64_signed(d) == -506097522914230529LL);
|
||||
#if defined(upx_is_constant_evaluated)
|
||||
static_assert(get_be16(d) == 0xfffe);
|
||||
static_assert(get_be16_signed(d) == -2);
|
||||
static_assert(get_be24(d) == 0xfffefd);
|
||||
static_assert(get_be24_signed(d) == -259);
|
||||
static_assert(get_be32(d) == 0xfffefdfc);
|
||||
static_assert(get_be32_signed(d) == -66052);
|
||||
static_assert(get_be64(d) == 0xfffefdfcfbfaf9f8ULL);
|
||||
static_assert(get_be64_signed(d) == -283686952306184LL);
|
||||
static_assert(get_le16(d) == 0xfeff);
|
||||
static_assert(get_le16_signed(d) == -257);
|
||||
static_assert(get_le24(d) == 0xfdfeff);
|
||||
static_assert(get_le24_signed(d) == -131329);
|
||||
static_assert(get_le32(d) == 0xfcfdfeff);
|
||||
static_assert(get_le32_signed(d) == -50462977);
|
||||
static_assert(get_le64(d) == 0xf8f9fafbfcfdfeffULL);
|
||||
static_assert(get_le64_signed(d) == -506097522914230529LL);
|
||||
#endif
|
||||
assert_noexcept(find_be16(d, 2, 0xfffe) == 0);
|
||||
assert_noexcept(find_le16(d, 2, 0xfeff) == 0);
|
||||
assert_noexcept(find_be32(d, 4, 0xfffefdfc) == 0);
|
||||
assert_noexcept(find_le32(d, 4, 0xfcfdfeff) == 0);
|
||||
d += 12;
|
||||
assert_noexcept(get_be16_signed(d) == 32638);
|
||||
assert_noexcept(get_be24_signed(d) == 8355453);
|
||||
assert_noexcept(get_be32_signed(d) == 2138996092);
|
||||
assert_noexcept(get_be64_signed(d) == 9186918263483431288LL);
|
||||
constexpr const byte *e = d + 12;
|
||||
assert_noexcept(get_be16_signed(e) == 32638);
|
||||
assert_noexcept(get_be24_signed(e) == 8355453);
|
||||
assert_noexcept(get_be32_signed(e) == 2138996092);
|
||||
assert_noexcept(get_be64_signed(e) == 9186918263483431288LL);
|
||||
#if defined(upx_is_constant_evaluated)
|
||||
static_assert(get_be16_signed(e) == 32638);
|
||||
static_assert(get_be24_signed(e) == 8355453);
|
||||
static_assert(get_be32_signed(e) == 2138996092);
|
||||
static_assert(get_be64_signed(e) == 9186918263483431288LL);
|
||||
#endif
|
||||
}
|
||||
#if DEBUG >= 1
|
||||
{
|
||||
|
||||
23
src/conf.h
23
src/conf.h
@ -121,6 +121,12 @@ inline constexpr bool upx_is_integral_v = upx_is_integral<T>::value;
|
||||
#define upx_alignas_max alignas(std::max_align_t)
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
#define upx_is_constant_evaluated std::is_constant_evaluated
|
||||
#elif __has_builtin(__builtin_is_constant_evaluated)
|
||||
#define upx_is_constant_evaluated __builtin_is_constant_evaluated
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
// core
|
||||
**************************************************************************/
|
||||
@ -289,6 +295,14 @@ typedef upx_int64_t upx_off_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// some platforms may provide their own system bswapXX() functions, so rename to avoid conflicts
|
||||
#undef bswap16
|
||||
#undef bswap32
|
||||
#undef bswap64
|
||||
#define bswap16 upx_bswap16
|
||||
#define bswap32 upx_bswap32
|
||||
#define bswap64 upx_bswap64
|
||||
|
||||
// avoid warnings about shadowing global symbols
|
||||
#undef _base
|
||||
#undef basename
|
||||
@ -347,7 +361,14 @@ inline void NO_fprintf(FILE *, const char *, ...) noexcept attribute_format(2, 3
|
||||
inline void NO_printf(const char *, ...) noexcept {}
|
||||
inline void NO_fprintf(FILE *, const char *, ...) noexcept {}
|
||||
|
||||
#if __has_builtin(__builtin_memcpy_inline)
|
||||
#if __has_builtin(__builtin_memcmp)
|
||||
#define upx_memcmp_inline __builtin_memcmp
|
||||
#elif defined(__clang__) || defined(__GNUC__)
|
||||
#define upx_memcmp_inline __builtin_memcmp
|
||||
#else
|
||||
#define upx_memcmp_inline memcmp
|
||||
#endif
|
||||
#if __has_builtin(__builtin_memcpy_inline) && 0 // TODO later: clang constexpr limitation?
|
||||
#define upx_memcpy_inline __builtin_memcpy_inline
|
||||
#elif __has_builtin(__builtin_memcpy)
|
||||
#define upx_memcpy_inline __builtin_memcpy
|
||||
|
||||
@ -591,6 +591,9 @@ void show_sysinfo(const char *options_var) {
|
||||
cf_print("__GLIBC_MINOR__", "%lld", __GLIBC_MINOR__ + 0);
|
||||
#endif
|
||||
// misc compilation options
|
||||
#if defined(upx_is_constant_evaluated)
|
||||
cf_print("upx_is_constant_evaluated", "%lld", 1, 3);
|
||||
#endif
|
||||
#if defined(UPX_CONFIG_DISABLE_WSTRICT)
|
||||
cf_print("UPX_CONFIG_DISABLE_WSTRICT", "%lld", UPX_CONFIG_DISABLE_WSTRICT + 0, 3);
|
||||
#endif
|
||||
|
||||
@ -177,23 +177,23 @@ forceinline constexpr bool has_single_bit(T x) noexcept {
|
||||
**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
inline T align_down(const T &x, const T &alignment) noexcept {
|
||||
assert_noexcept(has_single_bit(alignment));
|
||||
T r;
|
||||
inline constexpr T align_down(const T &x, const T &alignment) noexcept {
|
||||
// assert_noexcept(has_single_bit(alignment));
|
||||
T r = {};
|
||||
r = (x / alignment) * alignment;
|
||||
return r;
|
||||
}
|
||||
template <class T>
|
||||
inline T align_up(const T &x, const T &alignment) noexcept {
|
||||
assert_noexcept(has_single_bit(alignment));
|
||||
T r;
|
||||
inline constexpr T align_up(const T &x, const T &alignment) noexcept {
|
||||
// assert_noexcept(has_single_bit(alignment));
|
||||
T r = {};
|
||||
r = ((x + (alignment - 1)) / alignment) * alignment;
|
||||
return r;
|
||||
}
|
||||
template <class T>
|
||||
inline T align_gap(const T &x, const T &alignment) noexcept {
|
||||
assert_noexcept(has_single_bit(alignment));
|
||||
T r;
|
||||
inline constexpr T align_gap(const T &x, const T &alignment) noexcept {
|
||||
// assert_noexcept(has_single_bit(alignment));
|
||||
T r = {};
|
||||
r = align_up(x, alignment) - x;
|
||||
return r;
|
||||
}
|
||||
@ -232,14 +232,14 @@ struct UnsignedSizeOf {
|
||||
|
||||
// a static_cast that does not trigger -Wcast-align warnings
|
||||
template <class Result, class From>
|
||||
forceinline Result ptr_static_cast(From *ptr) noexcept {
|
||||
forceinline constexpr Result ptr_static_cast(From *ptr) noexcept {
|
||||
static_assert(std::is_pointer_v<Result>);
|
||||
static_assert(!std::is_const_v<std::remove_pointer_t<Result> >); // enforce same constness
|
||||
// NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion)
|
||||
return static_cast<Result>(static_cast<void *>(ptr));
|
||||
}
|
||||
template <class Result, class From>
|
||||
forceinline Result ptr_static_cast(const From *ptr) noexcept {
|
||||
forceinline constexpr Result ptr_static_cast(const From *ptr) noexcept {
|
||||
static_assert(std::is_pointer_v<Result>);
|
||||
static_assert(std::is_const_v<std::remove_pointer_t<Result> >); // required
|
||||
// NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion)
|
||||
|
||||
@ -119,6 +119,9 @@ static_assert(sizeof(void *) == sizeof(long));
|
||||
#endif
|
||||
|
||||
// C++ freestanding headers
|
||||
#if __cplusplus >= 202002L
|
||||
#include <bit>
|
||||
#endif
|
||||
#include <cstddef>
|
||||
#include <exception>
|
||||
#include <new>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user