131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris/*
231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * Copyright (c) 2013 ARM Ltd
331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * All rights reserved.
431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris *
531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * Redistribution and use in source and binary forms, with or without
631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * modification, are permitted provided that the following conditions
731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * are met:
831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * 1. Redistributions of source code must retain the above copyright
931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris *    notice, this list of conditions and the following disclaimer.
1031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * 2. Redistributions in binary form must reproduce the above copyright
1131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris *    notice, this list of conditions and the following disclaimer in the
1231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris *    documentation and/or other materials provided with the distribution.
1331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * 3. The name of the company may not be used to endorse or promote
1431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris *    products derived from this software without specific prior written
1531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris *    permission.
1631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris *
1731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
1831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
2231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris */
2831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
2931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#include <machine/cpu-features.h>
30851e68a2402fa414544e66650e09dfdaac813e51Elliott Hughes#include <private/bionic_asm.h>
3131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
3231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#ifdef __ARMEB__
3331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define S2LOMEM lsl
3431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define S2LOMEMEQ lsleq
3531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define S2HIMEM lsr
3631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define MSB 0x000000ff
3731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define LSB 0xff000000
3831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define BYTE0_OFFSET 24
3931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define BYTE1_OFFSET 16
4031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define BYTE2_OFFSET 8
4131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define BYTE3_OFFSET 0
4231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#else /* not  __ARMEB__ */
4331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define S2LOMEM lsr
4431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define S2LOMEMEQ lsreq
4531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define S2HIMEM lsl
4631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define BYTE0_OFFSET 0
4731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define BYTE1_OFFSET 8
4831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define BYTE2_OFFSET 16
4931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define BYTE3_OFFSET 24
5031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define MSB 0xff000000
5131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#define LSB 0x000000ff
5231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#endif /* not  __ARMEB__ */
5331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
5431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris.syntax         unified
5531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
5631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#if defined (__thumb__)
5731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .thumb
5831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .thumb_func
5931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#endif
6031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
6131dea25b8b6438df709f6b2c703cf385a2691e41Christopher FerrisENTRY(strcmp)
6231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris      /* Use LDRD whenever possible.  */
6331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
6431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris/* The main thing to look out for when comparing large blocks is that
6531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   the loads do not cross a page boundary when loading past the index
6631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   of the byte with the first difference or the first string-terminator.
6731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
6831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   For example, if the strings are identical and the string-terminator
6931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   is at index k, byte by byte comparison will not load beyond address
7031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   s1+k and s2+k; word by word comparison may load up to 3 bytes beyond
7131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   k; double word - up to 7 bytes.  If the load of these bytes crosses
7231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   a page boundary, it might cause a memory fault (if the page is not mapped)
7331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   that would not have happened in byte by byte comparison.
7431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
7531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   If an address is (double) word aligned, then a load of a (double) word
7631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   from that address will not cross a page boundary.
7731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   Therefore, the algorithm below considers word and double-word alignment
7831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   of strings separately.  */
7931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
8031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris/* High-level description of the algorithm.
8131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
8231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   * The fast path: if both strings are double-word aligned,
8331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     use LDRD to load two words from each string in every loop iteration.
8431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   * If the strings have the same offset from a word boundary,
8531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     use LDRB to load and compare byte by byte until
8631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     the first string is aligned to a word boundary (at most 3 bytes).
8731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     This is optimized for quick return on short unaligned strings.
8831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   * If the strings have the same offset from a double-word boundary,
8931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     use LDRD to load two words from each string in every loop iteration, as in the fast path.
9031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   * If the strings do not have the same offset from a double-word boundary,
9131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     load a word from the second string before the loop to initialize the queue.
9231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     Use LDRD to load two words from every string in every loop iteration.
9331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     Inside the loop, load the second word from the second string only after comparing
9431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     the first word, using the queued value, to guarantee safety across page boundaries.
9531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   * If the strings do not have the same offset from a word boundary,
9631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     use LDR and a shift queue. Order of loads and comparisons matters,
9731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     similarly to the previous case.
9831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
9931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   * Use UADD8 and SEL to compare words, and use REV and CLZ to compute the return value.
10031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   * The only difference between ARM and Thumb modes is the use of CBZ instruction.
10131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris   * The only difference between big and little endian is the use of REV in little endian
10231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     to compute the return value, instead of MOV.
10331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris*/
10431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
10531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .macro m_cbz reg label
10631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#ifdef __thumb2__
10731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cbz     \reg, \label
10831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#else   /* not defined __thumb2__ */
10931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmp     \reg, #0
11031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        beq     \label
11131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#endif /* not defined __thumb2__ */
11231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .endm /* m_cbz */
11331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
11431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .macro m_cbnz reg label
11531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#ifdef __thumb2__
11631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cbnz    \reg, \label
11731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#else   /* not defined __thumb2__ */
11831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmp     \reg, #0
11931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bne     \label
12031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#endif /* not defined __thumb2__ */
12131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .endm /* m_cbnz */
12231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
12331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .macro  init
12431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Macro to save temporary registers and prepare magic values.  */
12531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        subs    sp, sp, #16
126bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris        .cfi_def_cfa_offset 16
12731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        strd    r4, r5, [sp, #8]
128bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris        .cfi_rel_offset r4, 0
129bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris        .cfi_rel_offset r5, 4
13031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        strd    r6, r7, [sp]
131bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris        .cfi_rel_offset r6, 8
132bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris        .cfi_rel_offset r7, 12
13331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        mvn     r6, #0  /* all F */
13431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        mov     r7, #0  /* all 0 */
13531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .endm   /* init */
13631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
13731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .macro  magic_compare_and_branch w1 w2 label
13831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Macro to compare registers w1 and w2 and conditionally branch to label.  */
13931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmp     \w1, \w2        /* Are w1 and w2 the same?  */
14031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        magic_find_zero_bytes \w1
14131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        it      eq
14231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmpeq   ip, #0          /* Is there a zero byte in w1?  */
14331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bne     \label
14431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .endm /* magic_compare_and_branch */
14531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
14631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .macro  magic_find_zero_bytes w1
14731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Macro to find all-zero bytes in w1, result is in ip.  */
14831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        uadd8   ip, \w1, r6
14931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        sel     ip, r7, r6
15031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .endm /* magic_find_zero_bytes */
15131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
15231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .macro  setup_return w1 w2
15331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#ifdef __ARMEB__
15431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        mov     r1, \w1
15531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        mov     r2, \w2
15631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#else /* not  __ARMEB__ */
15731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        rev     r1, \w1
15831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        rev     r2, \w2
15931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#endif /* not  __ARMEB__ */
16031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .endm /* setup_return */
16131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
16231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        pld [r0, #0]
16331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        pld [r1, #0]
16431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
16531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Are both strings double-word aligned?  */
16631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        orr     ip, r0, r1
16731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        tst     ip, #7
168a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        bne     .L_do_align
16931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
17031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Fast path.  */
171a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        .save   {r4-r7}
17231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        init
17331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
174a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_doubleword_aligned:
17531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
17631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Get here when the strings to compare are double-word aligned.  */
17731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Compare two words in every iteration.  */
17831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .p2align        2
17931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris2:
18031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        pld [r0, #16]
18131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        pld [r1, #16]
18231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
18331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Load the next double-word from each string.  */
18431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrd    r2, r3, [r0], #8
18531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrd    r4, r5, [r1], #8
18631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
187a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        magic_compare_and_branch w1=r2, w2=r4, label=.L_return_24
188a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        magic_compare_and_branch w1=r3, w2=r5, label=.L_return_35
18931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        b       2b
19031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
191a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_do_align:
19231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Is the first string word-aligned?  */
19331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ands    ip, r0, #3
194a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        beq     .L_word_aligned_r0
19531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
19631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Fast compare byte by byte until the first string is word-aligned.  */
19731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* The offset of r0 from a word boundary is in ip. Thus, the number of bytes
19831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        to read until the next word boundary is 4-ip.  */
19931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bic     r0, r0, #3
20031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r2, [r0], #4
20131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        lsls    ip, ip, #31
202a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        beq     .L_byte2
203a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        bcs     .L_byte3
20431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
205a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_byte1:
20631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrb    ip, [r1], #1
20731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        uxtb    r3, r2, ror #BYTE1_OFFSET
20831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        subs    ip, r3, ip
209a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        bne     .L_fast_return
210a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        m_cbz   reg=r3, label=.L_fast_return
21131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
212a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_byte2:
21331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrb    ip, [r1], #1
21431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        uxtb    r3, r2, ror #BYTE2_OFFSET
21531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        subs    ip, r3, ip
216a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        bne     .L_fast_return
217a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        m_cbz   reg=r3, label=.L_fast_return
21831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
219a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_byte3:
22031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrb    ip, [r1], #1
22131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        uxtb    r3, r2, ror #BYTE3_OFFSET
22231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        subs    ip, r3, ip
223a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        bne     .L_fast_return
224a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        m_cbnz  reg=r3, label=.L_word_aligned_r0
22531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
226a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_fast_return:
22731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        mov     r0, ip
22831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bx      lr
22931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
230a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_word_aligned_r0:
23131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        init
23231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* The first string is word-aligned.  */
23331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Is the second string word-aligned?  */
23431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ands    ip, r1, #3
235a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        bne     .L_strcmp_unaligned
23631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
237a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_word_aligned:
23831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* The strings are word-aligned. */
23931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Is the first string double-word aligned?  */
24031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        tst     r0, #4
241a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        beq     .L_doubleword_aligned_r0
24231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
24331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* If r0 is not double-word aligned yet, align it by loading
24431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        and comparing the next word from each string.  */
24531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r2, [r0], #4
24631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r4, [r1], #4
247a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        magic_compare_and_branch w1=r2 w2=r4 label=.L_return_24
24831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
249a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_doubleword_aligned_r0:
25031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Get here when r0 is double-word aligned.  */
25131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Is r1 doubleword_aligned?  */
25231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        tst     r1, #4
253a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        beq     .L_doubleword_aligned
25431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
25531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Get here when the strings to compare are word-aligned,
25631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        r0 is double-word aligned, but r1 is not double-word aligned.  */
25731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
25831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Initialize the queue.  */
25931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r5, [r1], #4
26031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
26131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Compare two words in every iteration.  */
26231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .p2align        2
26331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris3:
26431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        pld [r0, #16]
26531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        pld [r1, #16]
26631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
26731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Load the next double-word from each string and compare.  */
26831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrd    r2, r3, [r0], #8
269a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        magic_compare_and_branch w1=r2 w2=r5 label=.L_return_25
27031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrd    r4, r5, [r1], #8
271a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        magic_compare_and_branch w1=r3 w2=r4 label=.L_return_34
27231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        b       3b
27331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
27431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .macro miscmp_word offsetlo offsethi
27531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Macro to compare misaligned strings.  */
27631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* r0, r1 are word-aligned, and at least one of the strings
27731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        is not double-word aligned.  */
27831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Compare one word in every loop iteration.  */
27931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* OFFSETLO is the original bit-offset of r1 from a word-boundary,
28031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        OFFSETHI is 32 - OFFSETLO (i.e., offset from the next word).  */
28131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
28231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Initialize the shift queue.  */
28331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r5, [r1], #4
28431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
28531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Compare one word from each string in every loop iteration.  */
28631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .p2align        2
28731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris7:
28831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r3, [r0], #4
28931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        S2LOMEM r5, r5, #\offsetlo
29031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        magic_find_zero_bytes w1=r3
29131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmp     r7, ip, S2HIMEM #\offsetlo
29231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        and     r2, r3, r6, S2LOMEM #\offsetlo
29331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        it      eq
29431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmpeq   r2, r5
295a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        bne     .L_return_25
29631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r5, [r1], #4
29731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmp     ip, #0
29831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        eor r3, r2, r3
29931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        S2HIMEM r2, r5, #\offsethi
30031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        it      eq
30131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmpeq   r3, r2
302a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        bne     .L_return_32
30331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        b       7b
30431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .endm /* miscmp_word */
30531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
306a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_return_32:
30731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        setup_return w1=r3, w2=r2
308a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        b       .L_do_return
309a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_return_34:
31031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        setup_return w1=r3, w2=r4
311a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        b       .L_do_return
312a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_return_25:
31331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        setup_return w1=r2, w2=r5
314a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        b       .L_do_return
315a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_return_35:
31631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        setup_return w1=r3, w2=r5
317a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        b       .L_do_return
318a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_return_24:
31931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        setup_return w1=r2, w2=r4
32031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
321a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_do_return:
32231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
32331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#ifdef __ARMEB__
32431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        mov     r0, ip
32531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#else /* not  __ARMEB__ */
32631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        rev     r0, ip
32731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#endif /* not  __ARMEB__ */
32831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
32931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Restore temporaries early, before computing the return value.  */
33031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrd    r6, r7, [sp]
33131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrd    r4, r5, [sp, #8]
33231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        adds    sp, sp, #16
333bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris        .cfi_def_cfa_offset 0
334bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris        .cfi_restore r4
335bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris        .cfi_restore r5
336bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris        .cfi_restore r6
337bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris        .cfi_restore r7
33831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
33931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* There is a zero or a different byte between r1 and r2.  */
34031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* r0 contains a mask of all-zero bytes in r1.  */
34131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Using r0 and not ip here because cbz requires low register.  */
342a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris        m_cbz   reg=r0, label=.L_compute_return_value
34331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        clz     r0, r0
34431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* r0 contains the number of bits on the left of the first all-zero byte in r1.  */
34531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        rsb     r0, r0, #24
34631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Here, r0 contains the number of bits on the right of the first all-zero byte in r1.  */
34731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        lsr     r1, r1, r0
34831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        lsr     r2, r2, r0
34931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
350a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_compute_return_value:
35131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        movs    r0, #1
35231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmp     r1, r2
35331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* The return value is computed as follows.
35431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        If r1>r2 then (C==1 and Z==0) and LS doesn't hold and r0 is #1 at return.
35531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        If r1<r2 then (C==0 and Z==0) and we execute SBC with carry_in=0,
35631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        which means r0:=r0-r0-1 and r0 is #-1 at return.
35731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        If r1=r2 then (C==1 and Z==1) and we execute SBC with carry_in=1,
35831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        which means r0:=r0-r0 and r0 is #0 at return.
35931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        (C==0 and Z==1) cannot happen because the carry bit is "not borrow".  */
36031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        it      ls
36131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        sbcls   r0, r0, r0
36231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bx      lr
36331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
36431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris    /* The code from the previous version of strcmp.S handles all of the
36531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     * cases where the first string and seconds string cannot both be
36631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     * aligned to a word boundary faster than the new algorithm. See
36731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     * bionic/libc/arch-arm/cortex-a15/bionic/strcmp.S for the unedited
36831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     * version of the code.
36931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris     */
370a57c9c084bc686a35f4f494ce23cf2a9bb3d5d00Christopher Ferris.L_strcmp_unaligned:
37131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	wp1 .req r0
37231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	wp2 .req r1
37331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	b1  .req r2
37431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	w1  .req r4
37531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	w2  .req r5
37631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	t1  .req ip
37731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	@ r3 is scratch
37831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
37931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris2:
38031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	mov	b1, #1
38131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	orr	b1, b1, b1, lsl #8
38231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	orr	b1, b1, b1, lsl #16
38331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
38431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	and	t1, wp2, #3
38531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bic	wp2, wp2, #3
38631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ldr	w1, [wp1], #4
38731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ldr	w2, [wp2], #4
38831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	cmp	t1, #2
38931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	beq	2f
39031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bhi	3f
39131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
39231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	/* Critical inner Loop: Block with 3 bytes initial overlap */
39331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	.p2align	2
39431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris1:
39531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bic	t1, w1, #MSB
39631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	cmp	t1, w2, S2LOMEM #8
39731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	sub	r3, w1, b1
39831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bic	r3, r3, w1
39931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bne	4f
40031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ands	r3, r3, b1, lsl #7
40131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	it	eq
40231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ldreq	w2, [wp2], #4
40331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bne	5f
40431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	eor	t1, t1, w1
40531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	cmp	t1, w2, S2HIMEM #24
40631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bne	6f
40731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ldr	w1, [wp1], #4
40831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	b	1b
40931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris4:
41031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2LOMEM	w2, w2, #8
41131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	b	8f
41231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
41331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris5:
41431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#ifdef __ARMEB__
41531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	/* The syndrome value may contain false ones if the string ends
41631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	 * with the bytes 0x01 0x00
41731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	 */
41831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	tst	w1, #0xff000000
41931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	itt	ne
42031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	tstne	w1, #0x00ff0000
42131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	tstne	w1, #0x0000ff00
42231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	beq	7f
42331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#else
42431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bics	r3, r3, #0xff000000
42531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bne	7f
42631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#endif
42731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ldrb	w2, [wp2]
42831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2LOMEM	t1, w1, #24
42931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#ifdef __ARMEB__
43031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	lsl	w2, w2, #24
43131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#endif
43231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	b	8f
43331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
43431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris6:
43531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2LOMEM	t1, w1, #24
43631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	and	w2, w2, #LSB
43731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	b	8f
43831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
43931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	/* Critical inner Loop: Block with 2 bytes initial overlap */
44031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	.p2align	2
44131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris2:
44231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2HIMEM	t1, w1, #16
44331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	sub	r3, w1, b1
44431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2LOMEM	t1, t1, #16
44531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bic	r3, r3, w1
44631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	cmp	t1, w2, S2LOMEM #16
44731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bne	4f
44831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ands	r3, r3, b1, lsl #7
44931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	it	eq
45031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ldreq	w2, [wp2], #4
45131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bne	5f
45231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	eor	t1, t1, w1
45331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	cmp	t1, w2, S2HIMEM #16
45431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bne	6f
45531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ldr	w1, [wp1], #4
45631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	b	2b
45731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
45831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris5:
45931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#ifdef __ARMEB__
46031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	/* The syndrome value may contain false ones if the string ends
46131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	 * with the bytes 0x01 0x00
46231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	 */
46331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	tst	w1, #0xff000000
46431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	it	ne
46531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	tstne	w1, #0x00ff0000
46631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	beq	7f
46731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#else
46831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	lsls	r3, r3, #16
46931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bne	7f
47031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#endif
47131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ldrh	w2, [wp2]
47231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2LOMEM	t1, w1, #16
47331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#ifdef __ARMEB__
47431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	lsl	w2, w2, #16
47531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#endif
47631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	b	8f
47731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
47831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris6:
47931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2HIMEM	w2, w2, #16
48031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2LOMEM	t1, w1, #16
48131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris4:
48231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2LOMEM	w2, w2, #16
48331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	b	8f
48431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
48531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	/* Critical inner Loop: Block with 1 byte initial overlap */
48631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	.p2align	2
48731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris3:
48831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	and	t1, w1, #LSB
48931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	cmp	t1, w2, S2LOMEM #24
49031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	sub	r3, w1, b1
49131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bic	r3, r3, w1
49231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bne	4f
49331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ands	r3, r3, b1, lsl #7
49431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	it	eq
49531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ldreq	w2, [wp2], #4
49631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bne	5f
49731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	eor	t1, t1, w1
49831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	cmp	t1, w2, S2HIMEM #8
49931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bne	6f
50031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ldr	w1, [wp1], #4
50131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	b	3b
50231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris4:
50331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2LOMEM	w2, w2, #24
50431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	b	8f
50531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris5:
50631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	/* The syndrome value may contain false ones if the string ends
50731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	 * with the bytes 0x01 0x00
50831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	 */
50931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	tst	w1, #LSB
51031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	beq	7f
51131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	ldr	w2, [wp2], #4
51231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris6:
51331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2LOMEM	t1, w1, #8
51431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bic	w2, w2, #MSB
51531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	b	8f
51631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris7:
51731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	mov	r0, #0
51831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
51931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris    /* Restore registers and stack. */
52031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris    ldrd    r6, r7, [sp]
52131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris    ldrd    r4, r5, [sp, #8]
52231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris    adds    sp, sp, #16
523bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris    .cfi_def_cfa_offset 0
524bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris    .cfi_restore r4
525bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris    .cfi_restore r5
526bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris    .cfi_restore r6
527bd7fe1d3c4c8877ac53839169851621249289bd7Christopher Ferris    .cfi_restore r7
52831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
52931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bx	lr
53031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
53131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris8:
53231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	and	r2, t1, #LSB
53331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	and	r0, w2, #LSB
53431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	cmp	r0, #1
53531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	it	cs
53631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	cmpcs	r0, r2
53731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	itt	eq
53831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2LOMEMEQ	t1, t1, #8
53931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2LOMEMEQ	w2, w2, #8
54031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	beq	8b
54131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	sub	r0, r2, r0
54231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
54331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris    /* Restore registers and stack. */
54431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris    ldrd    r6, r7, [sp]
54531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris    ldrd    r4, r5, [sp, #8]
54631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris    adds    sp, sp, #16
54731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
54831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bx	lr
54931dea25b8b6438df709f6b2c703cf385a2691e41Christopher FerrisEND(strcmp)
550