xref: /openbmc/linux/arch/arc/lib/strlen.S (revision 03638e62)
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
8ENTRY_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
80END_CFI(strlen)
81