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