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