inflate.h
inflate_p.h
inftrees.h
+ insert_string_tpl.h
match_p.h
memcopy.h
trees.h
infback.c
inftrees.c
inffast.c
+ insert_string.c
trees.c
uncompr.c
zutil.c
man3dir = ${mandir}/man3
pkgconfigdir = ${libdir}/pkgconfig
-OBJZ = adler32.o compress.o crc32.o deflate.o deflate_fast.o deflate_medium.o deflate_slow.o functable.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o $(ARCH_STATIC_OBJS)
+OBJZ = adler32.o compress.o crc32.o deflate.o deflate_fast.o deflate_medium.o deflate_slow.o functable.o infback.o inffast.o inflate.o inftrees.o insert_string.o trees.o uncompr.o zutil.o $(ARCH_STATIC_OBJS)
OBJG = gzclose.o gzlib.o gzread.o gzwrite.o
OBJC = $(OBJZ) $(OBJG)
-PIC_OBJZ = adler32.lo compress.lo crc32.lo deflate.lo deflate_fast.lo deflate_medium.lo deflate_slow.lo functable.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo uncompr.lo zutil.lo $(ARCH_SHARED_OBJS)
+PIC_OBJZ = adler32.lo compress.lo crc32.lo deflate.lo deflate_fast.lo deflate_medium.lo deflate_slow.lo functable.lo infback.lo inffast.lo inflate.lo inftrees.lo insert_string.lo trees.lo uncompr.lo zutil.lo $(ARCH_SHARED_OBJS)
PIC_OBJG = gzclose.lo gzlib.lo gzread.lo gzwrite.lo
PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG)
#include "../../zbuild.h"
#include "../../deflate.h"
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
- */
-Pos insert_string_acle(deflate_state *const s, const Pos str, unsigned int count) {
- Pos p, lp, ret;
-
- if (UNLIKELY(count == 0)) {
- return s->prev[str & s->w_mask];
- }
-
- ret = 0;
- lp = str + count - 1; /* last position */
-
- for (p = str; p <= lp; p++) {
- uint32_t val, h, hm;
- memcpy(&val, &s->window[p], sizeof(val));
-
- if (s->level >= TRIGGER_LEVEL)
- val &= 0xFFFFFF;
+#define UPDATE_HASH(s, h, val) \
+ h = __crc32w(0, val)
- h = __crc32w(0, val);
- hm = h & s->hash_mask;
+#define INSERT_STRING insert_string_acle
+#define QUICK_INSERT_STRING quick_insert_string_acle
- Pos head = s->head[hm];
- if (head != p) {
- s->prev[p & s->w_mask] = head;
- s->head[hm] = p;
- if (p == lp)
- ret = head;
- } else if (p == lp) {
- ret = p;
- }
- }
- return ret;
-}
+#include "../../insert_string_tpl.h"
#endif
extern void fill_window_sse(deflate_state *s);
extern void flush_pending(PREFIX3(stream) *strm);
+extern Pos quick_insert_string_sse4(deflate_state *const s, const Pos str);
static inline long compare258(const unsigned char *const src0, const unsigned char *const src1) {
#ifdef _MSC_VER
s->block_open = 0;
}
-static inline Pos quick_insert_string(deflate_state *const s, const Pos str) {
- Pos ret;
- unsigned h = 0;
-
-#ifdef _MSC_VER
- h = _mm_crc32_u32(h, *(unsigned *)(s->window + str));
-#else
- __asm__ __volatile__ (
- "crc32l (%[window], %[str], 1), %0\n\t"
- : "+r" (h)
- : [window] "r" (s->window),
- [str] "r" ((uintptr_t)str)
- );
-#endif
-
- ret = s->head[h & s->hash_mask];
- s->head[h & s->hash_mask] = str;
- return ret;
-}
-
ZLIB_INTERNAL block_state deflate_quick(deflate_state *s, int flush) {
IPos hash_head;
unsigned dist, match_len;
}
if (s->lookahead >= MIN_MATCH) {
- hash_head = quick_insert_string(s, s->strstart);
+ hash_head = quick_insert_string_sse4(s, s->strstart);
dist = s->strstart - hash_head;
if (dist > 0 && (dist-1) < (wsize - 1)) {
#endif
#include "../../deflate.h"
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
- */
-#ifdef X86_SSE42_CRC_HASH
-ZLIB_INTERNAL Pos insert_string_sse(deflate_state *const s, const Pos str, unsigned int count) {
- Pos ret = 0;
- unsigned int idx;
- unsigned int *ip, val, h;
-
- for (idx = 0; idx < count; idx++) {
- ip = (unsigned *)&s->window[str+idx];
- memcpy(&val, ip, sizeof(val));
- h = 0;
-
- if (s->level >= TRIGGER_LEVEL)
- val &= 0xFFFFFF;
-
-#if defined(X86_SSE42_CRC_INTRIN)
+#ifdef X86_SSE42_CRC_INTRIN
# ifdef _MSC_VER
- h = _mm_crc32_u32(h, val);
+# define UPDATE_HASH(s, h, val)\
+ h = _mm_crc32_u32(h, val)
# else
- h = __builtin_ia32_crc32si(h, val);
+# define UPDATE_HASH(s, h, val)\
+ h = __builtin_ia32_crc32si(h, val)
# endif
#else
# ifdef _MSC_VER
- __asm {
- mov edx, h
- mov eax, val
- crc32 eax, edx
- mov val, eax
- };
+# define UPDATE_HASH(s, h, val) {\
+ __asm {\
+ mov edx, h\
+ mov eax, val\
+ crc32 eax, edx\
+ mov val, eax\
+ };\
+ }
# else
- __asm__ __volatile__ (
- "crc32 %1,%0\n\t"
- : "+r" (h)
- : "r" (val)
+# define UPDATE_HASH(s, h, val) \
+ __asm__ __volatile__ (\
+ "crc32 %1,%0\n\t"\
+ : "+r" (h)\
+ : "r" (val)\
);
# endif
#endif
- Pos head = s->head[h & s->hash_mask];
- if (head != str+idx) {
- s->prev[(str+idx) & s->w_mask] = head;
- s->head[h & s->hash_mask] = str+idx;
- if (idx == count-1)
- ret = head;
- } else if (idx == count - 1) {
- ret = str + idx;
- }
- }
- return ret;
-}
+
+#define INSERT_STRING insert_string_sse4
+#define QUICK_INSERT_STRING quick_insert_string_sse4
+
+#ifdef X86_SSE42_CRC_HASH
+# include "../../insert_string_tpl.h"
#endif
* used.
*/
-/* ===========================================================================
- * Update a hash value with the given input byte
- * IN assertion: all calls to to UPDATE_HASH are made with consecutive
- * input characters, so that a running hash key can be computed from the
- * previous key instead of complete recalculation each time.
- */
-
#ifdef NOT_TWEAK_COMPILER
# define TRIGGER_LEVEL 6
#else
# define TRIGGER_LEVEL 5
#endif
-#if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
-# define UPDATE_HASH(s, h, i) \
- do {\
- if (s->level < TRIGGER_LEVEL) \
- h = (3483 * (s->window[i]) +\
- 23081* (s->window[i+1]) +\
- 6954 * (s->window[i+2]) +\
- 20947* (s->window[i+3])) & s->hash_mask;\
- else\
- h = (25881* (s->window[i]) +\
- 24674* (s->window[i+1]) +\
- 25811* (s->window[i+2])) & s->hash_mask;\
- } while (0)
-#else
-# define UPDATE_HASH(s, h, i) \
- (h = (((h) << s->hash_shift) ^ (s->window[i + (MIN_MATCH-1)])) & s->hash_mask)
-#endif
-
#ifdef ZLIB_DEBUG
# define send_code(s, c, tree, bit_buf, bits_valid) { \
if (z_verbose > 2) { \
#endif
void flush_pending(PREFIX3(stream) *strm);
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
- */
-
-static inline Pos insert_string_c(deflate_state *const s, const Pos str, unsigned int count) {
- Pos ret = 0;
- unsigned int idx;
-
- for (idx = 0; idx < count; idx++) {
- UPDATE_HASH(s, s->ins_h, str+idx);
-
- Pos head = s->head[s->ins_h];
- if (head != str+idx) {
- s->prev[(str+idx) & s->w_mask] = head;
- s->head[s->ins_h] = str+idx;
- if (idx == count - 1)
- ret = head;
- } else if (idx == count - 1) {
- ret = str + idx;
- }
- }
- return ret;
-}
-
/* ===========================================================================
* Save the match info and tally the frequency counts. Return true if
* the current block must be flushed.
#include "functable.h"
/* insert_string */
+extern Pos insert_string_c(deflate_state *const s, const Pos str, unsigned int count);
#ifdef X86_SSE42_CRC_HASH
-extern Pos insert_string_sse(deflate_state *const s, const Pos str, unsigned int count);
+extern Pos insert_string_sse4(deflate_state *const s, const Pos str, unsigned int count);
#elif defined(ARM_ACLE_CRC_HASH)
extern Pos insert_string_acle(deflate_state *const s, const Pos str, unsigned int count);
#endif
+/* quick_insert_string */
+extern Pos quick_insert_string_c(deflate_state *const s, const Pos str);
+#ifdef X86_SSE42_CRC_HASH
+extern Pos quick_insert_string_sse4(deflate_state *const s, const Pos str);
+#elif defined(ARM_ACLE_CRC_HASH)
+extern Pos quick_insert_string_acle(deflate_state *const s, const Pos str);
+#endif
+
/* fill_window */
#if defined(X86_SSE2)
extern void fill_window_sse(deflate_state *s);
/* stub definitions */
ZLIB_INTERNAL Pos insert_string_stub(deflate_state *const s, const Pos str, unsigned int count);
+ZLIB_INTERNAL Pos quick_insert_string_stub(deflate_state *const s, const Pos str);
ZLIB_INTERNAL void fill_window_stub(deflate_state *s);
ZLIB_INTERNAL uint32_t adler32_stub(uint32_t adler, const unsigned char *buf, size_t len);
ZLIB_INTERNAL uint32_t crc32_stub(uint32_t crc, const unsigned char *buf, uint64_t len);
ZLIB_INTERNAL __thread struct functable_s functable = {
fill_window_stub,
insert_string_stub,
+ quick_insert_string_stub,
adler32_stub,
crc32_stub,
slide_hash_stub
#ifdef X86_SSE42_CRC_HASH
if (x86_cpu_has_sse42)
- functable.insert_string = &insert_string_sse;
+ functable.insert_string = &insert_string_sse4;
#elif defined(__ARM_FEATURE_CRC32) && defined(ARM_ACLE_CRC_HASH)
if (arm_cpu_has_crc32)
functable.insert_string = &insert_string_acle;
return functable.insert_string(s, str, count);
}
+ZLIB_INTERNAL Pos quick_insert_string_stub(deflate_state *const s, const Pos str) {
+ functable.quick_insert_string = &quick_insert_string_c;
+
+#ifdef X86_SSE42_CRC_HASH
+ if (x86_cpu_has_sse42)
+ functable.quick_insert_string = &quick_insert_string_sse4;
+#elif defined(__ARM_FEATURE_CRC32) && defined(ARM_ACLE_CRC_HASH)
+ if (arm_cpu_has_crc32)
+ functable.quick_insert_string = &quick_insert_string_acle;
+#endif
+
+ return functable.quick_insert_string(s, str);
+}
+
ZLIB_INTERNAL void fill_window_stub(deflate_state *s) {
// Initialize default
functable.fill_window = &fill_window_c;
#include "deflate.h"
struct functable_s {
- void (* fill_window) (deflate_state *s);
- Pos (* insert_string) (deflate_state *const s, const Pos str, unsigned int count);
- uint32_t (* adler32) (uint32_t adler, const unsigned char *buf, size_t len);
- uint32_t (* crc32) (uint32_t crc, const unsigned char *buf, uint64_t len);
- void (* slide_hash) (deflate_state *s);
+ void (* fill_window) (deflate_state *s);
+ Pos (* insert_string) (deflate_state *const s, const Pos str, unsigned int count);
+ Pos (* quick_insert_string)(deflate_state *const s, const Pos str);
+ uint32_t (* adler32) (uint32_t adler, const unsigned char *buf, size_t len);
+ uint32_t (* crc32) (uint32_t crc, const unsigned char *buf, uint64_t len);
+ void (* slide_hash) (deflate_state *s);
};
ZLIB_INTERNAL extern __thread struct functable_s functable;
--- /dev/null
+/* insert_string_c -- insert_string variant for c
+ *
+ * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ */
+
+#include "zbuild.h"
+#include "deflate.h"
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
+ * input characters, so that a running hash key can be computed from the
+ * previous key instead of complete recalculation each time.
+ */
+
+#if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
+# define UPDATE_HASH(s, h, val) \
+ do {\
+ if (s->level < TRIGGER_LEVEL)\
+ h = (3483 * ((val) & 0xff) +\
+ 23081* (((val) >> 8) & 0xff) +\
+ 6954 * (((val) >> 16) & 0xff) +\
+ 20947* (((val) >> 24) & 0xff));\
+ else\
+ h = (25881* (((val)) & 0xff) +\
+ 24674* (((val) >> 8) & 0xff) +\
+ 25811* (((val) >> 16) & 0xff));\
+ } while (0)
+#else
+# define UPDATE_HASH(s, h, val)\
+ h = (s->ins_h = ((s->ins_h << s->hash_shift) ^ ((val) >> ((MIN_MATCH - 1) * 8))) & s->hash_mask)
+#endif
+
+#define INSERT_STRING insert_string_c
+#define QUICK_INSERT_STRING quick_insert_string_c
+
+#include "insert_string_tpl.h"
--- /dev/null
+#ifndef INSERT_STRING_H_
+#define INSERT_STRING_H_
+
+/* insert_string.h -- Private insert_string functions shared with more than
+ * one insert string implementation
+ *
+ * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
+ *
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ * Authors:
+ * Wajdi Feghali <wajdi.k.feghali@intel.com>
+ * Jim Guilford <james.guilford@intel.com>
+ * Vinodh Gopal <vinodh.gopal@intel.com>
+ * Erdinc Ozturk <erdinc.ozturk@intel.com>
+ * Jim Kukunas <james.t.kukunas@linux.intel.com>
+ *
+ * Portions are Copyright (C) 2016 12Sided Technology, LLC.
+ * Author:
+ * Phil Vachon <pvachon@12sidedtech.com>
+ *
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ */
+
+/* ===========================================================================
+ * Quick insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ */
+
+ZLIB_INTERNAL Pos QUICK_INSERT_STRING(deflate_state *const s, const Pos str) {
+ Pos head;
+ uint32_t val, hm, h = 0;
+
+#ifdef UNALIGNED_OK
+ val = *(uint32_t *)(s->window + str);
+#else
+ val = ((uint32_t)s->window[str]);
+ val |= ((uint32_t)s->window[str+1] << 8);
+ val |= ((uint32_t)s->window[str+2] << 16);
+ val |= ((uint32_t)s->window[str+3] << 24);
+#endif
+
+ if (s->level >= TRIGGER_LEVEL)
+ val &= 0xFFFFFF;
+
+ UPDATE_HASH(s, h, val);
+ hm = h & s->hash_mask;
+
+ head = s->head[hm];
+ if (head != str) {
+ s->prev[str & s->w_mask] = head;
+ s->head[hm] = str;
+ }
+ return head;
+}
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
+ * input characters and the first MIN_MATCH bytes of str are valid
+ * (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+
+ZLIB_INTERNAL Pos INSERT_STRING(deflate_state *const s, const Pos str, unsigned int count) {
+ Pos idx, ret;
+ uint8_t *strstart, *strend;
+
+ if (UNLIKELY(count == 0)) {
+ return s->prev[str & s->w_mask];
+ }
+
+ strstart = s->window + str;
+ strend = strstart + count - 1; /* last position */
+
+ for (ret = 0, idx = str; strstart <= strend; idx++, strstart++) {
+ uint32_t val, hm, h = 0;
+
+#ifdef UNALIGNED_OK
+ val = *(uint32_t *)(strstart);
+#else
+ val = ((uint32_t)(strstart[0]));
+ val |= ((uint32_t)(strstart[1]) << 8);
+ val |= ((uint32_t)(strstart[2]) << 16);
+ val |= ((uint32_t)(strstart[3]) << 24);
+#endif
+
+ if (s->level >= TRIGGER_LEVEL)
+ val &= 0xFFFFFF;
+
+ UPDATE_HASH(s, h, val);
+ hm = h & s->hash_mask;
+
+ Pos head = s->head[hm];
+ if (head != idx) {
+ s->prev[idx & s->w_mask] = head;
+ s->head[hm] = idx;
+ if (strstart == strend)
+ ret = head;
+ } else if (strstart == strend) {
+ ret = idx;
+ }
+ }
+ return ret;
+}
+#endif
OBJS = adler32.obj armfeature.obj compress.obj crc32.obj deflate.obj deflate_fast.obj deflate_slow.obj \
deflate_medium.obj \
- functable.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj fill_window_arm.obj
+ functable.obj infback.obj inflate.obj inftrees.obj inffast.obj insert_string.obj \
+ trees.obj uncompr.obj zutil.obj fill_window_arm.obj
!if "$(WITH_GZFILEOP)" != ""
WFLAGS = $(WFLAGS) -DWITH_GZFILEOP
OBJS = $(OBJS) gzclose.obj gzlib.obj gzread.obj gzwrite.obj
OBJS = adler32.obj armfeature.obj compress.obj crc32.obj deflate.obj deflate_fast.obj deflate_slow.obj \
deflate_medium.obj \
- functable.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj fill_window_arm.obj
+ functable.obj infback.obj inflate.obj inftrees.obj inffast.obj insert_string.obj \
+ trees.obj uncompr.obj zutil.obj fill_window_arm.obj
!if "$(WITH_GZFILEOP)" != ""
WFLAGS = $(WFLAGS) -DWITH_GZFILEOP
OBJS = $(OBJS) gzclose.obj gzlib.obj gzread.obj gzwrite.obj
OBJS = adler32.obj compress.obj crc32.obj deflate.obj deflate_fast.obj deflate_quick.obj deflate_slow.obj \
deflate_medium.obj \
- functable.obj infback.obj inflate.obj inftrees.obj inffast.obj slide_avx.obj slide_sse.obj trees.obj uncompr.obj zutil.obj \
+ functable.obj infback.obj inflate.obj inftrees.obj inffast.obj insert_string.obj \
+ slide_avx.obj slide_sse.obj trees.obj uncompr.obj zutil.obj \
x86.obj fill_window_sse.obj insert_string_sse.obj crc_folding.obj
!if "$(ZLIB_COMPAT)" != ""
WITH_GZFILEOP = yes