]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arc/lib/strchr-700.S
arc: add library functions
[people/ms/u-boot.git] / arch / arc / lib / strchr-700.S
1 /*
2 * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7 /*
8 * ARC700 has a relatively long pipeline and branch prediction, so we want
9 * to avoid branches that are hard to predict. On the other hand, the
10 * presence of the norm instruction makes it easier to operate on whole
11 * words branch-free.
12 */
13
14 .global strchr
15 .align 4
16 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 /* __BIG_ENDIAN__ */
30 lsr %r7, %r3, %r7
31 #endif /* _ENDIAN__ */
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 /* For speed, we want this branch to be unaligned. */
45 breq %r7, 0, .Loop
46 /* Likewise this one */
47 b .Lfound_char
48 #else /* __BIG_ENDIAN__ */
49 and %r12, %r12, %r4
50 /* For speed, we want this branch to be unaligned. */
51 breq %r12, 0, .Loop
52 lsr_s %r12, %r12, 7
53 bic %r2, %r7, %r6
54 b.d .Lfound_char_b
55 and_s %r2, %r2, %r12
56 #endif /* _ENDIAN__ */
57 /* We require this code address to be unaligned for speed... */
58 .Laligned:
59 ld_s %r2, [%r0]
60 or %r5, %r5, %r4
61 ror %r4, %r3
62 /* ... so that this code address is aligned, for itself and ... */
63 .Loop:
64 sub %r12, %r2, %r3
65 bic_s %r12, %r12, %r2
66 and %r12, %r12, %r4
67 brne.d %r12, 0, .Lfound0
68 xor %r6, %r2, %r5
69 ld.a %r2, [%r0, 4]
70 sub %r12, %r6, %r3
71 bic %r12, %r12, %r6
72 and %r7, %r12, %r4
73 breq %r7, 0, .Loop
74 /*
75 *... so that this branch is unaligned.
76 * Found searched-for character.
77 * r0 has already advanced to next word.
78 */
79 #ifdef __LITTLE_ENDIAN__
80 /*
81 * We only need the information about the first matching byte
82 * (i.e. the least significant matching byte) to be exact,
83 * hence there is no problem with carry effects.
84 */
85 .Lfound_char:
86 sub %r3, %r7, 1
87 bic %r3, %r3, %r7
88 norm %r2, %r3
89 sub_s %r0, %r0, 1
90 asr_s %r2, %r2, 3
91 j.d [%blink]
92 sub_s %r0, %r0, %r2
93
94 .balign 4
95 .Lfound0_ua:
96 mov %r3, %r7
97 .Lfound0:
98 sub %r3, %r6, %r3
99 bic %r3, %r3, %r6
100 and %r2, %r3, %r4
101 or_s %r12, %r12, %r2
102 sub_s %r3, %r12, 1
103 bic_s %r3, %r3, %r12
104 norm %r3, %r3
105 add_s %r0, %r0, 3
106 asr_s %r12, %r3, 3
107 asl.f 0, %r2, %r3
108 sub_s %r0, %r0, %r12
109 j_s.d [%blink]
110 mov.pl %r0, 0
111 #else /* __BIG_ENDIAN__ */
112 .Lfound_char:
113 lsr %r7, %r7, 7
114
115 bic %r2, %r7, %r6
116 .Lfound_char_b:
117 norm %r2, %r2
118 sub_s %r0, %r0, 4
119 asr_s %r2, %r2, 3
120 j.d [%blink]
121 add_s %r0, %r0, %r2
122
123 .Lfound0_ua:
124 mov_s %r3, %r7
125 .Lfound0:
126 asl_s %r2, %r2, 7
127 or %r7, %r6, %r4
128 bic_s %r12, %r12, %r2
129 sub %r2, %r7, %r3
130 or %r2, %r2, %r6
131 bic %r12, %r2, %r12
132 bic.f %r3, %r4, %r12
133 norm %r3, %r3
134
135 add.pl %r3, %r3, 1
136 asr_s %r12, %r3, 3
137 asl.f 0, %r2, %r3
138 add_s %r0, %r0, %r12
139 j_s.d [%blink]
140 mov.mi %r0, 0
141 #endif /* _ENDIAN__ */