1 /* SPDX-License-Identifier: GPL-2.0 */
2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3 
4 #include <linux/linkage.h>
5 #include "sysdep.h"
6 
7 ENTRY(strlen)
8 	/* Check if the start addr is aligned.  */
9 	mov	r3, r0
10 	andi	r1, r0, 3
11 	movi	r2, 4
12 	movi	r0, 0
13 	bnez	r1, .L_start_not_aligned
14 
15 	LABLE_ALIGN
16 .L_start_addr_aligned:
17 	/* Check if all the bytes in the word are not zero.  */
18 	ldw	r1, (r3)
19 	tstnbz	r1
20 	bf	.L_string_tail
21 
22 	ldw	r1, (r3, 4)
23 	addi	r0, 4
24 	tstnbz	r1
25 	bf	.L_string_tail
26 
27 	ldw	r1, (r3, 8)
28 	addi	r0, 4
29 	tstnbz	r1
30 	bf	.L_string_tail
31 
32 	ldw	r1, (r3, 12)
33 	addi	r0, 4
34 	tstnbz	r1
35 	bf	.L_string_tail
36 
37 	ldw	r1, (r3, 16)
38 	addi	r0, 4
39 	tstnbz	r1
40 	bf	.L_string_tail
41 
42 	ldw	r1, (r3, 20)
43 	addi	r0, 4
44 	tstnbz	r1
45 	bf	.L_string_tail
46 
47 	ldw	r1, (r3, 24)
48 	addi	r0, 4
49 	tstnbz	r1
50 	bf	.L_string_tail
51 
52 	ldw	r1, (r3, 28)
53 	addi	r0, 4
54 	tstnbz	r1
55 	bf	.L_string_tail
56 
57 	addi	r0, 4
58 	addi	r3, 32
59 	br	.L_start_addr_aligned
60 
61 .L_string_tail:
62 # ifdef __CSKYBE__
63 	xtrb0	r3, r1
64 	bez	r3, .L_return
65 	addi	r0, 1
66 	xtrb1	r3, r1
67 	bez	r3, .L_return
68 	addi	r0, 1
69 	xtrb2	r3, r1
70 	bez	r3, .L_return
71 	addi	r0, 1
72 # else
73 	xtrb3	r3, r1
74 	bez	r3, .L_return
75 	addi	r0, 1
76 	xtrb2	r3, r1
77 	bez	r3, .L_return
78 	addi	r0, 1
79 	xtrb1	r3, r1
80 	bez	r3, .L_return
81 	addi	r0, 1
82 # endif	/* !__CSKYBE__ */
83 
84 .L_return:
85 	rts
86 
87 .L_start_not_aligned:
88 	sub	r2, r2, r1
89 .L_start_not_aligned_loop:
90 	ldb	r1, (r3)
91 	PRE_BNEZAD (r2)
92 	addi	r3, 1
93 	bez	r1, .L_return
94 	addi	r0, 1
95 	BNEZAD (r2, .L_start_not_aligned_loop)
96 	br	.L_start_addr_aligned
97 ENDPROC(strlen)
98