blob: f939da221b33cf6184b35a5decc58a5d35f5de5e [file] [log] [blame]
Adhemerval Zanellad30faa52019-08-06 16:21:09 -03001/*
Szabolcs Nagy558699c2019-08-27 15:57:58 +01002 * strcmp for ARMv7
Adhemerval Zanellad30faa52019-08-06 16:21:09 -03003 *
Szabolcs Nagy558699c2019-08-27 15:57:58 +01004 * Copyright (c) 2012-2019, Arm Limited.
5 * SPDX-License-Identifier: MIT
Adhemerval Zanellad30faa52019-08-06 16:21:09 -03006 */
7
Szabolcs Nagy1dfd7b82020-02-12 15:10:29 +00008#if __ARM_ARCH >= 7 && __ARM_ARCH_ISA_ARM >= 1
9
Adhemerval Zanellad30faa52019-08-06 16:21:09 -030010/* Implementation of strcmp for ARMv7 when DSP instructions are
11 available. Use ldrd to support wider loads, provided the data
12 is sufficiently aligned. Use saturating arithmetic to optimize
13 the compares. */
14
Wilco Dijkstra31b560b2020-01-02 09:14:42 +000015#include "../asmdefs.h"
16
Adhemerval Zanellad30faa52019-08-06 16:21:09 -030017/* Build Options:
18 STRCMP_NO_PRECHECK: Don't run a quick pre-check of the first
19 byte in the string. If comparing completely random strings
20 the pre-check will save time, since there is a very high
21 probability of a mismatch in the first character: we save
22 significant overhead if this is the common case. However,
23 if strings are likely to be identical (eg because we're
24 verifying a hit in a hash table), then this check is largely
25 redundant. */
26
27#define STRCMP_NO_PRECHECK 0
28
29 /* This version uses Thumb-2 code. */
30 .thumb
31 .syntax unified
32
33#ifdef __ARM_BIG_ENDIAN
34#define S2LO lsl
35#define S2LOEQ lsleq
36#define S2HI lsr
37#define MSB 0x000000ff
38#define LSB 0xff000000
39#define BYTE0_OFFSET 24
40#define BYTE1_OFFSET 16
41#define BYTE2_OFFSET 8
42#define BYTE3_OFFSET 0
43#else /* not __ARM_BIG_ENDIAN */
44#define S2LO lsr
45#define S2LOEQ lsreq
46#define S2HI lsl
47#define BYTE0_OFFSET 0
48#define BYTE1_OFFSET 8
49#define BYTE2_OFFSET 16
50#define BYTE3_OFFSET 24
51#define MSB 0xff000000
52#define LSB 0x000000ff
53#endif /* not __ARM_BIG_ENDIAN */
54
Adhemerval Zanellad30faa52019-08-06 16:21:09 -030055/* Parameters and result. */
56#define src1 r0
57#define src2 r1
58#define result r0 /* Overlaps src1. */
59
60/* Internal variables. */
61#define tmp1 r4
62#define tmp2 r5
63#define const_m1 r12
64
65/* Additional internal variables for 64-bit aligned data. */
66#define data1a r2
67#define data1b r3
68#define data2a r6
69#define data2b r7
70#define syndrome_a tmp1
71#define syndrome_b tmp2
72
73/* Additional internal variables for 32-bit aligned data. */
74#define data1 r2
75#define data2 r3
76#define syndrome tmp2
77
78
79 /* Macro to compute and return the result value for word-aligned
80 cases. */
81 .macro strcmp_epilogue_aligned synd d1 d2 restore_r6
82#ifdef __ARM_BIG_ENDIAN
83 /* If data1 contains a zero byte, then syndrome will contain a 1 in
84 bit 7 of that byte. Otherwise, the highest set bit in the
85 syndrome will highlight the first different bit. It is therefore
86 sufficient to extract the eight bits starting with the syndrome
87 bit. */
88 clz tmp1, \synd
89 lsl r1, \d2, tmp1
90 .if \restore_r6
91 ldrd r6, r7, [sp, #8]
92 .endif
93 .cfi_restore 6
94 .cfi_restore 7
95 lsl \d1, \d1, tmp1
96 .cfi_remember_state
97 lsr result, \d1, #24
98 ldrd r4, r5, [sp], #16
99 .cfi_restore 4
100 .cfi_restore 5
101 sub result, result, r1, lsr #24
102 bx lr
103#else
104 /* To use the big-endian trick we'd have to reverse all three words.
105 that's slower than this approach. */
106 rev \synd, \synd
107 clz tmp1, \synd
108 bic tmp1, tmp1, #7
109 lsr r1, \d2, tmp1
110 .cfi_remember_state
111 .if \restore_r6
112 ldrd r6, r7, [sp, #8]
113 .endif
114 .cfi_restore 6
115 .cfi_restore 7
116 lsr \d1, \d1, tmp1
117 and result, \d1, #255
118 and r1, r1, #255
119 ldrd r4, r5, [sp], #16
120 .cfi_restore 4
121 .cfi_restore 5
122 sub result, result, r1
123
124 bx lr
125#endif
126 .endm
127
128 .text
129 .p2align 5
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000130L(strcmp_start_addr):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300131#if STRCMP_NO_PRECHECK == 0
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000132L(fastpath_exit):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300133 sub r0, r2, r3
134 bx lr
135 nop
136#endif
Wilco Dijkstra31b560b2020-01-02 09:14:42 +0000137ENTRY_ALIGN (__strcmp_arm, 0)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300138#if STRCMP_NO_PRECHECK == 0
139 ldrb r2, [src1]
140 ldrb r3, [src2]
141 cmp r2, #1
142 it cs
143 cmpcs r2, r3
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000144 bne L(fastpath_exit)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300145#endif
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300146 strd r4, r5, [sp, #-16]!
147 .cfi_def_cfa_offset 16
148 .cfi_offset 4, -16
149 .cfi_offset 5, -12
150 orr tmp1, src1, src2
151 strd r6, r7, [sp, #8]
152 .cfi_offset 6, -8
153 .cfi_offset 7, -4
154 mvn const_m1, #0
155 lsl r2, tmp1, #29
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000156 cbz r2, L(loop_aligned8)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300157
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000158L(not_aligned):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300159 eor tmp1, src1, src2
160 tst tmp1, #7
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000161 bne L(misaligned8)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300162
163 /* Deal with mutual misalignment by aligning downwards and then
164 masking off the unwanted loaded data to prevent a difference. */
165 and tmp1, src1, #7
166 bic src1, src1, #7
167 and tmp2, tmp1, #3
168 bic src2, src2, #7
169 lsl tmp2, tmp2, #3 /* Bytes -> bits. */
170 ldrd data1a, data1b, [src1], #16
171 tst tmp1, #4
172 ldrd data2a, data2b, [src2], #16
173 /* In thumb code we can't use MVN with a register shift, but
174 we do have ORN. */
175 S2HI tmp1, const_m1, tmp2
176 orn data1a, data1a, tmp1
177 orn data2a, data2a, tmp1
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000178 beq L(start_realigned8)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300179 orn data1b, data1b, tmp1
180 mov data1a, const_m1
181 orn data2b, data2b, tmp1
182 mov data2a, const_m1
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000183 b L(start_realigned8)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300184
185 /* Unwind the inner loop by a factor of 2, giving 16 bytes per
186 pass. */
187 .p2align 5,,12 /* Don't start in the tail bytes of a cache line. */
188 .p2align 2 /* Always word aligned. */
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000189L(loop_aligned8):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300190 ldrd data1a, data1b, [src1], #16
191 ldrd data2a, data2b, [src2], #16
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000192L(start_realigned8):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300193 uadd8 syndrome_b, data1a, const_m1 /* Only want GE bits, */
194 eor syndrome_a, data1a, data2a
195 sel syndrome_a, syndrome_a, const_m1
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000196 cbnz syndrome_a, L(diff_in_a)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300197 uadd8 syndrome_b, data1b, const_m1 /* Only want GE bits. */
198 eor syndrome_b, data1b, data2b
199 sel syndrome_b, syndrome_b, const_m1
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000200 cbnz syndrome_b, L(diff_in_b)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300201
202 ldrd data1a, data1b, [src1, #-8]
203 ldrd data2a, data2b, [src2, #-8]
204 uadd8 syndrome_b, data1a, const_m1 /* Only want GE bits, */
205 eor syndrome_a, data1a, data2a
206 sel syndrome_a, syndrome_a, const_m1
207 uadd8 syndrome_b, data1b, const_m1 /* Only want GE bits. */
208 eor syndrome_b, data1b, data2b
209 sel syndrome_b, syndrome_b, const_m1
210 /* Can't use CBZ for backwards branch. */
211 orrs syndrome_b, syndrome_b, syndrome_a /* Only need if s_a == 0 */
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000212 beq L(loop_aligned8)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300213
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000214L(diff_found):
215 cbnz syndrome_a, L(diff_in_a)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300216
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000217L(diff_in_b):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300218 strcmp_epilogue_aligned syndrome_b, data1b, data2b 1
219
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000220L(diff_in_a):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300221 .cfi_restore_state
222 strcmp_epilogue_aligned syndrome_a, data1a, data2a 1
223
224 .cfi_restore_state
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000225L(misaligned8):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300226 tst tmp1, #3
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000227 bne L(misaligned4)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300228 ands tmp1, src1, #3
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000229 bne L(mutual_align4)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300230
231 /* Unrolled by a factor of 2, to reduce the number of post-increment
232 operations. */
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000233L(loop_aligned4):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300234 ldr data1, [src1], #8
235 ldr data2, [src2], #8
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000236L(start_realigned4):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300237 uadd8 syndrome, data1, const_m1 /* Only need GE bits. */
238 eor syndrome, data1, data2
239 sel syndrome, syndrome, const_m1
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000240 cbnz syndrome, L(aligned4_done)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300241 ldr data1, [src1, #-4]
242 ldr data2, [src2, #-4]
243 uadd8 syndrome, data1, const_m1
244 eor syndrome, data1, data2
245 sel syndrome, syndrome, const_m1
246 cmp syndrome, #0
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000247 beq L(loop_aligned4)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300248
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000249L(aligned4_done):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300250 strcmp_epilogue_aligned syndrome, data1, data2, 0
251
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000252L(mutual_align4):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300253 .cfi_restore_state
254 /* Deal with mutual misalignment by aligning downwards and then
255 masking off the unwanted loaded data to prevent a difference. */
256 lsl tmp1, tmp1, #3 /* Bytes -> bits. */
257 bic src1, src1, #3
258 ldr data1, [src1], #8
259 bic src2, src2, #3
260 ldr data2, [src2], #8
261
262 /* In thumb code we can't use MVN with a register shift, but
263 we do have ORN. */
264 S2HI tmp1, const_m1, tmp1
265 orn data1, data1, tmp1
266 orn data2, data2, tmp1
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000267 b L(start_realigned4)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300268
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000269L(misaligned4):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300270 ands tmp1, src1, #3
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000271 beq L(src1_aligned)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300272 sub src2, src2, tmp1
273 bic src1, src1, #3
274 lsls tmp1, tmp1, #31
275 ldr data1, [src1], #4
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000276 beq L(aligned_m2)
277 bcs L(aligned_m1)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300278
279#if STRCMP_NO_PRECHECK == 1
280 ldrb data2, [src2, #1]
281 uxtb tmp1, data1, ror #BYTE1_OFFSET
282 subs tmp1, tmp1, data2
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000283 bne L(misaligned_exit)
284 cbz data2, L(misaligned_exit)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300285
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000286L(aligned_m2):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300287 ldrb data2, [src2, #2]
288 uxtb tmp1, data1, ror #BYTE2_OFFSET
289 subs tmp1, tmp1, data2
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000290 bne L(misaligned_exit)
291 cbz data2, L(misaligned_exit)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300292
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000293L(aligned_m1):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300294 ldrb data2, [src2, #3]
295 uxtb tmp1, data1, ror #BYTE3_OFFSET
296 subs tmp1, tmp1, data2
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000297 bne L(misaligned_exit)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300298 add src2, src2, #4
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000299 cbnz data2, L(src1_aligned)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300300#else /* STRCMP_NO_PRECHECK */
301 /* If we've done the pre-check, then we don't need to check the
302 first byte again here. */
303 ldrb data2, [src2, #2]
304 uxtb tmp1, data1, ror #BYTE2_OFFSET
305 subs tmp1, tmp1, data2
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000306 bne L(misaligned_exit)
307 cbz data2, L(misaligned_exit)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300308
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000309L(aligned_m2):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300310 ldrb data2, [src2, #3]
311 uxtb tmp1, data1, ror #BYTE3_OFFSET
312 subs tmp1, tmp1, data2
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000313 bne L(misaligned_exit)
314 cbnz data2, L(aligned_m1)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300315#endif
316
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000317L(misaligned_exit):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300318 .cfi_remember_state
319 mov result, tmp1
320 ldr r4, [sp], #16
321 .cfi_restore 4
322 bx lr
323
324#if STRCMP_NO_PRECHECK == 0
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000325L(aligned_m1):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300326 add src2, src2, #4
327#endif
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000328L(src1_aligned):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300329 .cfi_restore_state
330 /* src1 is word aligned, but src2 has no common alignment
331 with it. */
332 ldr data1, [src1], #4
333 lsls tmp1, src2, #31 /* C=src2[1], Z=src2[0]. */
334
335 bic src2, src2, #3
336 ldr data2, [src2], #4
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000337 bhi L(overlap1) /* C=1, Z=0 => src2[1:0] = 0b11. */
338 bcs L(overlap2) /* C=1, Z=1 => src2[1:0] = 0b10. */
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300339
340 /* (overlap3) C=0, Z=0 => src2[1:0] = 0b01. */
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000341L(overlap3):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300342 bic tmp1, data1, #MSB
343 uadd8 syndrome, data1, const_m1
344 eors syndrome, tmp1, data2, S2LO #8
345 sel syndrome, syndrome, const_m1
346 bne 4f
347 cbnz syndrome, 5f
348 ldr data2, [src2], #4
349 eor tmp1, tmp1, data1
350 cmp tmp1, data2, S2HI #24
351 bne 6f
352 ldr data1, [src1], #4
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000353 b L(overlap3)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -03003544:
355 S2LO data2, data2, #8
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000356 b L(strcmp_tail)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300357
3585:
359 bics syndrome, syndrome, #MSB
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000360 bne L(strcmp_done_equal)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300361
362 /* We can only get here if the MSB of data1 contains 0, so
363 fast-path the exit. */
364 ldrb result, [src2]
365 .cfi_remember_state
366 ldrd r4, r5, [sp], #16
367 .cfi_restore 4
368 .cfi_restore 5
369 /* R6/7 Not used in this sequence. */
370 .cfi_restore 6
371 .cfi_restore 7
372 neg result, result
373 bx lr
374
3756:
376 .cfi_restore_state
377 S2LO data1, data1, #24
378 and data2, data2, #LSB
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000379 b L(strcmp_tail)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300380
381 .p2align 5,,12 /* Ensure at least 3 instructions in cache line. */
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000382L(overlap2):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300383 and tmp1, data1, const_m1, S2LO #16
384 uadd8 syndrome, data1, const_m1
385 eors syndrome, tmp1, data2, S2LO #16
386 sel syndrome, syndrome, const_m1
387 bne 4f
388 cbnz syndrome, 5f
389 ldr data2, [src2], #4
390 eor tmp1, tmp1, data1
391 cmp tmp1, data2, S2HI #16
392 bne 6f
393 ldr data1, [src1], #4
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000394 b L(overlap2)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -03003954:
396 S2LO data2, data2, #16
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000397 b L(strcmp_tail)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -03003985:
399 ands syndrome, syndrome, const_m1, S2LO #16
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000400 bne L(strcmp_done_equal)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300401
402 ldrh data2, [src2]
403 S2LO data1, data1, #16
404#ifdef __ARM_BIG_ENDIAN
405 lsl data2, data2, #16
406#endif
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000407 b L(strcmp_tail)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300408
4096:
410 S2LO data1, data1, #16
411 and data2, data2, const_m1, S2LO #16
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000412 b L(strcmp_tail)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300413
414 .p2align 5,,12 /* Ensure at least 3 instructions in cache line. */
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000415L(overlap1):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300416 and tmp1, data1, #LSB
417 uadd8 syndrome, data1, const_m1
418 eors syndrome, tmp1, data2, S2LO #24
419 sel syndrome, syndrome, const_m1
420 bne 4f
421 cbnz syndrome, 5f
422 ldr data2, [src2], #4
423 eor tmp1, tmp1, data1
424 cmp tmp1, data2, S2HI #8
425 bne 6f
426 ldr data1, [src1], #4
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000427 b L(overlap1)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -03004284:
429 S2LO data2, data2, #24
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000430 b L(strcmp_tail)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -03004315:
432 tst syndrome, #LSB
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000433 bne L(strcmp_done_equal)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300434 ldr data2, [src2]
4356:
436 S2LO data1, data1, #8
437 bic data2, data2, #MSB
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000438 b L(strcmp_tail)
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300439
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000440L(strcmp_done_equal):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300441 mov result, #0
442 .cfi_remember_state
443 ldrd r4, r5, [sp], #16
444 .cfi_restore 4
445 .cfi_restore 5
446 /* R6/7 not used in this sequence. */
447 .cfi_restore 6
448 .cfi_restore 7
449 bx lr
450
Wilco Dijkstra833e8602020-01-02 13:36:34 +0000451L(strcmp_tail):
Adhemerval Zanellad30faa52019-08-06 16:21:09 -0300452 .cfi_restore_state
453#ifndef __ARM_BIG_ENDIAN
454 rev data1, data1
455 rev data2, data2
456 /* Now everything looks big-endian... */
457#endif
458 uadd8 tmp1, data1, const_m1
459 eor tmp1, data1, data2
460 sel syndrome, tmp1, const_m1
461 clz tmp1, syndrome
462 lsl data1, data1, tmp1
463 lsl data2, data2, tmp1
464 lsr result, data1, #24
465 ldrd r4, r5, [sp], #16
466 .cfi_restore 4
467 .cfi_restore 5
468 /* R6/7 not used in this sequence. */
469 .cfi_restore 6
470 .cfi_restore 7
471 sub result, result, data2, lsr #24
472 bx lr
Wilco Dijkstra31b560b2020-01-02 09:14:42 +0000473
474END (__strcmp_arm)
Szabolcs Nagy1dfd7b82020-02-12 15:10:29 +0000475
476#endif /* __ARM_ARCH >= 7 && __ARM_ARCH_ISA_ARM >= 1 */