11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved. 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met: 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * * Redistributions of source code must retain the above copyright 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer. 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * * Redistributions in binary form must reproduce the above copyright 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer in 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the documentation and/or other materials provided with the 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * distribution. 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE. 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <machine/cpu-features.h> 30851e68a2402fa414544e66650e09dfdaac813e51Elliott Hughes#include <private/bionic_asm.h> 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 323ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding 333ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding#ifdef HAVE_32_BYTE_CACHE_LINE 343ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding#define CACHE_LINE_SIZE 32 353ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding#else 363ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding#define CACHE_LINE_SIZE 64 373ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding#endif 383ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 403ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding * Optimized memcmp() for Cortex-A9. 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 43420878c6908cf9c2862888477ec3f424a06cf172Kenny RootENTRY(memcmp) 443ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding pld [r0, #(CACHE_LINE_SIZE * 0)] 453ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding pld [r0, #(CACHE_LINE_SIZE * 1)] 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* take of the case where length is 0 or the buffers are the same */ 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cmp r0, r1 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project moveq r0, #0 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bxeq lr 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 523ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding pld [r1, #(CACHE_LINE_SIZE * 0)] 533ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding pld [r1, #(CACHE_LINE_SIZE * 1)] 543ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding 553ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding /* make sure we have at least 8+4 bytes, this simplify things below 563ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding * and avoid some overhead for small blocks 573ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding */ 583ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding cmp r2, #(8+4) 593ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding bmi 10f 603ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding/* 613ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding * Neon optimization 623ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding * Comparing 32 bytes at a time 633ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding */ 643ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding#if defined(__ARM_NEON__) && defined(NEON_UNALIGNED_ACCESS) 653ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding subs r2, r2, #32 663ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding blo 3f 673ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding 683ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding /* preload all the cache lines we need. */ 693ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding pld [r0, #(CACHE_LINE_SIZE * 2)] 703ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding pld [r1, #(CACHE_LINE_SIZE * 2)] 713ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding 723ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding1: /* The main loop compares 32 bytes at a time */ 733ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding vld1.8 {d0 - d3}, [r0]! 743ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding pld [r0, #(CACHE_LINE_SIZE * 2)] 753ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding vld1.8 {d4 - d7}, [r1]! 763ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding pld [r1, #(CACHE_LINE_SIZE * 2)] 773ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding 783ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding /* Start subtracting the values and merge results */ 793ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding vsub.i8 q0, q2 803ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding vsub.i8 q1, q3 813ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding vorr q2, q0, q1 823ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding vorr d4, d5 833ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding vmov r3, ip, d4 843ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding /* Check if there are any differences among the 32 bytes */ 853ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding orrs r3, ip 863ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding bne 2f 873ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding subs r2, r2, #32 883ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding bhs 1b 893ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding b 3f 903ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding2: 913ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding /* Check if the difference was in the first or last 16 bytes */ 923ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding sub r0, #32 933ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding vorr d0, d1 943ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding sub r1, #32 953ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding vmov r3, ip, d0 963ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding orrs r3, ip 973ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding /* if the first 16 bytes are equal, we only have to rewind 16 bytes */ 983ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding ittt eq 993ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding subeq r2, #16 1003ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding addeq r0, #16 1013ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding addeq r1, #16 1023ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding 1033ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding3: /* fix-up the remaining count */ 1043ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding add r2, r2, #32 1053ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding 1063ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding cmp r2, #(8+4) 1073ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding bmi 10f 1083ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding#endif 1093ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding 1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* save registers */ 1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project stmfd sp!, {r4, lr} 112ed45970ac5a182e512669cfa5c15b9f4fa783ad7Christopher Ferris .cfi_def_cfa_offset 8 113ed45970ac5a182e512669cfa5c15b9f4fa783ad7Christopher Ferris .cfi_rel_offset r4, 0 114ed45970ac5a182e512669cfa5c15b9f4fa783ad7Christopher Ferris .cfi_rel_offset lr, 4 1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* since r0 hold the result, move the first source 1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * pointer somewhere else 1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project mov r4, r0 1206719500dbd9330d7539d2db3dcf3e8ad1858c7aaElliott Hughes 1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* align first pointer to word boundary 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * offset = -src & 3 1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rsb r3, r4, #0 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ands r3, r3, #3 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project beq 0f 1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* align first pointer */ 1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sub r2, r2, r3 1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project1: ldrb r0, [r4], #1 1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldrb ip, [r1], #1 1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project subs r0, r0, ip 1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bne 9f 1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project subs r3, r3, #1 1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bne 1b 1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project0: /* here the first pointer is aligned, and we have at least 4 bytes 1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * to process. 1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* see if the pointers are congruent */ 1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eor r0, r4, r1 1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ands r0, r0, #3 1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bne 5f 1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* congruent case, 32 bytes per iteration 1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * We need to make sure there are at least 32+4 bytes left 1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * because we effectively read ahead one word, and we could 1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * read past the buffer (and segfault) if we're not careful. 1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldr ip, [r1] 1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project subs r2, r2, #(32 + 4) 1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bmi 1f 1566719500dbd9330d7539d2db3dcf3e8ad1858c7aaElliott Hughes 1573ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding0: pld [r4, #(CACHE_LINE_SIZE * 2)] 1583ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding pld [r1, #(CACHE_LINE_SIZE * 2)] 1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldr r0, [r4], #4 1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldr lr, [r1, #4]! 1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eors r0, r0, ip 1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq r0, [r4], #4 1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq ip, [r1, #4]! 1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eoreqs r0, r0, lr 1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq r0, [r4], #4 1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq lr, [r1, #4]! 1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eoreqs r0, r0, ip 1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq r0, [r4], #4 1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq ip, [r1, #4]! 1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eoreqs r0, r0, lr 1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq r0, [r4], #4 1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq lr, [r1, #4]! 1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eoreqs r0, r0, ip 1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq r0, [r4], #4 1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq ip, [r1, #4]! 1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eoreqs r0, r0, lr 1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq r0, [r4], #4 1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq lr, [r1, #4]! 1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eoreqs r0, r0, ip 1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq r0, [r4], #4 1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq ip, [r1, #4]! 1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eoreqs r0, r0, lr 1836719500dbd9330d7539d2db3dcf3e8ad1858c7aaElliott Hughes bne 2f 1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project subs r2, r2, #32 1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bhs 0b 1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* do we have at least 4 bytes left? */ 1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project1: adds r2, r2, #(32 - 4 + 4) 1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bmi 4f 1906719500dbd9330d7539d2db3dcf3e8ad1858c7aaElliott Hughes 1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* finish off 4 bytes at a time */ 1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project3: ldr r0, [r4], #4 1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldr ip, [r1], #4 1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eors r0, r0, ip 1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bne 2f 1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project subs r2, r2, #4 1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bhs 3b 1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* are we done? */ 2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project4: adds r2, r2, #4 2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project moveq r0, #0 2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project beq 9f 2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* finish off the remaining bytes */ 2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project b 8f 2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project2: /* the last 4 bytes are different, restart them */ 2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sub r4, r4, #4 2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sub r1, r1, #4 2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project mov r2, #4 2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* process the last few bytes */ 2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project8: ldrb r0, [r4], #1 2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldrb ip, [r1], #1 2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // stall 2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project subs r0, r0, ip 2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bne 9f 2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project subs r2, r2, #1 2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bne 8b 2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project9: /* restore registers and return */ 2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldmfd sp!, {r4, lr} 2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bx lr 2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2253ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding10: /* process less than 12 bytes */ 2263ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding cmp r2, #0 2273ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding moveq r0, #0 2283ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding bxeq lr 2293ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding mov r3, r0 2303ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding11: 2313ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding ldrb r0, [r3], #1 2323ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding ldrb ip, [r1], #1 2333ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding subs r0, ip 2343ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding bxne lr 2353ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding subs r2, r2, #1 2363ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding bne 11b 2373ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding bx lr 2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project5: /*************** non-congruent case ***************/ 2406719500dbd9330d7539d2db3dcf3e8ad1858c7aaElliott Hughes and r0, r1, #3 2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cmp r0, #2 2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bne 4f 2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* here, offset is 2 (16-bits aligned, special cased) */ 2456719500dbd9330d7539d2db3dcf3e8ad1858c7aaElliott Hughes 2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* make sure we have at least 16 bytes to process */ 2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project subs r2, r2, #16 2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project addmi r2, r2, #16 2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bmi 8b 2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* align the unaligned pointer */ 2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bic r1, r1, #3 2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldr lr, [r1], #4 2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2553ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding6: pld [r1, #(CACHE_LINE_SIZE * 2)] 2563ebd31c0a1d343c3fd7845d7b1149e841ad83c6aHenrik Smiding pld [r4, #(CACHE_LINE_SIZE * 2)] 2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project mov ip, lr, lsr #16 2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldr lr, [r1], #4 2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldr r0, [r4], #4 2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project orr ip, ip, lr, lsl #16 2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eors r0, r0, ip 2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project moveq ip, lr, lsr #16 2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq lr, [r1], #4 2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq r0, [r4], #4 2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project orreq ip, ip, lr, lsl #16 2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eoreqs r0, r0, ip 2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project moveq ip, lr, lsr #16 2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq lr, [r1], #4 2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq r0, [r4], #4 2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project orreq ip, ip, lr, lsl #16 2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eoreqs r0, r0, ip 2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project moveq ip, lr, lsr #16 2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq lr, [r1], #4 2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq r0, [r4], #4 2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project orreq ip, ip, lr, lsl #16 2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eoreqs r0, r0, ip 2771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bne 7f 2781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project subs r2, r2, #16 2791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bhs 6b 2801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sub r1, r1, #2 2811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* are we done? */ 2821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project adds r2, r2, #16 2831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project moveq r0, #0 2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project beq 9b 2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* finish off the remaining bytes */ 2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project b 8b 2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project7: /* fix up the 2 pointers and fallthrough... */ 2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sub r1, r1, #(4+2) 2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sub r4, r4, #4 2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project mov r2, #4 2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project b 8b 2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project4: /*************** offset is 1 or 3 (less optimized) ***************/ 2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project stmfd sp!, {r5, r6, r7} 2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // r5 = rhs 3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // r6 = lhs 3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // r7 = scratch 3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project mov r5, r0, lsl #3 /* r5 = right shift */ 3041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rsb r6, r5, #32 /* r6 = left shift */ 3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* align the unaligned pointer */ 3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bic r1, r1, #3 3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldr r7, [r1], #4 3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sub r2, r2, #8 3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project6: mov ip, r7, lsr r5 3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldr r7, [r1], #4 3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldr r0, [r4], #4 3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project orr ip, ip, r7, lsl r6 3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eors r0, r0, ip 3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project moveq ip, r7, lsr r5 3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq r7, [r1], #4 3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldreq r0, [r4], #4 3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project orreq ip, ip, r7, lsl r6 3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eoreqs r0, r0, ip 3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bne 7f 3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project subs r2, r2, #8 3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bhs 6b 3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sub r1, r1, r6, lsr #3 3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldmfd sp!, {r5, r6, r7} 3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* are we done? */ 3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project adds r2, r2, #8 3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project moveq r0, #0 3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project beq 9b 3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* finish off the remaining bytes */ 3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project b 8b 3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project7: /* fix up the 2 pointers and fallthrough... */ 3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sub r1, r1, #4 3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sub r1, r1, r6, lsr #3 3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sub r4, r4, #4 3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project mov r2, #4 3411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldmfd sp!, {r5, r6, r7} 3421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project b 8b 3436719500dbd9330d7539d2db3dcf3e8ad1858c7aaElliott HughesEND(memcmp) 344