memccpy.S revision 1.2
11.2Smatt/*	$NetBSD: memccpy.S,v 1.2 2013/07/16 20:49:42 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.2Smatt	RCSID("$NetBSD: memccpy.S,v 1.2 2013/07/16 20:49:42 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.1Sscottr	subql	#1,%d0			|   prepare count for DBcc loop
411.2Smatt	movl	8(%sp),%a1		| a1 = fromaddr
421.2Smatt	movl	12(%sp),%d1		| d1 = terminator
431.1Sscottr	jeq	Lmcloop			|   handle ASCII NUL specially
441.1Sscottr
451.2Smatt	movl	%d2,-(%sp)		| save scratch register
461.1SscottrLmcnzloop:
471.2Smatt	movb	(%a1)+,%d2		| move a byte
481.2Smatt	movb	%d2,(%a0)+
491.1Sscottr	cmpb	%d2,%d1			| found the terminator?
501.1Sscottr	dbeq	%d0,Lmcnzloop		| if not, keep transferring,
511.1Sscottr	jeq	Lmcnzdone		|   otherwise done
521.1Sscottr	clrw	%d0			| check to see if more to do
531.1Sscottr	subql	#1,%d0
541.1Sscottr	jcc	Lmcnzloop		| yes, keep going...
551.1Sscottr
561.2Smatt	movl	(%sp)+,%d2		| restore scratch register
571.1Sscottr	movql	#0,%d0			| no terminator found, return NULL
581.1Sscottr#ifdef __SVR4_ABI__
591.1Sscottr	movl	%d0,%a0			| XXX maybe use lea to avoid stall?
601.1Sscottr#endif
611.1Sscottr	rts
621.1Sscottr
631.1SscottrLmcloop:
641.2Smatt	movb	(%a1)+,(%a0)+		| move a byte; was it NUL?
651.1Sscottr	dbeq	%d0,Lmcloop		| if not, keep transferring,
661.1Sscottr	jeq	Lmcdone			|   otherwise done
671.1Sscottr	clrw	%d0			| check to see if more to do
681.1Sscottr	subql	#1,%d0
691.1Sscottr	jcc	Lmcloop			| yes, keep going...
701.1Sscottr					| Note: %d0 is now -1!
711.1Sscottr	movql	#0,%d0			| no terminator found, return NULL
721.1SscottrLmcbail:
731.1Sscottr#ifdef __SVR4_ABI__
741.1Sscottr	movl	%d0,%a0			| XXX maybe use lea to avoid stall?
751.1Sscottr#endif
761.1Sscottr	rts
771.1Sscottr
781.1SscottrLmcnzdone:
791.2Smatt	movl	(%sp)+,%d2		| restore scratch register
801.1SscottrLmcdone:
811.1Sscottr	movl	%a0,%d0
821.1Sscottr	rts
83