1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
4  */
5 
6 #include <linux/linkage.h>
7 
8 ENTRY_CFI(strlen)
9 	or	r3,r0,7
10 	ld	r2,[r3,-7]
11 	ld.a	r6,[r3,-3]
12 	mov	r4,0x01010101
13 	; uses long immediate
14 #ifdef __LITTLE_ENDIAN__
15 	asl_s	r1,r0,3
16 	btst_s	r0,2
17 	asl	r7,r4,r1
18 	ror	r5,r4
19 	sub	r1,r2,r7
20 	bic_s	r1,r1,r2
21 	mov.eq	r7,r4
22 	sub	r12,r6,r7
23 	bic	r12,r12,r6
24 	or.eq	r12,r12,r1
25 	and	r12,r12,r5
26 	brne	r12,0,.Learly_end
27 #else /* BIG ENDIAN */
28 	ror	r5,r4
29 	btst_s	r0,2
30 	mov_s	r1,31
31 	sub3	r7,r1,r0
32 	sub	r1,r2,r4
33 	bic_s	r1,r1,r2
34 	bmsk	r1,r1,r7
35 	sub	r12,r6,r4
36 	bic	r12,r12,r6
37 	bmsk.ne	r12,r12,r7
38 	or.eq	r12,r12,r1
39 	and	r12,r12,r5
40 	brne	r12,0,.Learly_end
41 #endif /* ENDIAN */
42 
43 .Loop:
44 	ld_s	r2,[r3,4]
45 	ld.a	r6,[r3,8]
46 	; stall for load result
47 	sub	r1,r2,r4
48 	bic_s	r1,r1,r2
49 	sub	r12,r6,r4
50 	bic	r12,r12,r6
51 	or	r12,r12,r1
52 	and	r12,r12,r5
53 	breq r12,0,.Loop
54 .Lend:
55 	and.f	r1,r1,r5
56 	sub.ne	r3,r3,4
57 	mov.eq	r1,r12
58 #ifdef __LITTLE_ENDIAN__
59 	sub_s	r2,r1,1
60 	bic_s	r2,r2,r1
61 	norm	r1,r2
62 	sub_s	r0,r0,3
63 	lsr_s	r1,r1,3
64 	sub	    r0,r3,r0
65 	j_s.d	[blink]
66 	sub	    r0,r0,r1
67 #else /* BIG ENDIAN */
68 	lsr_s	r1,r1,7
69 	mov.eq	r2,r6
70 	bic_s	r1,r1,r2
71 	norm	r1,r1
72 	sub	    r0,r3,r0
73 	lsr_s	r1,r1,3
74 	j_s.d	[blink]
75 	add	    r0,r0,r1
76 #endif /* ENDIAN */
77 .Learly_end:
78 	b.d	.Lend
79 	sub_s.ne r1,r1,r1
80 END_CFI(strlen)
81