#ifndef LZMA_CRC32_ARM64_H
#define LZMA_CRC32_ARM64_H
#ifndef _MSC_VER
# include <arm_acle.h>
#endif
#if defined(CRC32_GENERIC) && defined(CRC32_ARCH_OPTIMIZED)
# if (defined(HAVE_GETAUXVAL) && defined(HAVE_HWCAP_CRC32)) \
|| defined(HAVE_ELF_AUX_INFO)
# include <sys/auxv.h>
# elif defined(_WIN32)
# include <processthreadsapi.h>
# elif defined(__APPLE__) && defined(HAVE_SYSCTLBYNAME)
# include <sys/sysctl.h>
# endif
#endif
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__EDG__)
# define crc_attr_target __attribute__((__target__("+crc")))
#else
# define crc_attr_target
#endif
crc_attr_target
static uint32_t
crc32_arch_optimized(const uint8_t *buf, size_t size, uint32_t crc)
{
crc = ~crc;
if (size >= 8) {
const size_t align = (0 - (uintptr_t)buf) & 7;
if (align & 1)
crc = __crc32b(crc, *buf++);
if (align & 2) {
crc = __crc32h(crc, aligned_read16le(buf));
buf += 2;
}
if (align & 4) {
crc = __crc32w(crc, aligned_read32le(buf));
buf += 4;
}
size -= align;
for (const uint8_t *limit = buf + (size & ~(size_t)7);
buf < limit; buf += 8)
crc = __crc32d(crc, aligned_read64le(buf));
size &= 7;
}
if (size & 4) {
crc = __crc32w(crc, aligned_read32le(buf));
buf += 4;
}
if (size & 2) {
crc = __crc32h(crc, aligned_read16le(buf));
buf += 2;
}
if (size & 1)
crc = __crc32b(crc, *buf);
return ~crc;
}
#if defined(CRC32_GENERIC) && defined(CRC32_ARCH_OPTIMIZED)
static inline bool
is_arch_extension_supported(void)
{
#if defined(HAVE_GETAUXVAL) && defined(HAVE_HWCAP_CRC32)
return (getauxval(AT_HWCAP) & HWCAP_CRC32) != 0;
#elif defined(HAVE_ELF_AUX_INFO)
unsigned long feature_flags;
if (elf_aux_info(AT_HWCAP, &feature_flags, sizeof(feature_flags)) != 0)
return false;
return (feature_flags & HWCAP_CRC32) != 0;
#elif defined(_WIN32)
return IsProcessorFeaturePresent(
PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE);
#elif defined(__APPLE__) && defined(HAVE_SYSCTLBYNAME)
int has_crc32 = 0;
size_t size = sizeof(has_crc32);
if (sysctlbyname("hw.optional.armv8_crc32", &has_crc32,
&size, NULL, 0) != 0)
return false;
return has_crc32;
#else
# error Runtime detection method unavailable.
#endif
}
#endif
#endif