1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/linkage.h>
14 #include <asm/assembler.h>
15
16
17
18
19
20
21
22
23
24
25
26
27 srcin .req x0
28 len .req x0
29 limit .req x1
30
31
32 src .req x2
33 data1 .req x3
34 data2 .req x4
35 data2a .req x5
36 has_nul1 .req x6
37 has_nul2 .req x7
38 tmp1 .req x8
39 tmp2 .req x9
40 tmp3 .req x10
41 tmp4 .req x11
42 zeroones .req x12
43 pos .req x13
44 limit_wd .req x14
45
46 #define REP8_01 0x0101010101010101
47 #define REP8_7f 0x7f7f7f7f7f7f7f7f
48 #define REP8_80 0x8080808080808080
49
50 WEAK(strnlen)
51 cbz limit, .Lhit_limit
52 mov zeroones, #REP8_01
53 bic src, srcin, #15
54 ands tmp1, srcin, #15
55 b.ne .Lmisaligned
56
57 sub limit_wd, limit, #1
58 lsr limit_wd, limit_wd, #4
59
60
61
62
63
64
65
66
67
68
69
70
71 .Lloop:
72 ldp data1, data2, [src], #16
73 .Lrealigned:
74 sub tmp1, data1, zeroones
75 orr tmp2, data1, #REP8_7f
76 sub tmp3, data2, zeroones
77 orr tmp4, data2, #REP8_7f
78 bic has_nul1, tmp1, tmp2
79 bic has_nul2, tmp3, tmp4
80 subs limit_wd, limit_wd, #1
81 orr tmp1, has_nul1, has_nul2
82 ccmp tmp1, #0, #0, pl
83 b.eq .Lloop
84
85 cbz tmp1, .Lhit_limit
86
87
88
89
90
91
92 sub len, src, srcin
93 cbz has_nul1, .Lnul_in_data2
94 CPU_BE( mov data2, data1 )
95
96 sub len, len, #8
97 mov has_nul2, has_nul1
98 .Lnul_in_data2:
99
100
101
102
103
104
105 CPU_BE( rev data2, data2 )
106 CPU_BE( sub tmp1, data2, zeroones )
107 CPU_BE( orr tmp2, data2, #REP8_7f )
108 CPU_BE( bic has_nul2, tmp1, tmp2 )
109
110 sub len, len, #8
111 rev has_nul2, has_nul2
112 clz pos, has_nul2
113 add len, len, pos, lsr #3
114 cmp len, limit
115 csel len, len, limit, ls
116 ret
117
118 .Lmisaligned:
119
120
121
122
123
124
125
126
127
128
129 ldp data1, data2, [src], #16
130
131 sub limit_wd, limit, #1
132 and tmp3, limit_wd, #15
133 lsr limit_wd, limit_wd, #4
134
135 add tmp3, tmp3, tmp1
136 add limit_wd, limit_wd, tmp3, lsr #4
137
138 neg tmp4, tmp1
139 lsl tmp4, tmp4, #3
140
141 mov tmp2, #~0
142
143 CPU_BE( lsl tmp2, tmp2, tmp4 )
144
145 CPU_LE( lsr tmp2, tmp2, tmp4 )
146
147 cmp tmp1, #8
148
149 orr data1, data1, tmp2
150 orr data2a, data2, tmp2
151
152 csinv data1, data1, xzr, le
153 csel data2, data2, data2a, le
154 b .Lrealigned
155
156 .Lhit_limit:
157 mov len, limit
158 ret
159 ENDPIPROC(strnlen)
160 EXPORT_SYMBOL_NOKASAN(strnlen)