1/* $OpenBSD: memcpy.S,v 1.3 2015/08/31 02:53:57 guenther Exp $ */ 2/* $NetBSD: memcpy.S,v 1.2 2006/04/22 23:53:47 uwe Exp $ */ 3 4/* 5 * Copyright (c) 2000 SHIMIZU Ryo <ryo@misakimix.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "SYS.h" 32 33#define REG_DST0 r3 34#define REG_SRC r5 35#define REG_DST r4 36#define REG_LEN r6 37 38ENTRY(memcpy) 39 mov REG_DST,REG_DST0 40 cmp/eq REG_DST,REG_SRC /* if ( src == dst ) return; */ 41 bt/s bcopy_return 42 43 /* copy forward */ 44 mov REG_SRC,r0 45 xor REG_DST,r0 46 and #3,r0 47 mov r0,r1 48 tst r0,r0 /* (src ^ dst) & 3 */ 49 bf/s word_align 50 51longword_align: 52 tst REG_LEN,REG_LEN /* if ( len==0 ) return; */ 53 bt/s bcopy_return 54 55 56 mov REG_SRC,r0 57 tst #1,r0 /* if ( src & 1 ) */ 58 bt 1f 59 mov.b @REG_SRC+,r0 /* *dst++ = *src++; */ 60 add #-1,REG_LEN 61 mov.b r0,@REG_DST 62 add #1,REG_DST 631: 64 65 66 mov #1,r0 67 cmp/hi r0,REG_LEN /* if ( (len > 1) && */ 68 bf/s 1f 69 mov REG_SRC,r0 70 tst #2,r0 /* (src & 2) { */ 71 bt 1f 72 mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */ 73 add #-2,REG_LEN /* len -= 2; */ 74 mov.w r0,@REG_DST 75 add #2,REG_DST /* } */ 761: 77 78 79 mov #3,r1 80 cmp/hi r1,REG_LEN /* while ( len > 3 ) { */ 81 bf/s no_align_delay 82 tst REG_LEN,REG_LEN 832: 84 mov.l @REG_SRC+,r0 /* *((unsigned long*)dst)++ = *((unsigned long*)src)++; */ 85 add #-4,REG_LEN /* len -= 4; */ 86 mov.l r0,@REG_DST 87 cmp/hi r1,REG_LEN 88 bt/s 2b 89 add #4,REG_DST /* } */ 90 91 bra no_align_delay 92 tst REG_LEN,REG_LEN 93 94 95word_align: 96 mov r1,r0 97 tst #1,r0 98 bf/s no_align_delay 99 tst REG_LEN,REG_LEN /* if ( len == 0 ) return; */ 100 bt bcopy_return 101 102 103 mov REG_SRC,r0 /* if ( src & 1 ) */ 104 tst #1,r0 105 bt 1f 106 mov.b @REG_SRC+,r0 /* *dst++ = *src++; */ 107 add #-1,REG_LEN 108 mov.b r0,@REG_DST 109 add #1,REG_DST 1101: 111 112 113 mov #1,r1 114 cmp/hi r1,REG_LEN /* while ( len > 1 ) { */ 115 bf/s no_align_delay 116 tst REG_LEN,REG_LEN 1172: 118 mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */ 119 add #-2,REG_LEN /* len -= 2; */ 120 mov.w r0,@REG_DST 121 cmp/hi r1,REG_LEN 122 bt/s 2b 123 add #2,REG_DST /* } */ 124 125 126no_align: 127 tst REG_LEN,REG_LEN /* while ( len!= ) { */ 128no_align_delay: 129 bt bcopy_return 1301: 131 mov.b @REG_SRC+,r0 /* *dst++ = *src++; */ 132 add #-1,REG_LEN /* len--; */ 133 mov.b r0,@REG_DST 134 tst REG_LEN,REG_LEN 135 bf/s 1b 136 add #1,REG_DST /* } */ 137bcopy_return: 138 rts 139 mov REG_DST0,r0 140END_STRONG(memcpy) 141