Merge tag 'for-linus-20190617' of git://git.sourceforge.jp/gitroot/uclinux-h8/linux
[linux-2.6-microblaze.git] / arch / arc / lib / strlen.S
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)