Home | History | Annotate | Line # | Download | only in string
      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 
     84 ENTRY(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
    281 END(XCOPY)
    282