1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* strlen.S: Sparc optimized strlen code
3  * Hand optimized from GNU libc's strlen
4  * Copyright (C) 1991,1996 Free Software Foundation
5  * Copyright (C) 1996,2008 David S. Miller (davem@davemloft.net)
6  * Copyright (C) 1996, 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
7  */
8 
9 #include <linux/linkage.h>
10 #include <asm/asm.h>
11 #include <asm/export.h>
12 
13 #define LO_MAGIC 0x01010101
14 #define HI_MAGIC 0x80808080
15 
16 	.text
17 ENTRY(strlen)
18 	mov	%o0, %o1
19 	andcc	%o0, 3, %g0
20 	BRANCH32(be, pt, 9f)
21 	 sethi	%hi(HI_MAGIC), %o4
22 	ldub	[%o0], %o5
23 	BRANCH_REG_ZERO(pn, %o5, 11f)
24 	 add	%o0, 1, %o0
25 	andcc	%o0, 3, %g0
26 	BRANCH32(be, pn, 4f)
27 	 or	%o4, %lo(HI_MAGIC), %o3
28 	ldub	[%o0], %o5
29 	BRANCH_REG_ZERO(pn, %o5, 12f)
30 	 add	%o0, 1, %o0
31 	andcc	%o0, 3, %g0
32 	BRANCH32(be, pt, 5f)
33 	 sethi	%hi(LO_MAGIC), %o4
34 	ldub	[%o0], %o5
35 	BRANCH_REG_ZERO(pn, %o5, 13f)
36 	 add	%o0, 1, %o0
37 	BRANCH32(ba, pt, 8f)
38 	 or	%o4, %lo(LO_MAGIC), %o2
39 9:
40 	or	%o4, %lo(HI_MAGIC), %o3
41 4:
42 	sethi	%hi(LO_MAGIC), %o4
43 5:
44 	or	%o4, %lo(LO_MAGIC), %o2
45 8:
46 	ld	[%o0], %o5
47 2:
48 	sub	%o5, %o2, %o4
49 	andcc	%o4, %o3, %g0
50 	BRANCH32(be, pt, 8b)
51 	 add	%o0, 4, %o0
52 
53 	/* Check every byte. */
54 	srl	%o5, 24, %g7
55 	andcc	%g7, 0xff, %g0
56 	BRANCH32(be, pn, 1f)
57 	 add	%o0, -4, %o4
58 	srl	%o5, 16, %g7
59 	andcc	%g7, 0xff, %g0
60 	BRANCH32(be, pn, 1f)
61 	 add	%o4, 1, %o4
62 	srl	%o5, 8, %g7
63 	andcc	%g7, 0xff, %g0
64 	BRANCH32(be, pn, 1f)
65 	 add	%o4, 1, %o4
66 	andcc	%o5, 0xff, %g0
67 	BRANCH32_ANNUL(bne, pt, 2b)
68 	 ld	[%o0], %o5
69 	add	%o4, 1, %o4
70 1:
71 	retl
72 	 sub	%o4, %o1, %o0
73 11:
74 	retl
75 	 mov	0, %o0
76 12:
77 	retl
78 	 mov	1, %o0
79 13:
80 	retl
81 	 mov	2, %o0
82 ENDPROC(strlen)
83 EXPORT_SYMBOL(strlen)
84