[NFC][Py Reformat] Added more commits to .git-blame-ignore-revs
[llvm-project.git] / libc / AOR_v20.02 / string / aarch64 / strchr-sve.S
blob7a98ee19244eadc981bc2b9a09bd30b513d64dbc
1 /*
2  * strchr/strchrnul - find a character in a string
3  *
4  * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5  * See https://llvm.org/LICENSE.txt for license information.
6  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7  */
9 #if __ARM_FEATURE_SVE
10 /* Assumptions:
11  *
12  * ARMv8-a, AArch64
13  * SVE Available.
14  */
16         .arch   armv8-a+sve
17         .text
19 /* To build as strchrnul, define BUILD_STRCHRNUL before compiling this file.  */
20 #ifdef BUILD_STRCHRNUL
21 #define FUNC  __strchrnul_aarch64_sve
22 #else
23 #define FUNC  __strchr_aarch64_sve
24 #endif
26         .globl  FUNC
27         .type   FUNC, %function
28         .p2align 4
29 FUNC:
30         dup     z1.b, w1                /* replicate byte across vector */
31         setffr                          /* initialize FFR */
32         ptrue   p1.b                    /* all ones; loop invariant */
34         .p2align 4
35         /* Read a vector's worth of bytes, stopping on first fault.  */
36 0:      ldff1b  z0.b, p1/z, [x0, xzr]
37         rdffrs  p0.b, p1/z
38         b.nlast 2f
40         /* First fault did not fail: the whole vector is valid.
41            Avoid depending on the contents of FFR beyond the branch.  */
42         incb    x0                              /* speculate increment */
43         cmpeq   p2.b, p1/z, z0.b, z1.b          /* search for c */
44         cmpeq   p3.b, p1/z, z0.b, 0             /* search for 0 */
45         orrs    p4.b, p1/z, p2.b, p3.b          /* c | 0 */
46         b.none  0b
47         decb    x0                              /* undo speculate */
49         /* Found C or 0.  */
50 1:      brka    p4.b, p1/z, p4.b        /* find first such */
51         sub     x0, x0, 1               /* adjust pointer for that byte */
52         incp    x0, p4.b
53 #ifndef BUILD_STRCHRNUL
54         ptest   p4, p2.b                /* was first in c? */
55         csel    x0, xzr, x0, none       /* if there was no c, return null */
56 #endif
57         ret
59         /* First fault failed: only some of the vector is valid.
60            Perform the comparison only on the valid bytes.  */
61 2:      cmpeq   p2.b, p0/z, z0.b, z1.b          /* search for c */
62         cmpeq   p3.b, p0/z, z0.b, 0             /* search for 0 */
63         orrs    p4.b, p0/z, p2.b, p3.b          /* c | 0 */
64         b.any   1b
66         /* No C or 0 found.  Re-init FFR, increment, and loop.  */
67         setffr
68         incp    x0, p0.b
69         b       0b
71         .size   FUNC, . - FUNC
72 #endif