1/* insert_string_sse -- insert_string variant using SSE4.2's CRC instructions
2 *
3 * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
4 * For conditions of distribution and use, see copyright notice in zlib.h
5 *
6 */
7
8#include "../../zbuild.h"
9#include <immintrin.h>
10#ifdef _MSC_VER
11# include <nmmintrin.h>
12#endif
13#include "../../deflate.h"
14
15/* ===========================================================================
16 * Insert string str in the dictionary and set match_head to the previous head
17 * of the hash chain (the most recent string with same hash key). Return
18 * the previous length of the hash chain.
19 * IN assertion: all calls to to INSERT_STRING are made with consecutive
20 * input characters and the first MIN_MATCH bytes of str are valid
21 * (except for the last MIN_MATCH-1 bytes of the input file).
22 */
23#ifdef X86_SSE42_CRC_HASH
24ZLIB_INTERNAL Pos insert_string_sse(deflate_state *const s, const Pos str, unsigned int count) {
25 Pos ret = 0;
26 unsigned int idx;
27 unsigned int *ip, val, h;
28
29 for (idx = 0; idx < count; idx++) {
30 ip = (unsigned *)&s->window[str+idx];
31 memcpy(&val, ip, sizeof(val));
32 h = 0;
33
34 if (s->level >= TRIGGER_LEVEL)
35 val &= 0xFFFFFF;
36
37#if defined(X86_SSE42_CRC_INTRIN)
38# ifdef _MSC_VER
39 h = _mm_crc32_u32(h, val);
40# else
41 h = __builtin_ia32_crc32si(h, val);
42# endif
43#else
44# ifdef _MSC_VER
45 __asm {
46 mov edx, h
47 mov eax, val
48 crc32 eax, edx
49 mov val, eax
50 };
51# else
52 __asm__ __volatile__ (
53 "crc32 %1,%0\n\t"
54 : "+r" (h)
55 : "r" (val)
56 );
57# endif
58#endif
59 Pos head = s->head[h & s->hash_mask];
60 if (head != str+idx) {
61 s->prev[(str+idx) & s->w_mask] = head;
62 s->head[h & s->hash_mask] = str+idx;
63 if (idx == count-1)
64 ret = head;
65 } else if (idx == count - 1) {
66 ret = str + idx;
67 }
68 }
69 return ret;
70}
71#endif
72