#endif
/* UNALIGNED_OK, AVX2 intrinsic comparison */
-int32_t compare258_unaligned_avx2(const unsigned char *src0, const unsigned char *src1) {
+static inline int32_t compare258_unaligned_avx2_static(const unsigned char *src0, const unsigned char *src1) {
const unsigned char *src0start = src0;
const unsigned char *src0end = src0 + 256;
return (int32_t)(src0 - src0start);
}
+int32_t compare258_unaligned_avx2(const unsigned char *src0, const unsigned char *src1) {
+ return compare258_unaligned_avx2_static(src0, src1);
+}
+
+#define LONGEST_MATCH longest_match_unaligned_avx2
+#define COMPARE258 compare258_unaligned_avx2_static
+
+#include "match_p.h"
+
#endif
#endif
/* UNALIGNED_OK, SSE4.2 intrinsic comparison */
-int32_t compare258_unaligned_sse4(const unsigned char *src0, const unsigned char *src1) {
+static inline int32_t compare258_unaligned_sse4_static(const unsigned char *src0, const unsigned char *src1) {
#ifdef _MSC_VER
const unsigned char *src0start = src0;
const unsigned char *src0end = src0 + 256;
#endif
}
+int32_t compare258_unaligned_sse4(const unsigned char *src0, const unsigned char *src1) {
+ return compare258_unaligned_sse4_static(src0, src1);
+}
+
+#define LONGEST_MATCH longest_match_unaligned_sse4
+#define COMPARE258 compare258_unaligned_sse4_static
+
+#include "match_p.h"
+
#endif
#include "fallback_builtins.h"
/* ALIGNED, byte comparison */
-int32_t compare258_c(const unsigned char *src0, const unsigned char *src1) {
+static inline int32_t compare258_c_static(const unsigned char *src0, const unsigned char *src1) {
const unsigned char *src0start = src0;
const unsigned char *src0end = src0 + 258;
return (int32_t)(src0 - src0start);
}
+int32_t compare258_c(const unsigned char *src0, const unsigned char *src1) {
+ return compare258_c_static(src0, src1);
+}
+
+#define LONGEST_MATCH longest_match_c
+#define COMPARE258 compare258_c_static
+
+#include "match_p.h"
+
#ifdef UNALIGNED_OK
/* UNALIGNED_OK, 16-bit integer comparison */
-int32_t compare258_unaligned_16(const unsigned char *src0, const unsigned char *src1) {
+static inline int32_t compare258_unaligned_16_static(const unsigned char *src0, const unsigned char *src1) {
const unsigned char *src0start = src0;
const unsigned char *src0end = src0 + 258;
return (int32_t)(src0 - src0start);
}
+int32_t compare258_unaligned_16(const unsigned char *src0, const unsigned char *src1) {
+ return compare258_unaligned_16_static(src0, src1);
+}
+
+#define LONGEST_MATCH longest_match_unaligned_16
+#define COMPARE258 compare258_unaligned_16_static
+
+#include "match_p.h"
+
#ifdef HAVE_BUILTIN_CTZ
/* UNALIGNED_OK, 32-bit integer comparison */
-int32_t compare258_unaligned_32(const unsigned char *src0, const unsigned char *src1) {
+static inline int32_t compare258_unaligned_32_static(const unsigned char *src0, const unsigned char *src1) {
const unsigned char *src0start = src0;
const unsigned char *src0end = src0 + 256;
return (int32_t)(src0 - src0start);
}
+int32_t compare258_unaligned_32(const unsigned char *src0, const unsigned char *src1) {
+ return compare258_unaligned_32_static(src0, src1);
+}
+
+#define LONGEST_MATCH longest_match_unaligned_32
+#define COMPARE258 compare258_unaligned_32_static
+
+#include "match_p.h"
+
#endif
#ifdef HAVE_BUILTIN_CTZLL
/* UNALIGNED_OK, 64-bit integer comparison */
-int32_t compare258_unaligned_64(const unsigned char *src0, const unsigned char *src1) {
+static inline int32_t compare258_unaligned_64_static(const unsigned char *src0, const unsigned char *src1) {
const unsigned char *src0start = src0;
const unsigned char *src0end = src0 + 256;
return (int32_t)(src0 - src0start);
}
+int32_t compare258_unaligned_64(const unsigned char *src0, const unsigned char *src1) {
+ return compare258_unaligned_64_static(src0, src1);
+}
+
+#define LONGEST_MATCH longest_match_unaligned_64
+#define COMPARE258 compare258_unaligned_64_static
+
+#include "match_p.h"
+
#endif
#endif
#include "zbuild.h"
#include "deflate.h"
#include "deflate_p.h"
-#include "match_p.h"
#include "functable.h"
/* ===========================================================================
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
- s->match_length = longest_match(s, hash_head);
+ s->match_length = functable.longest_match(s, hash_head);
/* longest_match() sets match_start */
}
if (s->match_length >= MIN_MATCH) {
#include "zbuild.h"
#include "deflate.h"
#include "deflate_p.h"
-#include "match_p.h"
#include "functable.h"
struct match {
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
- current_match.match_length = longest_match(s, hash_head);
+ current_match.match_length = functable.longest_match(s, hash_head);
current_match.match_start = s->match_start;
if (current_match.match_length < MIN_MATCH)
current_match.match_length = 1;
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
- next_match.match_length = longest_match(s, hash_head);
+ next_match.match_length = functable.longest_match(s, hash_head);
next_match.match_start = s->match_start;
if (next_match.match_start >= next_match.strstart) {
/* this can happen due to some restarts */
#include "zbuild.h"
#include "deflate.h"
#include "deflate_p.h"
-#include "match_p.h"
#include "functable.h"
/* ===========================================================================
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
- s->match_length = longest_match(s, hash_head);
+ s->match_length = functable.longest_match(s, hash_head);
/* longest_match() sets match_start */
if (s->match_length <= 5 && (s->strategy == Z_FILTERED
#endif
#endif
+/* longest_match */
+extern int32_t longest_match_c(deflate_state *const s, IPos cur_match);
+#ifdef UNALIGNED_OK
+extern int32_t longest_match_unaligned_16(deflate_state *const s, IPos cur_match);
+extern int32_t longest_match_unaligned_32(deflate_state *const s, IPos cur_match);
+extern int32_t longest_match_unaligned_64(deflate_state *const s, IPos cur_match);
+#ifdef X86_SSE42_CMP_STR
+extern int32_t longest_match_unaligned_sse4(deflate_state *const s, IPos cur_match);
+#endif
+#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ)
+extern int32_t longest_match_unaligned_avx2(deflate_state *const s, IPos cur_match);
+#endif
+#endif
+
/* 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 uint32_t crc32_stub(uint32_t crc, const unsigned char *buf, uint64_t len);
ZLIB_INTERNAL void slide_hash_stub(deflate_state *s);
ZLIB_INTERNAL int32_t compare258_stub(const unsigned char *src0, const unsigned char *src1);
+ZLIB_INTERNAL int32_t longest_match_stub(deflate_state *const s, IPos cur_match);
/* functable init */
ZLIB_INTERNAL __thread struct functable_s functable = {
adler32_stub,
crc32_stub,
slide_hash_stub,
- compare258_stub
+ compare258_stub,
+ longest_match_stub
};
ZLIB_INTERNAL void cpu_check_features(void)
return functable.compare258(src0, src1);
}
+ZLIB_INTERNAL int32_t longest_match_stub(deflate_state *const s, IPos cur_match) {
+
+ functable.longest_match = &longest_match_c;
+
+#ifdef UNALIGNED_OK
+# ifdef HAVE_BUILTIN_CTZLL
+ functable.longest_match = &longest_match_unaligned_64;
+# elif defined(HAVE_BUILTIN_CTZ)
+ functable.longest_match = &longest_match_unaligned_32;
+# else
+ functable.longest_match = &longest_match_unaligned_16;
+# endif
+# ifdef X86_SSE42_CMP_STR
+ if (x86_cpu_has_sse42)
+ functable.longest_match = &longest_match_unaligned_sse4;
+# endif
+# if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ)
+ if (x86_cpu_has_avx2)
+ functable.longest_match = &longest_match_unaligned_avx2;
+# endif
+#endif
+
+ return functable.longest_match(s, cur_match);
+}
+
uint32_t (* crc32) (uint32_t crc, const unsigned char *buf, uint64_t len);
void (* slide_hash) (deflate_state *s);
int32_t (* compare258) (const unsigned char *src0, const unsigned char *src1);
+ int32_t (* longest_match) (deflate_state *const s, IPos cur_match);
};
ZLIB_INTERNAL extern __thread struct functable_s functable;
* string (strstart) and its distance is <= MAX_DIST, and prev_length >=1
* OUT assertion: the match length is not greater than s->lookahead
*/
-static inline unsigned longest_match(deflate_state *const s, IPos cur_match) {
+int32_t LONGEST_MATCH(deflate_state *const s, IPos cur_match) {
unsigned int strstart = s->strstart;
const unsigned wmask = s->w_mask;
unsigned char *window = s->window;
if (!cont)
break;
- len = functable.compare258(scan, match);
+ len = COMPARE258(scan, match);
Assert(scan+len <= window+(unsigned)(s->window_size-1), "wild scan");
if (len > best_len) {