29 #ifndef SURICATA_UTIL_MEMCMP_H
30 #define SURICATA_UTIL_MEMCMP_H
37 static inline int SCMemcmpLowercase(
const void *,
const void *,
size_t);
42 MemcmpLowercase(
const void *s1,
const void *s2,
size_t n)
44 for (
size_t i = 0; i < n; i++) {
45 if (((uint8_t *)s1)[i] !=
u8_tolower(((uint8_t *)s2)[i]))
52 #if defined(__SSE4_2__)
53 #include <nmmintrin.h>
54 #define SCMEMCMP_BYTES 16
56 static inline int SCMemcmp(
const void *s1,
const void *s2,
size_t n)
62 if (
likely(n -
m < SCMEMCMP_BYTES)) {
63 return memcmp(s1, s2, n -
m) ? 1 : 0;
67 __m128i b1 = _mm_loadu_si128((
const __m128i *)s1);
68 __m128i b2 = _mm_loadu_si128((
const __m128i *)s2);
71 r = _mm_cmpestri(b1, SCMEMCMP_BYTES, b2, SCMEMCMP_BYTES,
72 _SIDD_CMP_EQUAL_EACH | _SIDD_MASKED_NEGATIVE_POLARITY);
76 }
while (r == SCMEMCMP_BYTES);
78 return ((
m == n) ? 0 : 1);
82 static char scmemcmp_uppercase[16]
__attribute__((aligned(16))) = {
83 'A',
'Z', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
89 static inline int SCMemcmpLowercase(
const void *s1,
const void *s2,
size_t n)
94 __m128i ucase = _mm_load_si128((
const __m128i *) scmemcmp_uppercase);
95 __m128i uplow = _mm_set1_epi8(0x20);
98 const size_t len = n -
m;
100 return MemcmpLowercase(s1, s2,
len);
103 __m128i b1 = _mm_loadu_si128((
const __m128i *)s1);
104 __m128i b2 = _mm_loadu_si128((
const __m128i *)s2);
107 __m128i mask = _mm_cmpestrm(ucase, 2, b2,
len, _SIDD_CMP_RANGES | _SIDD_UNIT_MASK);
110 mask = _mm_and_si128(uplow, mask);
113 b2 = _mm_add_epi8(b2, mask);
116 r = _mm_cmpestri(b1, SCMEMCMP_BYTES, b2, SCMEMCMP_BYTES,
117 _SIDD_CMP_EQUAL_EACH | _SIDD_MASKED_NEGATIVE_POLARITY);
119 s1 += SCMEMCMP_BYTES;
120 s2 += SCMEMCMP_BYTES;
121 }
while (r == SCMEMCMP_BYTES);
123 return ((
m == n) ? 0 : 1);
126 #elif defined(__SSE4_1__)
127 #include <smmintrin.h>
128 #define SCMEMCMP_BYTES 16
130 static inline int SCMemcmp(
const void *s1,
const void *s2,
size_t len)
135 return memcmp(s1, s2,
len -
offset) ? 1 : 0;
139 __m128i b1 = _mm_loadu_si128((
const __m128i *)s1);
140 __m128i b2 = _mm_loadu_si128((
const __m128i *)s2);
141 __m128i c = _mm_cmpeq_epi8(b1, b2);
143 if (_mm_movemask_epi8(c) != 0x0000FFFF) {
148 s1 += SCMEMCMP_BYTES;
149 s2 += SCMEMCMP_BYTES;
155 #define UPPER_LOW 0x40
156 #define UPPER_HIGH 0x5B
158 static inline int SCMemcmpLowercase(
const void *s1,
const void *s2,
size_t len)
161 __m128i b1, b2, mask1, mask2, upper1, upper2, uplow;
164 upper1 = _mm_set1_epi8(UPPER_LOW);
165 upper2 = _mm_set1_epi8(UPPER_HIGH);
166 uplow = _mm_set1_epi8(0x20);
170 return MemcmpLowercase(s1, s2,
len -
offset);
174 b1 = _mm_loadu_si128((
const __m128i *) s1);
175 b2 = _mm_loadu_si128((
const __m128i *) s2);
178 mask1 = _mm_cmpgt_epi8(b2, upper1);
180 mask2 = _mm_cmplt_epi8(b2, upper2);
182 mask1 = _mm_cmpeq_epi8(mask1, mask2);
185 mask1 = _mm_and_si128(uplow, mask1);
187 b2 = _mm_add_epi8(b2, mask1);
189 mask1 = _mm_cmpeq_epi8(b1, b2);
191 if (_mm_movemask_epi8(mask1) != 0x0000FFFF) {
196 s1 += SCMEMCMP_BYTES;
197 s2 += SCMEMCMP_BYTES;
203 #elif defined(__SSE3__)
204 #include <pmmintrin.h>
205 #define SCMEMCMP_BYTES 16
207 static inline int SCMemcmp(
const void *s1,
const void *s2,
size_t len)
214 return memcmp(s1, s2,
len -
offset) ? 1 : 0;
218 b1 = _mm_loadu_si128((
const __m128i *) s1);
219 b2 = _mm_loadu_si128((
const __m128i *) s2);
220 c = _mm_cmpeq_epi8(b1, b2);
222 if (_mm_movemask_epi8(c) != 0x0000FFFF) {
227 s1 += SCMEMCMP_BYTES;
228 s2 += SCMEMCMP_BYTES;
234 #define UPPER_LOW 0x40
235 #define UPPER_HIGH 0x5B
236 #define UPPER_DELTA 0xDF
238 static inline int SCMemcmpLowercase(
const void *s1,
const void *s2,
size_t len)
241 __m128i b1, b2, mask1, mask2, upper1, upper2, delta;
244 upper1 = _mm_set1_epi8(UPPER_LOW);
245 upper2 = _mm_set1_epi8(UPPER_HIGH);
246 delta = _mm_set1_epi8(UPPER_DELTA);
250 return MemcmpLowercase(s1, s2,
len -
offset);
254 b1 = _mm_loadu_si128((
const __m128i *) s1);
255 b2 = _mm_loadu_si128((
const __m128i *) s2);
258 mask1 = _mm_cmpgt_epi8(b2, upper1);
260 mask2 = _mm_cmplt_epi8(b2, upper2);
262 mask1 = _mm_cmpeq_epi8(mask1, mask2);
265 mask1 = _mm_subs_epu8(mask1, delta);
267 b2 = _mm_add_epi8(b2, mask1);
270 mask1 = _mm_cmpeq_epi8(b1, b2);
272 if (_mm_movemask_epi8(mask1) != 0x0000FFFF) {
277 s1 += SCMEMCMP_BYTES;
278 s2 += SCMEMCMP_BYTES;
289 #define SCMemcmp(a,b,c) ({ \
290 memcmp((a), (b), (c)) ? 1 : 0; \
293 static inline int SCMemcmpLowercase(
const void *s1,
const void *s2,
size_t len)
295 return MemcmpLowercase(s1, s2,
len);
300 static inline int SCBufferCmp(
const void *s1,
size_t len1,
const void *s2,
size_t len2)
304 }
else if (len1 < len2) {