xref: /netbsd-src/common/lib/libc/arch/m68k/string/bcopy.S (revision 18ec38ea7c8331c5bc28d877de4a5b1391957c39)
1/*	$NetBSD: bcopy.S,v 1.6 2013/09/07 19:06:29 chs Exp $	*/
2
3/*-
4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by J.T. Conklin.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*-
33 * Copyright (c) 1990 The Regents of the University of California.
34 * All rights reserved.
35 *
36 * This code is derived from software contributed to Berkeley by
37 * the Systems Programming Group of the University of Utah Computer
38 * Science Department.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 *    notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 *    notice, this list of conditions and the following disclaimer in the
47 *    documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the University nor the names of its contributors
49 *    may be used to endorse or promote products derived from this software
50 *    without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 */
64
65#include <machine/asm.h>
66
67#if defined(LIBC_SCCS) && !defined(lint)
68#if 0
69	RCSID("from: @(#)bcopy.s	5.1 (Berkeley) 5/12/90")
70#else
71	RCSID("$NetBSD: bcopy.S,v 1.6 2013/09/07 19:06:29 chs Exp $")
72#endif
73#endif /* LIBC_SCCS and not lint */
74
75
76#ifdef MEMCOPY
77#define	XCOPY	memcpy
78#elif defined(MEMMOVE)
79#define	XCOPY	memmove
80#else
81#define	XCOPY	bcopy
82#endif
83
84ENTRY(XCOPY)
85#if defined(MEMCOPY) || defined(MEMMOVE)
86	movl	4(%sp),%a1		| dest address
87	movl	8(%sp),%a0		| src address
88#else
89	movl	4(%sp),%a0		| src address
90	movl	8(%sp),%a1		| dest address
91#endif
92	movl	12(%sp),%d1		| count
93
94	cmpl	%a1,%a0			| src after dest?
95	jlt	.Lbcback			| yes, must copy backwards
96
97	/*
98	 * It isn't worth the overhead of aligning to {long}word boundries
99	 * if the string is too short.
100	 */
101	cmpl	#8,%d1
102	jlt	.Lbcfbyte
103
104#ifdef	__mc68010__
105	/*
106	 * The 68010 cannot access a word or long on an odd boundary,
107	 * period.  If the source and the destination addresses aren't
108	 * of the same evenness, we're forced to do a bytewise copy.
109	 */
110	movl	%a0,%d0
111	addl	%a1,%d0
112	btst	#0,%d0
113	jne	.Lbcfbyte
114#endif	/* __mc68010__ */
115
116	/* word align */
117	movl	%a1,%d0
118	btst	#0,%d0		| if (dst & 1)
119	jeq	.Lbcfalgndw	|
120	movb	(%a0)+,(%a1)+	|	*(char *)dst++ = *(char *) src++
121	subql	#1,%d1		|	len--
122.Lbcfalgndw:
123	/* long word align */
124	btst	#1,%d0		| if (dst & 2)
125	jeq	.Lbcfalgndl
126	movw	(%a0)+,(%a1)+	|	*(short *)dst++ = *(short *) dst++
127	subql	#2,%d1		|	len -= 2
128.Lbcfalgndl:
129	/* copy by 8 longwords */
130	movel	%d1,%d0
131	lsrl	#5,%d0		| cnt = len / 32
132	jeq	.Lbcflong	| if (cnt)
133	andl	#31,%d1		|	len %= 32
134	subql	#1,%d0		|	set up for dbf
135.Lbcf32loop:
136	movl	(%a0)+,(%a1)+	|	copy 8 long words
137	movl	(%a0)+,(%a1)+
138	movl	(%a0)+,(%a1)+
139	movl	(%a0)+,(%a1)+
140	movl	(%a0)+,(%a1)+
141	movl	(%a0)+,(%a1)+
142	movl	(%a0)+,(%a1)+
143	movl	(%a0)+,(%a1)+
144#ifndef __mcoldfire__
145	dbf	%d0,.Lbcf32loop	|	till done
146	clrw	%d0
147#endif
148	subql	#1,%d0
149	jcc	.Lbcf32loop
150
151.Lbcflong:
152	/* copy by longwords */
153	movel	%d1,%d0
154	lsrl	#2,%d0		| cnt = len / 4
155	jeq	.Lbcfbyte	| if (cnt)
156	subql	#1,%d0		|	set up for dbf
157.Lbcflloop:
158	movl	(%a0)+,(%a1)+	|	copy longwords
159#ifdef __mcoldfire__
160	subql	#1,%d0		|	decrement
161	jcc	.Lbcflloop	|	til done
162#else
163	dbf	%d0,.Lbcflloop	|	til done
164#endif
165	andl	#3,%d1		|	len %= 4
166	jeq	.Lbcdone
167
168	subql	#1,%d1		| set up for dbf
169.Lbcfbloop:
170	movb	(%a0)+,(%a1)+	| copy bytes
171.Lbcfbyte:
172#ifdef __mcoldfire__
173	subql	#1,%d0		|	decrement
174	jcc	.Lbcfbloop	|	til done
175#else
176	dbf	%d1,.Lbcfbloop	| till done
177#endif
178.Lbcdone:
179#if defined(MEMCOPY) || defined(MEMMOVE)
180	movl	4(%sp),%d0	| dest address
181#if defined(__SVR4_ABI__)
182	moveal	%d0,%a0
183#endif
184#endif
185	rts
186
187
188.Lbcback:
189	addl	%d1,%a0		| src pointer to end
190	addl	%d1,%a1		| dest pointer to end
191
192	/*
193	 * It isn't worth the overhead of aligning to {long}word boundries
194	 * if the string is too short.
195	 */
196	cmpl	#8,%d1
197	jlt	.Lbcbbyte
198
199#ifdef	__mc68010__
200	/*
201	 * The 68010 cannot access a word or long on an odd boundary,
202	 * period.  If the source and the destination addresses aren't
203	 * of the same evenness, we're forced to do a bytewise copy.
204	 */
205	movl	%a0,%d0
206	addl	%a1,%d0
207	btst	#0,%d0
208	jne	.Lbcbbyte
209#endif	/* __mc68010__ */
210
211	/* word align */
212	movl	%a1,%d0
213	btst	#0,%d0		| if (dst & 1)
214	jeq	.Lbcbalgndw	|
215	movb	-(%a0),-(%a1)	|	*(char *)dst-- = *(char *) src--
216	subql	#1,%d1		|	len--
217.Lbcbalgndw:
218	/* long word align */
219	btst	#1,%d0		| if (dst & 2)
220	jeq	.Lbcbalgndl
221	movw	-(%a0),-(%a1)	|	*(short *)dst-- = *(short *) dst--
222	subql	#2,%d1		|	len -= 2
223.Lbcbalgndl:
224	/* copy by 8 longwords */
225	movel	%d1,%d0
226	lsrl	#5,%d0		| cnt = len / 32
227	jeq	.Lbcblong	| if (cnt)
228	andl	#31,%d1		|	len %= 32
229	subql	#1,%d0		|	set up for dbf
230.Lbcb32loop:
231	movl	-(%a0),-(%a1)	|	copy 8 long words
232	movl	-(%a0),-(%a1)
233	movl	-(%a0),-(%a1)
234	movl	-(%a0),-(%a1)
235	movl	-(%a0),-(%a1)
236	movl	-(%a0),-(%a1)
237	movl	-(%a0),-(%a1)
238	movl	-(%a0),-(%a1)
239#ifndef __mcoldfire__
240	dbf	%d0,.Lbcb32loop	|	till done
241	clrw	%d0
242#endif
243	subql	#1,%d0
244	jcc	.Lbcb32loop
245
246.Lbcblong:
247	/* copy by longwords */
248	movel	%d1,%d0
249	lsrl	#2,%d0		| cnt = len / 4
250	jeq	.Lbcbbyte	| if (cnt)
251	subql	#1,%d0		|	set up for dbf
252.Lbcblloop:
253	movl	-(%a0),-(%a1)	|	copy longwords
254#ifdef __mcoldfire__
255	subql	#1,%d0		|	decrement
256	jcc	.Lbcblloop	|	til done
257#else
258	dbf	%d0,.Lbcblloop	|	til done
259#endif
260	andl	#3,%d1		|	len %= 4
261	jeq	.Lbcdone
262
263	subql	#1,%d1		| set up for dbf
264.Lbcbbloop:
265	movb	-(%a0),-(%a1)	| copy bytes
266.Lbcbbyte:
267#ifdef __mcoldfire__
268	subql	#1,%d0		| decrement
269	jcc	.Lbcbbloop	| til done
270#else
271	dbf	%d1,.Lbcbbloop	| till done
272#endif
273
274#if defined(MEMCOPY) || defined(MEMMOVE)
275	movl	4(%sp),%d0	| dest address
276#if defined(__SVR4_ABI__)
277	moveal	%d0,%a0
278#endif
279#endif
280	rts
281END(XCOPY)
282