blob: 03225a006e33e0d8dd2f690078215bab84ea9ffb [file] [log] [blame]
Christopher Ferris31dea252013-03-08 16:50:31 -08001/*
2 * Copyright (c) 2011 The Android Open Source Project
3 * Copyright (c) 2008 ARM Ltd
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the company may not be used to endorse or promote
15 * products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
23 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
Elliott Hughes851e68a2014-02-19 16:53:20 -080030#include <private/bionic_asm.h>
Christopher Ferris31dea252013-03-08 16:50:31 -080031
32 .text
33
Haibo Huangea9957a2018-11-19 11:00:32 -080034 // To avoid warning about deprecated instructions, add an explicit
35 // arch. The code generated is exactly the same.
36 .arch armv7-a
37
Christopher Ferris31dea252013-03-08 16:50:31 -080038#ifdef __ARMEB__
39#define SHFT2LSB lsl
40#define SHFT2LSBEQ lsleq
41#define SHFT2MSB lsr
42#define SHFT2MSBEQ lsreq
43#define MSB 0x000000ff
44#define LSB 0xff000000
45#else
46#define SHFT2LSB lsr
47#define SHFT2LSBEQ lsreq
48#define SHFT2MSB lsl
49#define SHFT2MSBEQ lsleq
50#define MSB 0xff000000
51#define LSB 0x000000ff
52#endif
53
54#define magic1(REG) REG
55#define magic2(REG) REG, lsl #7
56
Haibo Huangea9957a2018-11-19 11:00:32 -080057ENTRY(strcmp_generic)
Elliott Hughesc54ca402013-12-13 12:17:13 -080058 pld [r0, #0]
59 pld [r1, #0]
Christopher Ferris31dea252013-03-08 16:50:31 -080060 eor r2, r0, r1
61 tst r2, #3
62
63 /* Strings not at same byte offset from a word boundary. */
64 bne .Lstrcmp_unaligned
65 ands r2, r0, #3
66 bic r0, r0, #3
67 bic r1, r1, #3
68 ldr ip, [r0], #4
69 it eq
70 ldreq r3, [r1], #4
71 beq 1f
72
73 /* Although s1 and s2 have identical initial alignment, they are
74 * not currently word aligned. Rather than comparing bytes,
75 * make sure that any bytes fetched from before the addressed
76 * bytes are forced to 0xff. Then they will always compare
77 * equal.
78 */
79 eor r2, r2, #3
80 lsl r2, r2, #3
81 mvn r3, #MSB
82 SHFT2LSB r2, r3, r2
83 ldr r3, [r1], #4
84 orr ip, ip, r2
85 orr r3, r3, r2
861:
87 /* Load the 'magic' constant 0x01010101. */
88 str r4, [sp, #-4]!
89 mov r4, #1
90 orr r4, r4, r4, lsl #8
91 orr r4, r4, r4, lsl #16
92 .p2align 2
934:
Elliott Hughesc54ca402013-12-13 12:17:13 -080094 pld [r0, #8]
95 pld [r1, #8]
Christopher Ferris31dea252013-03-08 16:50:31 -080096 sub r2, ip, magic1(r4)
97 cmp ip, r3
98 itttt eq
99
100 /* check for any zero bytes in first word */
101 biceq r2, r2, ip
102 tsteq r2, magic2(r4)
103 ldreq ip, [r0], #4
104 ldreq r3, [r1], #4
105 beq 4b
1062:
107 /* There's a zero or a different byte in the word */
108 SHFT2MSB r0, ip, #24
109 SHFT2LSB ip, ip, #8
110 cmp r0, #1
111 it cs
112 cmpcs r0, r3, SHFT2MSB #24
113 it eq
114 SHFT2LSBEQ r3, r3, #8
115 beq 2b
116 /* On a big-endian machine, r0 contains the desired byte in bits
117 * 0-7; on a little-endian machine they are in bits 24-31. In
118 * both cases the other bits in r0 are all zero. For r3 the
119 * interesting byte is at the other end of the word, but the
120 * other bits are not necessarily zero. We need a signed result
121 * representing the differnece in the unsigned bytes, so for the
122 * little-endian case we can't just shift the interesting bits up.
123 */
124#ifdef __ARMEB__
125 sub r0, r0, r3, lsr #24
126#else
127 and r3, r3, #255
128 /* No RSB instruction in Thumb2 */
129#ifdef __thumb2__
130 lsr r0, r0, #24
131 sub r0, r0, r3
132#else
133 rsb r0, r3, r0, lsr #24
134#endif
135#endif
136 ldr r4, [sp], #4
137 bx lr
138
139.Lstrcmp_unaligned:
140 wp1 .req r0
141 wp2 .req r1
142 b1 .req r2
143 w1 .req r4
144 w2 .req r5
145 t1 .req ip
146 @ r3 is scratch
147
148 /* First of all, compare bytes until wp1(sp1) is word-aligned. */
1491:
150 tst wp1, #3
151 beq 2f
152 ldrb r2, [wp1], #1
153 ldrb r3, [wp2], #1
154 cmp r2, #1
155 it cs
156 cmpcs r2, r3
157 beq 1b
158 sub r0, r2, r3
159 bx lr
160
1612:
162 str r5, [sp, #-4]!
163 str r4, [sp, #-4]!
164 mov b1, #1
165 orr b1, b1, b1, lsl #8
166 orr b1, b1, b1, lsl #16
167
168 and t1, wp2, #3
169 bic wp2, wp2, #3
170 ldr w1, [wp1], #4
171 ldr w2, [wp2], #4
172 cmp t1, #2
173 beq 2f
174 bhi 3f
175
176 /* Critical inner Loop: Block with 3 bytes initial overlap */
177 .p2align 2
1781:
179 bic t1, w1, #MSB
180 cmp t1, w2, SHFT2LSB #8
181 sub r3, w1, b1
182 bic r3, r3, w1
183 bne 4f
184 ands r3, r3, b1, lsl #7
185 it eq
186 ldreq w2, [wp2], #4
187 bne 5f
188 eor t1, t1, w1
189 cmp t1, w2, SHFT2MSB #24
190 bne 6f
191 ldr w1, [wp1], #4
192 b 1b
1934:
194 SHFT2LSB w2, w2, #8
195 b 8f
196
1975:
198#ifdef __ARMEB__
199 /* The syndrome value may contain false ones if the string ends
200 * with the bytes 0x01 0x00
201 */
202 tst w1, #0xff000000
203 itt ne
204 tstne w1, #0x00ff0000
205 tstne w1, #0x0000ff00
206 beq 7f
207#else
208 bics r3, r3, #0xff000000
209 bne 7f
210#endif
211 ldrb w2, [wp2]
212 SHFT2LSB t1, w1, #24
213#ifdef __ARMEB__
214 lsl w2, w2, #24
215#endif
216 b 8f
217
2186:
219 SHFT2LSB t1, w1, #24
220 and w2, w2, #LSB
221 b 8f
222
223 /* Critical inner Loop: Block with 2 bytes initial overlap */
224 .p2align 2
2252:
226 SHFT2MSB t1, w1, #16
227 sub r3, w1, b1
228 SHFT2LSB t1, t1, #16
229 bic r3, r3, w1
230 cmp t1, w2, SHFT2LSB #16
231 bne 4f
232 ands r3, r3, b1, lsl #7
233 it eq
234 ldreq w2, [wp2], #4
235 bne 5f
236 eor t1, t1, w1
237 cmp t1, w2, SHFT2MSB #16
238 bne 6f
239 ldr w1, [wp1], #4
240 b 2b
241
2425:
243#ifdef __ARMEB__
244 /* The syndrome value may contain false ones if the string ends
245 * with the bytes 0x01 0x00
246 */
247 tst w1, #0xff000000
248 it ne
249 tstne w1, #0x00ff0000
250 beq 7f
251#else
252 lsls r3, r3, #16
253 bne 7f
254#endif
255 ldrh w2, [wp2]
256 SHFT2LSB t1, w1, #16
257#ifdef __ARMEB__
258 lsl w2, w2, #16
259#endif
260 b 8f
261
2626:
263 SHFT2MSB w2, w2, #16
264 SHFT2LSB t1, w1, #16
2654:
266 SHFT2LSB w2, w2, #16
267 b 8f
268
269 /* Critical inner Loop: Block with 1 byte initial overlap */
270 .p2align 2
2713:
272 and t1, w1, #LSB
273 cmp t1, w2, SHFT2LSB #24
274 sub r3, w1, b1
275 bic r3, r3, w1
276 bne 4f
277 ands r3, r3, b1, lsl #7
278 it eq
279 ldreq w2, [wp2], #4
280 bne 5f
281 eor t1, t1, w1
282 cmp t1, w2, SHFT2MSB #8
283 bne 6f
284 ldr w1, [wp1], #4
285 b 3b
2864:
287 SHFT2LSB w2, w2, #24
288 b 8f
2895:
290 /* The syndrome value may contain false ones if the string ends
291 * with the bytes 0x01 0x00
292 */
293 tst w1, #LSB
294 beq 7f
295 ldr w2, [wp2], #4
2966:
297 SHFT2LSB t1, w1, #8
298 bic w2, w2, #MSB
299 b 8f
3007:
301 mov r0, #0
302 ldr r4, [sp], #4
303 ldr r5, [sp], #4
304 bx lr
305
3068:
307 and r2, t1, #LSB
308 and r0, w2, #LSB
309 cmp r0, #1
310 it cs
311 cmpcs r0, r2
312 itt eq
313 SHFT2LSBEQ t1, t1, #8
314 SHFT2LSBEQ w2, w2, #8
315 beq 8b
316 sub r0, r2, r0
317 ldr r4, [sp], #4
318 ldr r5, [sp], #4
319 bx lr
Haibo Huangea9957a2018-11-19 11:00:32 -0800320END(strcmp_generic)