strcmp.S revision 31dea25b8b6438df709f6b2c703cf385a2691e41
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>
3031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#include <machine/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
12631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        strd    r4, r5, [sp, #8]
12731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        strd    r6, r7, [sp]
12831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        mvn     r6, #0  /* all F */
12931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        mov     r7, #0  /* all 0 */
13031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .endm   /* init */
13131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
13231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .macro  magic_compare_and_branch w1 w2 label
13331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Macro to compare registers w1 and w2 and conditionally branch to label.  */
13431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmp     \w1, \w2        /* Are w1 and w2 the same?  */
13531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        magic_find_zero_bytes \w1
13631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        it      eq
13731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmpeq   ip, #0          /* Is there a zero byte in w1?  */
13831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bne     \label
13931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .endm /* magic_compare_and_branch */
14031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
14131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .macro  magic_find_zero_bytes w1
14231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Macro to find all-zero bytes in w1, result is in ip.  */
14331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#if (defined (__ARM_FEATURE_DSP))
14431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        uadd8   ip, \w1, r6
14531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        sel     ip, r7, r6
14631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#else /* not defined (__ARM_FEATURE_DSP) */
14731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* __ARM_FEATURE_DSP is not defined for some Cortex-M processors.
14831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        Coincidently, these processors only have Thumb-2 mode, where we can use the
14931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        the (large) magic constant available directly as an immediate in instructions.
15031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        Note that we cannot use the magic constant in ARM mode, where we need
15131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        to create the constant in a register.  */
15231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        sub     ip, \w1, #0x01010101
15331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bic     ip, ip, \w1
15431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        and     ip, ip, #0x80808080
15531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#endif /* not defined (__ARM_FEATURE_DSP) */
15631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .endm /* magic_find_zero_bytes */
15731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
15831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .macro  setup_return w1 w2
15931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#ifdef __ARMEB__
16031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        mov     r1, \w1
16131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        mov     r2, \w2
16231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#else /* not  __ARMEB__ */
16331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        rev     r1, \w1
16431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        rev     r2, \w2
16531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#endif /* not  __ARMEB__ */
16631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .endm /* setup_return */
16731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
16831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        pld [r0, #0]
16931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        pld [r1, #0]
17031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
17131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Are both strings double-word aligned?  */
17231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        orr     ip, r0, r1
17331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        tst     ip, #7
17431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bne     do_align
17531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
17631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Fast path.  */
17731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        init
17831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
17931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisdoubleword_aligned:
18031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
18131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Get here when the strings to compare are double-word aligned.  */
18231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Compare two words in every iteration.  */
18331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .p2align        2
18431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris2:
18531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        pld [r0, #16]
18631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        pld [r1, #16]
18731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
18831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Load the next double-word from each string.  */
18931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrd    r2, r3, [r0], #8
19031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrd    r4, r5, [r1], #8
19131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
19231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        magic_compare_and_branch w1=r2, w2=r4, label=return_24
19331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        magic_compare_and_branch w1=r3, w2=r5, label=return_35
19431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        b       2b
19531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
19631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisdo_align:
19731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Is the first string word-aligned?  */
19831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ands    ip, r0, #3
19931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        beq     word_aligned_r0
20031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
20131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Fast compare byte by byte until the first string is word-aligned.  */
20231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* The offset of r0 from a word boundary is in ip. Thus, the number of bytes
20331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        to read until the next word boundary is 4-ip.  */
20431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bic     r0, r0, #3
20531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r2, [r0], #4
20631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        lsls    ip, ip, #31
20731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        beq     byte2
20831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bcs     byte3
20931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
21031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisbyte1:
21131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrb    ip, [r1], #1
21231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        uxtb    r3, r2, ror #BYTE1_OFFSET
21331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        subs    ip, r3, ip
21431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bne     fast_return
21531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        m_cbz   reg=r3, label=fast_return
21631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
21731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisbyte2:
21831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrb    ip, [r1], #1
21931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        uxtb    r3, r2, ror #BYTE2_OFFSET
22031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        subs    ip, r3, ip
22131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bne     fast_return
22231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        m_cbz   reg=r3, label=fast_return
22331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
22431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisbyte3:
22531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrb    ip, [r1], #1
22631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        uxtb    r3, r2, ror #BYTE3_OFFSET
22731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        subs    ip, r3, ip
22831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bne     fast_return
22931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        m_cbnz  reg=r3, label=word_aligned_r0
23031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
23131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisfast_return:
23231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        mov     r0, ip
23331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bx      lr
23431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
23531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisword_aligned_r0:
23631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        init
23731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* The first string is word-aligned.  */
23831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Is the second string word-aligned?  */
23931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ands    ip, r1, #3
24031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bne     strcmp_unaligned
24131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
24231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisword_aligned:
24331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* The strings are word-aligned. */
24431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Is the first string double-word aligned?  */
24531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        tst     r0, #4
24631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        beq     doubleword_aligned_r0
24731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
24831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* If r0 is not double-word aligned yet, align it by loading
24931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        and comparing the next word from each string.  */
25031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r2, [r0], #4
25131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r4, [r1], #4
25231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        magic_compare_and_branch w1=r2 w2=r4 label=return_24
25331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
25431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisdoubleword_aligned_r0:
25531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Get here when r0 is double-word aligned.  */
25631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Is r1 doubleword_aligned?  */
25731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        tst     r1, #4
25831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        beq     doubleword_aligned
25931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
26031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Get here when the strings to compare are word-aligned,
26131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        r0 is double-word aligned, but r1 is not double-word aligned.  */
26231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
26331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Initialize the queue.  */
26431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r5, [r1], #4
26531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
26631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Compare two words in every iteration.  */
26731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .p2align        2
26831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris3:
26931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        pld [r0, #16]
27031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        pld [r1, #16]
27131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
27231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Load the next double-word from each string and compare.  */
27331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrd    r2, r3, [r0], #8
27431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        magic_compare_and_branch w1=r2 w2=r5 label=return_25
27531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrd    r4, r5, [r1], #8
27631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        magic_compare_and_branch w1=r3 w2=r4 label=return_34
27731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        b       3b
27831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
27931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .macro miscmp_word offsetlo offsethi
28031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Macro to compare misaligned strings.  */
28131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* r0, r1 are word-aligned, and at least one of the strings
28231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        is not double-word aligned.  */
28331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Compare one word in every loop iteration.  */
28431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* OFFSETLO is the original bit-offset of r1 from a word-boundary,
28531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        OFFSETHI is 32 - OFFSETLO (i.e., offset from the next word).  */
28631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
28731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Initialize the shift queue.  */
28831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r5, [r1], #4
28931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
29031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Compare one word from each string in every loop iteration.  */
29131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .p2align        2
29231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris7:
29331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r3, [r0], #4
29431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        S2LOMEM r5, r5, #\offsetlo
29531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        magic_find_zero_bytes w1=r3
29631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmp     r7, ip, S2HIMEM #\offsetlo
29731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        and     r2, r3, r6, S2LOMEM #\offsetlo
29831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        it      eq
29931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmpeq   r2, r5
30031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bne     return_25
30131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldr     r5, [r1], #4
30231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmp     ip, #0
30331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        eor r3, r2, r3
30431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        S2HIMEM r2, r5, #\offsethi
30531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        it      eq
30631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        cmpeq   r3, r2
30731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        bne     return_32
30831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        b       7b
30931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        .endm /* miscmp_word */
31031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
31131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisreturn_32:
31231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        setup_return w1=r3, w2=r2
31331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        b       do_return
31431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisreturn_34:
31531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        setup_return w1=r3, w2=r4
31631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        b       do_return
31731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisreturn_25:
31831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        setup_return w1=r2, w2=r5
31931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        b       do_return
32031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisreturn_35:
32131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        setup_return w1=r3, w2=r5
32231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        b       do_return
32331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisreturn_24:
32431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        setup_return w1=r2, w2=r4
32531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
32631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisdo_return:
32731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
32831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#ifdef __ARMEB__
32931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        mov     r0, ip
33031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#else /* not  __ARMEB__ */
33131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        rev     r0, ip
33231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris#endif /* not  __ARMEB__ */
33331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
33431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        /* Restore temporaries early, before computing the return value.  */
33531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrd    r6, r7, [sp]
33631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        ldrd    r4, r5, [sp, #8]
33731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        adds    sp, sp, #16
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.  */
34231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris        m_cbz   reg=r0, label=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
35031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferriscompute_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     */
37031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferrisstrcmp_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
52331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
52431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bx	lr
52531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
52631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris8:
52731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	and	r2, t1, #LSB
52831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	and	r0, w2, #LSB
52931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	cmp	r0, #1
53031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	it	cs
53131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	cmpcs	r0, r2
53231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	itt	eq
53331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2LOMEMEQ	t1, t1, #8
53431dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	S2LOMEMEQ	w2, w2, #8
53531dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	beq	8b
53631dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	sub	r0, r2, r0
53731dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
53831dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris    /* Restore registers and stack. */
53931dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris    ldrd    r6, r7, [sp]
54031dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris    ldrd    r4, r5, [sp, #8]
54131dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris    adds    sp, sp, #16
54231dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris
54331dea25b8b6438df709f6b2c703cf385a2691e41Christopher Ferris	bx	lr
54431dea25b8b6438df709f6b2c703cf385a2691e41Christopher FerrisEND(strcmp)
545