1/*        $NetBSD: memccpy.S,v 1.5 2014/03/18 18:20:37 riastradh 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.5 2014/03/18 18:20:37 riastradh 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