Home | History | Annotate | Download | only in lib
      1 /* $Id: memcpy.S,v 1.3 2001/07/27 11:50:52 gniibe Exp $
      2  *
      3  * "memcpy" implementation of SuperH
      4  *
      5  * Copyright (C) 1999  Niibe Yutaka
      6  *
      7  */
      8 
      9 /*
     10  * void *memcpy(void *dst, const void *src, size_t n);
     11  * No overlap between the memory of DST and of SRC are assumed.
     12  */
     13 
     14 #include <linux/linkage.h>
     15 ENTRY(memcpy)
     16 	tst	r6,r6
     17 	bt/s	9f		! if n=0, do nothing
     18 	 mov	r4,r0
     19 	sub	r4,r5		! From here, r5 has the distance to r0
     20 	add	r6,r0		! From here, r0 points the end of copying point
     21 	mov	#12,r1
     22 	cmp/gt	r6,r1
     23 	bt/s	7f		! if it's too small, copy a byte at once
     24 	 add	#-1,r5
     25 	add	#1,r5
     26 	!			From here, r6 is free
     27 	!
     28 	!      r4   -->  [ ...  ] DST             [ ...  ] SRC
     29 	!	         [ ...  ]                 [ ...  ]
     30 	!	           :                        :
     31 	!      r0   -->  [ ...  ]       r0+r5 --> [ ...  ]
     32 	!
     33 	!
     34 	mov	r5,r1
     35 	mov	#3,r2
     36 	and	r2,r1
     37 	shll2	r1
     38 	mov	r0,r3		! Save the value on R0 to R3
     39 	mova	jmptable,r0
     40 	add	r1,r0
     41 	mov.l	@r0,r1
     42 	jmp	@r1
     43 	 mov	r3,r0		! and back to R0
     44 	.balign	4
     45 jmptable:
     46 	.long	case0
     47 	.long	case1
     48 	.long	case2
     49 	.long	case3
     50 
     51 	! copy a byte at once
     52 7:	mov	r4,r2
     53 	add	#1,r2
     54 8:
     55 	cmp/hi	r2,r0
     56 	mov.b	@(r0,r5),r1
     57 	bt/s	8b			! while (r0>r2)
     58 	 mov.b	r1,@-r0
     59 9:
     60 	rts
     61 	 nop
     62 
     63 case0:
     64 	!
     65 	!	GHIJ KLMN OPQR -->  GHIJ KLMN OPQR
     66 	!
     67 	! First, align to long word boundary
     68 	mov	r0,r3
     69 	and	r2,r3
     70 	tst	r3,r3
     71 	bt/s	2f
     72 	 add	#-4,r5
     73 	add	#3,r5
     74 1:	dt	r3
     75 	mov.b	@(r0,r5),r1
     76 	bf/s	1b
     77 	 mov.b	r1,@-r0
     78 	!
     79 	add	#-3,r5
     80 2:	! Second, copy a long word at once
     81 	mov	r4,r2
     82 	add	#7,r2
     83 3:	mov.l	@(r0,r5),r1
     84 	cmp/hi	r2,r0
     85 	bt/s	3b
     86 	 mov.l	r1,@-r0
     87 	!
     88 	! Third, copy a byte at once, if necessary
     89 	cmp/eq	r4,r0
     90 	bt/s	9b
     91 	 add	#3,r5
     92 	bra	8b
     93 	 add	#-6,r2
     94 
     95 case1:
     96 	!
     97 	!	GHIJ KLMN OPQR -->  ...G HIJK LMNO PQR.
     98 	!
     99 	! First, align to long word boundary
    100 	mov	r0,r3
    101 	and	r2,r3
    102 	tst	r3,r3
    103 	bt/s	2f
    104 	 add	#-1,r5
    105 1:	dt	r3
    106 	mov.b	@(r0,r5),r1
    107 	bf/s	1b
    108 	 mov.b	r1,@-r0
    109 	!
    110 2:	! Second, read a long word and write a long word at once
    111 	mov.l	@(r0,r5),r1
    112 	add	#-4,r5
    113 	mov	r4,r2
    114 	add	#7,r2
    115 	!
    116 #ifdef __LITTLE_ENDIAN__
    117 3:	mov	r1,r3		! RQPO
    118 	shll16	r3
    119 	shll8	r3		! Oxxx
    120 	mov.l	@(r0,r5),r1	! NMLK
    121 	mov	r1,r6
    122 	shlr8	r6		! xNML
    123 	or	r6,r3		! ONML
    124 	cmp/hi	r2,r0
    125 	bt/s	3b
    126 	 mov.l	r3,@-r0
    127 #else
    128 3:	mov	r1,r3		! OPQR
    129 	shlr16	r3
    130 	shlr8	r3		! xxxO
    131 	mov.l	@(r0,r5),r1	! KLMN
    132 	mov	r1,r6
    133 	shll8	r6		! LMNx
    134 	or	r6,r3		! LMNO
    135 	cmp/hi	r2,r0
    136 	bt/s	3b
    137 	 mov.l	r3,@-r0
    138 #endif
    139 	!
    140 	! Third, copy a byte at once, if necessary
    141 	cmp/eq	r4,r0
    142 	bt/s	9b
    143 	 add	#4,r5
    144 	bra	8b
    145 	 add	#-6,r2
    146 
    147 case2:
    148 	!
    149 	!	GHIJ KLMN OPQR -->  ..GH IJKL MNOP QR..
    150 	!
    151 	! First, align to word boundary
    152 	tst	#1,r0
    153 	bt/s	2f
    154 	 add	#-1,r5
    155 	mov.b	@(r0,r5),r1
    156 	mov.b	r1,@-r0
    157 	!
    158 2:	! Second, read a word and write a word at once
    159 	add	#-1,r5
    160 	mov	r4,r2
    161 	add	#3,r2
    162 	!
    163 3:	mov.w	@(r0,r5),r1
    164 	cmp/hi	r2,r0
    165 	bt/s	3b
    166 	 mov.w	r1,@-r0
    167 	!
    168 	! Third, copy a byte at once, if necessary
    169 	cmp/eq	r4,r0
    170 	bt/s	9b
    171 	 add	#1,r5
    172 	mov.b	@(r0,r5),r1
    173 	rts
    174 	 mov.b	r1,@-r0
    175 
    176 case3:
    177 	!
    178 	!	GHIJ KLMN OPQR -->  .GHI JKLM NOPQ R...
    179 	!
    180 	! First, align to long word boundary
    181 	mov	r0,r3
    182 	and	r2,r3
    183 	tst	r3,r3
    184 	bt/s	2f
    185 	 add	#-1,r5
    186 1:	dt	r3
    187 	mov.b	@(r0,r5),r1
    188 	bf/s	1b
    189 	 mov.b	r1,@-r0
    190 	!
    191 2:	! Second, read a long word and write a long word at once
    192 	add	#-2,r5
    193 	mov.l	@(r0,r5),r1
    194 	add	#-4,r5
    195 	mov	r4,r2
    196 	add	#7,r2
    197 	!
    198 #ifdef __LITTLE_ENDIAN__
    199 3:	mov	r1,r3		! RQPO
    200 	shll8	r3		! QPOx
    201 	mov.l	@(r0,r5),r1	! NMLK
    202 	mov	r1,r6
    203 	shlr16	r6
    204 	shlr8	r6		! xxxN
    205 	or	r6,r3		! QPON
    206 	cmp/hi	r2,r0
    207 	bt/s	3b
    208 	 mov.l	r3,@-r0
    209 #else
    210 3:	mov	r1,r3		! OPQR
    211 	shlr8	r3		! xOPQ
    212 	mov.l	@(r0,r5),r1	! KLMN
    213 	mov	r1,r6
    214 	shll16	r6
    215 	shll8	r6		! Nxxx
    216 	or	r6,r3		! NOPQ
    217 	cmp/hi	r2,r0
    218 	bt/s	3b
    219 	 mov.l	r3,@-r0
    220 #endif
    221 	!
    222 	! Third, copy a byte at once, if necessary
    223 	cmp/eq	r4,r0
    224 	bt/s	9b
    225 	 add	#6,r5
    226 	bra	8b
    227 	 add	#-6,r2
    228