memccpy.S revision 1.4
11.4Smatt/*	$NetBSD: memccpy.S,v 1.4 2013/07/18 21:37:47 matt Exp $	*/
21.1Sscottr
31.1Sscottr/*
41.1Sscottr * Copyright (C) 1999 Scott Reynolds.  All rights reserved.
51.1Sscottr *
61.1Sscottr * Redistribution and use in source and binary forms, with or without
71.1Sscottr * modification, are permitted provided that the following conditions
81.1Sscottr * are met:
91.1Sscottr * 1. Redistributions of source code must retain the above copyright
101.1Sscottr *    notice, this list of conditions and the following disclaimer.
111.1Sscottr * 2. Redistributions in binary form must reproduce the above copyright
121.1Sscottr *    notice, this list of conditions and the following disclaimer in the
131.1Sscottr *    documentation and/or other materials provided with the distribution.
141.1Sscottr * 3. The name of the author may not be used to endorse or promote products
151.1Sscottr *    derived from this software without specific prior written permission.
161.1Sscottr *
171.1Sscottr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
181.1Sscottr * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
191.1Sscottr * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
201.1Sscottr * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
211.1Sscottr * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
221.1Sscottr * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231.1Sscottr * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241.1Sscottr * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251.1Sscottr * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
261.1Sscottr * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271.1Sscottr */
281.1Sscottr
291.1Sscottr#include <machine/asm.h>
301.1Sscottr
311.1Sscottr#if defined(LIBC_SCCS) && !defined(lint)
321.4Smatt	RCSID("$NetBSD: memccpy.S,v 1.4 2013/07/18 21:37:47 matt Exp $")
331.1Sscottr#endif /* LIBC_SCCS and not lint */
341.1Sscottr
351.1SscottrENTRY(memccpy)
361.2Smatt	movl	16(%sp),%d0		| count
371.1Sscottr	jeq	Lmcbail			| nothing to do
381.1Sscottr
391.2Smatt	movl	4(%sp),%a0		| a0 = toaddr
401.4Smatt#ifndef __mcoldfire__
411.1Sscottr	subql	#1,%d0			|   prepare count for DBcc loop
421.4Smatt#endif
431.2Smatt	movl	8(%sp),%a1		| a1 = fromaddr
441.2Smatt	movl	12(%sp),%d1		| d1 = terminator
451.1Sscottr	jeq	Lmcloop			|   handle ASCII NUL specially
461.1Sscottr
471.2Smatt	movl	%d2,-(%sp)		| save scratch register
481.1SscottrLmcnzloop:
491.2Smatt	movb	(%a1)+,%d2		| move a byte
501.2Smatt	movb	%d2,(%a0)+
511.1Sscottr	cmpb	%d2,%d1			| found the terminator?
521.4Smatt#ifndef __mcoldfire__
531.1Sscottr	dbeq	%d0,Lmcnzloop		| if not, keep transferring,
541.4Smatt#endif
551.1Sscottr	jeq	Lmcnzdone		|   otherwise done
561.4Smatt#ifdef __mcoldfire__
571.4Smatt	subql	#1,%d0
581.4Smatt	jne	Lmcnzloop
591.4Smatt#else
601.1Sscottr	clrw	%d0			| check to see if more to do
611.1Sscottr	subql	#1,%d0
621.1Sscottr	jcc	Lmcnzloop		| yes, keep going...
631.4Smatt#endif
641.1Sscottr
651.2Smatt	movl	(%sp)+,%d2		| restore scratch register
661.1Sscottr	movql	#0,%d0			| no terminator found, return NULL
671.1Sscottr#ifdef __SVR4_ABI__
681.1Sscottr	movl	%d0,%a0			| XXX maybe use lea to avoid stall?
691.1Sscottr#endif
701.1Sscottr	rts
711.1Sscottr
721.1SscottrLmcloop:
731.2Smatt	movb	(%a1)+,(%a0)+		| move a byte; was it NUL?
741.4Smatt#ifndef __mcoldfire__
751.1Sscottr	dbeq	%d0,Lmcloop		| if not, keep transferring,
761.4Smatt#endif
771.1Sscottr	jeq	Lmcdone			|   otherwise done
781.4Smatt#ifdef __mcoldfire__
791.4Smatt	subql	#1,%d0
801.4Smatt	jne	Lmcloop
811.4Smatt#else
821.1Sscottr	clrw	%d0			| check to see if more to do
831.1Sscottr	subql	#1,%d0
841.1Sscottr	jcc	Lmcloop			| yes, keep going...
851.4Smatt#endif
861.1Sscottr					| Note: %d0 is now -1!
871.1Sscottr	movql	#0,%d0			| no terminator found, return NULL
881.1SscottrLmcbail:
891.1Sscottr#ifdef __SVR4_ABI__
901.1Sscottr	movl	%d0,%a0			| XXX maybe use lea to avoid stall?
911.1Sscottr#endif
921.1Sscottr	rts
931.1Sscottr
941.1SscottrLmcnzdone:
951.2Smatt	movl	(%sp)+,%d2		| restore scratch register
961.1SscottrLmcdone:
971.1Sscottr	movl	%a0,%d0
981.1Sscottr	rts
991.3SmattEND(memccpy)
100