2.9
[glibc/nacl-glibc.git] / sysdeps / sh / memcpy.S
blobb084cc93ccfce2ba19be85f65eeb33c212e8e700
1 /* Copyright (C) 1999, 2000, 2002, 2003 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, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
21 #include <sysdep.h>
22 #include <endian.h>
24 /* void *memcpy(void *dst, const void *src, size_t n);
25     No overlap between the memory of DST and of SRC are assumed.  */
27 ENTRY(memcpy)
28         mov     r4,r3           /* Save destination.  */
30         /* If less than 11 bytes, just do a byte copy.  */
31         mov     #11,r0
32         cmp/gt  r6,r0
33         bt      L_byteloop_init
35         /* Check if we need to word-align source.  */
36         mov     r5,r0
37         tst     #1,r0
38         bt      L_wordalign
40         mov.b   @r0+,r1         /* Copy one byte.  */
41         add     #-1,r6
42         mov.b   r1,@r4
43         add     #1,r4
45         .balignw 4,0x0009
46 L_wordalign:
47         /* Check if we need to longword-align source.  */
48         tst     #2,r0
49         bt      L_copy
51         mov.w   @r0+,r1         /* Copy one word.  */
52         add     #-2,r6
53 #if __BYTE_ORDER == __BIG_ENDIAN
54         add     #1,r4
55         mov.b   r1,@r4
56         shlr8   r1
57         mov.b   r1,@-r4
58         add     #2,r4
59 #else
60         mov.b   r1,@r4
61         add     #1,r4
62         shlr8   r1
63         mov.b   r1,@r4
64         add     #1,r4
65 #endif
66 L_copy:
67         mov     r0,r5
69         /* Calculate the correct routine to handle the destination
70            alignment and simultaneously calculate the loop counts for
71            both the 2 word copy loop and byte copy loop.  */
72         mova    L_jumptable,r0
73         mov     r0,r1
74         mov     r4,r0
75         mov     r6,r7
76         and     #3,r0
77         shlr2   r7
78         shll    r0
79         shlr    r7
80         mov.w   @(r0,r1),r2
81         mov     #7,r0
82         braf    r2
83         and     r0,r6
84 L_base:
86         .balign 4
87 L_jumptable:
88         .word   L_copydest0 - L_base
89         .word   L_copydest1_or_3 - L_base
90         .word   L_copydest2 - L_base
91         .word   L_copydest1_or_3 - L_base
93         .balign 4
94         /* Copy routine for (dest mod 4) == 1 or == 3.  */
95 L_copydest1_or_3:
96         add     #-1,r4
97         .balignw 4,0x0009
98 L_copydest1_or_3_loop:
99         mov.l   @r5+,r0         /* Read first longword.  */
100         dt      r7
101         mov.l   @r5+,r1         /* Read second longword.  */
102 #if __BYTE_ORDER == __BIG_ENDIAN
103         /* Write first longword as byte, word, byte.  */
104         mov.b   r0,@(4,r4)
105         shlr8   r0
106         mov.w   r0,@(2,r4)
107         shlr16  r0
108         mov.b   r0,@(1,r4)
109         mov     r1,r0
110         /* Write second longword as byte, word, byte.  */
111         mov.b   r0,@(8,r4)
112         shlr8   r0
113         mov.w   r0,@(6,r4)
114         shlr16  r0
115         mov.b   r0,@(5,r4)
116 #else
117         /* Write first longword as byte, word, byte.  */
118         mov.b   r0,@(1,r4)
119         shlr8   r0
120         mov.w   r0,@(2,r4)
121         shlr16  r0
122         mov.b   r0,@(4,r4)
123         mov     r1,r0
124         /* Write second longword as byte, word, byte.  */
125         mov.b   r0,@(5,r4)
126         shlr8   r0
127         mov.w   r0,@(6,r4)
128         shlr16  r0
129         mov.b   r0,@(8,r4)
130 #endif
131         bf/s    L_copydest1_or_3_loop
132         add     #8,r4
134         bra     L_byteloop_init
135         add     #1,r4
137         .balign 4
138         /* Copy routine for (dest mod 4) == 2.  */
139 L_copydest2:
140 L_copydest2_loop:
141         mov.l   @r5+,r0
142         dt      r7
143         mov.l   @r5+,r1
144 #if __BYTE_ORDER == __BIG_ENDIAN
145         mov.w   r0,@(2,r4)
146         shlr16  r0
147         mov.w   r0,@r4
148         mov     r1,r0
149         mov.w   r0,@(6,r4)
150         shlr16  r0
151         mov.w   r0,@(4,r4)
152 #else
153         mov.w   r0,@r4
154         shlr16  r0
155         mov.w   r0,@(2,r4)
156         mov     r1,r0
157         mov.w   r0,@(4,r4)
158         shlr16  r0
159         mov.w   r0,@(6,r4)
160 #endif
161         bf/s    L_copydest2_loop
162         add     #8,r4
164         bra     L_byteloop_init
165         nop
167         .balign 4
168         /* Copy routine for (dest mod 4) == 0.  */
169 L_copydest0:
170         add     #-8,r4
171         .balignw 4,0x0009
172 L_copydest0_loop:
173         mov.l   @r5+,r0
174         dt      r7
175         mov.l   @r5+,r1
176         add     #8,r4
177         mov.l   r0,@r4
178         bf/s    L_copydest0_loop
179         mov.l   r1,@(4,r4)
181         add     #8,r4           /* Fall through.  */
183 L_byteloop_init:
184         tst     r6,r6
185         bt      L_exit
187         .balignw 4,0x0009
188         /* Copy remaining bytes.  */
189 L_byteloop:
190         mov.b   @r5+,r0
191         dt      r6
192         mov.b   r0,@r4
193         bf/s    L_byteloop
194         add     #1,r4
196 L_exit:
197         rts
198         mov     r3,r0           /* Return destination.  */
199 END(memcpy)
200 libc_hidden_builtin_def (memcpy)