1/* Optimized strcpy implementation for PowerPC. 2 Copyright (C) 1997-2021 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19#include <sysdep.h> 20 21/* See strlen.s for comments on how the end-of-string testing works. */ 22 23/* char * [r3] strcpy (char *dest [r3], const char *src [r4]) */ 24 25EALIGN (strcpy, 4, 0) 26 27#define rTMP r0 28#define rRTN r3 /* incoming DEST arg preserved as result */ 29#define rSRC r4 /* pointer to previous word in src */ 30#define rDEST r5 /* pointer to previous word in dest */ 31#define rWORD r6 /* current word from src */ 32#define rFEFE r7 /* constant 0xfefefeff (-0x01010101) */ 33#define r7F7F r8 /* constant 0x7f7f7f7f */ 34#define rNEG r9 /* ~(word in s1 | 0x7f7f7f7f) */ 35#define rALT r10 /* alternate word from src */ 36 37 38 or rTMP, rSRC, rRTN 39 clrlwi. rTMP, rTMP, 30 40 addi rDEST, rRTN, -4 41 bne L(unaligned) 42 43 lis rFEFE, -0x101 44 lis r7F7F, 0x7f7f 45 lwz rWORD, 0(rSRC) 46 addi rFEFE, rFEFE, -0x101 47 addi r7F7F, r7F7F, 0x7f7f 48 b L(g2) 49 50L(g0): lwzu rALT, 4(rSRC) 51 stwu rWORD, 4(rDEST) 52 add rTMP, rFEFE, rALT 53 nor rNEG, r7F7F, rALT 54 and. rTMP, rTMP, rNEG 55 bne- L(g1) 56 lwzu rWORD, 4(rSRC) 57 stwu rALT, 4(rDEST) 58L(g2): add rTMP, rFEFE, rWORD 59 nor rNEG, r7F7F, rWORD 60 and. rTMP, rTMP, rNEG 61 beq+ L(g0) 62 63 mr rALT, rWORD 64/* We've hit the end of the string. Do the rest byte-by-byte. */ 65L(g1): 66#ifdef __LITTLE_ENDIAN__ 67 rlwinm. rTMP, rALT, 0, 24, 31 68 stb rALT, 4(rDEST) 69 beqlr- 70 rlwinm. rTMP, rALT, 24, 24, 31 71 stb rTMP, 5(rDEST) 72 beqlr- 73 rlwinm. rTMP, rALT, 16, 24, 31 74 stb rTMP, 6(rDEST) 75 beqlr- 76 rlwinm rTMP, rALT, 8, 24, 31 77 stb rTMP, 7(rDEST) 78 blr 79#else 80 rlwinm. rTMP, rALT, 8, 24, 31 81 stb rTMP, 4(rDEST) 82 beqlr- 83 rlwinm. rTMP, rALT, 16, 24, 31 84 stb rTMP, 5(rDEST) 85 beqlr- 86 rlwinm. rTMP, rALT, 24, 24, 31 87 stb rTMP, 6(rDEST) 88 beqlr- 89 stb rALT, 7(rDEST) 90 blr 91#endif 92 93/* Oh well. In this case, we just do a byte-by-byte copy. */ 94 .align 4 95 nop 96L(unaligned): 97 lbz rWORD, 0(rSRC) 98 addi rDEST, rRTN, -1 99 cmpwi rWORD, 0 100 beq- L(u2) 101 102L(u0): lbzu rALT, 1(rSRC) 103 stbu rWORD, 1(rDEST) 104 cmpwi rALT, 0 105 beq- L(u1) 106 nop /* Let 601 load start of loop. */ 107 lbzu rWORD, 1(rSRC) 108 stbu rALT, 1(rDEST) 109 cmpwi rWORD, 0 110 bne+ L(u0) 111L(u2): stb rWORD, 1(rDEST) 112 blr 113L(u1): stb rALT, 1(rDEST) 114 blr 115 116END (strcpy) 117libc_hidden_builtin_def (strcpy) 118