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
7ENTRY(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
97ENDPROC(strlen)
98