1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
| ;;; SPDX-License-Identifier: GPL-2.0
| ;;; memcpy.S
|
| #include <asm/linkage.h>
|
| #if defined(CONFIG_CPU_H8300H)
| .h8300h
| #endif
| #if defined(CONFIG_CPU_H8S)
| .h8300s
| #endif
| .text
| .global memcpy
|
| ;;; void *memcpy(void *to, void *from, size_t n)
| 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
|
| .end
|
|