diff options
Diffstat (limited to 'arch/h8300/lib/memcpy.S')
-rw-r--r-- | arch/h8300/lib/memcpy.S | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/arch/h8300/lib/memcpy.S b/arch/h8300/lib/memcpy.S new file mode 100644 index 000000000000..fdcbc1ee673c --- /dev/null +++ b/arch/h8300/lib/memcpy.S @@ -0,0 +1,84 @@ +;;; 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 |