[flang] Fix crash in HLFIR generation (#118399)
[llvm-project.git] / libc / AOR_v20.02 / string / aarch64 / memchr-sve.S
blob4261bf8543f846be671eb2da1fcd6f202798c5e3
1 /*
2  * memchr - find a character in a memory zone
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         .globl  __memchr_aarch64_sve
20         .type   __memchr_aarch64_sve, %function
21         .p2align 4
22 __memchr_aarch64_sve:
23         dup     z1.b, w1                        /* duplicate c to a vector */
24         setffr                                  /* initialize FFR */
25         mov     x3, 0                           /* initialize off */
26         nop
28 0:      whilelo p1.b, x3, x2                    /* make sure off < max */
29         b.none  9f
31         /* Read a vector's worth of bytes, bounded by max,
32            stopping on first fault.  */
33         ldff1b  z0.b, p1/z, [x0, x3]
34         rdffrs  p0.b, p1/z
35         b.nlast 2f
37         /* First fault did not fail: the vector bounded by max is valid.
38            Avoid depending on the contents of FFR beyond the branch.  */
39         incb    x3                              /* speculate increment */
40         cmpeq   p2.b, p1/z, z0.b, z1.b          /* search for c */
41         b.none  0b
42         decb    x3                              /* undo speculate */
44         /* Found C.  */
45 1:      brkb    p2.b, p1/z, p2.b        /* find the first c */
46         add     x0, x0, x3              /* form partial pointer */
47         incp    x0, p2.b                /* form final pointer to c */
48         ret
50         /* First fault failed: only some of the vector is valid.
51            Perform the comparison only on the valid bytes.  */
52 2:      cmpeq   p2.b, p0/z, z0.b, z1.b
53         b.any   1b
55         /* No C found.  Re-init FFR, increment, and loop.  */
56         setffr
57         incp    x3, p0.b
58         b       0b
60         /* Found end of count.  */
61 9:      mov     x0, 0                   /* return null */
62         ret
64         .size   __memchr_aarch64_sve, . - __memchr_aarch64_sve
65 #endif