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/strrchr-sve.S
39536 views
1
/*
2
* strrchr - find the last of a character in a string
3
*
4
* Copyright (c) 2019-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 (__strrchr_aarch64_sve)
19
dup z1.b, w1 /* replicate byte across vector */
20
setffr /* initialize FFR */
21
ptrue p1.b /* all ones; loop invariant */
22
mov x2, 0 /* no match found so far */
23
pfalse p2.b
24
25
.p2align 4
26
/* Read a vector's worth of bytes, stopping on first fault. */
27
0: ldff1b z0.b, p1/z, [x0, xzr]
28
rdffrs p0.b, p1/z
29
b.nlast 1f
30
31
/* First fault did not fail: the whole vector is valid.
32
Avoid depending on the contents of FFR beyond the branch. */
33
incb x0, all /* skip bytes this round */
34
cmpeq p3.b, p1/z, z0.b, 0 /* search for 0 */
35
b.any 3f
36
37
cmpeq p3.b, p1/z, z0.b, z1.b /* search for c; no eos */
38
b.none 0b
39
40
mov x2, x0 /* save advanced base */
41
mov p2.b, p3.b /* save current search */
42
b 0b
43
44
/* First fault failed: only some of the vector is valid.
45
Perform the comparisions only on the valid bytes. */
46
1: cmpeq p3.b, p0/z, z0.b, 0 /* search for 0 */
47
b.any 2f
48
49
cmpeq p3.b, p0/z, z0.b, z1.b /* search for c; no eos */
50
mov x3, x0
51
incp x0, p0.b /* skip bytes this round */
52
setffr /* re-init FFR */
53
b.none 0b
54
55
addvl x2, x3, 1 /* save advanced base */
56
mov p2.b, p3.b /* save current search */
57
b 0b
58
59
/* Found end-of-string. */
60
2: incb x0, all /* advance base */
61
3: brka p3.b, p1/z, p3.b /* mask after first 0 */
62
cmpeq p3.b, p3/z, z0.b, z1.b /* search for c not after eos */
63
b.any 4f
64
65
/* No C within last vector. Did we have one before? */
66
cbz x2, 5f
67
mov x0, x2 /* restore advanced base */
68
mov p3.b, p2.b /* restore saved search */
69
70
/* Find the *last* match in the predicate. This is slightly
71
more complicated than finding the first match. */
72
4: rev p3.b, p3.b /* reverse the bits */
73
brka p3.b, p1/z, p3.b /* find position of last match */
74
decp x0, p3.b /* retard pointer to last match */
75
ret
76
77
/* No C whatsoever. Return NULL. */
78
5: mov x0, 0
79
ret
80
81
END (__strrchr_aarch64_sve)
82
83