xref: /minix/lib/libc/arch/m68k/string/memccpy.S (revision 84d9c625)
1/*	$NetBSD: memccpy.S,v 1.4 2013/07/18 21:37:47 matt Exp $	*/
2
3/*
4 * Copyright (C) 1999 Scott Reynolds.  All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <machine/asm.h>
30
31#if defined(LIBC_SCCS) && !defined(lint)
32	RCSID("$NetBSD: memccpy.S,v 1.4 2013/07/18 21:37:47 matt Exp $")
33#endif /* LIBC_SCCS and not lint */
34
35ENTRY(memccpy)
36	movl	16(%sp),%d0		| count
37	jeq	Lmcbail			| nothing to do
38
39	movl	4(%sp),%a0		| a0 = toaddr
40#ifndef __mcoldfire__
41	subql	#1,%d0			|   prepare count for DBcc loop
42#endif
43	movl	8(%sp),%a1		| a1 = fromaddr
44	movl	12(%sp),%d1		| d1 = terminator
45	jeq	Lmcloop			|   handle ASCII NUL specially
46
47	movl	%d2,-(%sp)		| save scratch register
48Lmcnzloop:
49	movb	(%a1)+,%d2		| move a byte
50	movb	%d2,(%a0)+
51	cmpb	%d2,%d1			| found the terminator?
52#ifndef __mcoldfire__
53	dbeq	%d0,Lmcnzloop		| if not, keep transferring,
54#endif
55	jeq	Lmcnzdone		|   otherwise done
56#ifdef __mcoldfire__
57	subql	#1,%d0
58	jne	Lmcnzloop
59#else
60	clrw	%d0			| check to see if more to do
61	subql	#1,%d0
62	jcc	Lmcnzloop		| yes, keep going...
63#endif
64
65	movl	(%sp)+,%d2		| restore scratch register
66	movql	#0,%d0			| no terminator found, return NULL
67#ifdef __SVR4_ABI__
68	movl	%d0,%a0			| XXX maybe use lea to avoid stall?
69#endif
70	rts
71
72Lmcloop:
73	movb	(%a1)+,(%a0)+		| move a byte; was it NUL?
74#ifndef __mcoldfire__
75	dbeq	%d0,Lmcloop		| if not, keep transferring,
76#endif
77	jeq	Lmcdone			|   otherwise done
78#ifdef __mcoldfire__
79	subql	#1,%d0
80	jne	Lmcloop
81#else
82	clrw	%d0			| check to see if more to do
83	subql	#1,%d0
84	jcc	Lmcloop			| yes, keep going...
85#endif
86					| Note: %d0 is now -1!
87	movql	#0,%d0			| no terminator found, return NULL
88Lmcbail:
89#ifdef __SVR4_ABI__
90	movl	%d0,%a0			| XXX maybe use lea to avoid stall?
91#endif
92	rts
93
94Lmcnzdone:
95	movl	(%sp)+,%d2		| restore scratch register
96Lmcdone:
97	movl	%a0,%d0
98	rts
99END(memccpy)
100