Home | History | Annotate | Line # | Download | only in string
bcopy.S revision 1.1
      1 /*	$NetBSD: bcopy.S,v 1.1 2002/11/20 14:23:54 itohy Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2000 SHIMIZU Ryo <ryo (at) misakimix.org>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. The name of the author may not be used to endorse or promote products
     16  *    derived from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include <machine/asm.h>
     31 
     32 #if defined(LIBC_SCCS) && !defined(lint)
     33 	RCSID("$NetBSD: bcopy.S,v 1.1 2002/11/20 14:23:54 itohy Exp $")
     34 #endif
     35 
     36 #if defined(MEMCOPY) || defined(MEMMOVE)
     37 #define	REG_DST0	r3
     38 #define	REG_SRC		r5
     39 #define	REG_DST		r4
     40 #else
     41 #define	REG_SRC		r4
     42 #define	REG_DST		r5
     43 #endif
     44 
     45 #define	REG_LEN		r6
     46 
     47 #ifdef MEMCOPY
     48 ENTRY(memcpy)
     49 #else
     50 #ifdef MEMMOVE
     51 ENTRY(memmove)
     52 #else
     53 ENTRY(bcopy)
     54 #endif
     55 #endif
     56 #ifdef REG_DST0
     57 	mov	REG_DST,REG_DST0
     58 #endif
     59 	cmp/eq	REG_DST,REG_SRC	/* if ( src == dst ) return; */
     60 	bt/s	bcopy_return
     61 	cmp/hi	REG_DST,REG_SRC
     62 	bf/s	bcopy_overlap
     63 
     64 	mov	REG_SRC,r0
     65 	xor	REG_DST,r0
     66 	and	#3,r0
     67 	mov	r0,r1
     68 	tst	r0,r0		/* (src ^ dst) & 3         */
     69 	bf/s	word_align
     70 
     71 longword_align:
     72 	tst	REG_LEN,REG_LEN	/* if ( len==0 ) return;   */
     73 	bt/s	bcopy_return
     74 
     75 
     76 	mov	REG_SRC,r0
     77 	tst	#1,r0		/* if ( src & 1 )          */
     78 	bt	1f
     79 	mov.b	@REG_SRC+,r0	/*    *dst++ = *src++;     */
     80 	add	#-1,REG_LEN
     81 	mov.b	r0,@REG_DST
     82 	add	#1,REG_DST
     83 1:
     84 
     85 
     86 	mov	#1,r0
     87 	cmp/hi	r0,REG_LEN	/* if ( (len > 1) &&       */
     88 	bf/s	1f
     89 	mov	REG_SRC,r0
     90 	tst	#2,r0		/*      (src & 2) {        */
     91 	bt	1f
     92 	mov.w	@REG_SRC+,r0	/*        *((unsigned short*)dst)++ = *((unsigned short*)src)++; */
     93 	add	#-2,REG_LEN	/*        len -= 2;                                              */
     94 	mov.w	r0,@REG_DST
     95 	add	#2,REG_DST	/* }                       */
     96 1:
     97 
     98 
     99 	mov	#3,r1
    100 	cmp/hi	r1,REG_LEN	/* while ( len > 3 ) {     */
    101 	bf/s	no_align_delay
    102 	tst	REG_LEN,REG_LEN
    103 2:
    104 	mov.l	@REG_SRC+,r0	/*   *((unsigned long*)dst)++ = *((unsigned long*)src)++;        */
    105 	add	#-4,REG_LEN	/*   len -= 4;                                                   */
    106 	mov.l	r0,@REG_DST
    107 	cmp/hi	r1,REG_LEN
    108 	bt/s	2b
    109 	add	#4,REG_DST	/* }                       */
    110 
    111 	bra	no_align_delay
    112 	tst	REG_LEN,REG_LEN
    113 
    114 
    115 word_align:
    116 	mov	r1,r0
    117 	tst	#1,r0
    118 	bf/s	no_align_delay
    119 	tst	REG_LEN,REG_LEN	/* if ( len == 0 ) return; */
    120 	bt	bcopy_return
    121 
    122 
    123 	mov	REG_SRC,r0	/* if ( src & 1 )          */
    124 	tst	#1,r0
    125 	bt	1f
    126 	mov.b	@REG_SRC+,r0	/*    *dst++ = *src++;     */
    127 	add	#-1,REG_LEN
    128 	mov.b	r0,@REG_DST
    129 	add	#1,REG_DST
    130 1:
    131 
    132 
    133 	mov	#1,r1
    134 	cmp/hi	r1,REG_LEN	/* while ( len > 1 ) {     */
    135 	bf/s	no_align_delay
    136 	tst	REG_LEN,REG_LEN
    137 2:
    138 	mov.w	@REG_SRC+,r0	/*   *((unsigned short*)dst)++ = *((unsigned short*)src)++;      */
    139 	add	#-2,REG_LEN	/*   len -= 2;                                                   */
    140 	mov.w	r0,@REG_DST
    141 	cmp/hi	r1,REG_LEN
    142 	bt/s	2b
    143 	add	#2,REG_DST	/* }                       */
    144 
    145 
    146 no_align:
    147 	tst	REG_LEN,REG_LEN	/* while ( len!= ) {       */
    148 no_align_delay:
    149 	bt	bcopy_return
    150 1:
    151 	mov.b	@REG_SRC+,r0	/*    *dst++ = *src++;     */
    152 	add	#-1,REG_LEN	/*    len--;               */
    153 	mov.b	r0,@REG_DST
    154 	tst	REG_LEN,REG_LEN
    155 	bf/s	1b
    156 	add	#1,REG_DST	/* }                       */
    157 bcopy_return:
    158 	rts
    159 #ifdef REG_DST0
    160 	mov	REG_DST0,r0
    161 #else
    162 	nop
    163 #endif
    164 
    165 
    166 bcopy_overlap:
    167 	add	REG_LEN,REG_SRC
    168 	add	REG_LEN,REG_DST
    169 
    170 	mov	REG_SRC,r0
    171 	xor	REG_DST,r0
    172 	and	#3,r0
    173 	mov	r0,r1
    174 	tst	r0,r0		/* (src ^ dst) & 3         */
    175 	bf/s	ov_word_align
    176 
    177 ov_longword_align:
    178 	tst	REG_LEN,REG_LEN	/* if ( len==0 ) return;   */
    179 	bt/s	bcopy_return
    180 
    181 
    182 	mov	REG_SRC,r0
    183 	tst	#1,r0		/* if ( src & 1 )          */
    184 	bt	1f
    185 	add	#-1,REG_SRC	/*    *--dst = *--src;     */
    186 	mov.b	@REG_SRC,r0
    187 	mov.b	r0,@-REG_DST
    188 	add	#-1,REG_LEN
    189 1:
    190 
    191 
    192 	mov	#1,r0
    193 	cmp/hi	r0,REG_LEN	/* if ( (len > 1) &&       */
    194 	bf/s	1f
    195 	mov	REG_SRC,r0
    196 	tst	#2,r0		/*      (src & 2) {        */
    197 	bt	1f
    198 	add	#-2,REG_SRC	/*        *--((unsigned short*)dst) = *--((unsigned short*)src); */
    199 	mov.w	@REG_SRC,r0
    200 	add	#-2,REG_LEN	/*        len -= 2;                                              */
    201 	mov.w	r0,@-REG_DST	/* }                       */
    202 1:
    203 
    204 
    205 	mov	#3,r1
    206 	cmp/hi	r1,REG_LEN	/* while ( len > 3 ) {     */
    207 	bf/s	ov_no_align_delay
    208 	tst	REG_LEN,REG_LEN
    209 2:
    210 	add	#-4,REG_SRC
    211 	mov.l	@REG_SRC,r0	/*   *((unsigned long*)dst)++ = *((unsigned long*)src)++;        */
    212 	add	#-4,REG_LEN	/*   len -= 4;                                                   */
    213 	cmp/hi	r1,REG_LEN
    214 	bt/s	2b
    215 	mov.l	r0,@-REG_DST	/* }                       */
    216 
    217 	bra	ov_no_align_delay
    218 	tst	REG_LEN,REG_LEN
    219 
    220 
    221 ov_word_align:
    222 	mov	r1,r0
    223 	tst	#1,r0
    224 	bf/s	ov_no_align_delay
    225 	tst	REG_LEN,REG_LEN	/* if ( len == 0 ) return; */
    226 	bt	bcopy_return
    227 
    228 
    229 	mov	REG_SRC,r0	/* if ( src & 1 )          */
    230 	tst	#1,r0
    231 	bt	1f
    232 	add	#-1,REG_SRC
    233 	mov.b	@REG_SRC,r0	/*    *--dst = *--src;     */
    234 	add	#-1,REG_LEN
    235 	mov.b	r0,@-REG_DST
    236 1:
    237 
    238 
    239 	mov	#1,r1
    240 	cmp/hi	r1,REG_LEN	/* while ( len > 1 ) {     */
    241 	bf/s	ov_no_align_delay
    242 	tst	REG_LEN,REG_LEN
    243 2:
    244 	add	#-2,REG_SRC
    245 	mov.w	@REG_SRC,r0	/*   *--((unsigned short*)dst) = *--((unsigned short*)src);      */
    246 	add	#-2,REG_LEN	/*   len -= 2;                                                   */
    247 	cmp/hi	r1,REG_LEN
    248 	bt/s	2b
    249 	mov.w	r0,@-REG_DST	/* }                       */
    250 
    251 
    252 ov_no_align:
    253 	tst	REG_LEN,REG_LEN	/* while ( len!= ) {       */
    254 ov_no_align_delay:
    255 	bt	9f
    256 1:
    257 	add	#-1,REG_SRC
    258 	mov.b	@REG_SRC,r0	/*    *--dst = *--src;     */
    259 	add	#-1,REG_LEN	/*    len--;               */
    260 	tst	REG_LEN,REG_LEN
    261 	bf/s	1b
    262 	mov.b	r0,@-REG_DST	/* }                       */
    263 9:
    264 	rts
    265 #ifdef REG_DST0
    266 	mov	REG_DST0,r0
    267 #else
    268 	nop
    269 #endif
    270