1/* 2 * strcpy 3 * 4 * Copyright (c) 2008-2020, Arm Limited. 5 * SPDX-License-Identifier: MIT 6 */ 7 8/* For GLIBC: 9#include <string.h> 10#include <memcopy.h> 11 12#undef strcmp 13*/ 14 15#ifdef __thumb2__ 16#define magic1(REG) "#0x01010101" 17#define magic2(REG) "#0x80808080" 18#else 19#define magic1(REG) #REG 20#define magic2(REG) #REG ", lsl #7" 21#endif 22 23char* __attribute__((naked)) 24__strcpy_arm (char* dst, const char* src) 25{ 26 __asm__ ( 27 "pld [r1, #0]\n\t" 28 "eor r2, r0, r1\n\t" 29 "mov ip, r0\n\t" 30 "tst r2, #3\n\t" 31 "bne 4f\n\t" 32 "tst r1, #3\n\t" 33 "bne 3f\n" 34 "5:\n\t" 35# ifndef __thumb2__ 36 "str r5, [sp, #-4]!\n\t" 37 "mov r5, #0x01\n\t" 38 "orr r5, r5, r5, lsl #8\n\t" 39 "orr r5, r5, r5, lsl #16\n\t" 40# endif 41 42 "str r4, [sp, #-4]!\n\t" 43 "tst r1, #4\n\t" 44 "ldr r3, [r1], #4\n\t" 45 "beq 2f\n\t" 46 "sub r2, r3, "magic1(r5)"\n\t" 47 "bics r2, r2, r3\n\t" 48 "tst r2, "magic2(r5)"\n\t" 49 "itt eq\n\t" 50 "streq r3, [ip], #4\n\t" 51 "ldreq r3, [r1], #4\n" 52 "bne 1f\n\t" 53 /* Inner loop. We now know that r1 is 64-bit aligned, so we 54 can safely fetch up to two words. This allows us to avoid 55 load stalls. */ 56 ".p2align 2\n" 57 "2:\n\t" 58 "pld [r1, #8]\n\t" 59 "ldr r4, [r1], #4\n\t" 60 "sub r2, r3, "magic1(r5)"\n\t" 61 "bics r2, r2, r3\n\t" 62 "tst r2, "magic2(r5)"\n\t" 63 "sub r2, r4, "magic1(r5)"\n\t" 64 "bne 1f\n\t" 65 "str r3, [ip], #4\n\t" 66 "bics r2, r2, r4\n\t" 67 "tst r2, "magic2(r5)"\n\t" 68 "itt eq\n\t" 69 "ldreq r3, [r1], #4\n\t" 70 "streq r4, [ip], #4\n\t" 71 "beq 2b\n\t" 72 "mov r3, r4\n" 73 "1:\n\t" 74# ifdef __ARMEB__ 75 "rors r3, r3, #24\n\t" 76# endif 77 "strb r3, [ip], #1\n\t" 78 "tst r3, #0xff\n\t" 79# ifdef __ARMEL__ 80 "ror r3, r3, #8\n\t" 81# endif 82 "bne 1b\n\t" 83 "ldr r4, [sp], #4\n\t" 84# ifndef __thumb2__ 85 "ldr r5, [sp], #4\n\t" 86# endif 87 "BX LR\n" 88 89 /* Strings have the same offset from word alignment, but it's 90 not zero. */ 91 "3:\n\t" 92 "tst r1, #1\n\t" 93 "beq 1f\n\t" 94 "ldrb r2, [r1], #1\n\t" 95 "strb r2, [ip], #1\n\t" 96 "cmp r2, #0\n\t" 97 "it eq\n" 98 "BXEQ LR\n" 99 "1:\n\t" 100 "tst r1, #2\n\t" 101 "beq 5b\n\t" 102 "ldrh r2, [r1], #2\n\t" 103# ifdef __ARMEB__ 104 "tst r2, #0xff00\n\t" 105 "iteet ne\n\t" 106 "strneh r2, [ip], #2\n\t" 107 "lsreq r2, r2, #8\n\t" 108 "streqb r2, [ip]\n\t" 109 "tstne r2, #0xff\n\t" 110# else 111 "tst r2, #0xff\n\t" 112 "itet ne\n\t" 113 "strneh r2, [ip], #2\n\t" 114 "streqb r2, [ip]\n\t" 115 "tstne r2, #0xff00\n\t" 116# endif 117 "bne 5b\n\t" 118 "BX LR\n" 119 120 /* src and dst do not have a common word-alignement. Fall back to 121 byte copying. */ 122 "4:\n\t" 123 "ldrb r2, [r1], #1\n\t" 124 "strb r2, [ip], #1\n\t" 125 "cmp r2, #0\n\t" 126 "bne 4b\n\t" 127 "BX LR"); 128} 129/* For GLIBC: libc_hidden_builtin_def (strcpy) */ 130