1 /* Optimized memchr with sse2
2 Copyright (C) 2011-2020 Free Software Foundation, Inc.
3 Contributed by Intel Corporation.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
24 # define CFI_PUSH(REG) \
25 cfi_adjust_cfa_offset (4); \
26 cfi_rel_offset (REG, 0)
28 # define CFI_POP(REG) \
29 cfi_adjust_cfa_offset (-4); \
32 # define PUSH(REG) pushl REG; CFI_PUSH (REG)
33 # define POP(REG) popl REG; CFI_POP (REG)
39 # ifndef USE_AS_RAWMEMCHR
41 # define RETURN POP(%edi); ret; CFI_PUSH(%edi);
45 # define MEMCHR __memchr_sse2_bsf
52 movd STR2(%esp), %xmm1
54 # ifndef USE_AS_RAWMEMCHR
61 punpcklbw %xmm1, %xmm1
62 punpcklbw %xmm1, %xmm1
65 pshufd $0, %xmm1, %xmm1
72 /* Check if there is a match. */
75 je L(unaligned_no_match_1)
76 /* Check which byte is a match. */
79 # ifndef USE_AS_RAWMEMCHR
87 L(unaligned_no_match_1):
88 # ifndef USE_AS_RAWMEMCHR
107 # ifndef USE_AS_RAWMEMCHR
113 /* Handle unaligned string. */
115 # ifndef USE_AS_RAWMEMCHR
128 /* Check if there is a match. */
130 /* Remove the leading bytes. */
133 je L(unaligned_no_match)
134 /* Check which byte is a match. */
137 # ifndef USE_AS_RAWMEMCHR
150 L(unaligned_no_match):
151 # ifndef USE_AS_RAWMEMCHR
152 /* Calculate the last acceptable address and check for possible
153 addition overflow by using satured math:
155 edx |= -(edx < ecx) */
167 /* Loop start on aligned string. */
169 # ifndef USE_AS_RAWMEMCHR
181 # ifndef USE_AS_RAWMEMCHR
182 movdqa 16(%edi), %xmm2
184 movdqa 16(%edx), %xmm2
191 # ifndef USE_AS_RAWMEMCHR
192 movdqa 32(%edi), %xmm3
194 movdqa 32(%edx), %xmm3
201 # ifndef USE_AS_RAWMEMCHR
202 movdqa 48(%edi), %xmm4
204 movdqa 48(%edx), %xmm4
208 # ifndef USE_AS_RAWMEMCHR
217 # ifndef USE_AS_RAWMEMCHR
224 # ifndef USE_AS_RAWMEMCHR
236 # ifndef USE_AS_RAWMEMCHR
237 movdqa 16(%edi), %xmm2
239 movdqa 16(%edx), %xmm2
246 # ifndef USE_AS_RAWMEMCHR
247 movdqa 32(%edi), %xmm3
249 movdqa 32(%edx), %xmm3
256 # ifndef USE_AS_RAWMEMCHR
257 movdqa 48(%edi), %xmm3
259 movdqa 48(%edx), %xmm3
264 # ifndef USE_AS_RAWMEMCHR
272 # ifndef USE_AS_RAWMEMCHR
283 # ifndef USE_AS_RAWMEMCHR
287 movdqa 16(%edi), %xmm2
288 movdqa 32(%edi), %xmm3
289 movdqa 48(%edi), %xmm4
292 movdqa 16(%edx), %xmm2
293 movdqa 32(%edx), %xmm3
294 movdqa 48(%edx), %xmm4
306 # ifndef USE_AS_RAWMEMCHR
315 # ifndef USE_AS_RAWMEMCHR
329 # ifndef USE_AS_RAWMEMCHR
330 movdqa 32(%edi), %xmm3
332 movdqa 32(%edx), %xmm3
337 # ifndef USE_AS_RAWMEMCHR
338 pcmpeqb 48(%edi), %xmm1
340 pcmpeqb 48(%edx), %xmm1
349 # ifndef USE_AS_RAWMEMCHR
350 lea 48(%edi, %eax), %eax
353 lea 48(%edx, %eax), %eax
357 # ifndef USE_AS_RAWMEMCHR
370 movdqa 16(%edi), %xmm2
376 movdqa 32(%edi), %xmm3
384 pcmpeqb 48(%edi), %xmm1
401 pcmpeqb 16(%edi), %xmm1
411 # ifndef USE_AS_RAWMEMCHR
412 lea -16(%eax, %edi), %eax
415 lea -16(%eax, %edx), %eax
422 # ifndef USE_AS_RAWMEMCHR
433 # ifndef USE_AS_RAWMEMCHR
434 lea 16(%eax, %edi), %eax
437 lea 16(%eax, %edx), %eax
444 # ifndef USE_AS_RAWMEMCHR
445 lea 32(%eax, %edi), %eax
448 lea 32(%eax, %edx), %eax
452 # ifndef USE_AS_RAWMEMCHR
469 lea 16(%edi, %eax), %eax
479 lea 32(%edi, %eax), %eax
489 lea 48(%edi, %eax), %eax
495 # ifndef USE_AS_RAWMEMCHR