29 #ifndef SURICATA_UTIL_MEMCMP_H
30 #define SURICATA_UTIL_MEMCMP_H
38 static inline int SCMemcmpLowercase(
const void *,
const void *,
size_t);
43 MemcmpLowercase(
const void *s1,
const void *s2,
size_t n)
45 for (
size_t i = 0; i < n; i++) {
46 if (((uint8_t *)s1)[i] !=
u8_tolower(((uint8_t *)s2)[i]))
53 #if defined(__SSE4_2__)
54 #include <nmmintrin.h>
55 #define SCMEMCMP_BYTES 16
57 static inline int SCMemcmp(
const void *s1,
const void *s2,
size_t n)
63 if (
likely(n -
m < SCMEMCMP_BYTES)) {
64 return memcmp(s1, s2, n -
m) ? 1 : 0;
68 __m128i b1 = _mm_loadu_si128((
const __m128i *)s1);
69 __m128i b2 = _mm_loadu_si128((
const __m128i *)s2);
72 r = _mm_cmpestri(b1, SCMEMCMP_BYTES, b2, SCMEMCMP_BYTES,
73 _SIDD_CMP_EQUAL_EACH | _SIDD_MASKED_NEGATIVE_POLARITY);
77 }
while (r == SCMEMCMP_BYTES);
79 return ((
m == n) ? 0 : 1);
83 static char scmemcmp_uppercase[16]
__attribute__((aligned(16))) = {
84 'A',
'Z', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
90 static inline int SCMemcmpLowercase(
const void *s1,
const void *s2,
size_t n)
95 __m128i ucase = _mm_load_si128((
const __m128i *) scmemcmp_uppercase);
96 __m128i uplow = _mm_set1_epi8(0x20);
99 const size_t len = n -
m;
101 return MemcmpLowercase(s1, s2,
len);
104 __m128i b1 = _mm_loadu_si128((
const __m128i *)s1);
105 __m128i b2 = _mm_loadu_si128((
const __m128i *)s2);
108 __m128i mask = _mm_cmpestrm(ucase, 2, b2,
len, _SIDD_CMP_RANGES | _SIDD_UNIT_MASK);
111 mask = _mm_and_si128(uplow, mask);
114 b2 = _mm_add_epi8(b2, mask);
117 r = _mm_cmpestri(b1, SCMEMCMP_BYTES, b2, SCMEMCMP_BYTES,
118 _SIDD_CMP_EQUAL_EACH | _SIDD_MASKED_NEGATIVE_POLARITY);
120 s1 += SCMEMCMP_BYTES;
121 s2 += SCMEMCMP_BYTES;
122 }
while (r == SCMEMCMP_BYTES);
124 return ((
m == n) ? 0 : 1);
127 #elif defined(__SSE4_1__)
128 #include <smmintrin.h>
129 #define SCMEMCMP_BYTES 16
131 static inline int SCMemcmp(
const void *s1,
const void *s2,
size_t len)
136 return memcmp(s1, s2,
len -
offset) ? 1 : 0;
140 __m128i b1 = _mm_loadu_si128((
const __m128i *)s1);
141 __m128i b2 = _mm_loadu_si128((
const __m128i *)s2);
142 __m128i c = _mm_cmpeq_epi8(b1, b2);
144 if (_mm_movemask_epi8(c) != 0x0000FFFF) {
149 s1 += SCMEMCMP_BYTES;
150 s2 += SCMEMCMP_BYTES;
156 #define UPPER_LOW 0x40
157 #define UPPER_HIGH 0x5B
159 static inline int SCMemcmpLowercase(
const void *s1,
const void *s2,
size_t len)
162 __m128i b1, b2, mask1, mask2, upper1, upper2, uplow;
165 upper1 = _mm_set1_epi8(UPPER_LOW);
166 upper2 = _mm_set1_epi8(UPPER_HIGH);
167 uplow = _mm_set1_epi8(0x20);
171 return MemcmpLowercase(s1, s2,
len -
offset);
175 b1 = _mm_loadu_si128((
const __m128i *) s1);
176 b2 = _mm_loadu_si128((
const __m128i *) s2);
179 mask1 = _mm_cmpgt_epi8(b2, upper1);
181 mask2 = _mm_cmplt_epi8(b2, upper2);
183 mask1 = _mm_cmpeq_epi8(mask1, mask2);
186 mask1 = _mm_and_si128(uplow, mask1);
188 b2 = _mm_add_epi8(b2, mask1);
190 mask1 = _mm_cmpeq_epi8(b1, b2);
192 if (_mm_movemask_epi8(mask1) != 0x0000FFFF) {
197 s1 += SCMEMCMP_BYTES;
198 s2 += SCMEMCMP_BYTES;
204 #elif defined(__SSE3__)
205 #include <pmmintrin.h>
206 #define SCMEMCMP_BYTES 16
208 static inline int SCMemcmp(
const void *s1,
const void *s2,
size_t len)
215 return memcmp(s1, s2,
len -
offset) ? 1 : 0;
219 b1 = _mm_loadu_si128((
const __m128i *) s1);
220 b2 = _mm_loadu_si128((
const __m128i *) s2);
221 c = _mm_cmpeq_epi8(b1, b2);
223 if (_mm_movemask_epi8(c) != 0x0000FFFF) {
228 s1 += SCMEMCMP_BYTES;
229 s2 += SCMEMCMP_BYTES;
235 #define UPPER_LOW 0x40
236 #define UPPER_HIGH 0x5B
237 #define UPPER_DELTA 0xDF
239 static inline int SCMemcmpLowercase(
const void *s1,
const void *s2,
size_t len)
242 __m128i b1, b2, mask1, mask2, upper1, upper2, delta;
245 upper1 = _mm_set1_epi8(UPPER_LOW);
246 upper2 = _mm_set1_epi8(UPPER_HIGH);
247 delta = _mm_set1_epi8(UPPER_DELTA);
251 return MemcmpLowercase(s1, s2,
len -
offset);
255 b1 = _mm_loadu_si128((
const __m128i *) s1);
256 b2 = _mm_loadu_si128((
const __m128i *) s2);
259 mask1 = _mm_cmpgt_epi8(b2, upper1);
261 mask2 = _mm_cmplt_epi8(b2, upper2);
263 mask1 = _mm_cmpeq_epi8(mask1, mask2);
266 mask1 = _mm_subs_epu8(mask1, delta);
268 b2 = _mm_add_epi8(b2, mask1);
271 mask1 = _mm_cmpeq_epi8(b1, b2);
273 if (_mm_movemask_epi8(mask1) != 0x0000FFFF) {
278 s1 += SCMEMCMP_BYTES;
279 s2 += SCMEMCMP_BYTES;
290 #define SCMemcmp(a,b,c) ({ \
291 memcmp((a), (b), (c)) ? 1 : 0; \
294 static inline int SCMemcmpLowercase(
const void *s1,
const void *s2,
size_t len)
296 return MemcmpLowercase(s1, s2,
len);
301 static inline int SCBufferCmp(
const void *s1,
size_t len1,
const void *s2,
size_t len2)
305 }
else if (len1 < len2) {