1 /* Placeholder function, not used by any processor at the moment.
2 Copyright (C) 2022-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 /* UNUSED. Exists purely as reference implementation. */
21 #include <isa-level.h>
23 #if ISA_SHOULD_BUILD (4)
30 # define VPBROADCAST vpbroadcastd
32 # define VPCMPNE vpcmpneqd
33 # define VPMINU vpminud
34 # define VPTEST vptestmd
35 # define VPTESTN vptestnmd
39 # define VPBROADCAST vpbroadcastb
41 # define VPCMPNE vpcmpneqb
42 # define VPMINU vpminub
43 # define VPTEST vptestmb
44 # define VPTESTN vptestnmb
47 # define PAGE_SIZE 4096
48 # define CHAR_PER_VEC (VEC_SIZE / CHAR_SIZE)
49 # define VEC_MATCH_MASK ((1 << CHAR_PER_VEC) - 1)
51 .section SECTION(.text), "ax", @progbits
52 /* Aligning entry point to 64 byte, provides better performance for
53 one vector length string. */
54 ENTRY_P2ALIGN (STRCHR, 6)
56 /* Broadcast CHAR to VMM(0). */
57 VPBROADCAST %esi, %VMM(0)
60 cmpl $((PAGE_SIZE - VEC_SIZE) << 20), %eax
64 VPCMPNE %VMM(1), %VMM(0), %k1
65 VPTEST %VMM(1), %VMM(1), %k0{%k1}
67 /* Compare [w]char for null, mask bit will be set for match. */
70 sub $VEC_MATCH_MASK, %VRAX
79 leaq (%rdi, %rax, CHAR_SIZE), %rax
83 # ifndef USE_AS_STRCHRNUL
99 leaq (%rdi, %rax, CHAR_SIZE), %rax
104 # ifndef USE_AS_STRCHRNUL
105 cmp (%rax), %CHAR_REG
113 # ifdef USE_AS_WCSCHR
114 /* Calculate number of compare result bits to be skipped for
115 wide string alignment adjustment. */
116 andl $(VEC_SIZE - 1), %ecx
119 /* ecx contains number of w[char] to be skipped as a result
120 of address alignment. */
121 andq $-VEC_SIZE, %rax
123 VMOVA (%rax), %VMM(1)
124 VPCMPNE %VMM(1), %VMM(0), %k1
125 VPTEST %VMM(1), %VMM(1), %k0{%k1}
127 # ifdef USE_AS_WCSCHR
128 sub $VEC_MATCH_MASK, %VRAX
132 /* Ignore number of character for alignment adjustment. */
137 # ifdef USE_AS_WCSCHR
138 leaq (%rdi, %rax, CHAR_SIZE), %rax
143 # ifndef USE_AS_STRCHRNUL
144 cmp (%rax), %CHAR_REG
150 /* Align rax to VEC_SIZE. */
151 andq $-VEC_SIZE, %rdi
153 /* Loop unroll 4 times for 4 vector loop. */
154 VMOVA VEC_SIZE(%rdi), %VMM(1)
155 VPCMPNE %VMM(1), %VMM(0), %k1
156 VPTEST %VMM(1), %VMM(1), %k0{%k1}
158 /* Increment rdi by vector size for further comparison and
160 subq $-VEC_SIZE, %rdi
163 # ifdef USE_AS_WCSCHR
164 sub $VEC_MATCH_MASK, %VRAX
170 VMOVA VEC_SIZE(%rdi), %VMM(1)
171 VPCMPNE %VMM(1), %VMM(0), %k1
172 VPTEST %VMM(1), %VMM(1), %k0{%k1}
174 # ifdef USE_AS_WCSCHR
175 sub $VEC_MATCH_MASK, %VRAX
181 VMOVA (VEC_SIZE * 2)(%rdi), %VMM(1)
182 VPCMPNE %VMM(1), %VMM(0), %k1
183 VPTEST %VMM(1), %VMM(1), %k0{%k1}
185 # ifdef USE_AS_WCSCHR
186 sub $VEC_MATCH_MASK, %VRAX
192 VMOVA (VEC_SIZE * 3)(%rdi), %VMM(1)
193 VPCMPNE %VMM(1), %VMM(0), %k1
194 VPTEST %VMM(1), %VMM(1), %k0{%k1}
196 # ifdef USE_AS_WCSCHR
197 sub $VEC_MATCH_MASK, %VRDX
204 /* Align address to VEC_SIZE * 4 for loop. */
205 andq $-(VEC_SIZE * 4), %rdi
207 /* VPMINU and VPCMP combination provide better performance as
208 compared to alternative combinations. */
209 VMOVA (VEC_SIZE * 4)(%rdi), %VMM(1)
210 VMOVA (VEC_SIZE * 5)(%rdi), %VMM(2)
211 VMOVA (VEC_SIZE * 6)(%rdi), %VMM(3)
212 VMOVA (VEC_SIZE * 7)(%rdi), %VMM(4)
214 VPCMPNE %VMM(1), %VMM(0), %k1
215 VPCMPNE %VMM(2), %VMM(0), %k2
217 VPMINU %VMM(2), %VMM(1), %VMM(2)
219 VPCMPNE %VMM(3), %VMM(0), %k3{%k1}
220 VPCMPNE %VMM(4), %VMM(0), %k4{%k2}
222 VPMINU %VMM(4), %VMM(3), %VMM(4)
223 VPMINU %VMM(2), %VMM(4), %VMM(4){%k3}{z}
225 VPTEST %VMM(4), %VMM(4), %k5{%k4}
228 subq $-(VEC_SIZE * 4), %rdi
229 # ifdef USE_AS_WCSCHR
230 sub $VEC_MATCH_MASK, %VRDX
236 VPTEST %VMM(1), %VMM(1), %k0{%k1}
238 # ifdef USE_AS_WCSCHR
239 sub $VEC_MATCH_MASK, %VRAX
245 VPTEST %VMM(2), %VMM(2), %k0{%k2}
247 /* At this point, if k1 is non zero, null char must be in the
249 # ifdef USE_AS_WCSCHR
250 sub $VEC_MATCH_MASK, %VRAX
256 VPTEST %VMM(3), %VMM(3), %k0{%k3}
258 # ifdef USE_AS_WCSCHR
259 sub $VEC_MATCH_MASK, %VRAX
264 /* At this point null [w]char must be in the fourth vector so no
269 leaq (VEC_SIZE * 3)(%rdi, %rdx, CHAR_SIZE), %rax
270 # ifndef USE_AS_STRCHRNUL
271 cmp (%rax), %CHAR_REG
276 # ifndef USE_AS_STRCHRNUL