1 /* strchr - find a character in a string
3 Copyright (C) 2014-2023 Free Software Foundation, Inc.
5 This file is part of the GNU C Library.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library. If not, see
19 <https://www.gnu.org/licenses/>. */
25 * ARMv8-a, AArch64, Advanced SIMD.
50 For each 16-byte chunk we calculate a 64-bit syndrome value with four bits
51 per byte. For even bytes, bits 0-1 are set if the relevant byte matched the
52 requested character, bits 2-3 are set if the byte is NUL (or matched), and
53 bits 4-7 are not used and must be zero if none of bits 0-3 are set). Odd
54 bytes set bits 4-7 so that adjacent bytes can be merged. Since the bits
55 in the syndrome reflect the order in which things occur in the original
56 string, counting trailing zeros identifies exactly which byte matched. */
61 dup vrepchr.16b, chrin
62 ld1 {vdata.16b}, [src]
64 dup vrepmask.8h, wtmp2
65 cmeq vhas_nul.16b, vdata.16b, 0
66 cmeq vhas_chr.16b, vdata.16b, vrepchr.16b
68 dup vrepmask2.8h, wtmp2
70 bit vhas_nul.16b, vhas_chr.16b, vrepmask.16b
71 and vhas_nul.16b, vhas_nul.16b, vrepmask2.16b
73 addp vend.16b, vhas_nul.16b, vhas_nul.16b /* 128->64 */
81 /* Tmp1 is an even multiple of 2 if the target character was
82 found first. Otherwise we've found the end of string. */
84 add result, srcin, tmp1, lsr 2
85 csel result, result, xzr, eq
91 cmeq vhas_chr.16b, vdata.16b, vrepchr.16b
92 cmhs vhas_nul.16b, vhas_chr.16b, vdata.16b
93 umaxp vend.16b, vhas_nul.16b, vhas_nul.16b
98 bif vhas_nul.16b, vhas_chr.16b, vrepmask.16b
99 and vhas_nul.16b, vhas_nul.16b, vrepmask2.16b
100 addp vend.16b, vhas_nul.16b, vhas_nul.16b /* 128->64 */
103 bit vhas_nul.16b, vhas_chr.16b, vrepmask.16b
104 and vhas_nul.16b, vhas_nul.16b, vrepmask2.16b
105 addp vend.16b, vhas_nul.16b, vhas_nul.16b /* 128->64 */
110 /* Tmp1 is an even multiple of 2 if the target character was
111 found first. Otherwise we've found the end of string. */
113 add result, src, tmp1, lsr 2
114 csel result, result, xzr, eq
118 libc_hidden_builtin_def (strchr)
119 weak_alias (strchr, index)