Linux 4.6-rc6
[linux/fpc-iii.git] / arch / arc / lib / strlen.S
blob53cfd5685a5f9f80d44d180daecddf9a9c245c87
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  */
9 #include <linux/linkage.h>
11 ENTRY(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 */
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
83 END(strlen)