| ;;; memcpy.S |
| |
| #include <asm/linkage.h> |
| |
| #if defined(__H8300H__) |
| .h8300h |
| #endif |
| #if defined(__H8300S__) |
| .h8300s |
| #endif |
| |
| .text |
| .global SYMBOL_NAME(memcpy) |
| |
| ;;; void *memcpy(void *to, void *from, size_t n) |
| SYMBOL_NAME_LABEL(memcpy) |
| mov.l er2,er2 |
| bne 1f |
| rts |
| 1: |
| ;; address check |
| bld #0,r0l |
| bxor #0,r1l |
| bcs 4f |
| mov.l er4,@-sp |
| mov.l er0,@-sp |
| btst #0,r0l |
| beq 1f |
| ;; (aligned even) odd address |
| mov.b @er1,r3l |
| mov.b r3l,@er0 |
| adds #1,er1 |
| adds #1,er0 |
| dec.l #1,er2 |
| beq 3f |
| 1: |
| ;; n < sizeof(unsigned long) check |
| sub.l er4,er4 |
| adds #4,er4 ; loop count check value |
| cmp.l er4,er2 |
| blo 2f |
| ;; unsigned long copy |
| 1: |
| mov.l @er1,er3 |
| mov.l er3,@er0 |
| adds #4,er0 |
| adds #4,er1 |
| subs #4,er2 |
| cmp.l er4,er2 |
| bcc 1b |
| ;; rest |
| 2: |
| mov.l er2,er2 |
| beq 3f |
| 1: |
| mov.b @er1,r3l |
| mov.b r3l,@er0 |
| adds #1,er1 |
| adds #1,er0 |
| dec.l #1,er2 |
| bne 1b |
| 3: |
| mov.l @sp+,er0 |
| mov.l @sp+,er4 |
| rts |
| |
| ;; odd <- even / even <- odd |
| 4: |
| mov.l er4,er3 |
| mov.l er2,er4 |
| mov.l er5,er2 |
| mov.l er1,er5 |
| mov.l er6,er1 |
| mov.l er0,er6 |
| 1: |
| eepmov.w |
| mov.w r4,r4 |
| bne 1b |
| dec.w #1,e4 |
| bpl 1b |
| mov.l er1,er6 |
| mov.l er2,er5 |
| mov.l er3,er4 |
| rts |