1/* Optimized stpcpy implementation for PowerPC.
2 Copyright (C) 1997-2024 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] stpcpy (char *dest [r3], const char *src [r4]) */
24
25EALIGN (__stpcpy, 4, 0)
26
27#define rTMP r0
28#define rRTN r3
29#define rDEST r3 /* pointer to previous word in dest */
30#define rSRC r4 /* pointer to previous word in src */
31#define rWORD r6 /* current word from src */
32#define rFEFE r7 /* 0xfefefeff */
33#define r7F7F r8 /* 0x7f7f7f7f */
34#define rNEG r9 /* ~(word in src | 0x7f7f7f7f) */
35#define rALT r10 /* alternate word from src */
36
37
38 or rTMP, rSRC, rDEST
39 clrlwi. rTMP, rTMP, 30
40 addi rDEST, rDEST, -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 stbu rALT, 4(rDEST)
69 beqlr-
70 rlwinm. rTMP, rALT, 24, 24, 31
71 stbu rTMP, 1(rDEST)
72 beqlr-
73 rlwinm. rTMP, rALT, 16, 24, 31
74 stbu rTMP, 1(rDEST)
75 beqlr-
76 rlwinm rTMP, rALT, 8, 24, 31
77 stbu rTMP, 1(rDEST)
78 blr
79#else
80 rlwinm. rTMP, rALT, 8, 24, 31
81 stbu rTMP, 4(rDEST)
82 beqlr-
83 rlwinm. rTMP, rALT, 16, 24, 31
84 stbu rTMP, 1(rDEST)
85 beqlr-
86 rlwinm. rTMP, rALT, 24, 24, 31
87 stbu rTMP, 1(rDEST)
88 beqlr-
89 stbu rALT, 1(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, rDEST, 3
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): stbu rWORD, 1(rDEST)
112 blr
113L(u1): stbu rALT, 1(rDEST)
114 blr
115END (__stpcpy)
116
117weak_alias (__stpcpy, stpcpy)
118libc_hidden_def (__stpcpy)
119libc_hidden_builtin_def (stpcpy)
120

source code of glibc/sysdeps/powerpc/powerpc32/stpcpy.S