;;; 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 |