1/* 2 * Copyright (c) 2008 ARM Ltd 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the company may not be used to endorse or promote 14 * products derived from this software without specific prior written 15 * permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 22 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include "arm_asm.h" 30 31#ifdef __thumb2__ 32#define magic1(REG) #0x01010101 33#define magic2(REG) #0x80808080 34#else 35#define magic1(REG) REG 36#define magic2(REG) REG , lsl #7 37#endif 38 39 .syntax unified 40#ifdef __thumb__ 41 .thumb 42#endif 43 .text 44 .global strcpy 45 .type strcpy, %function 46strcpy: 47 .fnstart 48 .cfi_sections .debug_frame 49 .cfi_startproc 50 prologue push_ip=HAVE_PAC_LEAF 51 52#if !(defined(__OPTIMIZE_SIZE__) || defined (PREFER_SIZE_OVER_SPEED) || \ 53 (defined (__thumb__) && !defined (__thumb2__))) 54 55#ifdef _ISA_ARM_7 56 pld [r1] 57#endif 58 eor r2, r0, r1 59 mov ip, r0 60 tst r2, #3 61 bne 4f 62 tst r1, #3 63 bne 3f 645: 65#ifndef __thumb2__ 66 str r5, [sp, #-4]! 67 mov r5, #0x01 68 orr r5, r5, r5, lsl #8 69 orr r5, r5, r5, lsl #16 70#endif 71 72 str r4, [sp, #-4]! 73 tst r1, #4 74 ldr r3, [r1], #4 75 beq 2f 76 sub r2, r3, magic1(r5) 77 bics r2, r2, r3 78 tst r2, magic2(r5) 79 itt eq 80 streq r3, [ip], #4 81 ldreq r3, [r1], #4 82 bne 1f 83 /* Inner loop. We now know that r1 is 64-bit aligned, so we 84 can safely fetch up to two words. This allows us to avoid 85 load stalls. */ 86 .p2align 2 872: 88#ifdef _ISA_ARM_7 89 pld [r1, #8] 90#endif 91 ldr r4, [r1], #4 92 sub r2, r3, magic1(r5) 93 bics r2, r2, r3 94 tst r2, magic2(r5) 95 sub r2, r4, magic1(r5) 96 bne 1f 97 str r3, [ip], #4 98 bics r2, r2, r4 99 tst r2, magic2(r5) 100 itt eq 101 ldreq r3, [r1], #4 102 streq r4, [ip], #4 103 beq 2b 104 mov r3, r4 1051: 106#ifdef __ARMEB__ 107 rors r3, r3, #24 108#endif 109 strb r3, [ip], #1 110 tst r3, #0xff 111#ifdef __ARMEL__ 112 ror r3, r3, #8 113#endif 114 bne 1b 115 ldr r4, [sp], #4 116#ifndef __thumb2__ 117 ldr r5, [sp], #4 118#endif 119 bx lr 120 121 /* Strings have the same offset from word alignment, but it's 122 not zero. */ 1233: 124 tst r1, #1 125 beq 1f 126 ldrb r2, [r1], #1 127 strb r2, [ip], #1 128 cmp r2, #0 129 it eq 130 bxeq lr 1311: 132 tst r1, #2 133 beq 5b 134 ldrh r2, [r1], #2 135#ifdef __ARMEB__ 136 tst r2, #0xff00 137 iteet ne 138 strhne r2, [ip], #2 139 lsreq r2, r2, #8 140 strbeq r2, [ip] 141 tstne r2, #0xff 142#else 143 tst r2, #0xff 144 itet ne 145 strhne r2, [ip], #2 146 strbeq r2, [ip] 147 tstne r2, #0xff00 148#endif 149 bne 5b 150 .cfi_remember_state 151 epilogue push_ip=HAVE_PAC_LEAF 152 .cfi_restore_state 153 154 /* src and dst do not have a common word-alignement. Fall back to 155 byte copying. */ 1564: 157 ldrb r2, [r1], #1 158 strb r2, [ip], #1 159 cmp r2, #0 160 bne 4b 161 162#elif !defined (__thumb__) || defined (__thumb2__) 163 mov r3, r0 164 1: 165 ldrb r2, [r1], #1 166 strb r2, [r3], #1 167 cmp r2, #0 168 bne 1b 169#else 170 movs r3, r0 1711: 172 ldrb r2, [r1] 173 adds r1, #1 174 strb r2, [r3] 175 adds r3, #1 176 cmp r2, #0 177 bne 1b 178#endif 179 epilogue push_ip=HAVE_PAC_LEAF 180 .cfi_endproc 181 .cantunwind 182 .fnend 183 .size strcpy, . - strcpy 184 185#if defined(__linux__) && defined(__ELF__) 186.section .note.GNU-stack,"",%progbits 187#endif 188