1*0a6a1f1dSLionel Sambuc/* $NetBSD: memccpy.S,v 1.5 2014/03/18 18:20:37 riastradh Exp $ */ 22fe8fb19SBen Gras 32fe8fb19SBen Gras/* 42fe8fb19SBen Gras * Copyright (C) 1999 Scott Reynolds. All rights reserved. 52fe8fb19SBen Gras * 62fe8fb19SBen Gras * Redistribution and use in source and binary forms, with or without 72fe8fb19SBen Gras * modification, are permitted provided that the following conditions 82fe8fb19SBen Gras * are met: 92fe8fb19SBen Gras * 1. Redistributions of source code must retain the above copyright 102fe8fb19SBen Gras * notice, this list of conditions and the following disclaimer. 112fe8fb19SBen Gras * 2. Redistributions in binary form must reproduce the above copyright 122fe8fb19SBen Gras * notice, this list of conditions and the following disclaimer in the 132fe8fb19SBen Gras * documentation and/or other materials provided with the distribution. 142fe8fb19SBen Gras * 3. The name of the author may not be used to endorse or promote products 152fe8fb19SBen Gras * derived from this software without specific prior written permission. 162fe8fb19SBen Gras * 172fe8fb19SBen Gras * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 182fe8fb19SBen Gras * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 192fe8fb19SBen Gras * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 202fe8fb19SBen Gras * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 212fe8fb19SBen Gras * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 222fe8fb19SBen Gras * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232fe8fb19SBen Gras * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242fe8fb19SBen Gras * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252fe8fb19SBen Gras * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 262fe8fb19SBen Gras * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272fe8fb19SBen Gras */ 282fe8fb19SBen Gras 292fe8fb19SBen Gras#include <machine/asm.h> 302fe8fb19SBen Gras 312fe8fb19SBen Gras#if defined(LIBC_SCCS) && !defined(lint) 32*0a6a1f1dSLionel Sambuc RCSID("$NetBSD: memccpy.S,v 1.5 2014/03/18 18:20:37 riastradh Exp $") 332fe8fb19SBen Gras#endif /* LIBC_SCCS and not lint */ 342fe8fb19SBen Gras 352fe8fb19SBen GrasENTRY(memccpy) 3684d9c625SLionel Sambuc movl 16(%sp),%d0 | count 372fe8fb19SBen Gras jeq Lmcbail | nothing to do 382fe8fb19SBen Gras 3984d9c625SLionel Sambuc movl 4(%sp),%a0 | a0 = toaddr 4084d9c625SLionel Sambuc#ifndef __mcoldfire__ 412fe8fb19SBen Gras subql #1,%d0 | prepare count for DBcc loop 4284d9c625SLionel Sambuc#endif 4384d9c625SLionel Sambuc movl 8(%sp),%a1 | a1 = fromaddr 4484d9c625SLionel Sambuc movl 12(%sp),%d1 | d1 = terminator 452fe8fb19SBen Gras jeq Lmcloop | handle ASCII NUL specially 462fe8fb19SBen Gras 4784d9c625SLionel Sambuc movl %d2,-(%sp) | save scratch register 482fe8fb19SBen GrasLmcnzloop: 4984d9c625SLionel Sambuc movb (%a1)+,%d2 | move a byte 5084d9c625SLionel Sambuc movb %d2,(%a0)+ 512fe8fb19SBen Gras cmpb %d2,%d1 | found the terminator? 5284d9c625SLionel Sambuc#ifndef __mcoldfire__ 532fe8fb19SBen Gras dbeq %d0,Lmcnzloop | if not, keep transferring, 5484d9c625SLionel Sambuc#endif 552fe8fb19SBen Gras jeq Lmcnzdone | otherwise done 5684d9c625SLionel Sambuc#ifdef __mcoldfire__ 5784d9c625SLionel Sambuc subql #1,%d0 5884d9c625SLionel Sambuc jne Lmcnzloop 5984d9c625SLionel Sambuc#else 602fe8fb19SBen Gras clrw %d0 | check to see if more to do 612fe8fb19SBen Gras subql #1,%d0 622fe8fb19SBen Gras jcc Lmcnzloop | yes, keep going... 6384d9c625SLionel Sambuc#endif 642fe8fb19SBen Gras 6584d9c625SLionel Sambuc movl (%sp)+,%d2 | restore scratch register 662fe8fb19SBen Gras movql #0,%d0 | no terminator found, return NULL 672fe8fb19SBen Gras#ifdef __SVR4_ABI__ 682fe8fb19SBen Gras movl %d0,%a0 | XXX maybe use lea to avoid stall? 692fe8fb19SBen Gras#endif 702fe8fb19SBen Gras rts 712fe8fb19SBen Gras 722fe8fb19SBen GrasLmcloop: 7384d9c625SLionel Sambuc movb (%a1)+,(%a0)+ | move a byte; was it NUL? 7484d9c625SLionel Sambuc#ifndef __mcoldfire__ 752fe8fb19SBen Gras dbeq %d0,Lmcloop | if not, keep transferring, 7684d9c625SLionel Sambuc#endif 772fe8fb19SBen Gras jeq Lmcdone | otherwise done 7884d9c625SLionel Sambuc#ifdef __mcoldfire__ 7984d9c625SLionel Sambuc subql #1,%d0 8084d9c625SLionel Sambuc jne Lmcloop 8184d9c625SLionel Sambuc#else 822fe8fb19SBen Gras clrw %d0 | check to see if more to do 832fe8fb19SBen Gras subql #1,%d0 842fe8fb19SBen Gras jcc Lmcloop | yes, keep going... 8584d9c625SLionel Sambuc#endif 862fe8fb19SBen Gras | Note: %d0 is now -1! 872fe8fb19SBen Gras movql #0,%d0 | no terminator found, return NULL 882fe8fb19SBen GrasLmcbail: 892fe8fb19SBen Gras#ifdef __SVR4_ABI__ 902fe8fb19SBen Gras movl %d0,%a0 | XXX maybe use lea to avoid stall? 912fe8fb19SBen Gras#endif 922fe8fb19SBen Gras rts 932fe8fb19SBen Gras 942fe8fb19SBen GrasLmcnzdone: 9584d9c625SLionel Sambuc movl (%sp)+,%d2 | restore scratch register 962fe8fb19SBen GrasLmcdone: 972fe8fb19SBen Gras movl %a0,%d0 982fe8fb19SBen Gras rts 9984d9c625SLionel SambucEND(memccpy) 100