Update copyright notices with scripts/update-copyrights.
[glibc.git] / sysdeps / powerpc / powerpc32 / stpcpy.S
blob49f993d1c8dff6f692ea1e89acae7da6064f1ce9
1 /* Optimized stpcpy implementation for PowerPC.
2    Copyright (C) 1997-2013 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    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
20 #include <bp-sym.h>
21 #include <bp-asm.h>
23 /* See strlen.s for comments on how the end-of-string testing works.  */
25 /* char * [r3] stpcpy (char *dest [r3], const char *src [r4])  */
27 EALIGN (BP_SYM (__stpcpy), 4, 0)
29 #define rTMP    r0
30 #define rRTN    r3
31 #if __BOUNDED_POINTERS__
32 # define rDEST  r4              /* pointer to previous word in dest */
33 # define rSRC   r5              /* pointer to previous word in src */
34 # define rLOW   r11
35 # define rHIGH  r12
36 #else
37 # define rDEST  r3              /* pointer to previous word in dest */
38 # define rSRC   r4              /* pointer to previous word in src */
39 #endif
40 #define rWORD   r6              /* current word from src */
41 #define rFEFE   r7              /* 0xfefefeff */
42 #define r7F7F   r8              /* 0x7f7f7f7f */
43 #define rNEG    r9              /* ~(word in src | 0x7f7f7f7f) */
44 #define rALT    r10             /* alternate word from src */
46         CHECK_BOUNDS_LOW (rSRC, rLOW, rHIGH)
47         CHECK_BOUNDS_LOW (rDEST, rLOW, rHIGH)
48         STORE_RETURN_BOUNDS (rLOW, rHIGH)
50         or      rTMP, rSRC, rDEST
51         clrlwi. rTMP, rTMP, 30
52         addi    rDEST, rDEST, -4
53         bne     L(unaligned)
55         lis     rFEFE, -0x101
56         lis     r7F7F, 0x7f7f
57         lwz     rWORD, 0(rSRC)
58         addi    rFEFE, rFEFE, -0x101
59         addi    r7F7F, r7F7F, 0x7f7f
60         b       L(g2)
62 L(g0):  lwzu    rALT, 4(rSRC)
63         stwu    rWORD, 4(rDEST)
64         add     rTMP, rFEFE, rALT
65         nor     rNEG, r7F7F, rALT
66         and.    rTMP, rTMP, rNEG
67         bne-    L(g1)
68         lwzu    rWORD, 4(rSRC)
69         stwu    rALT, 4(rDEST)
70 L(g2):  add     rTMP, rFEFE, rWORD
71         nor     rNEG, r7F7F, rWORD
72         and.    rTMP, rTMP, rNEG
73         beq+    L(g0)
75         mr      rALT, rWORD
76 /* We've hit the end of the string.  Do the rest byte-by-byte.  */
77 L(g1):  rlwinm. rTMP, rALT, 8, 24, 31
78         stbu    rTMP, 4(rDEST)
79         beqlr-
80         rlwinm. rTMP, rALT, 16, 24, 31
81         stbu    rTMP, 1(rDEST)
82         beqlr-
83         rlwinm. rTMP, rALT, 24, 24, 31
84         stbu    rTMP, 1(rDEST)
85         beqlr-
86         stbu    rALT, 1(rDEST)
87         CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt)
88         STORE_RETURN_VALUE (rDEST)
89         blr
91 /* Oh well.  In this case, we just do a byte-by-byte copy.  */
92         .align 4
93         nop
94 L(unaligned):
95         lbz     rWORD, 0(rSRC)
96         addi    rDEST, rDEST, 3
97         cmpwi   rWORD, 0
98         beq-    L(u2)
100 L(u0):  lbzu    rALT, 1(rSRC)
101         stbu    rWORD, 1(rDEST)
102         cmpwi   rALT, 0
103         beq-    L(u1)
104         nop             /* Let 601 load start of loop.  */
105         lbzu    rWORD, 1(rSRC)
106         stbu    rALT, 1(rDEST)
107         cmpwi   rWORD, 0
108         bne+    L(u0)
109 L(u2):  stbu    rWORD, 1(rDEST)
110         CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt)
111         STORE_RETURN_VALUE (rDEST)
112         blr
113 L(u1):  stbu    rALT, 1(rDEST)
114         CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt)
115         STORE_RETURN_VALUE (rDEST)
116         blr
117 END (BP_SYM (__stpcpy))
119 weak_alias (BP_SYM (__stpcpy), BP_SYM (stpcpy))
120 libc_hidden_def (__stpcpy)
121 libc_hidden_builtin_def (stpcpy)