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 | */ |
8 | |
9 | #if __ARM_FEATURE_SVE |
10 | /* Assumptions: |
11 | * |
12 | * ARMv8-a, AArch64 |
13 | * SVE Available. |
14 | */ |
15 | |
16 | .arch armv8-a+sve |
17 | .text |
18 | |
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 |
26 | |
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 |
32 | |
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 |
38 | |
39 | 1: whilelo p0.b, x2, x1 |
40 | b.last 0b |
41 | |
42 | /* We have off + vl < max. Test for off == max before proceeding. */ |
43 | b.none 9f |
44 | |
45 | ldff1b z0.b, p0/z, [x0, x2] |
46 | rdffrs p1.b, p0/z |
47 | b.nlast 2f |
48 | |
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 |
53 | |
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 |
59 | |
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 |
64 | |
65 | /* No inequality or zero found. Re-init FFR, incr and loop. */ |
66 | setffr |
67 | incp x2, p1.b |
68 | b 1b |
69 | |
70 | /* End of count. Return max. */ |
71 | 9: mov x0, x2 |
72 | ret |
73 | |
74 | .size __strnlen_aarch64_sve, . - __strnlen_aarch64_sve |
75 | #endif |
76 | |