]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/powerpc/powerpc64/strcpy.S
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / powerpc / powerpc64 / strcpy.S
CommitLineData
cfc91acd 1/* Optimized strcpy implementation for PowerPC64.
b168057a 2 Copyright (C) 1997-2015 Free Software Foundation, Inc.
cfc91acd
RM
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
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
cfc91acd
RM
18
19#include <sysdep.h>
cfc91acd
RM
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
69f13dbf
AZ
25#ifdef USE_AS_STPCPY
26# define FUNC_NAME __stpcpy
27#else
28# define FUNC_NAME strcpy
29#endif
30
31EALIGN (FUNC_NAME, 4, 0)
d7d06f79 32 CALL_MCOUNT 2
cfc91acd
RM
33
34#define rTMP r0
69f13dbf
AZ
35#ifdef USE_AS_STPCPY
36#define rRTN r3 /* pointer to previous word/doubleword in dest */
37#else
38#define rRTN r12 /* pointer to previous word/doubleword in dest */
39#endif
40#define rSRC r4 /* pointer to previous word/doubleword in src */
cfc91acd 41#define rWORD r6 /* current word from src */
69f13dbf
AZ
42#define rFEFE r7 /* constant 0xfefefeff | 0xfefefefefefefeff */
43#define r7F7F r8 /* constant 0x7f7f7f7f | 0x7f7f7f7f7f7f7f7f */
44#define rNEG r9 /* ~(word in s1 | r7F7F) */
cfc91acd
RM
45#define rALT r10 /* alternate word from src */
46
69f13dbf
AZ
47#ifndef USE_AS_STPCPY
48/* Save the dst pointer to use as return value. */
49 mr rRTN, r3
50#endif
cfc91acd 51 or rTMP, rSRC, rRTN
482eb33c 52 clrldi. rTMP, rTMP, 61
69f13dbf
AZ
53 bne L(check_word_alignment)
54
55/* For doubleword aligned memory, operate using doubleword load and stores. */
56 addi rRTN, rRTN, -8
cfc91acd
RM
57
58 lis rFEFE, -0x101
59 lis r7F7F, 0x7f7f
482eb33c 60 ld rWORD, 0(rSRC)
cfc91acd
RM
61 addi rFEFE, rFEFE, -0x101
62 addi r7F7F, r7F7F, 0x7f7f
482eb33c
UD
63 sldi rTMP, rFEFE, 32
64 insrdi r7F7F, r7F7F, 32, 0
65 add rFEFE, rFEFE, rTMP
cfc91acd
RM
66 b L(g2)
67
482eb33c 68L(g0): ldu rALT, 8(rSRC)
69f13dbf 69 stdu rWORD, 8(rRTN)
cfc91acd
RM
70 add rTMP, rFEFE, rALT
71 nor rNEG, r7F7F, rALT
72 and. rTMP, rTMP, rNEG
73 bne- L(g1)
482eb33c 74 ldu rWORD, 8(rSRC)
69f13dbf 75 stdu rALT, 8(rRTN)
cfc91acd
RM
76L(g2): add rTMP, rFEFE, rWORD
77 nor rNEG, r7F7F, rWORD
78 and. rTMP, rTMP, rNEG
79 beq+ L(g0)
80
81 mr rALT, rWORD
82/* We've hit the end of the string. Do the rest byte-by-byte. */
482eb33c 83L(g1):
43b84013
AM
84#ifdef __LITTLE_ENDIAN__
85 extrdi. rTMP, rALT, 8, 56
69f13dbf 86 stbu rALT, 8(rRTN)
43b84013
AM
87 beqlr-
88 extrdi. rTMP, rALT, 8, 48
69f13dbf 89 stbu rTMP, 1(rRTN)
43b84013
AM
90 beqlr-
91 extrdi. rTMP, rALT, 8, 40
69f13dbf 92 stbu rTMP, 1(rRTN)
43b84013
AM
93 beqlr-
94 extrdi. rTMP, rALT, 8, 32
69f13dbf 95 stbu rTMP, 1(rRTN)
43b84013
AM
96 beqlr-
97 extrdi. rTMP, rALT, 8, 24
69f13dbf 98 stbu rTMP, 1(rRTN)
43b84013
AM
99 beqlr-
100 extrdi. rTMP, rALT, 8, 16
69f13dbf 101 stbu rTMP, 1(rRTN)
43b84013
AM
102 beqlr-
103 extrdi. rTMP, rALT, 8, 8
69f13dbf 104 stbu rTMP, 1(rRTN)
43b84013
AM
105 beqlr-
106 extrdi rTMP, rALT, 8, 0
69f13dbf 107 stbu rTMP, 1(rRTN)
43b84013 108#else
482eb33c 109 extrdi. rTMP, rALT, 8, 0
69f13dbf 110 stbu rTMP, 8(rRTN)
cfc91acd 111 beqlr-
482eb33c 112 extrdi. rTMP, rALT, 8, 8
69f13dbf 113 stbu rTMP, 1(rRTN)
cfc91acd 114 beqlr-
482eb33c 115 extrdi. rTMP, rALT, 8, 16
69f13dbf 116 stbu rTMP, 1(rRTN)
cfc91acd 117 beqlr-
482eb33c 118 extrdi. rTMP, rALT, 8, 24
69f13dbf 119 stbu rTMP, 1(rRTN)
482eb33c
UD
120 beqlr-
121 extrdi. rTMP, rALT, 8, 32
69f13dbf
AZ
122 stbu rTMP, 1(rRTN)
123 beqlr
482eb33c 124 extrdi. rTMP, rALT, 8, 40
69f13dbf 125 stbu rTMP, 1(rRTN)
482eb33c
UD
126 beqlr-
127 extrdi. rTMP, rALT, 8, 48
69f13dbf 128 stbu rTMP, 1(rRTN)
482eb33c 129 beqlr-
69f13dbf
AZ
130 stbu rALT, 1(rRTN)
131#endif
cfc91acd 132 blr
69f13dbf
AZ
133
134L(check_word_alignment):
135 clrldi. rTMP, rTMP, 62
136 bne L(unaligned)
137
138/* For word aligned memory, operate using word load and stores. */
139 addi rRTN, rRTN, -4
140
141 lis rFEFE, -0x101
142 lis r7F7F, 0x7f7f
143 lwz rWORD, 0(rSRC)
144 addi rFEFE, rFEFE, -0x101
145 addi r7F7F, r7F7F, 0x7f7f
146 b L(g5)
147
148L(g3): lwzu rALT, 4(rSRC)
149 stwu rWORD, 4(rRTN)
150 add rTMP, rFEFE, rALT
151 nor rNEG, r7F7F, rALT
152 and. rTMP, rTMP, rNEG
153 bne- L(g4)
154 lwzu rWORD, 4(rSRC)
155 stwu rALT, 4(rRTN)
156L(g5): add rTMP, rFEFE, rWORD
157 nor rNEG, r7F7F, rWORD
158 and. rTMP, rTMP, rNEG
159 beq+ L(g3)
160
161 mr rALT, rWORD
162/* We've hit the end of the string. Do the rest byte-by-byte. */
163L(g4):
164#ifdef __LITTLE_ENDIAN__
165 rlwinm. rTMP, rALT, 0, 24, 31
166 stbu rALT, 4(rRTN)
167 beqlr-
168 rlwinm. rTMP, rALT, 24, 24, 31
169 stbu rTMP, 1(rRTN)
170 beqlr-
171 rlwinm. rTMP, rALT, 16, 24, 31
172 stbu rTMP, 1(rRTN)
173 beqlr-
174 rlwinm rTMP, rALT, 8, 24, 31
175 stbu rTMP, 1(rRTN)
176#else
177 rlwinm. rTMP, rALT, 8, 24, 31
178 stbu rTMP, 4(rRTN)
179 beqlr-
180 rlwinm. rTMP, rALT, 16, 24, 31
181 stbu rTMP, 1(rRTN)
182 beqlr-
183 rlwinm. rTMP, rALT, 24, 24, 31
184 stbu rTMP, 1(rRTN)
185 beqlr-
186 stbu rALT, 1(rRTN)
43b84013 187#endif
69f13dbf 188 blr
cfc91acd
RM
189
190/* Oh well. In this case, we just do a byte-by-byte copy. */
191 .align 4
192 nop
193L(unaligned):
194 lbz rWORD, 0(rSRC)
69f13dbf 195 addi rRTN, rRTN, -1
cfc91acd
RM
196 cmpwi rWORD, 0
197 beq- L(u2)
198
199L(u0): lbzu rALT, 1(rSRC)
69f13dbf 200 stbu rWORD, 1(rRTN)
cfc91acd
RM
201 cmpwi rALT, 0
202 beq- L(u1)
203 nop /* Let 601 load start of loop. */
204 lbzu rWORD, 1(rSRC)
69f13dbf 205 stbu rALT, 1(rRTN)
cfc91acd
RM
206 cmpwi rWORD, 0
207 bne+ L(u0)
69f13dbf 208L(u2): stbu rWORD, 1(rRTN)
cfc91acd 209 blr
69f13dbf 210L(u1): stbu rALT, 1(rRTN)
cfc91acd 211 blr
69f13dbf 212END (FUNC_NAME)
cfc91acd 213
69f13dbf 214#ifndef USE_AS_STPCPY
85dd1003 215libc_hidden_builtin_def (strcpy)
69f13dbf 216#endif