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