[NFC][Py Reformat] Added more commits to .git-blame-ignore-revs
[llvm-project.git] / libc / AOR_v20.02 / string / aarch64 / strncmp-sve.S
blobf5d4f95fdf0fa4b96cc2c840b508e3ee5813f4bd
1 /*
2  * strncmp - compare two strings 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  __strncmp_aarch64_sve
20         .type   __strncmp_aarch64_sve, %function
21         .p2align 4
22 __strncmp_aarch64_sve:
23         setffr                          /* initialize FFR */
24         mov     x3, 0                   /* initialize off */
26 0:      whilelo p0.b, x3, x2            /* while off < max */
27         b.none  9f
29         ldff1b  z0.b, p0/z, [x0, x3]
30         ldff1b  z1.b, p0/z, [x1, x3]
31         rdffrs  p1.b, p0/z
32         b.nlast 2f
34         /* First fault did not fail: the vector up to max is valid.
35            Avoid depending on the contents of FFR beyond the branch.
36            Increment for a whole vector, even if we've only read a partial.
37            This is significantly cheaper than INCP, and since OFF is not
38            used after the loop it is ok to increment OFF past MAX.  */
39         incb    x3
40         cmpeq   p1.b, p0/z, z0.b, z1.b  /* compare strings */
41         cmpne   p2.b, p0/z, z0.b, 0     /* search for ~zero */
42         nands   p2.b, p0/z, p1.b, p2.b  /* ~(eq & ~zero) -> ne | zero */
43         b.none  0b
45         /* Found end-of-string or inequality.  */
46 1:      brkb    p2.b, p0/z, p2.b        /* find first such */
47         lasta   w0, p2, z0.b            /* extract each char */
48         lasta   w1, p2, z1.b
49         sub     x0, x0, x1              /* return comparison */
50         ret
52         /* First fault failed: only some of the vector is valid.
53            Perform the comparison only on the valid bytes.  */
54 2:      cmpeq   p2.b, p1/z, z0.b, z1.b  /* compare strings, as above */
55         cmpne   p3.b, p1/z, z0.b, 0
56         nands   p2.b, p1/z, p2.b, p3.b
57         b.any   1b
59         /* No inequality or zero found.  Re-init FFR, incr and loop.  */
60         setffr
61         incp    x3, p1.b
62         b       0b
64         /* Found end-of-count.  */
65 9:      mov     x0, 0                   /* return equal */
66         ret
68         .size   __strncmp_aarch64_sve, . - __strncmp_aarch64_sve
69 #endif