1*c9945492SAndroid Build Coastguard Worker/* 2*c9945492SAndroid Build Coastguard Worker * Copyright (C) 2008 The Android Open Source Project 3*c9945492SAndroid Build Coastguard Worker * All rights reserved. 4*c9945492SAndroid Build Coastguard Worker * 5*c9945492SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without 6*c9945492SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions 7*c9945492SAndroid Build Coastguard Worker * are met: 8*c9945492SAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright 9*c9945492SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer. 10*c9945492SAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above copyright 11*c9945492SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in 12*c9945492SAndroid Build Coastguard Worker * the documentation and/or other materials provided with the 13*c9945492SAndroid Build Coastguard Worker * distribution. 14*c9945492SAndroid Build Coastguard Worker * 15*c9945492SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16*c9945492SAndroid Build Coastguard Worker * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17*c9945492SAndroid Build Coastguard Worker * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18*c9945492SAndroid Build Coastguard Worker * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19*c9945492SAndroid Build Coastguard Worker * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20*c9945492SAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21*c9945492SAndroid Build Coastguard Worker * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22*c9945492SAndroid Build Coastguard Worker * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23*c9945492SAndroid Build Coastguard Worker * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24*c9945492SAndroid Build Coastguard Worker * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25*c9945492SAndroid Build Coastguard Worker * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*c9945492SAndroid Build Coastguard Worker * SUCH DAMAGE. 27*c9945492SAndroid Build Coastguard Worker */ 28*c9945492SAndroid Build Coastguard Worker 29*c9945492SAndroid Build Coastguard Worker 30*c9945492SAndroid Build Coastguard Worker/* 31*c9945492SAndroid Build Coastguard Worker * Optimized memcpy() for ARM. 32*c9945492SAndroid Build Coastguard Worker * 33*c9945492SAndroid Build Coastguard Worker * note that memcpy() always returns the destination pointer, 34*c9945492SAndroid Build Coastguard Worker * so we have to preserve R0. 35*c9945492SAndroid Build Coastguard Worker */ 36*c9945492SAndroid Build Coastguard Worker 37*c9945492SAndroid Build Coastguard Worker/* 38*c9945492SAndroid Build Coastguard Worker * This file has been modified from the original for use in musl libc. 39*c9945492SAndroid Build Coastguard Worker * The main changes are: addition of .type memcpy,%function to make the 40*c9945492SAndroid Build Coastguard Worker * code safely callable from thumb mode, adjusting the return 41*c9945492SAndroid Build Coastguard Worker * instructions to be compatible with pre-thumb ARM cpus, removal of 42*c9945492SAndroid Build Coastguard Worker * prefetch code that is not compatible with older cpus and support for 43*c9945492SAndroid Build Coastguard Worker * building as thumb 2 and big-endian. 44*c9945492SAndroid Build Coastguard Worker */ 45*c9945492SAndroid Build Coastguard Worker 46*c9945492SAndroid Build Coastguard Worker.syntax unified 47*c9945492SAndroid Build Coastguard Worker 48*c9945492SAndroid Build Coastguard Worker.global memcpy 49*c9945492SAndroid Build Coastguard Worker.type memcpy,%function 50*c9945492SAndroid Build Coastguard Workermemcpy: 51*c9945492SAndroid Build Coastguard Worker /* The stack must always be 64-bits aligned to be compliant with the 52*c9945492SAndroid Build Coastguard Worker * ARM ABI. Since we have to save R0, we might as well save R4 53*c9945492SAndroid Build Coastguard Worker * which we can use for better pipelining of the reads below 54*c9945492SAndroid Build Coastguard Worker */ 55*c9945492SAndroid Build Coastguard Worker .fnstart 56*c9945492SAndroid Build Coastguard Worker .save {r0, r4, lr} 57*c9945492SAndroid Build Coastguard Worker stmfd sp!, {r0, r4, lr} 58*c9945492SAndroid Build Coastguard Worker /* Making room for r5-r11 which will be spilled later */ 59*c9945492SAndroid Build Coastguard Worker .pad #28 60*c9945492SAndroid Build Coastguard Worker sub sp, sp, #28 61*c9945492SAndroid Build Coastguard Worker 62*c9945492SAndroid Build Coastguard Worker /* it simplifies things to take care of len<4 early */ 63*c9945492SAndroid Build Coastguard Worker cmp r2, #4 64*c9945492SAndroid Build Coastguard Worker blo copy_last_3_and_return 65*c9945492SAndroid Build Coastguard Worker 66*c9945492SAndroid Build Coastguard Worker /* compute the offset to align the source 67*c9945492SAndroid Build Coastguard Worker * offset = (4-(src&3))&3 = -src & 3 68*c9945492SAndroid Build Coastguard Worker */ 69*c9945492SAndroid Build Coastguard Worker rsb r3, r1, #0 70*c9945492SAndroid Build Coastguard Worker ands r3, r3, #3 71*c9945492SAndroid Build Coastguard Worker beq src_aligned 72*c9945492SAndroid Build Coastguard Worker 73*c9945492SAndroid Build Coastguard Worker /* align source to 32 bits. We need to insert 2 instructions between 74*c9945492SAndroid Build Coastguard Worker * a ldr[b|h] and str[b|h] because byte and half-word instructions 75*c9945492SAndroid Build Coastguard Worker * stall 2 cycles. 76*c9945492SAndroid Build Coastguard Worker */ 77*c9945492SAndroid Build Coastguard Worker movs r12, r3, lsl #31 78*c9945492SAndroid Build Coastguard Worker sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */ 79*c9945492SAndroid Build Coastguard Worker ldrbmi r3, [r1], #1 80*c9945492SAndroid Build Coastguard Worker ldrbcs r4, [r1], #1 81*c9945492SAndroid Build Coastguard Worker ldrbcs r12,[r1], #1 82*c9945492SAndroid Build Coastguard Worker strbmi r3, [r0], #1 83*c9945492SAndroid Build Coastguard Worker strbcs r4, [r0], #1 84*c9945492SAndroid Build Coastguard Worker strbcs r12,[r0], #1 85*c9945492SAndroid Build Coastguard Worker 86*c9945492SAndroid Build Coastguard Workersrc_aligned: 87*c9945492SAndroid Build Coastguard Worker 88*c9945492SAndroid Build Coastguard Worker /* see if src and dst are aligned together (congruent) */ 89*c9945492SAndroid Build Coastguard Worker eor r12, r0, r1 90*c9945492SAndroid Build Coastguard Worker tst r12, #3 91*c9945492SAndroid Build Coastguard Worker bne non_congruent 92*c9945492SAndroid Build Coastguard Worker 93*c9945492SAndroid Build Coastguard Worker /* Use post-incriment mode for stm to spill r5-r11 to reserved stack 94*c9945492SAndroid Build Coastguard Worker * frame. Don't update sp. 95*c9945492SAndroid Build Coastguard Worker */ 96*c9945492SAndroid Build Coastguard Worker stmea sp, {r5-r11} 97*c9945492SAndroid Build Coastguard Worker 98*c9945492SAndroid Build Coastguard Worker /* align the destination to a cache-line */ 99*c9945492SAndroid Build Coastguard Worker rsb r3, r0, #0 100*c9945492SAndroid Build Coastguard Worker ands r3, r3, #0x1C 101*c9945492SAndroid Build Coastguard Worker beq congruent_aligned32 102*c9945492SAndroid Build Coastguard Worker cmp r3, r2 103*c9945492SAndroid Build Coastguard Worker andhi r3, r2, #0x1C 104*c9945492SAndroid Build Coastguard Worker 105*c9945492SAndroid Build Coastguard Worker /* conditionnaly copies 0 to 7 words (length in r3) */ 106*c9945492SAndroid Build Coastguard Worker movs r12, r3, lsl #28 107*c9945492SAndroid Build Coastguard Worker ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */ 108*c9945492SAndroid Build Coastguard Worker ldmmi r1!, {r8, r9} /* 8 bytes */ 109*c9945492SAndroid Build Coastguard Worker stmcs r0!, {r4, r5, r6, r7} 110*c9945492SAndroid Build Coastguard Worker stmmi r0!, {r8, r9} 111*c9945492SAndroid Build Coastguard Worker tst r3, #0x4 112*c9945492SAndroid Build Coastguard Worker ldrne r10,[r1], #4 /* 4 bytes */ 113*c9945492SAndroid Build Coastguard Worker strne r10,[r0], #4 114*c9945492SAndroid Build Coastguard Worker sub r2, r2, r3 115*c9945492SAndroid Build Coastguard Worker 116*c9945492SAndroid Build Coastguard Workercongruent_aligned32: 117*c9945492SAndroid Build Coastguard Worker /* 118*c9945492SAndroid Build Coastguard Worker * here source is aligned to 32 bytes. 119*c9945492SAndroid Build Coastguard Worker */ 120*c9945492SAndroid Build Coastguard Worker 121*c9945492SAndroid Build Coastguard Workercached_aligned32: 122*c9945492SAndroid Build Coastguard Worker subs r2, r2, #32 123*c9945492SAndroid Build Coastguard Worker blo less_than_32_left 124*c9945492SAndroid Build Coastguard Worker 125*c9945492SAndroid Build Coastguard Worker /* 126*c9945492SAndroid Build Coastguard Worker * We preload a cache-line up to 64 bytes ahead. On the 926, this will 127*c9945492SAndroid Build Coastguard Worker * stall only until the requested world is fetched, but the linefill 128*c9945492SAndroid Build Coastguard Worker * continues in the the background. 129*c9945492SAndroid Build Coastguard Worker * While the linefill is going, we write our previous cache-line 130*c9945492SAndroid Build Coastguard Worker * into the write-buffer (which should have some free space). 131*c9945492SAndroid Build Coastguard Worker * When the linefill is done, the writebuffer will 132*c9945492SAndroid Build Coastguard Worker * start dumping its content into memory 133*c9945492SAndroid Build Coastguard Worker * 134*c9945492SAndroid Build Coastguard Worker * While all this is going, we then load a full cache line into 135*c9945492SAndroid Build Coastguard Worker * 8 registers, this cache line should be in the cache by now 136*c9945492SAndroid Build Coastguard Worker * (or partly in the cache). 137*c9945492SAndroid Build Coastguard Worker * 138*c9945492SAndroid Build Coastguard Worker * This code should work well regardless of the source/dest alignment. 139*c9945492SAndroid Build Coastguard Worker * 140*c9945492SAndroid Build Coastguard Worker */ 141*c9945492SAndroid Build Coastguard Worker 142*c9945492SAndroid Build Coastguard Worker /* Align the preload register to a cache-line because the cpu does 143*c9945492SAndroid Build Coastguard Worker * "critical word first" (the first word requested is loaded first). 144*c9945492SAndroid Build Coastguard Worker */ 145*c9945492SAndroid Build Coastguard Worker @ bic r12, r1, #0x1F 146*c9945492SAndroid Build Coastguard Worker @ add r12, r12, #64 147*c9945492SAndroid Build Coastguard Worker 148*c9945492SAndroid Build Coastguard Worker1: ldmia r1!, { r4-r11 } 149*c9945492SAndroid Build Coastguard Worker subs r2, r2, #32 150*c9945492SAndroid Build Coastguard Worker 151*c9945492SAndroid Build Coastguard Worker /* 152*c9945492SAndroid Build Coastguard Worker * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi 153*c9945492SAndroid Build Coastguard Worker * for ARM9 preload will not be safely guarded by the preceding subs. 154*c9945492SAndroid Build Coastguard Worker * When it is safely guarded the only possibility to have SIGSEGV here 155*c9945492SAndroid Build Coastguard Worker * is because the caller overstates the length. 156*c9945492SAndroid Build Coastguard Worker */ 157*c9945492SAndroid Build Coastguard Worker @ ldrhi r3, [r12], #32 /* cheap ARM9 preload */ 158*c9945492SAndroid Build Coastguard Worker stmia r0!, { r4-r11 } 159*c9945492SAndroid Build Coastguard Worker bhs 1b 160*c9945492SAndroid Build Coastguard Worker 161*c9945492SAndroid Build Coastguard Worker add r2, r2, #32 162*c9945492SAndroid Build Coastguard Worker 163*c9945492SAndroid Build Coastguard Workerless_than_32_left: 164*c9945492SAndroid Build Coastguard Worker /* 165*c9945492SAndroid Build Coastguard Worker * less than 32 bytes left at this point (length in r2) 166*c9945492SAndroid Build Coastguard Worker */ 167*c9945492SAndroid Build Coastguard Worker 168*c9945492SAndroid Build Coastguard Worker /* skip all this if there is nothing to do, which should 169*c9945492SAndroid Build Coastguard Worker * be a common case (if not executed the code below takes 170*c9945492SAndroid Build Coastguard Worker * about 16 cycles) 171*c9945492SAndroid Build Coastguard Worker */ 172*c9945492SAndroid Build Coastguard Worker tst r2, #0x1F 173*c9945492SAndroid Build Coastguard Worker beq 1f 174*c9945492SAndroid Build Coastguard Worker 175*c9945492SAndroid Build Coastguard Worker /* conditionnaly copies 0 to 31 bytes */ 176*c9945492SAndroid Build Coastguard Worker movs r12, r2, lsl #28 177*c9945492SAndroid Build Coastguard Worker ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */ 178*c9945492SAndroid Build Coastguard Worker ldmmi r1!, {r8, r9} /* 8 bytes */ 179*c9945492SAndroid Build Coastguard Worker stmcs r0!, {r4, r5, r6, r7} 180*c9945492SAndroid Build Coastguard Worker stmmi r0!, {r8, r9} 181*c9945492SAndroid Build Coastguard Worker movs r12, r2, lsl #30 182*c9945492SAndroid Build Coastguard Worker ldrcs r3, [r1], #4 /* 4 bytes */ 183*c9945492SAndroid Build Coastguard Worker ldrhmi r4, [r1], #2 /* 2 bytes */ 184*c9945492SAndroid Build Coastguard Worker strcs r3, [r0], #4 185*c9945492SAndroid Build Coastguard Worker strhmi r4, [r0], #2 186*c9945492SAndroid Build Coastguard Worker tst r2, #0x1 187*c9945492SAndroid Build Coastguard Worker ldrbne r3, [r1] /* last byte */ 188*c9945492SAndroid Build Coastguard Worker strbne r3, [r0] 189*c9945492SAndroid Build Coastguard Worker 190*c9945492SAndroid Build Coastguard Worker /* we're done! restore everything and return */ 191*c9945492SAndroid Build Coastguard Worker1: ldmfd sp!, {r5-r11} 192*c9945492SAndroid Build Coastguard Worker ldmfd sp!, {r0, r4, lr} 193*c9945492SAndroid Build Coastguard Worker bx lr 194*c9945492SAndroid Build Coastguard Worker 195*c9945492SAndroid Build Coastguard Worker /********************************************************************/ 196*c9945492SAndroid Build Coastguard Worker 197*c9945492SAndroid Build Coastguard Workernon_congruent: 198*c9945492SAndroid Build Coastguard Worker /* 199*c9945492SAndroid Build Coastguard Worker * here source is aligned to 4 bytes 200*c9945492SAndroid Build Coastguard Worker * but destination is not. 201*c9945492SAndroid Build Coastguard Worker * 202*c9945492SAndroid Build Coastguard Worker * in the code below r2 is the number of bytes read 203*c9945492SAndroid Build Coastguard Worker * (the number of bytes written is always smaller, because we have 204*c9945492SAndroid Build Coastguard Worker * partial words in the shift queue) 205*c9945492SAndroid Build Coastguard Worker */ 206*c9945492SAndroid Build Coastguard Worker cmp r2, #4 207*c9945492SAndroid Build Coastguard Worker blo copy_last_3_and_return 208*c9945492SAndroid Build Coastguard Worker 209*c9945492SAndroid Build Coastguard Worker /* Use post-incriment mode for stm to spill r5-r11 to reserved stack 210*c9945492SAndroid Build Coastguard Worker * frame. Don't update sp. 211*c9945492SAndroid Build Coastguard Worker */ 212*c9945492SAndroid Build Coastguard Worker stmea sp, {r5-r11} 213*c9945492SAndroid Build Coastguard Worker 214*c9945492SAndroid Build Coastguard Worker /* compute shifts needed to align src to dest */ 215*c9945492SAndroid Build Coastguard Worker rsb r5, r0, #0 216*c9945492SAndroid Build Coastguard Worker and r5, r5, #3 /* r5 = # bytes in partial words */ 217*c9945492SAndroid Build Coastguard Worker mov r12, r5, lsl #3 /* r12 = right */ 218*c9945492SAndroid Build Coastguard Worker rsb lr, r12, #32 /* lr = left */ 219*c9945492SAndroid Build Coastguard Worker 220*c9945492SAndroid Build Coastguard Worker /* read the first word */ 221*c9945492SAndroid Build Coastguard Worker ldr r3, [r1], #4 222*c9945492SAndroid Build Coastguard Worker sub r2, r2, #4 223*c9945492SAndroid Build Coastguard Worker 224*c9945492SAndroid Build Coastguard Worker /* write a partial word (0 to 3 bytes), such that destination 225*c9945492SAndroid Build Coastguard Worker * becomes aligned to 32 bits (r5 = nb of words to copy for alignment) 226*c9945492SAndroid Build Coastguard Worker */ 227*c9945492SAndroid Build Coastguard Worker movs r5, r5, lsl #31 228*c9945492SAndroid Build Coastguard Worker 229*c9945492SAndroid Build Coastguard Worker#if __ARMEB__ 230*c9945492SAndroid Build Coastguard Worker movmi r3, r3, ror #24 231*c9945492SAndroid Build Coastguard Worker strbmi r3, [r0], #1 232*c9945492SAndroid Build Coastguard Worker movcs r3, r3, ror #24 233*c9945492SAndroid Build Coastguard Worker strbcs r3, [r0], #1 234*c9945492SAndroid Build Coastguard Worker movcs r3, r3, ror #24 235*c9945492SAndroid Build Coastguard Worker strbcs r3, [r0], #1 236*c9945492SAndroid Build Coastguard Worker#else 237*c9945492SAndroid Build Coastguard Worker strbmi r3, [r0], #1 238*c9945492SAndroid Build Coastguard Worker movmi r3, r3, lsr #8 239*c9945492SAndroid Build Coastguard Worker strbcs r3, [r0], #1 240*c9945492SAndroid Build Coastguard Worker movcs r3, r3, lsr #8 241*c9945492SAndroid Build Coastguard Worker strbcs r3, [r0], #1 242*c9945492SAndroid Build Coastguard Worker movcs r3, r3, lsr #8 243*c9945492SAndroid Build Coastguard Worker#endif 244*c9945492SAndroid Build Coastguard Worker 245*c9945492SAndroid Build Coastguard Worker cmp r2, #4 246*c9945492SAndroid Build Coastguard Worker blo partial_word_tail 247*c9945492SAndroid Build Coastguard Worker 248*c9945492SAndroid Build Coastguard Worker#if __ARMEB__ 249*c9945492SAndroid Build Coastguard Worker mov r3, r3, lsr r12 250*c9945492SAndroid Build Coastguard Worker mov r3, r3, lsl r12 251*c9945492SAndroid Build Coastguard Worker#endif 252*c9945492SAndroid Build Coastguard Worker 253*c9945492SAndroid Build Coastguard Worker /* Align destination to 32 bytes (cache line boundary) */ 254*c9945492SAndroid Build Coastguard Worker1: tst r0, #0x1c 255*c9945492SAndroid Build Coastguard Worker beq 2f 256*c9945492SAndroid Build Coastguard Worker ldr r5, [r1], #4 257*c9945492SAndroid Build Coastguard Worker sub r2, r2, #4 258*c9945492SAndroid Build Coastguard Worker#if __ARMEB__ 259*c9945492SAndroid Build Coastguard Worker mov r4, r5, lsr lr 260*c9945492SAndroid Build Coastguard Worker orr r4, r4, r3 261*c9945492SAndroid Build Coastguard Worker mov r3, r5, lsl r12 262*c9945492SAndroid Build Coastguard Worker#else 263*c9945492SAndroid Build Coastguard Worker mov r4, r5, lsl lr 264*c9945492SAndroid Build Coastguard Worker orr r4, r4, r3 265*c9945492SAndroid Build Coastguard Worker mov r3, r5, lsr r12 266*c9945492SAndroid Build Coastguard Worker#endif 267*c9945492SAndroid Build Coastguard Worker str r4, [r0], #4 268*c9945492SAndroid Build Coastguard Worker cmp r2, #4 269*c9945492SAndroid Build Coastguard Worker bhs 1b 270*c9945492SAndroid Build Coastguard Worker blo partial_word_tail 271*c9945492SAndroid Build Coastguard Worker 272*c9945492SAndroid Build Coastguard Worker /* copy 32 bytes at a time */ 273*c9945492SAndroid Build Coastguard Worker2: subs r2, r2, #32 274*c9945492SAndroid Build Coastguard Worker blo less_than_thirtytwo 275*c9945492SAndroid Build Coastguard Worker 276*c9945492SAndroid Build Coastguard Worker /* Use immediate mode for the shifts, because there is an extra cycle 277*c9945492SAndroid Build Coastguard Worker * for register shifts, which could account for up to 50% of 278*c9945492SAndroid Build Coastguard Worker * performance hit. 279*c9945492SAndroid Build Coastguard Worker */ 280*c9945492SAndroid Build Coastguard Worker 281*c9945492SAndroid Build Coastguard Worker cmp r12, #24 282*c9945492SAndroid Build Coastguard Worker beq loop24 283*c9945492SAndroid Build Coastguard Worker cmp r12, #8 284*c9945492SAndroid Build Coastguard Worker beq loop8 285*c9945492SAndroid Build Coastguard Worker 286*c9945492SAndroid Build Coastguard Workerloop16: 287*c9945492SAndroid Build Coastguard Worker ldr r12, [r1], #4 288*c9945492SAndroid Build Coastguard Worker1: mov r4, r12 289*c9945492SAndroid Build Coastguard Worker ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} 290*c9945492SAndroid Build Coastguard Worker subs r2, r2, #32 291*c9945492SAndroid Build Coastguard Worker ldrhs r12, [r1], #4 292*c9945492SAndroid Build Coastguard Worker#if __ARMEB__ 293*c9945492SAndroid Build Coastguard Worker orr r3, r3, r4, lsr #16 294*c9945492SAndroid Build Coastguard Worker mov r4, r4, lsl #16 295*c9945492SAndroid Build Coastguard Worker orr r4, r4, r5, lsr #16 296*c9945492SAndroid Build Coastguard Worker mov r5, r5, lsl #16 297*c9945492SAndroid Build Coastguard Worker orr r5, r5, r6, lsr #16 298*c9945492SAndroid Build Coastguard Worker mov r6, r6, lsl #16 299*c9945492SAndroid Build Coastguard Worker orr r6, r6, r7, lsr #16 300*c9945492SAndroid Build Coastguard Worker mov r7, r7, lsl #16 301*c9945492SAndroid Build Coastguard Worker orr r7, r7, r8, lsr #16 302*c9945492SAndroid Build Coastguard Worker mov r8, r8, lsl #16 303*c9945492SAndroid Build Coastguard Worker orr r8, r8, r9, lsr #16 304*c9945492SAndroid Build Coastguard Worker mov r9, r9, lsl #16 305*c9945492SAndroid Build Coastguard Worker orr r9, r9, r10, lsr #16 306*c9945492SAndroid Build Coastguard Worker mov r10, r10, lsl #16 307*c9945492SAndroid Build Coastguard Worker orr r10, r10, r11, lsr #16 308*c9945492SAndroid Build Coastguard Worker stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} 309*c9945492SAndroid Build Coastguard Worker mov r3, r11, lsl #16 310*c9945492SAndroid Build Coastguard Worker#else 311*c9945492SAndroid Build Coastguard Worker orr r3, r3, r4, lsl #16 312*c9945492SAndroid Build Coastguard Worker mov r4, r4, lsr #16 313*c9945492SAndroid Build Coastguard Worker orr r4, r4, r5, lsl #16 314*c9945492SAndroid Build Coastguard Worker mov r5, r5, lsr #16 315*c9945492SAndroid Build Coastguard Worker orr r5, r5, r6, lsl #16 316*c9945492SAndroid Build Coastguard Worker mov r6, r6, lsr #16 317*c9945492SAndroid Build Coastguard Worker orr r6, r6, r7, lsl #16 318*c9945492SAndroid Build Coastguard Worker mov r7, r7, lsr #16 319*c9945492SAndroid Build Coastguard Worker orr r7, r7, r8, lsl #16 320*c9945492SAndroid Build Coastguard Worker mov r8, r8, lsr #16 321*c9945492SAndroid Build Coastguard Worker orr r8, r8, r9, lsl #16 322*c9945492SAndroid Build Coastguard Worker mov r9, r9, lsr #16 323*c9945492SAndroid Build Coastguard Worker orr r9, r9, r10, lsl #16 324*c9945492SAndroid Build Coastguard Worker mov r10, r10, lsr #16 325*c9945492SAndroid Build Coastguard Worker orr r10, r10, r11, lsl #16 326*c9945492SAndroid Build Coastguard Worker stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} 327*c9945492SAndroid Build Coastguard Worker mov r3, r11, lsr #16 328*c9945492SAndroid Build Coastguard Worker#endif 329*c9945492SAndroid Build Coastguard Worker bhs 1b 330*c9945492SAndroid Build Coastguard Worker b less_than_thirtytwo 331*c9945492SAndroid Build Coastguard Worker 332*c9945492SAndroid Build Coastguard Workerloop8: 333*c9945492SAndroid Build Coastguard Worker ldr r12, [r1], #4 334*c9945492SAndroid Build Coastguard Worker1: mov r4, r12 335*c9945492SAndroid Build Coastguard Worker ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} 336*c9945492SAndroid Build Coastguard Worker subs r2, r2, #32 337*c9945492SAndroid Build Coastguard Worker ldrhs r12, [r1], #4 338*c9945492SAndroid Build Coastguard Worker#if __ARMEB__ 339*c9945492SAndroid Build Coastguard Worker orr r3, r3, r4, lsr #24 340*c9945492SAndroid Build Coastguard Worker mov r4, r4, lsl #8 341*c9945492SAndroid Build Coastguard Worker orr r4, r4, r5, lsr #24 342*c9945492SAndroid Build Coastguard Worker mov r5, r5, lsl #8 343*c9945492SAndroid Build Coastguard Worker orr r5, r5, r6, lsr #24 344*c9945492SAndroid Build Coastguard Worker mov r6, r6, lsl #8 345*c9945492SAndroid Build Coastguard Worker orr r6, r6, r7, lsr #24 346*c9945492SAndroid Build Coastguard Worker mov r7, r7, lsl #8 347*c9945492SAndroid Build Coastguard Worker orr r7, r7, r8, lsr #24 348*c9945492SAndroid Build Coastguard Worker mov r8, r8, lsl #8 349*c9945492SAndroid Build Coastguard Worker orr r8, r8, r9, lsr #24 350*c9945492SAndroid Build Coastguard Worker mov r9, r9, lsl #8 351*c9945492SAndroid Build Coastguard Worker orr r9, r9, r10, lsr #24 352*c9945492SAndroid Build Coastguard Worker mov r10, r10, lsl #8 353*c9945492SAndroid Build Coastguard Worker orr r10, r10, r11, lsr #24 354*c9945492SAndroid Build Coastguard Worker stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} 355*c9945492SAndroid Build Coastguard Worker mov r3, r11, lsl #8 356*c9945492SAndroid Build Coastguard Worker#else 357*c9945492SAndroid Build Coastguard Worker orr r3, r3, r4, lsl #24 358*c9945492SAndroid Build Coastguard Worker mov r4, r4, lsr #8 359*c9945492SAndroid Build Coastguard Worker orr r4, r4, r5, lsl #24 360*c9945492SAndroid Build Coastguard Worker mov r5, r5, lsr #8 361*c9945492SAndroid Build Coastguard Worker orr r5, r5, r6, lsl #24 362*c9945492SAndroid Build Coastguard Worker mov r6, r6, lsr #8 363*c9945492SAndroid Build Coastguard Worker orr r6, r6, r7, lsl #24 364*c9945492SAndroid Build Coastguard Worker mov r7, r7, lsr #8 365*c9945492SAndroid Build Coastguard Worker orr r7, r7, r8, lsl #24 366*c9945492SAndroid Build Coastguard Worker mov r8, r8, lsr #8 367*c9945492SAndroid Build Coastguard Worker orr r8, r8, r9, lsl #24 368*c9945492SAndroid Build Coastguard Worker mov r9, r9, lsr #8 369*c9945492SAndroid Build Coastguard Worker orr r9, r9, r10, lsl #24 370*c9945492SAndroid Build Coastguard Worker mov r10, r10, lsr #8 371*c9945492SAndroid Build Coastguard Worker orr r10, r10, r11, lsl #24 372*c9945492SAndroid Build Coastguard Worker stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} 373*c9945492SAndroid Build Coastguard Worker mov r3, r11, lsr #8 374*c9945492SAndroid Build Coastguard Worker#endif 375*c9945492SAndroid Build Coastguard Worker bhs 1b 376*c9945492SAndroid Build Coastguard Worker b less_than_thirtytwo 377*c9945492SAndroid Build Coastguard Worker 378*c9945492SAndroid Build Coastguard Workerloop24: 379*c9945492SAndroid Build Coastguard Worker ldr r12, [r1], #4 380*c9945492SAndroid Build Coastguard Worker1: mov r4, r12 381*c9945492SAndroid Build Coastguard Worker ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} 382*c9945492SAndroid Build Coastguard Worker subs r2, r2, #32 383*c9945492SAndroid Build Coastguard Worker ldrhs r12, [r1], #4 384*c9945492SAndroid Build Coastguard Worker#if __ARMEB__ 385*c9945492SAndroid Build Coastguard Worker orr r3, r3, r4, lsr #8 386*c9945492SAndroid Build Coastguard Worker mov r4, r4, lsl #24 387*c9945492SAndroid Build Coastguard Worker orr r4, r4, r5, lsr #8 388*c9945492SAndroid Build Coastguard Worker mov r5, r5, lsl #24 389*c9945492SAndroid Build Coastguard Worker orr r5, r5, r6, lsr #8 390*c9945492SAndroid Build Coastguard Worker mov r6, r6, lsl #24 391*c9945492SAndroid Build Coastguard Worker orr r6, r6, r7, lsr #8 392*c9945492SAndroid Build Coastguard Worker mov r7, r7, lsl #24 393*c9945492SAndroid Build Coastguard Worker orr r7, r7, r8, lsr #8 394*c9945492SAndroid Build Coastguard Worker mov r8, r8, lsl #24 395*c9945492SAndroid Build Coastguard Worker orr r8, r8, r9, lsr #8 396*c9945492SAndroid Build Coastguard Worker mov r9, r9, lsl #24 397*c9945492SAndroid Build Coastguard Worker orr r9, r9, r10, lsr #8 398*c9945492SAndroid Build Coastguard Worker mov r10, r10, lsl #24 399*c9945492SAndroid Build Coastguard Worker orr r10, r10, r11, lsr #8 400*c9945492SAndroid Build Coastguard Worker stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} 401*c9945492SAndroid Build Coastguard Worker mov r3, r11, lsl #24 402*c9945492SAndroid Build Coastguard Worker#else 403*c9945492SAndroid Build Coastguard Worker orr r3, r3, r4, lsl #8 404*c9945492SAndroid Build Coastguard Worker mov r4, r4, lsr #24 405*c9945492SAndroid Build Coastguard Worker orr r4, r4, r5, lsl #8 406*c9945492SAndroid Build Coastguard Worker mov r5, r5, lsr #24 407*c9945492SAndroid Build Coastguard Worker orr r5, r5, r6, lsl #8 408*c9945492SAndroid Build Coastguard Worker mov r6, r6, lsr #24 409*c9945492SAndroid Build Coastguard Worker orr r6, r6, r7, lsl #8 410*c9945492SAndroid Build Coastguard Worker mov r7, r7, lsr #24 411*c9945492SAndroid Build Coastguard Worker orr r7, r7, r8, lsl #8 412*c9945492SAndroid Build Coastguard Worker mov r8, r8, lsr #24 413*c9945492SAndroid Build Coastguard Worker orr r8, r8, r9, lsl #8 414*c9945492SAndroid Build Coastguard Worker mov r9, r9, lsr #24 415*c9945492SAndroid Build Coastguard Worker orr r9, r9, r10, lsl #8 416*c9945492SAndroid Build Coastguard Worker mov r10, r10, lsr #24 417*c9945492SAndroid Build Coastguard Worker orr r10, r10, r11, lsl #8 418*c9945492SAndroid Build Coastguard Worker stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} 419*c9945492SAndroid Build Coastguard Worker mov r3, r11, lsr #24 420*c9945492SAndroid Build Coastguard Worker#endif 421*c9945492SAndroid Build Coastguard Worker bhs 1b 422*c9945492SAndroid Build Coastguard Worker 423*c9945492SAndroid Build Coastguard Workerless_than_thirtytwo: 424*c9945492SAndroid Build Coastguard Worker /* copy the last 0 to 31 bytes of the source */ 425*c9945492SAndroid Build Coastguard Worker rsb r12, lr, #32 /* we corrupted r12, recompute it */ 426*c9945492SAndroid Build Coastguard Worker add r2, r2, #32 427*c9945492SAndroid Build Coastguard Worker cmp r2, #4 428*c9945492SAndroid Build Coastguard Worker blo partial_word_tail 429*c9945492SAndroid Build Coastguard Worker 430*c9945492SAndroid Build Coastguard Worker1: ldr r5, [r1], #4 431*c9945492SAndroid Build Coastguard Worker sub r2, r2, #4 432*c9945492SAndroid Build Coastguard Worker#if __ARMEB__ 433*c9945492SAndroid Build Coastguard Worker mov r4, r5, lsr lr 434*c9945492SAndroid Build Coastguard Worker orr r4, r4, r3 435*c9945492SAndroid Build Coastguard Worker mov r3, r5, lsl r12 436*c9945492SAndroid Build Coastguard Worker#else 437*c9945492SAndroid Build Coastguard Worker mov r4, r5, lsl lr 438*c9945492SAndroid Build Coastguard Worker orr r4, r4, r3 439*c9945492SAndroid Build Coastguard Worker mov r3, r5, lsr r12 440*c9945492SAndroid Build Coastguard Worker#endif 441*c9945492SAndroid Build Coastguard Worker str r4, [r0], #4 442*c9945492SAndroid Build Coastguard Worker cmp r2, #4 443*c9945492SAndroid Build Coastguard Worker bhs 1b 444*c9945492SAndroid Build Coastguard Worker 445*c9945492SAndroid Build Coastguard Workerpartial_word_tail: 446*c9945492SAndroid Build Coastguard Worker /* we have a partial word in the input buffer */ 447*c9945492SAndroid Build Coastguard Worker movs r5, lr, lsl #(31-3) 448*c9945492SAndroid Build Coastguard Worker#if __ARMEB__ 449*c9945492SAndroid Build Coastguard Worker movmi r3, r3, ror #24 450*c9945492SAndroid Build Coastguard Worker strbmi r3, [r0], #1 451*c9945492SAndroid Build Coastguard Worker movcs r3, r3, ror #24 452*c9945492SAndroid Build Coastguard Worker strbcs r3, [r0], #1 453*c9945492SAndroid Build Coastguard Worker movcs r3, r3, ror #24 454*c9945492SAndroid Build Coastguard Worker strbcs r3, [r0], #1 455*c9945492SAndroid Build Coastguard Worker#else 456*c9945492SAndroid Build Coastguard Worker strbmi r3, [r0], #1 457*c9945492SAndroid Build Coastguard Worker movmi r3, r3, lsr #8 458*c9945492SAndroid Build Coastguard Worker strbcs r3, [r0], #1 459*c9945492SAndroid Build Coastguard Worker movcs r3, r3, lsr #8 460*c9945492SAndroid Build Coastguard Worker strbcs r3, [r0], #1 461*c9945492SAndroid Build Coastguard Worker#endif 462*c9945492SAndroid Build Coastguard Worker 463*c9945492SAndroid Build Coastguard Worker /* Refill spilled registers from the stack. Don't update sp. */ 464*c9945492SAndroid Build Coastguard Worker ldmfd sp, {r5-r11} 465*c9945492SAndroid Build Coastguard Worker 466*c9945492SAndroid Build Coastguard Workercopy_last_3_and_return: 467*c9945492SAndroid Build Coastguard Worker movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */ 468*c9945492SAndroid Build Coastguard Worker ldrbmi r2, [r1], #1 469*c9945492SAndroid Build Coastguard Worker ldrbcs r3, [r1], #1 470*c9945492SAndroid Build Coastguard Worker ldrbcs r12,[r1] 471*c9945492SAndroid Build Coastguard Worker strbmi r2, [r0], #1 472*c9945492SAndroid Build Coastguard Worker strbcs r3, [r0], #1 473*c9945492SAndroid Build Coastguard Worker strbcs r12,[r0] 474*c9945492SAndroid Build Coastguard Worker 475*c9945492SAndroid Build Coastguard Worker /* we're done! restore sp and spilled registers and return */ 476*c9945492SAndroid Build Coastguard Worker add sp, sp, #28 477*c9945492SAndroid Build Coastguard Worker ldmfd sp!, {r0, r4, lr} 478*c9945492SAndroid Build Coastguard Worker bx lr 479*c9945492SAndroid Build Coastguard Worker 480