1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
/* compare258_sse.c -- SSE4.2 version of compare258
*
* 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
*/
#include "../../zbuild.h"
#include "../../zutil.h"
#ifdef X86_SSE42_CMP_STR
#include <immintrin.h>
#ifdef _MSC_VER
# include <nmmintrin.h>
#endif
/* UNALIGNED_OK, SSE4.2 intrinsic comparison */
static inline uint32_t compare256_unaligned_sse4_static(const unsigned char *src0, const unsigned char *src1) {
uint32_t len = 0;
do {
#define mode _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_EACH | _SIDD_NEGATIVE_POLARITY
__m128i xmm_src0, xmm_src1;
uint32_t ret;
xmm_src0 = _mm_loadu_si128((__m128i *)src0);
xmm_src1 = _mm_loadu_si128((__m128i *)src1);
ret = (uint32_t)_mm_cmpestri(xmm_src0, 16, xmm_src1, 16, mode);
if (_mm_cmpestrc(xmm_src0, 16, xmm_src1, 16, mode)) {
return len + ret;
}
src0 += 16, src1 += 16, len += 16;
xmm_src0 = _mm_loadu_si128((__m128i *)src0);
xmm_src1 = _mm_loadu_si128((__m128i *)src1);
ret = (uint32_t)_mm_cmpestri(xmm_src0, 16, xmm_src1, 16, mode);
if (_mm_cmpestrc(xmm_src0, 16, xmm_src1, 16, mode)) {
return len + ret;
}
src0 += 16, src1 += 16, len += 16;
} while (len < 256);
return 256;
}
static inline uint32_t compare258_unaligned_sse4_static(const unsigned char *src0, const unsigned char *src1) {
if (*(uint16_t *)src0 != *(uint16_t *)src1)
return (*src0 == *src1);
return compare256_unaligned_sse4_static(src0+2, src1+2) + 2;
}
Z_INTERNAL uint32_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 COMPARE256 compare256_unaligned_sse4_static
#define COMPARE258 compare258_unaligned_sse4_static
#include "match_tpl.h"
#endif
|