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