Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/riscv/string/strchrnul.S
96309 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2024 Strahinja Stanisic <[email protected]>
5
*/
6
7
#include <machine/asm.h>
8
9
.weak strchrnul
10
.set strchrnul, __strchrnul
11
12
/*
13
* a0 - const char *str
14
* a1 - int c;
15
*/
16
ENTRY(__strchrnul)
17
/*
18
* a0 - const char *ptr;
19
* a1 - char cccccccc[8];
20
* a2 - char iter[8];
21
* a3 - char mask_end
22
*/
23
24
/* int to char */
25
andi a1, a1, 0xFF
26
27
/* t0 = 0x0101010101010101 */
28
li t0, 0x01010101
29
slli t1, t0, 32
30
or t0, t0, t1
31
32
/* t1 = 0x8080808080808080 */
33
slli t1, t0, 7
34
35
/* spread char across bytes */
36
mul a1, a1, t0
37
38
/* align_offset */
39
andi t2, a0, 0b111
40
41
/* align pointer */
42
andi a0, a0, ~0b111
43
44
/* if pointer is aligned skip to loop */
45
beqz t2, .Lloop
46
47
ld a2, (a0)
48
49
/* mask_start calculation */
50
slli t2, t2, 3
51
neg t2, t2
52
srl t2, t0, t2
53
54
/* fill bytes before start with non-zero */
55
or a3, a2, t2
56
57
xor a2, a2, a1
58
or a2, a2, t2
59
60
/* has_zero for \0 */
61
not t3, a3
62
not t2, a2
63
sub a3, a3, t0
64
sub a2, a2, t0
65
and a3, a3, t3
66
and a2, a2, t2
67
and a3, a3, t1
68
and a2, a2, t1
69
70
71
/* if \0 or c was found, exit */
72
or a2, a2, a3
73
addi a0, a0, 8
74
bnez a2, .Lfind_char
75
76
77
.Lloop:
78
ld a2, (a0)
79
80
/* has_zero for both \0 or c */
81
xor a3, a2, a1
82
83
not t2, a2
84
not t3, a3
85
sub a2, a2, t0
86
sub a3, a3, t0
87
and a2, a2, t2
88
and a3, a3, t3
89
and a2, a2, t1
90
and a3, a3, t1
91
92
/* if \0 or c was found, exit */
93
or a2, a2, a3
94
addi a0, a0, 8
95
beqz a2, .Lloop
96
97
.Lfind_char:
98
addi a0, a0, -8
99
100
/* isolate lowest set bit */
101
neg t0, a2
102
and a2, a2, t0
103
104
li t0, 0x0001020304050607
105
srli a2, a2, 7
106
107
/* lowest set bit is 2^(8*k)
108
* multiplying by it shifts the idx array in t0 by k bytes to the left */
109
mul a2, a2, t0
110
111
/* highest byte contains idx of first zero */
112
srli a2, a2, 56
113
114
add a0, a0, a2
115
ret
116
END(__strchrnul)
117
118