1*18ec38eaSchs/* $NetBSD: bcopy.S,v 1.6 2013/09/07 19:06:29 chs Exp $ */ 237c9f0a6Schristos 337c9f0a6Schristos/*- 437c9f0a6Schristos * Copyright (c) 1997 The NetBSD Foundation, Inc. 537c9f0a6Schristos * All rights reserved. 637c9f0a6Schristos * 737c9f0a6Schristos * This code is derived from software contributed to The NetBSD Foundation 837c9f0a6Schristos * by J.T. Conklin. 937c9f0a6Schristos * 1037c9f0a6Schristos * Redistribution and use in source and binary forms, with or without 1137c9f0a6Schristos * modification, are permitted provided that the following conditions 1237c9f0a6Schristos * are met: 1337c9f0a6Schristos * 1. Redistributions of source code must retain the above copyright 1437c9f0a6Schristos * notice, this list of conditions and the following disclaimer. 1537c9f0a6Schristos * 2. Redistributions in binary form must reproduce the above copyright 1637c9f0a6Schristos * notice, this list of conditions and the following disclaimer in the 1737c9f0a6Schristos * documentation and/or other materials provided with the distribution. 1837c9f0a6Schristos * 1937c9f0a6Schristos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 2037c9f0a6Schristos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2137c9f0a6Schristos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2237c9f0a6Schristos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2337c9f0a6Schristos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2437c9f0a6Schristos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2537c9f0a6Schristos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2637c9f0a6Schristos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2737c9f0a6Schristos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2837c9f0a6Schristos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2937c9f0a6Schristos * POSSIBILITY OF SUCH DAMAGE. 3037c9f0a6Schristos */ 3137c9f0a6Schristos 3237c9f0a6Schristos/*- 3337c9f0a6Schristos * Copyright (c) 1990 The Regents of the University of California. 3437c9f0a6Schristos * All rights reserved. 3537c9f0a6Schristos * 3637c9f0a6Schristos * This code is derived from software contributed to Berkeley by 3737c9f0a6Schristos * the Systems Programming Group of the University of Utah Computer 3837c9f0a6Schristos * Science Department. 3937c9f0a6Schristos * 4037c9f0a6Schristos * Redistribution and use in source and binary forms, with or without 4137c9f0a6Schristos * modification, are permitted provided that the following conditions 4237c9f0a6Schristos * are met: 4337c9f0a6Schristos * 1. Redistributions of source code must retain the above copyright 4437c9f0a6Schristos * notice, this list of conditions and the following disclaimer. 4537c9f0a6Schristos * 2. Redistributions in binary form must reproduce the above copyright 4637c9f0a6Schristos * notice, this list of conditions and the following disclaimer in the 4737c9f0a6Schristos * documentation and/or other materials provided with the distribution. 4837c9f0a6Schristos * 3. Neither the name of the University nor the names of its contributors 4937c9f0a6Schristos * may be used to endorse or promote products derived from this software 5037c9f0a6Schristos * without specific prior written permission. 5137c9f0a6Schristos * 5237c9f0a6Schristos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 5337c9f0a6Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 5437c9f0a6Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 5537c9f0a6Schristos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 5637c9f0a6Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 5737c9f0a6Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 5837c9f0a6Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 5937c9f0a6Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 6037c9f0a6Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 6137c9f0a6Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 6237c9f0a6Schristos * SUCH DAMAGE. 6337c9f0a6Schristos */ 6437c9f0a6Schristos 6537c9f0a6Schristos#include <machine/asm.h> 6637c9f0a6Schristos 6737c9f0a6Schristos#if defined(LIBC_SCCS) && !defined(lint) 6837c9f0a6Schristos#if 0 6937c9f0a6Schristos RCSID("from: @(#)bcopy.s 5.1 (Berkeley) 5/12/90") 7037c9f0a6Schristos#else 71*18ec38eaSchs RCSID("$NetBSD: bcopy.S,v 1.6 2013/09/07 19:06:29 chs Exp $") 7237c9f0a6Schristos#endif 7337c9f0a6Schristos#endif /* LIBC_SCCS and not lint */ 7437c9f0a6Schristos 7537c9f0a6Schristos 7637c9f0a6Schristos#ifdef MEMCOPY 7765726debSmatt#define XCOPY memcpy 7865726debSmatt#elif defined(MEMMOVE) 7965726debSmatt#define XCOPY memmove 8037c9f0a6Schristos#else 8165726debSmatt#define XCOPY bcopy 8237c9f0a6Schristos#endif 8365726debSmatt 8465726debSmattENTRY(XCOPY) 8537c9f0a6Schristos#if defined(MEMCOPY) || defined(MEMMOVE) 8607a0a325Smatt movl 4(%sp),%a1 | dest address 8707a0a325Smatt movl 8(%sp),%a0 | src address 8837c9f0a6Schristos#else 8907a0a325Smatt movl 4(%sp),%a0 | src address 9007a0a325Smatt movl 8(%sp),%a1 | dest address 9137c9f0a6Schristos#endif 9207a0a325Smatt movl 12(%sp),%d1 | count 9337c9f0a6Schristos 9437c9f0a6Schristos cmpl %a1,%a0 | src after dest? 95*18ec38eaSchs jlt .Lbcback | yes, must copy backwards 9637c9f0a6Schristos 9737c9f0a6Schristos /* 9837c9f0a6Schristos * It isn't worth the overhead of aligning to {long}word boundries 9937c9f0a6Schristos * if the string is too short. 10037c9f0a6Schristos */ 10137c9f0a6Schristos cmpl #8,%d1 102*18ec38eaSchs jlt .Lbcfbyte 10337c9f0a6Schristos 10437c9f0a6Schristos#ifdef __mc68010__ 10537c9f0a6Schristos /* 10637c9f0a6Schristos * The 68010 cannot access a word or long on an odd boundary, 10737c9f0a6Schristos * period. If the source and the destination addresses aren't 10837c9f0a6Schristos * of the same evenness, we're forced to do a bytewise copy. 10937c9f0a6Schristos */ 11037c9f0a6Schristos movl %a0,%d0 11137c9f0a6Schristos addl %a1,%d0 11237c9f0a6Schristos btst #0,%d0 113*18ec38eaSchs jne .Lbcfbyte 11437c9f0a6Schristos#endif /* __mc68010__ */ 11537c9f0a6Schristos 11637c9f0a6Schristos /* word align */ 11737c9f0a6Schristos movl %a1,%d0 11837c9f0a6Schristos btst #0,%d0 | if (dst & 1) 119*18ec38eaSchs jeq .Lbcfalgndw | 12007a0a325Smatt movb (%a0)+,(%a1)+ | *(char *)dst++ = *(char *) src++ 12137c9f0a6Schristos subql #1,%d1 | len-- 122*18ec38eaSchs.Lbcfalgndw: 12337c9f0a6Schristos /* long word align */ 12437c9f0a6Schristos btst #1,%d0 | if (dst & 2) 125*18ec38eaSchs jeq .Lbcfalgndl 12607a0a325Smatt movw (%a0)+,(%a1)+ | *(short *)dst++ = *(short *) dst++ 12737c9f0a6Schristos subql #2,%d1 | len -= 2 128*18ec38eaSchs.Lbcfalgndl: 12937c9f0a6Schristos /* copy by 8 longwords */ 13037c9f0a6Schristos movel %d1,%d0 13137c9f0a6Schristos lsrl #5,%d0 | cnt = len / 32 132*18ec38eaSchs jeq .Lbcflong | if (cnt) 13337c9f0a6Schristos andl #31,%d1 | len %= 32 13437c9f0a6Schristos subql #1,%d0 | set up for dbf 135*18ec38eaSchs.Lbcf32loop: 13607a0a325Smatt movl (%a0)+,(%a1)+ | copy 8 long words 13707a0a325Smatt movl (%a0)+,(%a1)+ 13807a0a325Smatt movl (%a0)+,(%a1)+ 13907a0a325Smatt movl (%a0)+,(%a1)+ 14007a0a325Smatt movl (%a0)+,(%a1)+ 14107a0a325Smatt movl (%a0)+,(%a1)+ 14207a0a325Smatt movl (%a0)+,(%a1)+ 14307a0a325Smatt movl (%a0)+,(%a1)+ 1441d398a17Smatt#ifndef __mcoldfire__ 145*18ec38eaSchs dbf %d0,.Lbcf32loop | till done 14637c9f0a6Schristos clrw %d0 1471d398a17Smatt#endif 14837c9f0a6Schristos subql #1,%d0 149*18ec38eaSchs jcc .Lbcf32loop 15037c9f0a6Schristos 151*18ec38eaSchs.Lbcflong: 15237c9f0a6Schristos /* copy by longwords */ 15337c9f0a6Schristos movel %d1,%d0 15437c9f0a6Schristos lsrl #2,%d0 | cnt = len / 4 155*18ec38eaSchs jeq .Lbcfbyte | if (cnt) 15637c9f0a6Schristos subql #1,%d0 | set up for dbf 157*18ec38eaSchs.Lbcflloop: 15807a0a325Smatt movl (%a0)+,(%a1)+ | copy longwords 1591d398a17Smatt#ifdef __mcoldfire__ 1601d398a17Smatt subql #1,%d0 | decrement 161*18ec38eaSchs jcc .Lbcflloop | til done 1621d398a17Smatt#else 163*18ec38eaSchs dbf %d0,.Lbcflloop | til done 1641d398a17Smatt#endif 16537c9f0a6Schristos andl #3,%d1 | len %= 4 166*18ec38eaSchs jeq .Lbcdone 16737c9f0a6Schristos 16837c9f0a6Schristos subql #1,%d1 | set up for dbf 169*18ec38eaSchs.Lbcfbloop: 17007a0a325Smatt movb (%a0)+,(%a1)+ | copy bytes 171*18ec38eaSchs.Lbcfbyte: 1721d398a17Smatt#ifdef __mcoldfire__ 1731d398a17Smatt subql #1,%d0 | decrement 174*18ec38eaSchs jcc .Lbcfbloop | til done 1751d398a17Smatt#else 176*18ec38eaSchs dbf %d1,.Lbcfbloop | till done 1771d398a17Smatt#endif 178*18ec38eaSchs.Lbcdone: 17937c9f0a6Schristos#if defined(MEMCOPY) || defined(MEMMOVE) 18007a0a325Smatt movl 4(%sp),%d0 | dest address 18137c9f0a6Schristos#if defined(__SVR4_ABI__) 18237c9f0a6Schristos moveal %d0,%a0 18337c9f0a6Schristos#endif 18437c9f0a6Schristos#endif 18537c9f0a6Schristos rts 18637c9f0a6Schristos 18737c9f0a6Schristos 188*18ec38eaSchs.Lbcback: 18937c9f0a6Schristos addl %d1,%a0 | src pointer to end 19037c9f0a6Schristos addl %d1,%a1 | dest pointer to end 19137c9f0a6Schristos 19237c9f0a6Schristos /* 19337c9f0a6Schristos * It isn't worth the overhead of aligning to {long}word boundries 19437c9f0a6Schristos * if the string is too short. 19537c9f0a6Schristos */ 19637c9f0a6Schristos cmpl #8,%d1 197*18ec38eaSchs jlt .Lbcbbyte 19837c9f0a6Schristos 19937c9f0a6Schristos#ifdef __mc68010__ 20037c9f0a6Schristos /* 20137c9f0a6Schristos * The 68010 cannot access a word or long on an odd boundary, 20237c9f0a6Schristos * period. If the source and the destination addresses aren't 20337c9f0a6Schristos * of the same evenness, we're forced to do a bytewise copy. 20437c9f0a6Schristos */ 20537c9f0a6Schristos movl %a0,%d0 20637c9f0a6Schristos addl %a1,%d0 20737c9f0a6Schristos btst #0,%d0 208*18ec38eaSchs jne .Lbcbbyte 20937c9f0a6Schristos#endif /* __mc68010__ */ 21037c9f0a6Schristos 21137c9f0a6Schristos /* word align */ 21237c9f0a6Schristos movl %a1,%d0 21337c9f0a6Schristos btst #0,%d0 | if (dst & 1) 214*18ec38eaSchs jeq .Lbcbalgndw | 21507a0a325Smatt movb -(%a0),-(%a1) | *(char *)dst-- = *(char *) src-- 21637c9f0a6Schristos subql #1,%d1 | len-- 217*18ec38eaSchs.Lbcbalgndw: 21837c9f0a6Schristos /* long word align */ 21937c9f0a6Schristos btst #1,%d0 | if (dst & 2) 220*18ec38eaSchs jeq .Lbcbalgndl 22107a0a325Smatt movw -(%a0),-(%a1) | *(short *)dst-- = *(short *) dst-- 22237c9f0a6Schristos subql #2,%d1 | len -= 2 223*18ec38eaSchs.Lbcbalgndl: 22437c9f0a6Schristos /* copy by 8 longwords */ 22537c9f0a6Schristos movel %d1,%d0 22637c9f0a6Schristos lsrl #5,%d0 | cnt = len / 32 227*18ec38eaSchs jeq .Lbcblong | if (cnt) 22837c9f0a6Schristos andl #31,%d1 | len %= 32 22937c9f0a6Schristos subql #1,%d0 | set up for dbf 230*18ec38eaSchs.Lbcb32loop: 23107a0a325Smatt movl -(%a0),-(%a1) | copy 8 long words 23207a0a325Smatt movl -(%a0),-(%a1) 23307a0a325Smatt movl -(%a0),-(%a1) 23407a0a325Smatt movl -(%a0),-(%a1) 23507a0a325Smatt movl -(%a0),-(%a1) 23607a0a325Smatt movl -(%a0),-(%a1) 23707a0a325Smatt movl -(%a0),-(%a1) 23807a0a325Smatt movl -(%a0),-(%a1) 2391d398a17Smatt#ifndef __mcoldfire__ 240*18ec38eaSchs dbf %d0,.Lbcb32loop | till done 24137c9f0a6Schristos clrw %d0 2421d398a17Smatt#endif 24337c9f0a6Schristos subql #1,%d0 244*18ec38eaSchs jcc .Lbcb32loop 24537c9f0a6Schristos 246*18ec38eaSchs.Lbcblong: 24737c9f0a6Schristos /* copy by longwords */ 24837c9f0a6Schristos movel %d1,%d0 24937c9f0a6Schristos lsrl #2,%d0 | cnt = len / 4 250*18ec38eaSchs jeq .Lbcbbyte | if (cnt) 25137c9f0a6Schristos subql #1,%d0 | set up for dbf 252*18ec38eaSchs.Lbcblloop: 25307a0a325Smatt movl -(%a0),-(%a1) | copy longwords 2541d398a17Smatt#ifdef __mcoldfire__ 2551d398a17Smatt subql #1,%d0 | decrement 256*18ec38eaSchs jcc .Lbcblloop | til done 2571d398a17Smatt#else 258*18ec38eaSchs dbf %d0,.Lbcblloop | til done 2591d398a17Smatt#endif 26037c9f0a6Schristos andl #3,%d1 | len %= 4 261*18ec38eaSchs jeq .Lbcdone 26237c9f0a6Schristos 26337c9f0a6Schristos subql #1,%d1 | set up for dbf 264*18ec38eaSchs.Lbcbbloop: 26507a0a325Smatt movb -(%a0),-(%a1) | copy bytes 266*18ec38eaSchs.Lbcbbyte: 2671d398a17Smatt#ifdef __mcoldfire__ 2681d398a17Smatt subql #1,%d0 | decrement 269*18ec38eaSchs jcc .Lbcbbloop | til done 2701d398a17Smatt#else 271*18ec38eaSchs dbf %d1,.Lbcbbloop | till done 2721d398a17Smatt#endif 27337c9f0a6Schristos 27437c9f0a6Schristos#if defined(MEMCOPY) || defined(MEMMOVE) 27507a0a325Smatt movl 4(%sp),%d0 | dest address 27637c9f0a6Schristos#if defined(__SVR4_ABI__) 27737c9f0a6Schristos moveal %d0,%a0 27837c9f0a6Schristos#endif 27937c9f0a6Schristos#endif 28037c9f0a6Schristos rts 28165726debSmattEND(XCOPY) 282