1*9b9d2a55Sguenther/* $OpenBSD: memmove.S,v 1.3 2015/08/31 02:53:57 guenther Exp $ */ 25b859c19Sderaadt/* $NetBSD: memcpy.S,v 1.2 2006/04/22 23:53:47 uwe Exp $ */ 3cf252584Smiod 45b859c19Sderaadt/* 55b859c19Sderaadt * Copyright (c) 2000 SHIMIZU Ryo <ryo@misakimix.org> 65b859c19Sderaadt * All rights reserved. 75b859c19Sderaadt * 85b859c19Sderaadt * Redistribution and use in source and binary forms, with or without 95b859c19Sderaadt * modification, are permitted provided that the following conditions 105b859c19Sderaadt * are met: 115b859c19Sderaadt * 1. Redistributions of source code must retain the above copyright 125b859c19Sderaadt * notice, this list of conditions and the following disclaimer. 135b859c19Sderaadt * 2. Redistributions in binary form must reproduce the above copyright 145b859c19Sderaadt * notice, this list of conditions and the following disclaimer in the 155b859c19Sderaadt * documentation and/or other materials provided with the distribution. 165b859c19Sderaadt * 3. The name of the author may not be used to endorse or promote products 175b859c19Sderaadt * derived from this software without specific prior written permission. 185b859c19Sderaadt * 195b859c19Sderaadt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 205b859c19Sderaadt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 215b859c19Sderaadt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 225b859c19Sderaadt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 235b859c19Sderaadt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 245b859c19Sderaadt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255b859c19Sderaadt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265b859c19Sderaadt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275b859c19Sderaadt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285b859c19Sderaadt * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295b859c19Sderaadt */ 305b859c19Sderaadt 31*9b9d2a55Sguenther#include "SYS.h" 325b859c19Sderaadt 335b859c19Sderaadt#define REG_DST0 r3 345b859c19Sderaadt#define REG_SRC r5 355b859c19Sderaadt#define REG_DST r4 365b859c19Sderaadt#define REG_LEN r6 375b859c19Sderaadt 385b859c19SderaadtENTRY(memmove) 395b859c19Sderaadt mov REG_DST,REG_DST0 405b859c19Sderaadt cmp/eq REG_DST,REG_SRC /* if ( src == dst ) return; */ 415b859c19Sderaadt bt/s bcopy_return 425b859c19Sderaadt cmp/hi REG_DST,REG_SRC 435b859c19Sderaadt bf/s bcopy_overlap 445b859c19Sderaadt 455b859c19Sderaadt mov REG_SRC,r0 465b859c19Sderaadt xor REG_DST,r0 475b859c19Sderaadt and #3,r0 485b859c19Sderaadt mov r0,r1 495b859c19Sderaadt tst r0,r0 /* (src ^ dst) & 3 */ 505b859c19Sderaadt bf/s word_align 515b859c19Sderaadt 525b859c19Sderaadtlongword_align: 535b859c19Sderaadt tst REG_LEN,REG_LEN /* if ( len==0 ) return; */ 545b859c19Sderaadt bt/s bcopy_return 555b859c19Sderaadt 565b859c19Sderaadt 575b859c19Sderaadt mov REG_SRC,r0 585b859c19Sderaadt tst #1,r0 /* if ( src & 1 ) */ 595b859c19Sderaadt bt 1f 605b859c19Sderaadt mov.b @REG_SRC+,r0 /* *dst++ = *src++; */ 615b859c19Sderaadt add #-1,REG_LEN 625b859c19Sderaadt mov.b r0,@REG_DST 635b859c19Sderaadt add #1,REG_DST 645b859c19Sderaadt1: 655b859c19Sderaadt 665b859c19Sderaadt 675b859c19Sderaadt mov #1,r0 685b859c19Sderaadt cmp/hi r0,REG_LEN /* if ( (len > 1) && */ 695b859c19Sderaadt bf/s 1f 705b859c19Sderaadt mov REG_SRC,r0 715b859c19Sderaadt tst #2,r0 /* (src & 2) { */ 725b859c19Sderaadt bt 1f 735b859c19Sderaadt mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */ 745b859c19Sderaadt add #-2,REG_LEN /* len -= 2; */ 755b859c19Sderaadt mov.w r0,@REG_DST 765b859c19Sderaadt add #2,REG_DST /* } */ 775b859c19Sderaadt1: 785b859c19Sderaadt 795b859c19Sderaadt 805b859c19Sderaadt mov #3,r1 815b859c19Sderaadt cmp/hi r1,REG_LEN /* while ( len > 3 ) { */ 825b859c19Sderaadt bf/s no_align_delay 835b859c19Sderaadt tst REG_LEN,REG_LEN 845b859c19Sderaadt2: 855b859c19Sderaadt mov.l @REG_SRC+,r0 /* *((unsigned long*)dst)++ = *((unsigned long*)src)++; */ 865b859c19Sderaadt add #-4,REG_LEN /* len -= 4; */ 875b859c19Sderaadt mov.l r0,@REG_DST 885b859c19Sderaadt cmp/hi r1,REG_LEN 895b859c19Sderaadt bt/s 2b 905b859c19Sderaadt add #4,REG_DST /* } */ 915b859c19Sderaadt 925b859c19Sderaadt bra no_align_delay 935b859c19Sderaadt tst REG_LEN,REG_LEN 945b859c19Sderaadt 955b859c19Sderaadt 965b859c19Sderaadtword_align: 975b859c19Sderaadt mov r1,r0 985b859c19Sderaadt tst #1,r0 995b859c19Sderaadt bf/s no_align_delay 1005b859c19Sderaadt tst REG_LEN,REG_LEN /* if ( len == 0 ) return; */ 1015b859c19Sderaadt bt bcopy_return 1025b859c19Sderaadt 1035b859c19Sderaadt 1045b859c19Sderaadt mov REG_SRC,r0 /* if ( src & 1 ) */ 1055b859c19Sderaadt tst #1,r0 1065b859c19Sderaadt bt 1f 1075b859c19Sderaadt mov.b @REG_SRC+,r0 /* *dst++ = *src++; */ 1085b859c19Sderaadt add #-1,REG_LEN 1095b859c19Sderaadt mov.b r0,@REG_DST 1105b859c19Sderaadt add #1,REG_DST 1115b859c19Sderaadt1: 1125b859c19Sderaadt 1135b859c19Sderaadt 1145b859c19Sderaadt mov #1,r1 1155b859c19Sderaadt cmp/hi r1,REG_LEN /* while ( len > 1 ) { */ 1165b859c19Sderaadt bf/s no_align_delay 1175b859c19Sderaadt tst REG_LEN,REG_LEN 1185b859c19Sderaadt2: 1195b859c19Sderaadt mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */ 1205b859c19Sderaadt add #-2,REG_LEN /* len -= 2; */ 1215b859c19Sderaadt mov.w r0,@REG_DST 1225b859c19Sderaadt cmp/hi r1,REG_LEN 1235b859c19Sderaadt bt/s 2b 1245b859c19Sderaadt add #2,REG_DST /* } */ 1255b859c19Sderaadt 1265b859c19Sderaadt 1275b859c19Sderaadtno_align: 1285b859c19Sderaadt tst REG_LEN,REG_LEN /* while ( len!= ) { */ 1295b859c19Sderaadtno_align_delay: 1305b859c19Sderaadt bt bcopy_return 1315b859c19Sderaadt1: 1325b859c19Sderaadt mov.b @REG_SRC+,r0 /* *dst++ = *src++; */ 1335b859c19Sderaadt add #-1,REG_LEN /* len--; */ 1345b859c19Sderaadt mov.b r0,@REG_DST 1355b859c19Sderaadt tst REG_LEN,REG_LEN 1365b859c19Sderaadt bf/s 1b 1375b859c19Sderaadt add #1,REG_DST /* } */ 1385b859c19Sderaadtbcopy_return: 1395b859c19Sderaadt rts 1405b859c19Sderaadt mov REG_DST0,r0 1415b859c19Sderaadt 1425b859c19Sderaadtbcopy_overlap: 1435b859c19Sderaadt add REG_LEN,REG_SRC 1445b859c19Sderaadt add REG_LEN,REG_DST 1455b859c19Sderaadt 1465b859c19Sderaadt mov REG_SRC,r0 1475b859c19Sderaadt xor REG_DST,r0 1485b859c19Sderaadt and #3,r0 1495b859c19Sderaadt mov r0,r1 1505b859c19Sderaadt tst r0,r0 /* (src ^ dst) & 3 */ 1515b859c19Sderaadt bf/s ov_word_align 1525b859c19Sderaadt 1535b859c19Sderaadtov_longword_align: 1545b859c19Sderaadt tst REG_LEN,REG_LEN /* if ( len==0 ) return; */ 1555b859c19Sderaadt bt/s bcopy_return 1565b859c19Sderaadt 1575b859c19Sderaadt 1585b859c19Sderaadt mov REG_SRC,r0 1595b859c19Sderaadt tst #1,r0 /* if ( src & 1 ) */ 1605b859c19Sderaadt bt 1f 1615b859c19Sderaadt add #-1,REG_SRC /* *--dst = *--src; */ 1625b859c19Sderaadt mov.b @REG_SRC,r0 1635b859c19Sderaadt mov.b r0,@-REG_DST 1645b859c19Sderaadt add #-1,REG_LEN 1655b859c19Sderaadt1: 1665b859c19Sderaadt 1675b859c19Sderaadt 1685b859c19Sderaadt mov #1,r0 1695b859c19Sderaadt cmp/hi r0,REG_LEN /* if ( (len > 1) && */ 1705b859c19Sderaadt bf/s 1f 1715b859c19Sderaadt mov REG_SRC,r0 1725b859c19Sderaadt tst #2,r0 /* (src & 2) { */ 1735b859c19Sderaadt bt 1f 1745b859c19Sderaadt add #-2,REG_SRC /* *--((unsigned short*)dst) = *--((unsigned short*)src); */ 1755b859c19Sderaadt mov.w @REG_SRC,r0 1765b859c19Sderaadt add #-2,REG_LEN /* len -= 2; */ 1775b859c19Sderaadt mov.w r0,@-REG_DST /* } */ 1785b859c19Sderaadt1: 1795b859c19Sderaadt 1805b859c19Sderaadt 1815b859c19Sderaadt mov #3,r1 1825b859c19Sderaadt cmp/hi r1,REG_LEN /* while ( len > 3 ) { */ 1835b859c19Sderaadt bf/s ov_no_align_delay 1845b859c19Sderaadt tst REG_LEN,REG_LEN 1855b859c19Sderaadt2: 1865b859c19Sderaadt add #-4,REG_SRC 1875b859c19Sderaadt mov.l @REG_SRC,r0 /* *((unsigned long*)dst)++ = *((unsigned long*)src)++; */ 1885b859c19Sderaadt add #-4,REG_LEN /* len -= 4; */ 1895b859c19Sderaadt cmp/hi r1,REG_LEN 1905b859c19Sderaadt bt/s 2b 1915b859c19Sderaadt mov.l r0,@-REG_DST /* } */ 1925b859c19Sderaadt 1935b859c19Sderaadt bra ov_no_align_delay 1945b859c19Sderaadt tst REG_LEN,REG_LEN 1955b859c19Sderaadt 1965b859c19Sderaadt 1975b859c19Sderaadtov_word_align: 1985b859c19Sderaadt mov r1,r0 1995b859c19Sderaadt tst #1,r0 2005b859c19Sderaadt bf/s ov_no_align_delay 2015b859c19Sderaadt tst REG_LEN,REG_LEN /* if ( len == 0 ) return; */ 2025b859c19Sderaadt bt bcopy_return 2035b859c19Sderaadt 2045b859c19Sderaadt 2055b859c19Sderaadt mov REG_SRC,r0 /* if ( src & 1 ) */ 2065b859c19Sderaadt tst #1,r0 2075b859c19Sderaadt bt 1f 2085b859c19Sderaadt add #-1,REG_SRC 2095b859c19Sderaadt mov.b @REG_SRC,r0 /* *--dst = *--src; */ 2105b859c19Sderaadt add #-1,REG_LEN 2115b859c19Sderaadt mov.b r0,@-REG_DST 2125b859c19Sderaadt1: 2135b859c19Sderaadt 2145b859c19Sderaadt 2155b859c19Sderaadt mov #1,r1 2165b859c19Sderaadt cmp/hi r1,REG_LEN /* while ( len > 1 ) { */ 2175b859c19Sderaadt bf/s ov_no_align_delay 2185b859c19Sderaadt tst REG_LEN,REG_LEN 2195b859c19Sderaadt2: 2205b859c19Sderaadt add #-2,REG_SRC 2215b859c19Sderaadt mov.w @REG_SRC,r0 /* *--((unsigned short*)dst) = *--((unsigned short*)src); */ 2225b859c19Sderaadt add #-2,REG_LEN /* len -= 2; */ 2235b859c19Sderaadt cmp/hi r1,REG_LEN 2245b859c19Sderaadt bt/s 2b 2255b859c19Sderaadt mov.w r0,@-REG_DST /* } */ 2265b859c19Sderaadt 2275b859c19Sderaadt 2285b859c19Sderaadtov_no_align: 2295b859c19Sderaadt tst REG_LEN,REG_LEN /* while ( len!= ) { */ 2305b859c19Sderaadtov_no_align_delay: 2315b859c19Sderaadt bt 9f 2325b859c19Sderaadt1: 2335b859c19Sderaadt add #-1,REG_SRC 2345b859c19Sderaadt mov.b @REG_SRC,r0 /* *--dst = *--src; */ 2355b859c19Sderaadt add #-1,REG_LEN /* len--; */ 2365b859c19Sderaadt tst REG_LEN,REG_LEN 2375b859c19Sderaadt bf/s 1b 2385b859c19Sderaadt mov.b r0,@-REG_DST /* } */ 2395b859c19Sderaadt9: 2405b859c19Sderaadt rts 2415b859c19Sderaadt mov REG_DST0,r0 242*9b9d2a55SguentherEND_STRONG(memmove) 243