[NFC][Py Reformat] Added more commits to .git-blame-ignore-revs
[llvm-project.git] / libc / AOR_v20.02 / string / aarch64 / strcmp-sve.S
blob35aac0b7d0d2aa423d9a800da83416348b4ddb19
1 /*
2  * __strcmp_aarch64_sve - compare two strings
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  __strcmp_aarch64_sve
20         .type   __strcmp_aarch64_sve, %function
21         .p2align 4
22 __strcmp_aarch64_sve:
23         setffr                          /* initialize FFR */
24         ptrue   p1.b, all               /* all ones; loop invariant */
25         mov     x2, 0                   /* initialize offset */
26         nop
28         /* Read a vector's worth of bytes, stopping on first fault.  */
29 0:      ldff1b  z0.b, p1/z, [x0, x2]
30         ldff1b  z1.b, p1/z, [x1, x2]
31         rdffrs  p0.b, p1/z
32         b.nlast 2f
34         /* First fault did not fail: the whole vector is valid.
35            Avoid depending on the contents of FFR beyond the branch.  */
36         incb    x2, all                 /* skip bytes for next round */
37         cmpeq   p2.b, p1/z, z0.b, z1.b  /* compare strings */
38         cmpne   p3.b, p1/z, z0.b, 0     /* search for ~zero */
39         nands   p2.b, p1/z, p2.b, p3.b  /* ~(eq & ~zero) -> ne | zero */
40         b.none  0b
42         /* Found end-of-string or inequality.  */
43 1:      brkb    p2.b, p1/z, p2.b        /* find first such */
44         lasta   w0, p2, z0.b            /* extract each char */
45         lasta   w1, p2, z1.b
46         sub     x0, x0, x1              /* return comparison */
47         ret
49         /* First fault failed: only some of the vector is valid.
50            Perform the comparison only on the valid bytes.  */
51 2:      incp    x2, p0.b                /* skip bytes for next round */
52         setffr                          /* re-init FFR for next round */
53         cmpeq   p2.b, p0/z, z0.b, z1.b  /* compare strings, as above */
54         cmpne   p3.b, p0/z, z0.b, 0
55         nands   p2.b, p0/z, p2.b, p3.b
56         b.none  0b
57         b       1b
59         .size   __strcmp_aarch64_sve, . - __strcmp_aarch64_sve
60 #endif