Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / sh / memcpy.S
blob4d2984123250d6aaad1c9d49b94b998b356adb40
1 /* Copyright (C) 1999-2014 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Kazumoto Kojima <kkojima@rr.iij4u.or.jp>
4    Optimized by Toshiyasu Morita <toshiyasu.morita@hsa.hitachi.com>
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, see
18    <http://www.gnu.org/licenses/>.  */
20 #include <sysdep.h>
22 /* void *memcpy(void *dst, const void *src, size_t n);
23     No overlap between the memory of DST and of SRC are assumed.  */
25 ENTRY(memcpy)
26         mov     r4,r3           /* Save destination.  */
28         /* If less than 11 bytes, just do a byte copy.  */
29         mov     #11,r0
30         cmp/gt  r6,r0
31         bt      L_byteloop_init
33         /* Check if we need to word-align source.  */
34         mov     r5,r0
35         tst     #1,r0
36         bt      L_wordalign
38         mov.b   @r0+,r1         /* Copy one byte.  */
39         add     #-1,r6
40         mov.b   r1,@r4
41         add     #1,r4
43         .balignw 4,0x0009
44 L_wordalign:
45         /* Check if we need to longword-align source.  */
46         tst     #2,r0
47         bt      L_copy
49         mov.w   @r0+,r1         /* Copy one word.  */
50         add     #-2,r6
51 #ifdef __BIG_ENDIAN__
52         add     #1,r4
53         mov.b   r1,@r4
54         shlr8   r1
55         mov.b   r1,@-r4
56         add     #2,r4
57 #else
58         mov.b   r1,@r4
59         add     #1,r4
60         shlr8   r1
61         mov.b   r1,@r4
62         add     #1,r4
63 #endif
64 L_copy:
65         mov     r0,r5
67         /* Calculate the correct routine to handle the destination
68            alignment and simultaneously calculate the loop counts for
69            both the 2 word copy loop and byte copy loop.  */
70         mova    L_jumptable,r0
71         mov     r0,r1
72         mov     r4,r0
73         mov     r6,r7
74         and     #3,r0
75         shlr2   r7
76         shll    r0
77         shlr    r7
78         mov.w   @(r0,r1),r2
79         mov     #7,r0
80         braf    r2
81         and     r0,r6
82 L_base:
84         .balign 4
85 L_jumptable:
86         .word   L_copydest0 - L_base
87         .word   L_copydest1_or_3 - L_base
88         .word   L_copydest2 - L_base
89         .word   L_copydest1_or_3 - L_base
91         .balign 4
92         /* Copy routine for (dest mod 4) == 1 or == 3.  */
93 L_copydest1_or_3:
94         add     #-1,r4
95         .balignw 4,0x0009
96 L_copydest1_or_3_loop:
97         mov.l   @r5+,r0         /* Read first longword.  */
98         dt      r7
99         mov.l   @r5+,r1         /* Read second longword.  */
100 #ifdef __BIG_ENDIAN__
101         /* Write first longword as byte, word, byte.  */
102         mov.b   r0,@(4,r4)
103         shlr8   r0
104         mov.w   r0,@(2,r4)
105         shlr16  r0
106         mov.b   r0,@(1,r4)
107         mov     r1,r0
108         /* Write second longword as byte, word, byte.  */
109         mov.b   r0,@(8,r4)
110         shlr8   r0
111         mov.w   r0,@(6,r4)
112         shlr16  r0
113         mov.b   r0,@(5,r4)
114 #else
115         /* Write first longword as byte, word, byte.  */
116         mov.b   r0,@(1,r4)
117         shlr8   r0
118         mov.w   r0,@(2,r4)
119         shlr16  r0
120         mov.b   r0,@(4,r4)
121         mov     r1,r0
122         /* Write second longword as byte, word, byte.  */
123         mov.b   r0,@(5,r4)
124         shlr8   r0
125         mov.w   r0,@(6,r4)
126         shlr16  r0
127         mov.b   r0,@(8,r4)
128 #endif
129         bf/s    L_copydest1_or_3_loop
130         add     #8,r4
132         bra     L_byteloop_init
133         add     #1,r4
135         .balign 4
136         /* Copy routine for (dest mod 4) == 2.  */
137 L_copydest2:
138 L_copydest2_loop:
139         mov.l   @r5+,r0
140         dt      r7
141         mov.l   @r5+,r1
142 #ifdef __BIG_ENDIAN__
143         mov.w   r0,@(2,r4)
144         shlr16  r0
145         mov.w   r0,@r4
146         mov     r1,r0
147         mov.w   r0,@(6,r4)
148         shlr16  r0
149         mov.w   r0,@(4,r4)
150 #else
151         mov.w   r0,@r4
152         shlr16  r0
153         mov.w   r0,@(2,r4)
154         mov     r1,r0
155         mov.w   r0,@(4,r4)
156         shlr16  r0
157         mov.w   r0,@(6,r4)
158 #endif
159         bf/s    L_copydest2_loop
160         add     #8,r4
162         bra     L_byteloop_init
163         nop
165         .balign 4
166         /* Copy routine for (dest mod 4) == 0.  */
167 L_copydest0:
168         add     #-8,r4
169         .balignw 4,0x0009
170 L_copydest0_loop:
171         mov.l   @r5+,r0
172         dt      r7
173         mov.l   @r5+,r1
174         add     #8,r4
175         mov.l   r0,@r4
176         bf/s    L_copydest0_loop
177         mov.l   r1,@(4,r4)
179         add     #8,r4           /* Fall through.  */
181 L_byteloop_init:
182         tst     r6,r6
183         bt      L_exit
185         .balignw 4,0x0009
186         /* Copy remaining bytes.  */
187 L_byteloop:
188         mov.b   @r5+,r0
189         dt      r6
190         mov.b   r0,@r4
191         bf/s    L_byteloop
192         add     #1,r4
194 L_exit:
195         rts
196         mov     r3,r0           /* Return destination.  */
197 END(memcpy)
198 libc_hidden_builtin_def (memcpy)