[NFC][Py Reformat] Added more commits to .git-blame-ignore-revs
[llvm-project.git] / libc / AOR_v20.02 / string / aarch64 / strnlen-sve.S
blob5d3957348a0c1d2d36311df3d608b52e84886c88
1 /*
2  * strnlen - calculate the length of a string with limit.
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  __strnlen_aarch64_sve
20         .type   __strnlen_aarch64_sve, %function
21         .p2align 4
22 __strnlen_aarch64_sve:
23         setffr                          /* initialize FFR */
24         mov     x2, 0                   /* initialize len */
25         b       1f
27         .p2align 4
28         /* We have off + vl <= max, and so may read the whole vector.  */
29 0:      ldff1b  z0.b, p0/z, [x0, x2]
30         rdffrs  p1.b, p0/z
31         b.nlast 2f
33         /* First fault did not fail: the whole vector is valid.
34            Avoid depending on the contents of FFR beyond the branch.  */
35         cmpeq   p2.b, p0/z, z0.b, 0
36         b.any   8f
37         incb    x2
39 1:      whilelo p0.b, x2, x1
40         b.last  0b
42         /* We have off + vl < max.  Test for off == max before proceeding.  */
43         b.none  9f
45         ldff1b  z0.b, p0/z, [x0, x2]
46         rdffrs  p1.b, p0/z
47         b.nlast 2f
49         /* First fault did not fail: the vector up to max is valid.
50            Avoid depending on the contents of FFR beyond the branch.
51            Compare for end-of-string, but there are no more bytes.  */
52         cmpeq   p2.b, p0/z, z0.b, 0
54         /* Found end-of-string or zero.  */
55 8:      brkb    p2.b, p0/z, p2.b
56         mov     x0, x2
57         incp    x0, p2.b
58         ret
60         /* First fault failed: only some of the vector is valid.
61            Perform the comparison only on the valid bytes.  */
62 2:      cmpeq   p2.b, p1/z, z0.b, 0
63         b.any   8b
65         /* No inequality or zero found.  Re-init FFR, incr and loop.  */
66         setffr
67         incp    x2, p1.b
68         b       1b
70         /* End of count.  Return max.  */
71 9:      mov     x0, x2
72         ret
74         .size   __strnlen_aarch64_sve, . - __strnlen_aarch64_sve
75 #endif