xref: /openbsd-src/lib/libc/arch/sh/string/memmove.S (revision 9b9d2a55a62c8e82206c25f94fcc7f4e2765250e)
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