elf: Make dl-rseq-symbols Linux only
[glibc.git] / sysdeps / csky / abiv2 / memcpy.S
blob322d4281d2e4021397334048c6940f81197f070c
1 /* The assembly function for memcpy.  C-SKY ABIV2 version.
2    Copyright (C) 2018-2024 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    <https://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
21 ENTRY (memcpy)
22         /* Test if len less than 4 bytes.  */
23         mov     r12, r0
24         cmplti  r2, 4
25         bt      .L_copy_by_byte
27         andi    r13, r0, 3
28         movi    r19, 4
29         /* Test if dest is not 4 bytes aligned.  */
30         bnez    r13, .L_dest_not_aligned
31 .L_dest_aligned:
32         /* If dest is aligned, then copy.  */
33         zext    r18, r2, 31, 4
34         /* Test if len less than 16 bytes.  */
35         bez     r18, .L_len_less_16bytes
36         movi    r19, 0
38         LABLE_ALIGN
39 .L_len_larger_16bytes:
40 #if defined (__CSKY_VDSPV2__)
41         vldx.8  vr0, (r1), r19
42         PRE_BNEZAD (r18)
43         addi    r1, 16
44         vstx.8  vr0, (r0), r19
45         addi    r0, 16
46 #elif defined (__csky_fpuv2__) && defined(__CK810__)
47         fldd    fr4, (r1, 0)
48         PRE_BNEZAD (r18)
49         fstd    fr4, (r0, 0)
50         fldd    fr4, (r1, 8)
51         addi    r1, 16
52         fstd    fr4, (r0, 8)
53         addi    r0, 16
54 #elif defined (__CK860__)
55         ldw     r3, (r1, 0)
56         stw     r3, (r0, 0)
57         ldw     r3, (r1, 4)
58         stw     r3, (r0, 4)
59         ldw     r3, (r1, 8)
60         stw     r3, (r0, 8)
61         ldw     r3, (r1, 12)
62         addi    r1, 16
63         stw     r3, (r0, 12)
64         addi    r0, 16
65 #else
66         ldw     r20, (r1, 0)
67         ldw     r21, (r1, 4)
68         ldw     r22, (r1, 8)
69         ldw     r23, (r1, 12)
70         stw     r20, (r0, 0)
71         stw     r21, (r0, 4)
72         stw     r22, (r0, 8)
73         stw     r23, (r0, 12)
74         PRE_BNEZAD (r18)
75         addi    r1, 16
76         addi    r0, 16
77 #endif
78         BNEZAD (r18, .L_len_larger_16bytes)
80 .L_len_less_16bytes:
81         zext    r18, r2, 3, 2
82         bez     r18, .L_copy_by_byte
83 .L_len_less_16bytes_loop:
84         ldw     r3, (r1, 0)
85         PRE_BNEZAD (r18)
86         addi    r1, 4
87         stw     r3, (r0, 0)
88         addi    r0, 4
89         BNEZAD (r18, .L_len_less_16bytes_loop)
91         /* Test if len less than 4 bytes.  */
92 .L_copy_by_byte:
93         zext    r18, r2, 1, 0
94         bez     r18, .L_return
95 .L_copy_by_byte_loop:
96         ldb     r3, (r1, 0)
97         PRE_BNEZAD (r18)
98         addi    r1, 1
99         stb     r3, (r0, 0)
100         addi    r0, 1
101         BNEZAD (r18, .L_copy_by_byte_loop)
103 .L_return:
104         mov     r0, r12
105         rts
107         /* If dest is not aligned, just copying some bytes makes the dest
108            align.  */
110 .L_dest_not_aligned:
111         sub     r13, r19, r13
112         mov     r19, r13
113 .L_dest_not_aligned_loop:
114         /* Makes the dest align.  */
115         ldb     r3, (r1, 0)
116         PRE_BNEZAD (r13)
117         addi    r1, 1
118         stb     r3, (r0, 0)
119         addi    r0, 1
120         BNEZAD (r13, .L_dest_not_aligned_loop)
121         sub     r2, r19
122         cmplti  r2, 4
123         bt      .L_copy_by_byte
124         /* Check whether the src is aligned.  */
125         br      .L_dest_aligned
126 END (memcpy)
128 libc_hidden_builtin_def (memcpy)
129 .weak memcpy
132 ENTRY (memmove)
133         subu    r3, r0, r1
134         cmphs   r3, r2
135         bt      memcpy
137         mov     r12, r0
138         addu    r0, r0, r2
139         addu    r1, r1, r2
141         /* Test if len less than 4 bytes.  */
142         cmplti  r2, 4
143         bt      .L_copy_by_byte_m
145         andi    r13, r0, 3
146         /* Test if dest is not 4 bytes aligned.  */
147         bnez    r13, .L_dest_not_aligned_m
148 .L_dest_aligned_m:
149         /* If dest is aligned, then copy.  */
150         zext    r18, r2, 31, 4
151         /* Test if len less than 16 bytes.  */
152         bez     r18, .L_len_less_16bytes_m
153         movi    r19, 0
155         /* len > 16 bytes */
156         LABLE_ALIGN
157 .L_len_larger_16bytes_m:
158         subi    r1, 16
159         subi    r0, 16
160 #if defined (__CSKY_VDSPV2__)
161         vldx.8  vr0, (r1), r19
162         PRE_BNEZAD (r18)
163         vstx.8  vr0, (r0), r19
164 #elif defined (__csky_fpuv2__) && defined(__CK810__)
165         fldd    fr4, (r1, 8)
166         PRE_BNEZAD (r18)
167         fstd    fr4, (r0, 8)
168         fldd    fr4, (r1, 0)
169         fstd    fr4, (r0, 0)
170 #elif defined (__CK860__)
171         ldw     r3, (r1, 12)
172         stw     r3, (r0, 12)
173         ldw     r3, (r1, 8)
174         stw     r3, (r0, 8)
175         ldw     r3, (r1, 4)
176         stw     r3, (r0, 4)
177         ldw     r3, (r1, 0)
178         stw     r3, (r0, 0)
179 #else
180         ldw     r20, (r1, 0)
181         ldw     r21, (r1, 4)
182         ldw     r22, (r1, 8)
183         ldw     r23, (r1, 12)
184         stw     r20, (r0, 0)
185         stw     r21, (r0, 4)
186         stw     r22, (r0, 8)
187         stw     r23, (r0, 12)
188         PRE_BNEZAD (r18)
189 #endif
190         BNEZAD (r18, .L_len_larger_16bytes_m)
192 .L_len_less_16bytes_m:
193         zext    r18, r2, 3, 2
194         bez     r18, .L_copy_by_byte_m
195 .L_len_less_16bytes_loop_m:
196         subi    r1, 4
197         subi    r0, 4
198         ldw     r3, (r1, 0)
199         PRE_BNEZAD (r18)
200         stw     r3, (r0, 0)
201         BNEZAD (r18, .L_len_less_16bytes_loop_m)
203         /* Test if len less than 4 bytes.  */
204 .L_copy_by_byte_m:
205         zext    r18, r2, 1, 0
206         bez     r18, .L_return_m
207 .L_copy_by_byte_loop_m:
208         subi    r1, 1
209         subi    r0, 1
210         ldb     r3, (r1, 0)
211         PRE_BNEZAD (r18)
212         stb     r3, (r0, 0)
213         BNEZAD (r18, .L_copy_by_byte_loop_m)
215 .L_return_m:
216         mov     r0, r12
217         rts
219         /* If dest is not aligned, just copying some bytes makes the dest
220            align.  */
221 .L_dest_not_aligned_m:
222         sub     r2, r13
223 .L_dest_not_aligned_loop_m:
224         subi    r1, 1
225         subi    r0, 1
226         /* Makes the dest align.  */
227         ldb     r3, (r1, 0)
228         PRE_BNEZAD (r13)
229         stb     r3, (r0, 0)
230         BNEZAD (r13, .L_dest_not_aligned_loop_m)
231         cmplti  r2, 4
232         bt      .L_copy_by_byte_m
233         /* Check whether the src is aligned.  */
234         br      .L_dest_aligned_m
235 END (memmove)
237 libc_hidden_builtin_def (memmove)
238 .weak memmove