]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
ARM: check cpu feature once at init time
authorSebastian Pop <s.pop@samsung.com>
Fri, 25 Jan 2019 17:44:46 +0000 (11:44 -0600)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Fri, 1 Mar 2019 10:40:23 +0000 (11:40 +0100)
This makes the checks for arm cpu features as inexpensive as on the x86 side
by calling the runtime feature detection once in deflate/inflate init and then
storing the result in a global variable.

12 files changed:
arch/aarch64/arm.h [new file with mode: 0644]
arch/aarch64/armfeature.c
arch/arm/Makefile.in
arch/arm/arm.h [new file with mode: 0644]
arch/arm/armfeature.c
arch/x86/x86.c
arch/x86/x86.h
deflate.c
deflate_p.h
functable.c
inflate.c
zutil.h

diff --git a/arch/aarch64/arm.h b/arch/aarch64/arm.h
new file mode 100644 (file)
index 0000000..baee87f
--- /dev/null
@@ -0,0 +1,13 @@
+/* arm.h -- check for ARM features.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifndef ARM_H_
+#define ARM_H_
+
+extern int arm_cpu_has_neon;
+extern int arm_cpu_has_crc32;
+
+void ZLIB_INTERNAL arm_check_features(void);
+
+#endif /* ARM_H_ */
index 9f2af03f9204dca5fe38bf46d4187931f7eb5d22..39f185d467c60adb11d2ce179eea79804c86e5e4 100644 (file)
@@ -1,9 +1,11 @@
+#include "zutil.h"
+
 #if defined(__linux__)
 # include <sys/auxv.h>
 # include <asm/hwcap.h>
 #endif
 
