1/* The assembly function for string length.  C-SKY ABIV2 version.
2   Copyright (C) 2018-2022 Free Software Foundation, Inc.
3   This file is part of the GNU C Library.
4
5   The GNU C Library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9
10   The GNU C Library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public
16   License along with the GNU C Library.  If not, see
17   <https://www.gnu.org/licenses/>.  */
18
19#include <sysdep.h>
20
21ENTRY (strlen)
22	/* Check if the start addr is aligned.  */
23	mov	r3, r0
24	andi	r1, r0, 3
25	movi	r2, 4
26	movi	r0, 0
27	bnez	r1, .L_start_not_aligned
28
29	LABLE_ALIGN
30.L_start_addr_aligned:
31	/* Check if all the bytes in the word are not zero.  */
32	ldw	r1, (r3)
33	tstnbz	r1
34	bf	.L_string_tail
35
36	ldw	r1, (r3, 4)
37	addi	r0, 4
38	tstnbz	r1
39	bf	.L_string_tail
40
41	ldw	r1, (r3, 8)
42	addi	r0, 4
43	tstnbz	r1
44	bf	.L_string_tail
45
46	ldw	r1, (r3, 12)
47	addi	r0, 4
48	tstnbz	r1
49	bf	.L_string_tail
50
51	ldw	r1, (r3, 16)
52	addi	r0, 4
53	tstnbz	r1
54	bf	.L_string_tail
55
56	ldw	r1, (r3, 20)
57	addi	r0, 4
58	tstnbz	r1
59	bf	.L_string_tail
60
61	ldw	r1, (r3, 24)
62	addi	r0, 4
63	tstnbz	r1
64	bf	.L_string_tail
65
66	ldw	r1, (r3, 28)
67	addi	r0, 4
68	tstnbz	r1
69	bf	.L_string_tail
70
71	addi	r0, 4
72	addi	r3, 32
73	br	.L_start_addr_aligned
74
75.L_string_tail:
76	xtrb3	r3, r1
77	bez	r3, .L_return
78	addi	r0, 1
79	xtrb2	r3, r1
80	bez	r3, .L_return
81	addi	r0, 1
82	xtrb1	r3, r1
83	bez	r3, .L_return
84	addi	r0, 1
85
86.L_return:
87	rts
88
89.L_start_not_aligned:
90	sub	r2, r2, r1
91.L_start_not_aligned_loop:
92	ldb	r1, (r3)
93	PRE_BNEZAD (r2)
94	addi	r3, 1
95	bez	r1, .L_return
96	addi	r0, 1
97	BNEZAD (r2, .L_start_not_aligned_loop)
98	br	.L_start_addr_aligned
99END (strlen)
100
101libc_hidden_def (strlen)
102.weak strlen
103