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