1/* $NetBSD: bcopy.S,v 1.1 2002/11/20 14:23:54 itohy Exp $ */ 2 3/* 4 * Copyright (c) 2000 SHIMIZU Ryo <ryo@misakimix.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <machine/asm.h> 31 32#if defined(LIBC_SCCS) && !defined(lint) 33 RCSID("$NetBSD: bcopy.S,v 1.1 2002/11/20 14:23:54 itohy Exp $") 34#endif 35 36#if defined(MEMCOPY) || defined(MEMMOVE) 37#define REG_DST0 r3 38#define REG_SRC r5 39#define REG_DST r4 40#else 41#define REG_SRC r4 42#define REG_DST r5 43#endif 44 45#define REG_LEN r6 46 47#ifdef MEMCOPY 48ENTRY(memcpy) 49#else 50#ifdef MEMMOVE 51ENTRY(memmove) 52#else 53ENTRY(bcopy) 54#endif 55#endif 56#ifdef REG_DST0 57 mov REG_DST,REG_DST0 58#endif 59 cmp/eq REG_DST,REG_SRC /* if ( src == dst ) return; */ 60 bt/s bcopy_return 61 cmp/hi REG_DST,REG_SRC 62 bf/s bcopy_overlap 63 64 mov REG_SRC,r0 65 xor REG_DST,r0 66 and #3,r0 67 mov r0,r1 68 tst r0,r0 /* (src ^ dst) & 3 */ 69 bf/s word_align 70 71longword_align: 72 tst REG_LEN,REG_LEN /* if ( len==0 ) return; */ 73 bt/s bcopy_return 74 75 76 mov REG_SRC,r0 77 tst #1,r0 /* if ( src & 1 ) */ 78 bt 1f 79 mov.b @REG_SRC+,r0 /* *dst++ = *src++; */ 80 add #-1,REG_LEN 81 mov.b r0,@REG_DST 82 add #1,REG_DST 831: 84 85 86 mov #1,r0 87 cmp/hi r0,REG_LEN /* if ( (len > 1) && */ 88 bf/s 1f 89 mov REG_SRC,r0 90 tst #2,r0 /* (src & 2) { */ 91 bt 1f 92 mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */ 93 add #-2,REG_LEN /* len -= 2; */ 94 mov.w r0,@REG_DST 95 add #2,REG_DST /* } */ 961: 97 98 99 mov #3,r1 100 cmp/hi r1,REG_LEN /* while ( len > 3 ) { */ 101 bf/s no_align_delay 102 tst REG_LEN,REG_LEN 1032: 104 mov.l @REG_SRC+,r0 /* *((unsigned long*)dst)++ = *((unsigned long*)src)++; */ 105 add #-4,REG_LEN /* len -= 4; */ 106 mov.l r0,@REG_DST 107 cmp/hi r1,REG_LEN 108 bt/s 2b 109 add #4,REG_DST /* } */ 110 111 bra no_align_delay 112 tst REG_LEN,REG_LEN 113 114 115word_align: 116 mov r1,r0 117 tst #1,r0 118 bf/s no_align_delay 119 tst REG_LEN,REG_LEN /* if ( len == 0 ) return; */ 120 bt bcopy_return 121 122 123 mov REG_SRC,r0 /* if ( src & 1 ) */ 124 tst #1,r0 125 bt 1f 126 mov.b @REG_SRC+,r0 /* *dst++ = *src++; */ 127 add #-1,REG_LEN 128 mov.b r0,@REG_DST 129 add #1,REG_DST 1301: 131 132 133 mov #1,r1 134 cmp/hi r1,REG_LEN /* while ( len > 1 ) { */ 135 bf/s no_align_delay 136 tst REG_LEN,REG_LEN 1372: 138 mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */ 139 add #-2,REG_LEN /* len -= 2; */ 140 mov.w r0,@REG_DST 141 cmp/hi r1,REG_LEN 142 bt/s 2b 143 add #2,REG_DST /* } */ 144 145 146no_align: 147 tst REG_LEN,REG_LEN /* while ( len!= ) { */ 148no_align_delay: 149 bt bcopy_return 1501: 151 mov.b @REG_SRC+,r0 /* *dst++ = *src++; */ 152 add #-1,REG_LEN /* len--; */ 153 mov.b r0,@REG_DST 154 tst REG_LEN,REG_LEN 155 bf/s 1b 156 add #1,REG_DST /* } */ 157bcopy_return: 158 rts 159#ifdef REG_DST0 160 mov REG_DST0,r0 161#else 162 nop 163#endif 164 165 166bcopy_overlap: 167 add REG_LEN,REG_SRC 168 add REG_LEN,REG_DST 169 170 mov REG_SRC,r0 171 xor REG_DST,r0 172 and #3,r0 173 mov r0,r1 174 tst r0,r0 /* (src ^ dst) & 3 */ 175 bf/s ov_word_align 176 177ov_longword_align: 178 tst REG_LEN,REG_LEN /* if ( len==0 ) return; */ 179 bt/s bcopy_return 180 181 182 mov REG_SRC,r0 183 tst #1,r0 /* if ( src & 1 ) */ 184 bt 1f 185 add #-1,REG_SRC /* *--dst = *--src; */ 186 mov.b @REG_SRC,r0 187 mov.b r0,@-REG_DST 188 add #-1,REG_LEN 1891: 190 191 192 mov #1,r0 193 cmp/hi r0,REG_LEN /* if ( (len > 1) && */ 194 bf/s 1f 195 mov REG_SRC,r0 196 tst #2,r0 /* (src & 2) { */ 197 bt 1f 198 add #-2,REG_SRC /* *--((unsigned short*)dst) = *--((unsigned short*)src); */ 199 mov.w @REG_SRC,r0 200 add #-2,REG_LEN /* len -= 2; */ 201 mov.w r0,@-REG_DST /* } */ 2021: 203 204 205 mov #3,r1 206 cmp/hi r1,REG_LEN /* while ( len > 3 ) { */ 207 bf/s ov_no_align_delay 208 tst REG_LEN,REG_LEN 2092: 210 add #-4,REG_SRC 211 mov.l @REG_SRC,r0 /* *((unsigned long*)dst)++ = *((unsigned long*)src)++; */ 212 add #-4,REG_LEN /* len -= 4; */ 213 cmp/hi r1,REG_LEN 214 bt/s 2b 215 mov.l r0,@-REG_DST /* } */ 216 217 bra ov_no_align_delay 218 tst REG_LEN,REG_LEN 219 220 221ov_word_align: 222 mov r1,r0 223 tst #1,r0 224 bf/s ov_no_align_delay 225 tst REG_LEN,REG_LEN /* if ( len == 0 ) return; */ 226 bt bcopy_return 227 228 229 mov REG_SRC,r0 /* if ( src & 1 ) */ 230 tst #1,r0 231 bt 1f 232 add #-1,REG_SRC 233 mov.b @REG_SRC,r0 /* *--dst = *--src; */ 234 add #-1,REG_LEN 235 mov.b r0,@-REG_DST 2361: 237 238 239 mov #1,r1 240 cmp/hi r1,REG_LEN /* while ( len > 1 ) { */ 241 bf/s ov_no_align_delay 242 tst REG_LEN,REG_LEN 2432: 244 add #-2,REG_SRC 245 mov.w @REG_SRC,r0 /* *--((unsigned short*)dst) = *--((unsigned short*)src); */ 246 add #-2,REG_LEN /* len -= 2; */ 247 cmp/hi r1,REG_LEN 248 bt/s 2b 249 mov.w r0,@-REG_DST /* } */ 250 251 252ov_no_align: 253 tst REG_LEN,REG_LEN /* while ( len!= ) { */ 254ov_no_align_delay: 255 bt 9f 2561: 257 add #-1,REG_SRC 258 mov.b @REG_SRC,r0 /* *--dst = *--src; */ 259 add #-1,REG_LEN /* len--; */ 260 tst REG_LEN,REG_LEN 261 bf/s 1b 262 mov.b r0,@-REG_DST /* } */ 2639: 264 rts 265#ifdef REG_DST0 266 mov REG_DST0,r0 267#else 268 nop 269#endif 270