diff options
author | Danny Lin <danny@kdrag0n.dev> | 2021-04-06 21:39:07 -0700 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2022-05-13 14:58:00 +0800 |
commit | 2ca0d0b38b60e8d6d49a8959bf674a79e7d16f41 (patch) | |
tree | 0b9a6cb57102589741eaec759a95438f8acd0f5c /arch/arm | |
parent | b56a2fd0b126cfe5f13e68ab9090cd4f6a773286 (diff) |
Port zlib-ng to the Android platformHEADsugisawa-mr1
- Add Soong blueprint
- Add CRC32 fixes
- Add NDK mappings
All changes were based on the Android fork of Chromium zlib.
Change-Id: Icf0f00d95e1534a0f5683cce40679916a464cc12
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/crc32_acle.c | 40 | ||||
-rw-r--r-- | arch/arm/insert_string_acle.c | 42 |
2 files changed, 80 insertions, 2 deletions
diff --git a/arch/arm/crc32_acle.c b/arch/arm/crc32_acle.c index 88ba6c3..99013e1 100644 --- a/arch/arm/crc32_acle.c +++ b/arch/arm/crc32_acle.c @@ -11,6 +11,46 @@ #endif #include "../../zutil.h" +#if defined(__clang__) +/* CRC32 intrinsics are #ifdef'ed out of arm_acle.h unless we build with an + * armv8 target, which is incompatible with ThinLTO optimizations on Android. + * (Namely, mixing and matching different module-level targets makes ThinLTO + * warn, and Android defaults to armv7-a. This restriction does not apply to + * function-level `target`s, however.) + * + * Since we only need four crc intrinsics, and since clang's implementation of + * those are just wrappers around compiler builtins, it's simplest to #define + * those builtins directly. If this #define list grows too much (or we depend on + * an intrinsic that isn't a trivial wrapper), we may have to find a better way + * to go about this. + * + * NOTE: clang currently complains that "'+soft-float-abi' is not a recognized + * feature for this target (ignoring feature)." This appears to be a harmless + * bug in clang. + */ +#define __crc32b __builtin_arm_crc32b +#define __crc32d __builtin_arm_crc32d +#define __crc32w __builtin_arm_crc32w +#define __crc32cw __builtin_arm_crc32cw +#define __crc32h __builtin_arm_crc32h + +#if defined(__aarch64__) +#define TARGET_ARMV8_WITH_CRC __attribute__((target("crc"))) +#else // !defined(__aarch64__) +#define TARGET_ARMV8_WITH_CRC __attribute__((target("armv8-a,crc"))) +#endif // defined(__aarch64__) + +#elif defined(__GNUC__) +/* For GCC, we are setting CRC extensions at module level, so ThinLTO is not + * allowed. We can just include arm_acle.h. + */ +#include <arm_acle.h> +#define TARGET_ARMV8_WITH_CRC +#else // !defined(__GNUC__) && !defined(_aarch64__) +#error ARM CRC32 SIMD extensions only supported for Clang and GCC +#endif + +TARGET_ARMV8_WITH_CRC uint32_t crc32_acle(uint32_t crc, const unsigned char *buf, uint64_t len) { Z_REGISTER uint32_t c; Z_REGISTER const uint16_t *buf2; diff --git a/arch/arm/insert_string_acle.c b/arch/arm/insert_string_acle.c index 2daf9ba..4fd5fa7 100644 --- a/arch/arm/insert_string_acle.c +++ b/arch/arm/insert_string_acle.c @@ -12,11 +12,49 @@ #include "../../zbuild.h" #include "../../deflate.h" +#if defined(__clang__) +/* CRC32 intrinsics are #ifdef'ed out of arm_acle.h unless we build with an + * armv8 target, which is incompatible with ThinLTO optimizations on Android. + * (Namely, mixing and matching different module-level targets makes ThinLTO + * warn, and Android defaults to armv7-a. This restriction does not apply to + * function-level `target`s, however.) + * + * Since we only need four crc intrinsics, and since clang's implementation of + * those are just wrappers around compiler builtins, it's simplest to #define + * those builtins directly. If this #define list grows too much (or we depend on + * an intrinsic that isn't a trivial wrapper), we may have to find a better way + * to go about this. + * + * NOTE: clang currently complains that "'+soft-float-abi' is not a recognized + * feature for this target (ignoring feature)." This appears to be a harmless + * bug in clang. + */ +#define __crc32b __builtin_arm_crc32b +#define __crc32d __builtin_arm_crc32d +#define __crc32w __builtin_arm_crc32w +#define __crc32cw __builtin_arm_crc32cw + +#if defined(__aarch64__) +#define TARGET_ARMV8_WITH_CRC __attribute__((target("crc"))) +#else // !defined(__aarch64__) +#define TARGET_ARMV8_WITH_CRC __attribute__((target("armv8-a,crc"))) +#endif // defined(__aarch64__) + +#elif defined(__GNUC__) +/* For GCC, we are setting CRC extensions at module level, so ThinLTO is not + * allowed. We can just include arm_acle.h. + */ +#include <arm_acle.h> +#define TARGET_ARMV8_WITH_CRC +#else // !defined(__GNUC__) && !defined(_aarch64__) +#error ARM CRC32 SIMD extensions only supported for Clang and GCC +#endif + #define UPDATE_HASH(s, h, val) \ h = __crc32w(0, val) -#define INSERT_STRING insert_string_acle -#define QUICK_INSERT_STRING quick_insert_string_acle +#define INSERT_STRING TARGET_ARMV8_WITH_CRC insert_string_acle +#define QUICK_INSERT_STRING TARGET_ARMV8_WITH_CRC quick_insert_string_acle #include "../../insert_string_tpl.h" #endif |