Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/arm-optimized-routines/string/aarch64/experimental/strncmp-sve.S
39536 views
1
/*
2
* strncmp - compare two strings with limit
3
*
4
* Copyright (c) 2018-2022, Arm Limited.
5
* SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
6
*/
7
8
#include "asmdefs.h"
9
10
.arch armv8-a+sve
11
12
/* Assumptions:
13
*
14
* ARMv8-a, AArch64
15
* SVE Available.
16
*/
17
18
ENTRY (__strncmp_aarch64_sve)
19
setffr /* initialize FFR */
20
mov x3, 0 /* initialize off */
21
22
0: whilelo p0.b, x3, x2 /* while off < max */
23
b.none 9f
24
25
ldff1b z0.b, p0/z, [x0, x3]
26
ldff1b z1.b, p0/z, [x1, x3]
27
rdffrs p1.b, p0/z
28
b.nlast 2f
29
30
/* First fault did not fail: the vector up to max is valid.
31
Avoid depending on the contents of FFR beyond the branch.
32
Increment for a whole vector, even if we've only read a partial.
33
This is significantly cheaper than INCP, and since OFF is not
34
used after the loop it is ok to increment OFF past MAX. */
35
incb x3
36
cmpeq p1.b, p0/z, z0.b, z1.b /* compare strings */
37
cmpne p2.b, p0/z, z0.b, 0 /* search for ~zero */
38
nands p2.b, p0/z, p1.b, p2.b /* ~(eq & ~zero) -> ne | zero */
39
b.none 0b
40
41
/* Found end-of-string or inequality. */
42
1: brkb p2.b, p0/z, p2.b /* find first such */
43
lasta w0, p2, z0.b /* extract each char */
44
lasta w1, p2, z1.b
45
sub x0, x0, x1 /* return comparison */
46
ret
47
48
/* First fault failed: only some of the vector is valid.
49
Perform the comparison only on the valid bytes. */
50
2: cmpeq p2.b, p1/z, z0.b, z1.b /* compare strings, as above */
51
cmpne p3.b, p1/z, z0.b, 0
52
nands p2.b, p1/z, p2.b, p3.b
53
b.any 1b
54
55
/* No inequality or zero found. Re-init FFR, incr and loop. */
56
setffr
57
incp x3, p1.b
58
b 0b
59
60
/* Found end-of-count. */
61
9: mov x0, 0 /* return equal */
62
ret
63
64
END (__strncmp_aarch64_sve)
65
66