1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 by Jens Arnold
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 .section .icode,"ax",@progbits
25 #define FULLSPEED /* use burst writing for word aligned destinations */
28 .type memmove,@function
30 /* Moves <length> bytes of data in memory from <source> to <dest>
31 * Regions may overlap.
32 * This version is optimized for speed, and needs the corresponding memcpy
33 * implementation for the forward copy branch.
36 * (4,%sp) - destination address
37 * (8,%sp) - source address
41 * %d0 - destination address (like ANSI version)
44 * %a0 - current source address
45 * %a1 - current dest address
46 * %a2 - source start address (in line-copy loops)
47 * %d0 - source start address (byte and longword copy) / data / scratch
48 * %d1 - data / scratch
49 * %d2 - data / scratch
52 * For maximum speed this routine reads and writes whole lines using burst
53 * move (movem.l) where possible. For byte aligned destinations (long-1 and
54 * long-3) it writes longwords only. Same goes for word aligned destinations
55 * if FULLSPEED is undefined.
58 move.l (4,%sp),%a1 /* Destination */
59 move.l (8,%sp),%a0 /* Source */
60 move.l (12,%sp),%d1 /* Length */
63 bhi.b .backward /* dest > src -> backward copy */
64 jmp __memcpy_fwd_entry
67 move.l %a0,%d0 /* %d0 = source start */
68 add.l %d1,%a0 /* %a0 = source end */
69 add.l %d1,%a1 /* %a1 = destination end */
72 and.l #0xFFFFFFFC,%d1 /* %d1 = last source long bound */
74 cmp.l %d0,%d1 /* at least one aligned longword to copy? */
77 addq.l #4,%d1 /* %d1 = last source long bound */
78 cmp.l %d1,%a0 /* any bytes to copy */
79 jls .bytes1r_end /* no: skip byte loop */
81 /* leading byte loop: copies 0..3 bytes */
83 move.b -(%a0),-(%a1) /* copy byte */
84 cmp.l %d1,%a0 /* runs %a0 down to last long bound */
90 and.l #0xFFFFFFF0,%d1 /* %d1 = last source line bound - 16 */
91 cmp.l %d0,%d1 /* at least one aligned line to copy? */
92 blo.w .longr_start /* no: jump to longword copy loop */
94 lea.l (-28,%sp),%sp /* free up some registers */
95 movem.l %d2-%d7/%a2,(%sp)
98 add.l %d2,%d1 /* %d1 = last source line bound */
99 move.l %d0,%a2 /* %a2 = start address */
100 lea.l (15,%a2),%a2 /* adjust start address for loops doing 16 bytes/pass */
102 moveq.l #3,%d2 /* mask */
104 jmp.l (2,%pc,%d0.l*4) /* switch (dest_addr & 3) */
105 bra.w .lines_do0r_start
106 bra.w .lines_do1r_start
107 bra.w .lines_do2r_start
108 /* bra.w .lines_do3r_start implicit */
110 /* byte aligned destination (long - 1): use line burst reads in main loop */
112 moveq.l #24,%d0 /* shift count for shifting by 3 bytes */
113 cmp.l %d1,%a0 /* any leading longwords? */
114 jhi .lines_do3r_head_start /* yes: leading longword copy */
117 movem.l (%a0),%d3-%d6 /* load initial line */
118 move.l %d6,%d2 /* last longword, bytes 3210 */
119 move.b %d2,-(%a1) /* store byte */
120 lsr.l #8,%d2 /* last longword, bytes .321 */
121 move.w %d2,-(%a1) /* store word */
122 jra .lines_do3r_entry
124 .lines_do3r_head_start:
125 move.l -(%a0),%d3 /* load initial longword */
126 move.l %d3,%d2 /* bytes 3210 */
127 move.b %d2,-(%a1) /* store byte */
128 lsr.l #8,%d2 /* bytes .321 */
129 move.w %d2,-(%a1) /* store word */
130 jra .lines_do3r_head_entry
132 .lines_do3r_head_loop:
133 move.l %d3,%d4 /* move old longword away */
134 move.l -(%a0),%d3 /* load new longword */
136 lsl.l #8,%d2 /* get bytes 210. */
137 or.l %d2,%d4 /* combine with old high byte */
138 move.l %d4,-(%a1) /* store longword */
139 .lines_do3r_head_entry:
140 lsr.l %d0,%d3 /* shift down high byte */
141 cmp.l %d1,%a0 /* run %a0 down to last line bound */
142 jhi .lines_do3r_head_loop
145 move.l %d3,%d7 /* move first longword of last line away */
147 movem.l (%a0),%d3-%d6 /* load new line */
149 lsl.l #8,%d2 /* get bytes 210. of 4th longword */
150 or.l %d2,%d7 /* combine with high byte of old longword */
151 move.l %d7,-(%a1) /* store longword */
153 lsr.l %d0,%d6 /* shift down high byte */
155 lsl.l #8,%d2 /* get bytes 210. of 3rd longword */
156 or.l %d2,%d6 /* combine with high byte of 4th longword */
157 move.l %d6,-(%a1) /* store longword */
158 lsr.l %d0,%d5 /* shift down high byte */
160 lsl.l #8,%d2 /* get bytes 210. of 2nd longword */
161 or.l %d2,%d5 /* combine with high byte or 3rd longword */
162 move.l %d5,-(%a1) /* store longword */
163 lsr.l %d0,%d4 /* shift down high byte */
165 lsl.l #8,%d2 /* get bytes 210. of 1st longword */
166 or.l %d2,%d4 /* combine with high byte of 2nd longword */
167 move.l %d4,-(%a1) /* store longword */
168 lsr.l %d0,%d3 /* shift down high byte */
169 cmp.l %a2,%a0 /* run %a0 down to first line bound */
172 lea.l (-12,%a2),%a2 /* readjust start address for doing longwords */
173 cmp.l %a2,%a0 /* any trailing longwords? */
174 jls .lines_do3r_tail_end /* no: just store last high byte */
176 .lines_do3r_tail_loop:
177 move.l %d3,%d4 /* move old longword away */
178 move.l -(%a0),%d3 /* load new longword */
180 lsl.l #8,%d2 /* get bytes 210. */
181 or.l %d2,%d4 /* combine with old high byte */
182 move.l %d4,-(%a1) /* store longword */
183 lsr.l %d0,%d3 /* shift down high byte */
184 cmp.l %a2,%a0 /* run %a0 down to first long bound */
185 jhi .lines_do3r_tail_loop
187 .lines_do3r_tail_end:
188 move.b %d3,-(%a1) /* store shifted-down high byte */
191 /* byte aligned destination (long - 3): use line burst reads in main loop */
193 moveq.l #24,%d0 /* shift count for shifting by 3 bytes */
194 cmp.l %d1,%a0 /* any leading longwords? */
195 jhi .lines_do1r_head_start /* yes: leading longword copy */
198 movem.l (%a0),%d3-%d6 /* load initial line */
199 move.b %d6,-(%a1) /* store low byte of last longword */
200 jra .lines_do1r_entry
202 .lines_do1r_head_start:
203 move.l -(%a0),%d3 /* load initial longword */
204 move.b %d3,-(%a1) /* store low byte */
205 jra .lines_do1r_head_entry
207 .lines_do1r_head_loop:
208 move.l %d3,%d4 /* move old longword away */
209 move.l -(%a0),%d3 /* load new longword */
211 lsl.l %d0,%d2 /* get low byte */
212 or.l %d2,%d4 /* combine with old bytes .321 */
213 move.l %d4,-(%a1) /* store longword */
214 .lines_do1r_head_entry:
215 lsr.l #8,%d3 /* get bytes .321 */
216 cmp.l %d1,%a0 /* run %a0 down to last line bound */
217 jhi .lines_do1r_head_loop
220 move.l %d3,%d7 /* move first longword of old line away */
222 movem.l (%a0),%d3-%d6 /* load new line */
224 lsl.l %d0,%d2 /* get low byte of 4th longword */
225 or.l %d2,%d7 /* combine with bytes .321 of old longword */
226 move.l %d7,-(%a1) /* store longword */
228 lsr.l #8,%d6 /* get bytes .321 */
230 lsl.l %d0,%d2 /* get low byte of 3rd longword */
231 or.l %d2,%d6 /* combine with bytes .321 of 4th longword */
232 move.l %d6,-(%a1) /* store longword */
233 lsr.l #8,%d5 /* get bytes .321 */
235 lsl.l %d0,%d2 /* get low byte of 2nd longword */
236 or.l %d2,%d5 /* combine with bytes .321 of 3rd longword */
237 move.l %d5,-(%a1) /* store longword */
238 lsr.l #8,%d4 /* get bytes .321 */
240 lsl.l %d0,%d2 /* get low byte of 1st longword */
241 or.l %d2,%d4 /* combine with bytes .321 of 2nd longword */
242 move.l %d4,-(%a1) /* store longword */
243 lsr.l #8,%d3 /* get bytes .321 */
244 cmp.l %a2,%a0 /* run %a0 down to first line bound */
247 lea.l (-12,%a2),%a2 /* readjust start address for doing longwords */
248 cmp.l %a2,%a0 /* any trailing longwords? */
249 jls .lines_do1r_tail_end /* no: just store last high byte */
251 .lines_do1r_tail_loop:
252 move.l %d3,%d4 /* move old longword away */
253 move.l -(%a0),%d3 /* load new longword */
255 lsl.l %d0,%d2 /* get low byte */
256 or.l %d2,%d4 /* combine with old bytes .321 */
257 move.l %d4,-(%a1) /* store longword */
258 lsr.l #8,%d3 /* get bytes .321 */
259 cmp.l %a2,%a0 /* run %a0 down to first long bound */
260 jhi .lines_do1r_tail_loop
262 .lines_do1r_tail_end:
263 move.w %d3,-(%a1) /* store word 21 */
265 move.b %d3,-(%a1) /* store byte 3 */
268 /* long aligned destination (line - 0/4/8/12): head */
269 .lines_do0r_head_loop:
270 move.l -(%a0),-(%a1) /* copy longword */
272 cmp.l %d1,%a0 /* run %a0 down to last line bound */
273 jhi .lines_do0r_head_loop
275 .lines_do0r_head_end:
278 moveq.l #3,%d0 /* mask */
280 moveq.l #16,%d0 /* address decrement for one main loop pass */
281 jmp.l (2,%pc,%d1.l*2) /* switch ((dest_addr >> 2) & 3) */
282 bra.b .lines_lo0r_start
283 bra.b .lines_lo4r_start
284 bra.b .lines_lo8r_start
285 /* bra.b .lines_lo12r_start implicit */
287 /* long aligned destination (line - 4): use line bursts in the loop */
290 movem.l (%a0),%d1-%d4 /* load initial line */
291 move.l %d4,-(%a1) /* store 4th longword */
292 move.l %d3,-(%a1) /* store 3rd longword */
293 move.l %d2,-(%a1) /* store 2nd longword */
294 cmp.l %a2,%a0 /* any full lines? */
295 jls .lines_lo12r_end /* no: skip main loop */
298 move.l %d1,%d5 /* move first longword of old line away */
300 movem.l (%a0),%d1-%d4 /* load new line */
302 movem.l %d2-%d5,(%a1) /* store line (1 old + 3 new longwords */
303 cmp.l %a2,%a0 /* run %a0 down to first line bound */
304 jhi .lines_lo12r_loop
306 jra .lines_lo12r_end /* handle trailing longwords */
308 /* line aligned destination: use line bursts in the loop */
312 movem.l (%a0),%d1-%d4 /* load line */
314 movem.l %d1-%d4,(%a1) /* store line */
315 cmp.l %a2,%a0 /* run %a0 down to first line bound */
318 jra .lines_lo0r_end /* handle trailing longwords */
320 /* long aligned destination (line - 8): use line bursts in the loop */
323 movem.l (%a0),%d1-%d4 /* load initial line */
324 move.l %d4,-(%a1) /* store 4th longword */
325 move.l %d3,-(%a1) /* store 3rd longword */
326 cmp.l %a2,%a0 /* any full lines? */
327 jls .lines_lo8r_end /* no: skip main loop */
330 move.l %d2,%d6 /* move first 2 longwords of old line away */
333 movem.l (%a0),%d1-%d4 /* load new line */
335 movem.l %d3-%d6,(%a1) /* store line (2 old + 2 new longwords */
336 cmp.l %a2,%a0 /* run %a0 down to first line bound */
339 jra .lines_lo8r_end /* handle trailing longwords */
341 /* long aligned destination (line - 12): use line bursts in the loop */
344 movem.l (%a0),%d1-%d4 /* load initial line */
345 move.l %d4,-(%a1) /* store 4th longword */
346 cmp.l %a2,%a0 /* any full lines? */
347 jls .lines_lo4r_end /* no: skip main loop */
350 move.l %d3,%d7 /* move first 3 longwords of old line away */
354 movem.l (%a0),%d1-%d4 /* load new line */
356 movem.l %d4-%d7,(%a1) /* store line (3 old + 1 new longwords */
357 cmp.l %a2,%a0 /* run %a0 down to first line bound */
360 /* long aligned destination (line - 0/4/8/12): tail */
362 move.l %d3,-(%a1) /* store 3rd last longword */
364 move.l %d2,-(%a1) /* store 2nd last longword */
366 move.l %d1,-(%a1) /* store last longword */
368 lea.l (-12,%a2),%a2 /* readjust end address for doing longwords */
369 cmp.l %a2,%a0 /* any trailing longwords? */
370 jls .linesr_end /* no: get outta here */
372 .lines_do0r_tail_loop:
373 move.l -(%a0),-(%a1) /* copy longword */
374 cmp.l %a2,%a0 /* run %a0 down to first long bound */
375 jhi .lines_do0r_tail_loop
380 /* word aligned destination (line - 2/6/10/14): head */
382 cmp.l %d1,%a0 /* any leading longwords? */
383 jls .lines_do2r_selector /* no: jump to mainloop selector */
385 move.l -(%a0),%d3 /* load initial longword */
386 move.w %d3,-(%a1) /* store low word */
387 cmp.l %d1,%a0 /* any more longwords? */
388 jls .lines_do2r_head_end /* no: skip head loop */
390 .lines_do2r_head_loop:
391 move.l %d3,%d4 /* move old longword away */
392 move.l -(%a0),%d3 /* load new longword */
393 move.w %d3,%d4 /* combine low word with old high word */
394 swap %d4 /* swap words */
395 move.l %d4,-(%a1) /* store longword */
396 cmp.l %d1,%a0 /* run %a0 down to last line bound */
397 jhi .lines_do2r_head_loop
399 .lines_do2r_head_end:
400 swap %d3 /* get high word */
401 move.w %d3,-(%a1) /* and store it */
403 .lines_do2r_selector:
406 moveq.l #3,%d0 /* mask */
408 moveq.l #16,%d7 /* address decrement for one main loop pass */
409 jmp.l (2,%pc,%d1.l*4) /* switch ((dest_addr >> 2) & 3) */
410 bra.w .lines_lo2r_start
411 bra.w .lines_lo6r_start
412 bra.w .lines_lo10r_start
413 /* bra.w .lines_lo14r_start implicit */
415 /* word aligned destination (line - 2): use line bursts in the loop */
418 movem.l (%a0),%d0-%d3 /* load initial line */
419 move.w %d3,-(%a1) /* store last low word */
420 move.w %d2,%d3 /* combine 3rd low word with 4th high word */
421 swap %d3 /* swap words of 3rd long */
422 move.w %d1,%d2 /* combine 2nd low word with 3rd high word */
423 swap %d2 /* swap words of 2nd long */
424 move.w %d0,%d1 /* combine 1st low word with 2nd high word */
425 swap %d1 /* swap words of 1st long */
426 move.l %d3,-(%a1) /* store 3rd longword */
427 move.l %d2,-(%a1) /* store 2nd longword */
428 move.l %d1,-(%a1) /* store 1st longword */
429 cmp.l %a2,%a0 /* any full lines? */
430 jls .lines_lo14r_end /* no: skip main loop */
433 move.l %d0,%d4 /* move first longword of old line away */
435 movem.l (%a0),%d0-%d3 /* load line */
436 move.w %d3,%d4 /* combine 4th low word with old high word */
437 swap %d4 /* swap words of 4th long */
438 move.w %d2,%d3 /* combine 3rd low word with 4th high word */
439 swap %d3 /* swap words of 3rd long */
440 move.w %d1,%d2 /* combine 2nd low word with 3rd high word */
441 swap %d2 /* swap words of 2nd long */
442 move.w %d0,%d1 /* combine 1st low word with 2nd high word */
443 swap %d1 /* swap words of 1st long */
445 movem.l %d1-%d4,(%a1) /* store line */
446 cmp.l %a2,%a0 /* run %a0 down to first line bound */
447 jhi .lines_lo14r_loop
449 jra .lines_lo14r_end /* handle trailing longwords */
451 /* word aligned destination (line - 6): use line bursts in the loop */
454 movem.l (%a0),%d0-%d3 /* load initial line */
455 move.w %d3,-(%a1) /* store last low word */
456 move.w %d2,%d3 /* combine 3rd low word with 4th high word */
457 swap %d3 /* swap words of 3rd long */
458 move.w %d1,%d2 /* combine 2nd low word with 3rd high word */
459 swap %d2 /* swap words of 2nd long */
460 move.l %d3,-(%a1) /* store 3rd longword */
461 move.l %d2,-(%a1) /* store 2nd longword */
462 jra .lines_lo10r_entry /* jump into main loop */
465 move.l %d0,%d4 /* move first 2 longwords of old line away */
468 movem.l (%a0),%d0-%d3 /* load line */
469 move.w %d3,%d4 /* combine 4th low word with old high word */
470 swap %d4 /* swap words of 4th long */
471 move.w %d2,%d3 /* combine 3rd low word with 4th high word */
472 swap %d3 /* swap words of 3rd long */
473 move.w %d1,%d2 /* combine 2nd low word with 3rd high word */
474 swap %d2 /* swap words of 2nd long */
476 movem.l %d2-%d5,(%a1) /* store line */
478 move.w %d0,%d1 /* combine 1st low word with 2nd high word */
479 swap %d1 /* swap words of 1st long */
480 cmp.l %a2,%a0 /* run %a0 down to first line bound */
481 jhi .lines_lo10r_loop
483 jra .lines_lo10r_end /* handle trailing longwords */
485 /* word aligned destination (line - 10): use line bursts in the loop */
488 movem.l (%a0),%d0-%d3 /* load initial line */
489 move.w %d3,-(%a1) /* store last low word */
490 move.w %d2,%d3 /* combine 3rd low word with 4th high word */
491 swap %d3 /* swap words of 3rd long */
492 move.l %d3,-(%a1) /* store 3rd longword */
493 jra .lines_lo6r_entry /* jump into main loop */
496 move.l %d0,%d4 /* move first 3 longwords of old line away */
500 movem.l (%a0),%d0-%d3 /* load line */
501 move.w %d3,%d4 /* combine 4th low word with old high word */
502 swap %d4 /* swap words of 4th long */
503 move.w %d2,%d3 /* combine 3rd low word with 4th high word */
504 swap %d3 /* swap words of 3rd long */
506 movem.l %d3-%d6,(%a1) /* store line */
508 move.w %d1,%d2 /* combine 2nd low word with 3rd high word */
509 swap %d2 /* swap words of 2nd long */
510 move.w %d0,%d1 /* combine 1st low word with 2nd high word */
511 swap %d1 /* swap words of 1st long */
512 cmp.l %a2,%a0 /* run %a0 down to first line bound */
515 jra .lines_lo6r_end /* handle trailing longwords */
517 /* word aligned destination (line - 14): use line bursts in the loop */
520 movem.l (%a0),%d0-%d3 /* load initial line */
521 move.w %d3,-(%a1) /* store last low word */
522 jra .lines_lo2r_entry /* jump into main loop */
525 move.l %d0,%d4 /* move old line away */
530 movem.l (%a0),%d0-%d3 /* load line */
531 move.w %d3,%d4 /* combine 4th low word with old high word */
532 swap %d4 /* swap words of 4th long */
534 movem.l %d4-%d7,(%a1) /* store line */
536 move.w %d2,%d3 /* combine 3rd low word with 4th high word */
537 swap %d3 /* swap words of 3rd long */
538 move.w %d1,%d2 /* combine 2nd low word with 3rd high word */
539 swap %d2 /* swap words of 2nd long */
540 move.w %d0,%d1 /* combine 1st low word with 2nd high word */
541 swap %d1 /* swap words of 1st long */
542 cmp.l %a2,%a0 /* run %a0 down to first line bound */
545 /* word aligned destination (line - 2/6/10/14): tail */
547 move.l %d3,-(%a1) /* store third last longword */
549 move.l %d2,-(%a1) /* store second last longword */
551 move.l %d1,-(%a1) /* store last longword */
553 lea.l (-12,%a2),%a2 /* readjust start address for doing longwords */
554 cmp.l %a2,%a0 /* any trailing longwords? */
555 jls .lines_do2r_tail_end /* no: skip tail loop */
557 .lines_do2r_tail_loop:
558 move.l %d0,%d1 /* move old longword away */
559 move.l -(%a0),%d0 /* load new longword */
560 move.w %d0,%d1 /* combine low word with old high word */
561 swap %d1 /* swap words */
562 move.l %d1,-(%a1) /* store longword */
563 cmp.l %a2,%a0 /* run %a0 down to first long bound */
564 jhi .lines_do2r_tail_loop
566 .lines_do2r_tail_end:
567 swap %d0 /* get final high word */
568 move.w %d0,-(%a1) /* store it */
569 /* jra .linesr_end implicit */
571 #else /* !FULLSPEED */
573 /* word aligned destination (long - 2): use line burst reads in the loop */
575 cmp.l %d1,%a0 /* any leading longwords? */
576 jhi .lines_do2r_head_start /* yes: leading longword copy */
579 movem.l (%a0),%d3-%d6 /* load initial line */
580 move.w %d6,-(%a1) /* store last low word */
581 jra .lines_do2r_entry /* jump into main loop */
583 .lines_do2r_head_start:
584 move.l -(%a0),%d3 /* load initial longword */
585 move.w %d3,-(%a1) /* store low word */
586 cmp.l %d1,%a0 /* any full longword? */
587 jls .lines_do2r_loop /* no: skip head loop */
589 .lines_do2r_head_loop:
590 move.l %d3,%d4 /* move old longword away */
591 move.l -(%a0),%d3 /* load new longword */
592 move.w %d3,%d4 /* combine low word with old high word */
593 swap %d4 /* swap words */
594 move.l %d4,-(%a1) /* store longword */
595 cmp.l %d1,%a0 /* run %a0 down to last line bound */
596 jhi .lines_do2r_head_loop
599 move.l %d3,%d7 /* move first longword of old line away */
601 movem.l (%a0),%d3-%d6 /* load line */
602 move.w %d6,%d7 /* combine 4th low word with old high word */
603 swap %d7 /* swap words of 4th long */
604 move.l %d7,-(%a1) /* store 4th longword */
606 move.w %d5,%d6 /* combine 3rd low word with 4th high word */
607 swap %d6 /* swap words of 3rd long */
608 move.l %d6,-(%a1) /* store 3rd longword */
609 move.w %d4,%d5 /* combine 2nd low word with 3rd high word */
610 swap %d5 /* swap words of 2nd long */
611 move.l %d5,-(%a1) /* store 2nd longword */
612 move.w %d3,%d4 /* combine 1st low word with 2nd high word */
613 swap %d4 /* swap words of 1st long */
614 move.l %d4,-(%a1) /* store 1st longword */
615 cmp.l %a2,%a0 /* run %a0 down to first line bound */
619 lea.l (-12,%a2),%a2 /* readjust start address for doing longwords */
620 cmp.l %a2,%a0 /* any trailing longwords? */
621 jls .lines_do2r_tail_end /* no: skip tail loop */
623 .lines_do2r_tail_loop:
624 move.l %d3,%d4 /* move old longword away */
625 move.l -(%a0),%d3 /* load new longword */
626 move.w %d3,%d4 /* combine low word with old high word */
627 swap %d4 /* swap words */
628 move.l %d4,-(%a1) /* store longword */
629 cmp.l %a2,%a0 /* run %a0 down to first long bound */
630 jhi .lines_do2r_tail_loop
632 .lines_do2r_tail_end:
633 swap %d3 /* get final high word */
634 move.w %d3,-(%a1) /* store it */
635 /* jra .linesr_end implicit */
637 #endif /* !FULLSPEED */
640 subq.l #3,%a2 /* readjust end address */
641 move.l %a2,%d0 /* start address in %d0 again */
642 movem.l (%sp),%d2-%d7/%a2 /* restore registers */
644 jra .bytes2r_start /* jump to trailing byte loop */
647 addq.l #3,%d0 /* adjust start address for doing 4 bytes/ pass */
649 /* longword copy loop - no lines */
651 move.l -(%a0),-(%a1) /* copy longword (write can be unaligned) */
652 cmp.l %d0,%a0 /* runs %a0 down to first long bound */
655 subq.l #3,%d0 /* readjust start address */
656 cmp.l %d0,%a0 /* any bytes left? */
657 jls .bytes2r_end /* no: skip trailing byte loop */
659 /* trailing byte loop */
661 move.b -(%a0),-(%a1) /* copy byte */
663 cmp.l %d0,%a0 /* runs %a0 down to start address */
667 rts /* returns start address */
670 .size memmove,.end-memmove