1 /* Optimized strcpy implementation for PowerPC64/POWER9.
2 Copyright (C) 2020 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
23 # define FUNC_NAME __stpcpy
25 # define FUNC_NAME STPCPY
29 # define FUNC_NAME strcpy
31 # define FUNC_NAME STRCPY
33 #endif /* !USE_AS_STPCPY */
35 /* Implements the function
37 char * [r3] strcpy (char *dest [r3], const char *src [r4])
41 char * [r3] stpcpy (char *dest [r3], const char *src [r4])
43 if USE_AS_STPCPY is defined.
45 The implementation can load bytes past a null terminator, but only
46 up to the next 16B boundary, so it never crosses a page. */
49 ENTRY_TOCLESS (FUNC_NAME, 4)
52 /* NULL string optimisation */
61 vspltisb v18,0 /* Zeroes in v18 */
64 rldicl r9,r5,0,60 /* How many bytes to get source 16B aligned? */
66 /* Get source 16B aligned */
71 vcmpequb v6,v0,v18 /* 0xff if byte is NULL, 0x00 otherwise */
72 vctzlsbb r7,v6 /* Number of trailing zeroes */
73 addi r8,r7,1 /* Add null terminator */
75 /* r8 = bytes including null
76 r9 = bytes to get source 16B aligned
78 no null, copy r9 bytes
80 there is a null, copy r8 bytes and return. */
84 sldi r10,r8,56 /* stxvl wants size in top 8 bits */
85 stxvl 32+v0,r11,r10 /* Partial store */
88 /* stpcpy returns the dest address plus the size not counting the
95 sldi r10,r9,56 /* stxvl wants size in top 8 bits */
96 stxvl 32+v0,r11,r10 /* Partial store */
103 vcmpequb. v6,v0,v18 /* Any zero bytes? */
107 vcmpequb. v6,v1,v18 /* Any zero bytes? */
111 vcmpequb. v6,v2,v18 /* Any zero bytes? */
115 vcmpequb. v6,v3,v18 /* Any zero bytes? */
131 sldi r9,r9,56 /* stxvl wants size in top 8 bits */
134 /* stpcpy returns the dest address plus the size not counting the
142 vctzlsbb r8,v6 /* Number of trailing zeroes */
143 addi r9,r8,1 /* Add null terminator */
144 sldi r10,r9,56 /* stxvl wants size in top 8 bits */
146 stxvl 32+v1,r11,r10 /* Partial store */
148 /* stpcpy returns the dest address plus the size not counting the
157 vctzlsbb r8,v6 /* Number of trailing zeroes */
158 addi r9,r8,1 /* Add null terminator */
159 sldi r10,r9,56 /* stxvl wants size in top 8 bits */
161 stxvl 32+v2,r11,r10 /* Partial store */
163 /* stpcpy returns the dest address plus the size not counting the
173 vctzlsbb r8,v6 /* Number of trailing zeroes */
174 addi r9,r8,1 /* Add null terminator */
175 sldi r10,r9,56 /* stxvl wants size in top 8 bits */
177 stxvl 32+v3,r11,r10 /* Partial store */
179 /* stpcpy returns the dest address plus the size not counting the
185 #ifndef USE_AS_STPCPY
186 libc_hidden_builtin_def (strcpy)