1*9b9d2a55Sguenther/* $OpenBSD: bcopy.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_SRC r4 345b859c19Sderaadt#define REG_DST r5 355b859c19Sderaadt#define REG_LEN r6 365b859c19Sderaadt 375b859c19SderaadtENTRY(bcopy) 385b859c19Sderaadt cmp/eq REG_DST,REG_SRC /* if ( src == dst ) return; */ 395b859c19Sderaadt bt/s bcopy_return 405b859c19Sderaadt cmp/hi REG_DST,REG_SRC 415b859c19Sderaadt bf/s bcopy_overlap 425b859c19Sderaadt 435b859c19Sderaadt mov REG_SRC,r0 445b859c19Sderaadt xor REG_DST,r0 455b859c19Sderaadt and #3,r0 465b859c19Sderaadt mov r0,r1 475b859c19Sderaadt tst r0,r0 /* (src ^ dst) & 3 */ 485b859c19Sderaadt bf/s word_align 495b859c19Sderaadt 505b859c19Sderaadtlongword_align: 515b859c19Sderaadt tst REG_LEN,REG_LEN /* if ( len==0 ) return; */ 525b859c19Sderaadt bt/s bcopy_return 535b859c19Sderaadt 545b859c19Sderaadt 555b859c19Sderaadt mov REG_SRC,r0 565b859c19Sderaadt tst #1,r0 /* if ( src & 1 ) */ 575b859c19Sderaadt bt 1f 585b859c19Sderaadt mov.b @REG_SRC+,r0 /* *dst++ = *src++; */ 595b859c19Sderaadt add #-1,REG_LEN 605b859c19Sderaadt mov.b r0,@REG_DST 615b859c19Sderaadt add #1,REG_DST 625b859c19Sderaadt1: 635b859c19Sderaadt 645b859c19Sderaadt 655b859c19Sderaadt mov #1,r0 665b859c19Sderaadt cmp/hi r0,REG_LEN /* if ( (len > 1) && */ 675b859c19Sderaadt bf/s 1f 685b859c19Sderaadt mov REG_SRC,r0 695b859c19Sderaadt tst #2,r0 /* (src & 2) { */ 705b859c19Sderaadt bt 1f 715b859c19Sderaadt mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */ 725b859c19Sderaadt add #-2,REG_LEN /* len -= 2; */ 735b859c19Sderaadt mov.w r0,@REG_DST 745b859c19Sderaadt add #2,REG_DST /* } */ 755b859c19Sderaadt1: 765b859c19Sderaadt 775b859c19Sderaadt 785b859c19Sderaadt mov #3,r1 795b859c19Sderaadt cmp/hi r1,REG_LEN /* while ( len > 3 ) { */ 805b859c19Sderaadt bf/s no_align_delay 815b859c19Sderaadt tst REG_LEN,REG_LEN 825b859c19Sderaadt2: 835b859c19Sderaadt mov.l @REG_SRC+,r0 /* *((unsigned long*)dst)++ = *((unsigned long*)src)++; */ 845b859c19Sderaadt add #-4,REG_LEN /* len -= 4; */ 855b859c19Sderaadt mov.l r0,@REG_DST 865b859c19Sderaadt cmp/hi r1,REG_LEN 875b859c19Sderaadt bt/s 2b 885b859c19Sderaadt add #4,REG_DST /* } */ 895b859c19Sderaadt 905b859c19Sderaadt bra no_align_delay 915b859c19Sderaadt tst REG_LEN,REG_LEN 925b859c19Sderaadt 935b859c19Sderaadt 945b859c19Sderaadtword_align: 955b859c19Sderaadt mov r1,r0 965b859c19Sderaadt tst #1,r0 975b859c19Sderaadt bf/s no_align_delay 985b859c19Sderaadt tst REG_LEN,REG_LEN /* if ( len == 0 ) return; */ 995b859c19Sderaadt bt bcopy_return 1005b859c19Sderaadt 1015b859c19Sderaadt 1025b859c19Sderaadt mov REG_SRC,r0 /* if ( src & 1 ) */ 1035b859c19Sderaadt tst #1,r0 1045b859c19Sderaadt bt 1f 1055b859c19Sderaadt mov.b @REG_SRC+,r0 /* *dst++ = *src++; */ 1065b859c19Sderaadt add #-1,REG_LEN 1075b859c19Sderaadt mov.b r0,@REG_DST 1085b859c19Sderaadt add #1,REG_DST 1095b859c19Sderaadt1: 1105b859c19Sderaadt 1115b859c19Sderaadt 1125b859c19Sderaadt mov #1,r1 1135b859c19Sderaadt cmp/hi r1,REG_LEN /* while ( len > 1 ) { */ 1145b859c19Sderaadt bf/s no_align_delay 1155b859c19Sderaadt tst REG_LEN,REG_LEN 1165b859c19Sderaadt2: 1175b859c19Sderaadt mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */ 1185b859c19Sderaadt add #-2,REG_LEN /* len -= 2; */ 1195b859c19Sderaadt mov.w r0,@REG_DST 1205b859c19Sderaadt cmp/hi r1,REG_LEN 1215b859c19Sderaadt bt/s 2b 1225b859c19Sderaadt add #2,REG_DST /* } */ 1235b859c19Sderaadt 1245b859c19Sderaadt 1255b859c19Sderaadtno_align: 1265b859c19Sderaadt tst REG_LEN,REG_LEN /* while ( len!= ) { */ 1275b859c19Sderaadtno_align_delay: 1285b859c19Sderaadt bt bcopy_return 1295b859c19Sderaadt1: 1305b859c19Sderaadt mov.b @REG_SRC+,r0 /* *dst++ = *src++; */ 1315b859c19Sderaadt add #-1,REG_LEN /* len--; */ 1325b859c19Sderaadt mov.b r0,@REG_DST 1335b859c19Sderaadt tst REG_LEN,REG_LEN 1345b859c19Sderaadt bf/s 1b 1355b859c19Sderaadt add #1,REG_DST /* } */ 1365b859c19Sderaadtbcopy_return: 1375b859c19Sderaadt rts 1385b859c19Sderaadt nop 1395b859c19Sderaadt 1405b859c19Sderaadt 1415b859c19Sderaadtbcopy_overlap: 1425b859c19Sderaadt add REG_LEN,REG_SRC 1435b859c19Sderaadt add REG_LEN,REG_DST 1445b859c19Sderaadt 1455b859c19Sderaadt mov REG_SRC,r0 1465b859c19Sderaadt xor REG_DST,r0 1475b859c19Sderaadt and #3,r0 1485b859c19Sderaadt mov r0,r1 1495b859c19Sderaadt tst r0,r0 /* (src ^ dst) & 3 */ 1505b859c19Sderaadt bf/s ov_word_align 1515b859c19Sderaadt 1525b859c19Sderaadtov_longword_align: 1535b859c19Sderaadt tst REG_LEN,REG_LEN /* if ( len==0 ) return; */ 1545b859c19Sderaadt bt/s bcopy_return 1555b859c19Sderaadt 1565b859c19Sderaadt 1575b859c19Sderaadt mov REG_SRC,r0 1585b859c19Sderaadt tst #1,r0 /* if ( src & 1 ) */ 1595b859c19Sderaadt bt 1f 1605b859c19Sderaadt add #-1,REG_SRC /* *--dst = *--src; */ 1615b859c19Sderaadt mov.b @REG_SRC,r0 1625b859c19Sderaadt mov.b r0,@-REG_DST 1635b859c19Sderaadt add #-1,REG_LEN 1645b859c19Sderaadt1: 1655b859c19Sderaadt 1665b859c19Sderaadt 1675b859c19Sderaadt mov #1,r0 1685b859c19Sderaadt cmp/hi r0,REG_LEN /* if ( (len > 1) && */ 1695b859c19Sderaadt bf/s 1f 1705b859c19Sderaadt mov REG_SRC,r0 1715b859c19Sderaadt tst #2,r0 /* (src & 2) { */ 1725b859c19Sderaadt bt 1f 1735b859c19Sderaadt add #-2,REG_SRC /* *--((unsigned short*)dst) = *--((unsigned short*)src); */ 1745b859c19Sderaadt mov.w @REG_SRC,r0 1755b859c19Sderaadt add #-2,REG_LEN /* len -= 2; */ 1765b859c19Sderaadt mov.w r0,@-REG_DST /* } */ 1775b859c19Sderaadt1: 1785b859c19Sderaadt 1795b859c19Sderaadt 1805b859c19Sderaadt mov #3,r1 1815b859c19Sderaadt cmp/hi r1,REG_LEN /* while ( len > 3 ) { */ 1825b859c19Sderaadt bf/s ov_no_align_delay 1835b859c19Sderaadt tst REG_LEN,REG_LEN 1845b859c19Sderaadt2: 1855b859c19Sderaadt add #-4,REG_SRC 1865b859c19Sderaadt mov.l @REG_SRC,r0 /* *((unsigned long*)dst)++ = *((unsigned long*)src)++; */ 1875b859c19Sderaadt add #-4,REG_LEN /* len -= 4; */ 1885b859c19Sderaadt cmp/hi r1,REG_LEN 1895b859c19Sderaadt bt/s 2b 1905b859c19Sderaadt mov.l r0,@-REG_DST /* } */ 1915b859c19Sderaadt 1925b859c19Sderaadt bra ov_no_align_delay 1935b859c19Sderaadt tst REG_LEN,REG_LEN 1945b859c19Sderaadt 1955b859c19Sderaadt 1965b859c19Sderaadtov_word_align: 1975b859c19Sderaadt mov r1,r0 1985b859c19Sderaadt tst #1,r0 1995b859c19Sderaadt bf/s ov_no_align_delay 2005b859c19Sderaadt tst REG_LEN,REG_LEN /* if ( len == 0 ) return; */ 2015b859c19Sderaadt bt bcopy_return 2025b859c19Sderaadt 2035b859c19Sderaadt 2045b859c19Sderaadt mov REG_SRC,r0 /* if ( src & 1 ) */ 2055b859c19Sderaadt tst #1,r0 2065b859c19Sderaadt bt 1f 2075b859c19Sderaadt add #-1,REG_SRC 2085b859c19Sderaadt mov.b @REG_SRC,r0 /* *--dst = *--src; */ 2095b859c19Sderaadt add #-1,REG_LEN 2105b859c19Sderaadt mov.b r0,@-REG_DST 2115b859c19Sderaadt1: 2125b859c19Sderaadt 2135b859c19Sderaadt 2145b859c19Sderaadt mov #1,r1 2155b859c19Sderaadt cmp/hi r1,REG_LEN /* while ( len > 1 ) { */ 2165b859c19Sderaadt bf/s ov_no_align_delay 2175b859c19Sderaadt tst REG_LEN,REG_LEN 2185b859c19Sderaadt2: 2195b859c19Sderaadt add #-2,REG_SRC 2205b859c19Sderaadt mov.w @REG_SRC,r0 /* *--((unsigned short*)dst) = *--((unsigned short*)src); */ 2215b859c19Sderaadt add #-2,REG_LEN /* len -= 2; */ 2225b859c19Sderaadt cmp/hi r1,REG_LEN 2235b859c19Sderaadt bt/s 2b 2245b859c19Sderaadt mov.w r0,@-REG_DST /* } */ 2255b859c19Sderaadt 2265b859c19Sderaadt 2275b859c19Sderaadtov_no_align: 2285b859c19Sderaadt tst REG_LEN,REG_LEN /* while ( len!= ) { */ 2295b859c19Sderaadtov_no_align_delay: 2305b859c19Sderaadt bt 9f 2315b859c19Sderaadt1: 2325b859c19Sderaadt add #-1,REG_SRC 2335b859c19Sderaadt mov.b @REG_SRC,r0 /* *--dst = *--src; */ 2345b859c19Sderaadt add #-1,REG_LEN /* len--; */ 2355b859c19Sderaadt tst REG_LEN,REG_LEN 2365b859c19Sderaadt bf/s 1b 2375b859c19Sderaadt mov.b r0,@-REG_DST /* } */ 2385b859c19Sderaadt9: 2395b859c19Sderaadt rts 2405b859c19Sderaadt nop 241*9b9d2a55SguentherEND_WEAK(bcopy) 242