1 ;;; SPDX-License-Identifier: GPL-2.0
2 ;;; memcpy.S
3 
4 #include <asm/linkage.h>
5 
6 #if defined(CONFIG_CPU_H8300H)
7 	.h8300h
8 #endif
9 #if defined(CONFIG_CPU_H8S)
10 	.h8300s
11 #endif
12 	.text
13 .global memcpy
14 
15 ;;; void *memcpy(void *to, void *from, size_t n)
16 memcpy:
17 	mov.l	er2,er2
18 	bne	1f
19 	rts
20 1:
21 	;; address check
22 	bld	#0,r0l
23 	bxor	#0,r1l
24 	bcs	4f
25 	mov.l	er4,@-sp
26 	mov.l	er0,@-sp
27 	btst	#0,r0l
28 	beq	1f
29 	;; (aligned even) odd address
30 	mov.b	@er1,r3l
31 	mov.b	r3l,@er0
32 	adds	#1,er1
33 	adds	#1,er0
34 	dec.l	#1,er2
35 	beq	3f
36 1:
37 	;; n < sizeof(unsigned long) check
38 	sub.l	er4,er4
39 	adds	#4,er4		; loop count check value
40 	cmp.l	er4,er2
41 	blo	2f
42 	;; unsigned long copy
43 1:
44 	mov.l	@er1,er3
45 	mov.l	er3,@er0
46 	adds	#4,er0
47 	adds	#4,er1
48 	subs	#4,er2
49 	cmp.l	er4,er2
50 	bcc	1b
51 	;; rest
52 2:
53 	mov.l	er2,er2
54 	beq	3f
55 1:
56 	mov.b	@er1,r3l
57 	mov.b	r3l,@er0
58 	adds	#1,er1
59 	adds	#1,er0
60 	dec.l	#1,er2
61 	bne	1b
62 3:
63 	mov.l	@sp+,er0
64 	mov.l	@sp+,er4
65 	rts
66 
67 	;; odd <- even / even <- odd
68 4:
69 	mov.l	er4,er3
70 	mov.l	er2,er4
71 	mov.l	er5,er2
72 	mov.l	er1,er5
73 	mov.l	er6,er1
74 	mov.l	er0,er6
75 1:
76 	eepmov.w
77 	mov.w	r4,r4
78 	bne	1b
79 	dec.w	#1,e4
80 	bpl	1b
81 	mov.l	er1,er6
82 	mov.l	er2,er5
83 	mov.l	er3,er4
84 	rts
85 
86 	.end
87