Loading...
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/* ARC700 has a relatively long pipeline and branch prediction, so we want
10 to avoid branches that are hard to predict. On the other hand, the
11 presence of the norm instruction makes it easier to operate on whole
12 words branch-free. */
13
14#include <linux/linkage.h>
15
16ENTRY(strchr)
17 extb_s r1,r1
18 asl r5,r1,8
19 bmsk r2,r0,1
20 or r5,r5,r1
21 mov_s r3,0x01010101
22 breq.d r2,r0,.Laligned
23 asl r4,r5,16
24 sub_s r0,r0,r2
25 asl r7,r2,3
26 ld_s r2,[r0]
27#ifdef __LITTLE_ENDIAN__
28 asl r7,r3,r7
29#else
30 lsr r7,r3,r7
31#endif
32 or r5,r5,r4
33 ror r4,r3
34 sub r12,r2,r7
35 bic_s r12,r12,r2
36 and r12,r12,r4
37 brne.d r12,0,.Lfound0_ua
38 xor r6,r2,r5
39 ld.a r2,[r0,4]
40 sub r12,r6,r7
41 bic r12,r12,r6
42#ifdef __LITTLE_ENDIAN__
43 and r7,r12,r4
44 breq r7,0,.Loop ; For speed, we want this branch to be unaligned.
45 b .Lfound_char ; Likewise this one.
46#else
47 and r12,r12,r4
48 breq r12,0,.Loop ; For speed, we want this branch to be unaligned.
49 lsr_s r12,r12,7
50 bic r2,r7,r6
51 b.d .Lfound_char_b
52 and_s r2,r2,r12
53#endif
54; /* We require this code address to be unaligned for speed... */
55.Laligned:
56 ld_s r2,[r0]
57 or r5,r5,r4
58 ror r4,r3
59; /* ... so that this code address is aligned, for itself and ... */
60.Loop:
61 sub r12,r2,r3
62 bic_s r12,r12,r2
63 and r12,r12,r4
64 brne.d r12,0,.Lfound0
65 xor r6,r2,r5
66 ld.a r2,[r0,4]
67 sub r12,r6,r3
68 bic r12,r12,r6
69 and r7,r12,r4
70 breq r7,0,.Loop /* ... so that this branch is unaligned. */
71 ; Found searched-for character. r0 has already advanced to next word.
72#ifdef __LITTLE_ENDIAN__
73/* We only need the information about the first matching byte
74 (i.e. the least significant matching byte) to be exact,
75 hence there is no problem with carry effects. */
76.Lfound_char:
77 sub r3,r7,1
78 bic r3,r3,r7
79 norm r2,r3
80 sub_s r0,r0,1
81 asr_s r2,r2,3
82 j.d [blink]
83 sub_s r0,r0,r2
84
85 .balign 4
86.Lfound0_ua:
87 mov r3,r7
88.Lfound0:
89 sub r3,r6,r3
90 bic r3,r3,r6
91 and r2,r3,r4
92 or_s r12,r12,r2
93 sub_s r3,r12,1
94 bic_s r3,r3,r12
95 norm r3,r3
96 add_s r0,r0,3
97 asr_s r12,r3,3
98 asl.f 0,r2,r3
99 sub_s r0,r0,r12
100 j_s.d [blink]
101 mov.pl r0,0
102#else /* BIG ENDIAN */
103.Lfound_char:
104 lsr r7,r7,7
105
106 bic r2,r7,r6
107.Lfound_char_b:
108 norm r2,r2
109 sub_s r0,r0,4
110 asr_s r2,r2,3
111 j.d [blink]
112 add_s r0,r0,r2
113
114.Lfound0_ua:
115 mov_s r3,r7
116.Lfound0:
117 asl_s r2,r2,7
118 or r7,r6,r4
119 bic_s r12,r12,r2
120 sub r2,r7,r3
121 or r2,r2,r6
122 bic r12,r2,r12
123 bic.f r3,r4,r12
124 norm r3,r3
125
126 add.pl r3,r3,1
127 asr_s r12,r3,3
128 asl.f 0,r2,r3
129 add_s r0,r0,r12
130 j_s.d [blink]
131 mov.mi r0,0
132#endif /* ENDIAN */
133END(strchr)
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/* ARC700 has a relatively long pipeline and branch prediction, so we want
7 to avoid branches that are hard to predict. On the other hand, the
8 presence of the norm instruction makes it easier to operate on whole
9 words branch-free. */
10
11#include <linux/linkage.h>
12
13ENTRY_CFI(strchr)
14 extb_s r1,r1
15 asl r5,r1,8
16 bmsk r2,r0,1
17 or r5,r5,r1
18 mov_s r3,0x01010101
19 breq.d r2,r0,.Laligned
20 asl r4,r5,16
21 sub_s r0,r0,r2
22 asl r7,r2,3
23 ld_s r2,[r0]
24#ifdef __LITTLE_ENDIAN__
25 asl r7,r3,r7
26#else
27 lsr r7,r3,r7
28#endif
29 or r5,r5,r4
30 ror r4,r3
31 sub r12,r2,r7
32 bic_s r12,r12,r2
33 and r12,r12,r4
34 brne.d r12,0,.Lfound0_ua
35 xor r6,r2,r5
36 ld.a r2,[r0,4]
37 sub r12,r6,r7
38 bic r12,r12,r6
39#ifdef __LITTLE_ENDIAN__
40 and r7,r12,r4
41 breq r7,0,.Loop ; For speed, we want this branch to be unaligned.
42 b .Lfound_char ; Likewise this one.
43#else
44 and r12,r12,r4
45 breq r12,0,.Loop ; For speed, we want this branch to be unaligned.
46 lsr_s r12,r12,7
47 bic r2,r7,r6
48 b.d .Lfound_char_b
49 and_s r2,r2,r12
50#endif
51; /* We require this code address to be unaligned for speed... */
52.Laligned:
53 ld_s r2,[r0]
54 or r5,r5,r4
55 ror r4,r3
56; /* ... so that this code address is aligned, for itself and ... */
57.Loop:
58 sub r12,r2,r3
59 bic_s r12,r12,r2
60 and r12,r12,r4
61 brne.d r12,0,.Lfound0
62 xor r6,r2,r5
63 ld.a r2,[r0,4]
64 sub r12,r6,r3
65 bic r12,r12,r6
66 and r7,r12,r4
67 breq r7,0,.Loop /* ... so that this branch is unaligned. */
68 ; Found searched-for character. r0 has already advanced to next word.
69#ifdef __LITTLE_ENDIAN__
70/* We only need the information about the first matching byte
71 (i.e. the least significant matching byte) to be exact,
72 hence there is no problem with carry effects. */
73.Lfound_char:
74 sub r3,r7,1
75 bic r3,r3,r7
76 norm r2,r3
77 sub_s r0,r0,1
78 asr_s r2,r2,3
79 j.d [blink]
80 sub_s r0,r0,r2
81
82 .balign 4
83.Lfound0_ua:
84 mov r3,r7
85.Lfound0:
86 sub r3,r6,r3
87 bic r3,r3,r6
88 and r2,r3,r4
89 or_s r12,r12,r2
90 sub_s r3,r12,1
91 bic_s r3,r3,r12
92 norm r3,r3
93 add_s r0,r0,3
94 asr_s r12,r3,3
95 asl.f 0,r2,r3
96 sub_s r0,r0,r12
97 j_s.d [blink]
98 mov.pl r0,0
99#else /* BIG ENDIAN */
100.Lfound_char:
101 lsr r7,r7,7
102
103 bic r2,r7,r6
104.Lfound_char_b:
105 norm r2,r2
106 sub_s r0,r0,4
107 asr_s r2,r2,3
108 j.d [blink]
109 add_s r0,r0,r2
110
111.Lfound0_ua:
112 mov_s r3,r7
113.Lfound0:
114 asl_s r2,r2,7
115 or r7,r6,r4
116 bic_s r12,r12,r2
117 sub r2,r7,r3
118 or r2,r2,r6
119 bic r12,r2,r12
120 bic.f r3,r4,r12
121 norm r3,r3
122
123 add.pl r3,r3,1
124 asr_s r12,r3,3
125 asl.f 0,r2,r3
126 add_s r0,r0,r12
127 j_s.d [blink]
128 mov.mi r0,0
129#endif /* ENDIAN */
130END_CFI(strchr)