-int arm_has_crc32() {
+static int arm_has_crc32() {
 #if defined(__linux__) && defined(HWCAP_CRC32)
   return (getauxval(AT_HWCAP) & HWCAP_CRC32) != 0 ? 1 : 0;
 #elif defined(ARM_NOCHECK_ACLE)
@@ -13,7 +15,10 @@ int arm_has_crc32() {
 #endif
 }
 
-int arm_has_neon()
-{
-  return 1; /* always available */
+ZLIB_INTERNAL int arm_cpu_has_neon;
+ZLIB_INTERNAL int arm_cpu_has_crc32;
+
+void ZLIB_INTERNAL arm_check_features(void) {
+  arm_cpu_has_neon = 1; /* always available */
+  arm_cpu_has_crc32 = arm_has_crc32();
 }
index 6fcf919a93cd1ce807c3e319ae91e188f65e1a1b..34d27107f65443bdf03969a11fbe6b514bbf8f1b 100644 (file)
@@ -24,7 +24,7 @@ armfeature.o: $(SRCDIR)/armfeature.c
        $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/armfeature.c
 
 armfeature.lo: $(SRCDIR)/armfeature.c
-       $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/armfeature.c
+       $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/armfeature.c
 
 crc32_acle.o: $(SRCDIR)/crc32_acle.c
        $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_acle.c
diff --git a/arch/arm/arm.h b/arch/arm/arm.h
new file mode 100644 (file)
index 0000000..baee87f
--- /dev/null
@@ -0,0 +1,13 @@
+/* arm.h -- check for ARM features.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifndef ARM_H_
+#define ARM_H_
+
+extern int arm_cpu_has_neon;
+extern int arm_cpu_has_crc32;
+
+void ZLIB_INTERNAL arm_check_features(void);
+
+#endif /* ARM_H_ */
index 7c78dda81c763161ffb56af7c8dc18253f2de0fc..a06fd528037cbcc7cb1035adc415df99392f9c06 100644 (file)
@@ -1,3 +1,5 @@
+#include "zutil.h"
+
 #if defined(__linux__)
 # include <sys/auxv.h>
 # include <asm/hwcap.h>
@@ -5,7 +7,7 @@
 # include <winapifamily.h>
 #endif
 
-int arm_has_crc32() {
+static int arm_has_crc32() {
 #if defined(__linux__) && defined(HWCAP2_CRC32)
   return (getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0 ? 1 : 0;
 #elif defined(ARM_NOCHECK_ACLE)
@@ -15,7 +17,7 @@ int arm_has_crc32() {
 #endif
 }
 
-int arm_has_neon()
+static int arm_has_neon()
 {
 #if defined(__linux__) && defined(HWCAP_NEON)
   return (getauxval(AT_HWCAP) & HWCAP_NEON) != 0 ? 1 : 0;
@@ -31,3 +33,11 @@ int arm_has_neon()
   return 0;
 #endif
 }
+
+ZLIB_INTERNAL int arm_cpu_has_neon;
+ZLIB_INTERNAL int arm_cpu_has_crc32;
+
+void ZLIB_INTERNAL arm_check_features(void) {
+  arm_cpu_has_neon = arm_has_neon();
+  arm_cpu_has_crc32 = arm_has_crc32();
+}
index c04e0a79ad750114e5ea1cbc77ee922b8fe14824..382f72a2b6c26de885a8edd2e7e899e685293205 100644 (file)
@@ -8,7 +8,7 @@
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
-#include "x86.h"
+#include "zutil.h"
 
 #ifdef _MSC_VER
 #include <intrin.h>
index 9b06cc6659804bfe90bc91b99d6c3bf46b26fcc9..860e64154aef59b218ad86dd9989cf5c048425ac 100644 (file)
@@ -6,14 +6,6 @@
 #ifndef CPU_H_
 #define CPU_H_
 
-#if defined(HAVE_INTERNAL)
-#  define ZLIB_INTERNAL __attribute__((visibility ("internal")))
-#elif defined(HAVE_HIDDEN)
-# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
-#else
-# define ZLIB_INTERNAL
-#endif
-
 extern int x86_cpu_has_sse2;
 extern int x86_cpu_has_sse42;
 extern int x86_cpu_has_pclmulqdq;
index 7275120c126d3f17d15fc1244ceb6cc686d1c8b9..63d67478077ebe4094d0326395a78ef8f0d6c6c0 100644 (file)
--- a/deflate.c
+++ b/deflate.c
@@ -236,6 +236,8 @@ int ZEXPORT PREFIX(deflateInit2_)(PREFIX3(stream) *strm, int level, int method,
 
 #ifdef X86_CPUID
     x86_check_features();
+#elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM)
+    arm_check_features();
 #endif
 
     if (version == NULL || version[0] != my_version[0] || stream_size != sizeof(PREFIX3(stream))) {
index 6008a970d6d61ebcf571caf469f430b6f18e657b..69a7c82a0fa0b2906426231ae4d49bc5a40844f1 100644 (file)
@@ -9,10 +9,6 @@
 #ifndef DEFLATE_P_H
 #define DEFLATE_P_H
 
-#if defined(X86_CPUID)
-# include "arch/x86/x86.h"
-#endif
-
 /* Forward declare common non-inlined functions declared in deflate.c */
 
 #ifdef ZLIB_DEBUG
index 93fbd23d4d03e94cf43aca6cd111895cacaacb61..91a2a20612c253ef7a2940324225b0a8826abf5e 100644 (file)
 
 #include "gzendian.h"
 
-#if defined(X86_CPUID)
-# include "arch/x86/x86.h"
-#elif (defined(__arm__) || defined(__aarch64__) || defined(_M_ARM))
-extern int arm_has_crc32();
-extern int arm_has_neon();
-#endif
-
-
 /* insert_string */
 #ifdef X86_SSE4_2_CRC_HASH
 extern Pos insert_string_sse(deflate_state *const s, const Pos str, unsigned int count);
@@ -69,7 +61,7 @@ ZLIB_INTERNAL Pos insert_string_stub(deflate_state *const s, const Pos str, unsi
     if (x86_cpu_has_sse42)
         functable.insert_string=&insert_string_sse;
     #elif defined(__ARM_FEATURE_CRC32) && defined(ARM_ACLE_CRC_HASH)
-    if (arm_has_crc32())
+    if (arm_cpu_has_crc32)
         functable.insert_string=&insert_string_acle;
     #endif
 
@@ -97,7 +89,7 @@ ZLIB_INTERNAL uint32_t adler32_stub(uint32_t adler, const unsigned char *buf, si
     functable.adler32=&adler32_c;
 
     #if ((defined(__ARM_NEON__) || defined(__ARM_NEON)) && defined(ARM_NEON_ADLER32))
-    if (arm_has_neon())
+    if (arm_cpu_has_neon)
         functable.adler32=&adler32_neon;
     #endif
 
@@ -120,7 +112,7 @@ ZLIB_INTERNAL uint32_t crc32_stub(uint32_t crc, const unsigned char *buf, uint64
 #if BYTE_ORDER == LITTLE_ENDIAN
       functable.crc32=crc32_little;
 #  if __ARM_FEATURE_CRC32 && defined(ARM_ACLE_CRC_HASH)
-      if (arm_has_crc32())
+      if (arm_cpu_has_crc32)
         functable.crc32=crc32_acle;
 #  endif
 #elif BYTE_ORDER == BIG_ENDIAN
index d17bc274d738311dc46b0f991c033f143450ba66..c4241cc676adb4c8bd3e0a5e990fed54c20bbb46 100644 (file)
--- a/inflate.c
+++ b/inflate.c
@@ -189,6 +189,12 @@ int ZEXPORT PREFIX(inflateInit2_)(PREFIX3(stream) *strm, int windowBits, const c
     int ret;
     struct inflate_state *state;
 
+#ifdef X86_CPUID
+    x86_check_features();
+#elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM)
+    arm_check_features();
+#endif
+
     if (version == NULL || version[0] != PREFIX2(VERSION)[0] || stream_size != (int)(sizeof(PREFIX3(stream))))
         return Z_VERSION_ERROR;
     if (strm == NULL)
diff --git a/zutil.h b/zutil.h
index 6cb2bad6d6e369f273a10ef661d61a3824c00c56..e80cc31601670792660ec654c0b086ad8d9290f1 100644 (file)
--- a/zutil.h
+++ b/zutil.h
@@ -116,6 +116,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
 
 /* provide prototypes for these when building zlib without LFS */
 #if !defined(WIN32) && !defined(__MSYS__) && (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
+# include "zbuild.h"  /* For PREFIX() */
     ZEXTERN uint32_t ZEXPORT PREFIX(adler32_combine64)(uint32_t, uint32_t, z_off_t);
     ZEXTERN uint32_t ZEXPORT PREFIX(crc32_combine64)(uint32_t, uint32_t, z_off_t);
 #endif
@@ -245,4 +246,12 @@ void ZLIB_INTERNAL   zcfree(void *opaque, void *ptr);
 #define MEMSET memset
 #endif
 
+#if defined(X86_CPUID)
+# include "arch/x86/x86.h"
+#elif defined(__aarch64__)
+# include "arch/aarch64/arm.h"
+#elif defined(__arm__) || defined(_M_ARM)
+# include "arch/arm/arm.h"
+#endif
+
 #endif /* ZUTIL_H_ */