1 | /* compare258.c -- aligned and unaligned versions of compare258 |
2 | * Copyright (C) 2020 Nathan Moinvaziri |
3 | * For conditions of distribution and use, see copyright notice in zlib.h |
4 | */ |
5 | |
6 | #include "zbuild.h" |
7 | #include "zutil.h" |
8 | |
9 | #include "fallback_builtins.h" |
10 | |
11 | /* ALIGNED, byte comparison */ |
12 | static inline uint32_t compare256_c_static(const unsigned char *src0, const unsigned char *src1) { |
13 | uint32_t len = 0; |
14 | |
15 | do { |
16 | if (*src0 != *src1) |
17 | return len + (*src0 == *src1); |
18 | src0 += 1, src1 += 1, len += 1; |
19 | if (*src0 != *src1) |
20 | return len + (*src0 == *src1); |
21 | src0 += 1, src1 += 1, len += 1; |
22 | if (*src0 != *src1) |
23 | return len + (*src0 == *src1); |
24 | src0 += 1, src1 += 1, len += 1; |
25 | if (*src0 != *src1) |
26 | return len + (*src0 == *src1); |
27 | src0 += 1, src1 += 1, len += 1; |
28 | if (*src0 != *src1) |
29 | return len + (*src0 == *src1); |
30 | src0 += 1, src1 += 1, len += 1; |
31 | if (*src0 != *src1) |
32 | return len + (*src0 == *src1); |
33 | src0 += 1, src1 += 1, len += 1; |
34 | if (*src0 != *src1) |
35 | return len + (*src0 == *src1); |
36 | src0 += 1, src1 += 1, len += 1; |
37 | if (*src0 != *src1) |
38 | return len + (*src0 == *src1); |
39 | src0 += 1, src1 += 1, len += 1; |
40 | } while (len < 256); |
41 | |
42 | return 256; |
43 | } |
44 | |
45 | static inline uint32_t compare258_c_static(const unsigned char *src0, const unsigned char *src1) { |
46 | if (*src0 != *src1) |
47 | return 0; |
48 | src0 += 1, src1 += 1; |
49 | if (*src0 != *src1) |
50 | return 1; |
51 | src0 += 1, src1 += 1; |
52 | |
53 | return compare256_c_static(src0, src1) + 2; |
54 | } |
55 | |
56 | Z_INTERNAL uint32_t compare258_c(const unsigned char *src0, const unsigned char *src1) { |
57 | return compare258_c_static(src0, src1); |
58 | } |
59 | |
60 | #define LONGEST_MATCH longest_match_c |
61 | #define COMPARE256 compare256_c_static |
62 | #define COMPARE258 compare258_c_static |
63 | |
64 | #include "match_tpl.h" |
65 | |
66 | #ifdef UNALIGNED_OK |
67 | /* UNALIGNED_OK, 16-bit integer comparison */ |
68 | static inline uint32_t compare256_unaligned_16_static(const unsigned char *src0, const unsigned char *src1) { |
69 | uint32_t len = 0; |
70 | |
71 | do { |
72 | if (*(uint16_t *)src0 != *(uint16_t *)src1) |
73 | return len + (*src0 == *src1); |
74 | src0 += 2, src1 += 2, len += 2; |
75 | if (*(uint16_t *)src0 != *(uint16_t *)src1) |
76 | return len + (*src0 == *src1); |
77 | src0 += 2, src1 += 2, len += 2; |
78 | if (*(uint16_t *)src0 != *(uint16_t *)src1) |
79 | return len + (*src0 == *src1); |
80 | src0 += 2, src1 += 2, len += 2; |
81 | if (*(uint16_t *)src0 != *(uint16_t *)src1) |
82 | return len + (*src0 == *src1); |
83 | src0 += 2, src1 += 2, len += 2; |
84 | } while (len < 256); |
85 | |
86 | return 256; |
87 | } |
88 | |
89 | static inline uint32_t compare258_unaligned_16_static(const unsigned char *src0, const unsigned char *src1) { |
90 | if (*(uint16_t *)src0 != *(uint16_t *)src1) |
91 | return (*src0 == *src1); |
92 | |
93 | return compare256_unaligned_16_static(src0: src0+2, src1: src1+2) + 2; |
94 | } |
95 | |
96 | Z_INTERNAL uint32_t compare258_unaligned_16(const unsigned char *src0, const unsigned char *src1) { |
97 | return compare258_unaligned_16_static(src0, src1); |
98 | } |
99 | |
100 | #define LONGEST_MATCH longest_match_unaligned_16 |
101 | #define COMPARE256 compare256_unaligned_16_static |
102 | #define COMPARE258 compare258_unaligned_16_static |
103 | |
104 | #include "match_tpl.h" |
105 | |
106 | #ifdef HAVE_BUILTIN_CTZ |
107 | /* UNALIGNED_OK, 32-bit integer comparison */ |
108 | static inline uint32_t compare256_unaligned_32_static(const unsigned char *src0, const unsigned char *src1) { |
109 | uint32_t len = 0; |
110 | |
111 | do { |
112 | uint32_t sv = *(uint32_t *)src0; |
113 | uint32_t mv = *(uint32_t *)src1; |
114 | uint32_t diff = sv ^ mv; |
115 | |
116 | if (diff) { |
117 | uint32_t match_byte = __builtin_ctz(diff) / 8; |
118 | return len + match_byte; |
119 | } |
120 | |
121 | src0 += 4, src1 += 4, len += 4; |
122 | } while (len < 256); |
123 | |
124 | return 256; |
125 | } |
126 | |
127 | static inline uint32_t compare258_unaligned_32_static(const unsigned char *src0, const unsigned char *src1) { |
128 | if (*(uint16_t *)src0 != *(uint16_t *)src1) |
129 | return (*src0 == *src1); |
130 | |
131 | return compare256_unaligned_32_static(src0: src0+2, src1: src1+2) + 2; |
132 | } |
133 | |
134 | Z_INTERNAL uint32_t compare258_unaligned_32(const unsigned char *src0, const unsigned char *src1) { |
135 | return compare258_unaligned_32_static(src0, src1); |
136 | } |
137 | |
138 | #define LONGEST_MATCH longest_match_unaligned_32 |
139 | #define COMPARE256 compare256_unaligned_32_static |
140 | #define COMPARE258 compare258_unaligned_32_static |
141 | |
142 | #include "match_tpl.h" |
143 | |
144 | #endif |
145 | |
146 | #if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) |
147 | /* UNALIGNED64_OK, 64-bit integer comparison */ |
148 | static inline uint32_t compare256_unaligned_64_static(const unsigned char *src0, const unsigned char *src1) { |
149 | uint32_t len = 0; |
150 | |
151 | do { |
152 | uint64_t sv = *(uint64_t *)src0; |
153 | uint64_t mv = *(uint64_t *)src1; |
154 | uint64_t diff = sv ^ mv; |
155 | |
156 | if (diff) { |
157 | uint64_t match_byte = __builtin_ctzll(diff) / 8; |
158 | return len + (uint32_t)match_byte; |
159 | } |
160 | |
161 | src0 += 8, src1 += 8, len += 8; |
162 | } while (len < 256); |
163 | |
164 | return 256; |
165 | } |
166 | |
167 | static inline uint32_t compare258_unaligned_64_static(const unsigned char *src0, const unsigned char *src1) { |
168 | if (*(uint16_t *)src0 != *(uint16_t *)src1) |
169 | return (*src0 == *src1); |
170 | |
171 | return compare256_unaligned_64_static(src0: src0+2, src1: src1+2) + 2; |
172 | } |
173 | |
174 | Z_INTERNAL uint32_t compare258_unaligned_64(const unsigned char *src0, const unsigned char *src1) { |
175 | return compare258_unaligned_64_static(src0, src1); |
176 | } |
177 | |
178 | #define LONGEST_MATCH longest_match_unaligned_64 |
179 | #define COMPARE256 compare256_unaligned_64_static |
180 | #define COMPARE258 compare258_unaligned_64_static |
181 | |
182 | #include "match_tpl.h" |
183 | |
184 | #endif |
185 | |
186 | #endif |
187 | |