18c2ecf20Sopenharmony_ci;;; SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci;;; memcpy.S
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci#include <asm/linkage.h>
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_H8300H)
78c2ecf20Sopenharmony_ci	.h8300h
88c2ecf20Sopenharmony_ci#endif
98c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_H8S)
108c2ecf20Sopenharmony_ci	.h8300s
118c2ecf20Sopenharmony_ci#endif
128c2ecf20Sopenharmony_ci	.text
138c2ecf20Sopenharmony_ci.global memcpy
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci;;; void *memcpy(void *to, void *from, size_t n)
168c2ecf20Sopenharmony_cimemcpy:
178c2ecf20Sopenharmony_ci	mov.l	er2,er2
188c2ecf20Sopenharmony_ci	bne	1f
198c2ecf20Sopenharmony_ci	rts
208c2ecf20Sopenharmony_ci1:
218c2ecf20Sopenharmony_ci	;; address check
228c2ecf20Sopenharmony_ci	bld	#0,r0l
238c2ecf20Sopenharmony_ci	bxor	#0,r1l
248c2ecf20Sopenharmony_ci	bcs	4f
258c2ecf20Sopenharmony_ci	mov.l	er4,@-sp
268c2ecf20Sopenharmony_ci	mov.l	er0,@-sp
278c2ecf20Sopenharmony_ci	btst	#0,r0l
288c2ecf20Sopenharmony_ci	beq	1f
298c2ecf20Sopenharmony_ci	;; (aligned even) odd address
308c2ecf20Sopenharmony_ci	mov.b	@er1,r3l
318c2ecf20Sopenharmony_ci	mov.b	r3l,@er0
328c2ecf20Sopenharmony_ci	adds	#1,er1
338c2ecf20Sopenharmony_ci	adds	#1,er0
348c2ecf20Sopenharmony_ci	dec.l	#1,er2
358c2ecf20Sopenharmony_ci	beq	3f
368c2ecf20Sopenharmony_ci1:
378c2ecf20Sopenharmony_ci	;; n < sizeof(unsigned long) check
388c2ecf20Sopenharmony_ci	sub.l	er4,er4
398c2ecf20Sopenharmony_ci	adds	#4,er4		; loop count check value
408c2ecf20Sopenharmony_ci	cmp.l	er4,er2
418c2ecf20Sopenharmony_ci	blo	2f
428c2ecf20Sopenharmony_ci	;; unsigned long copy
438c2ecf20Sopenharmony_ci1:
448c2ecf20Sopenharmony_ci	mov.l	@er1,er3
458c2ecf20Sopenharmony_ci	mov.l	er3,@er0
468c2ecf20Sopenharmony_ci	adds	#4,er0
478c2ecf20Sopenharmony_ci	adds	#4,er1
488c2ecf20Sopenharmony_ci	subs	#4,er2
498c2ecf20Sopenharmony_ci	cmp.l	er4,er2
508c2ecf20Sopenharmony_ci	bcc	1b
518c2ecf20Sopenharmony_ci	;; rest
528c2ecf20Sopenharmony_ci2:
538c2ecf20Sopenharmony_ci	mov.l	er2,er2
548c2ecf20Sopenharmony_ci	beq	3f
558c2ecf20Sopenharmony_ci1:
568c2ecf20Sopenharmony_ci	mov.b	@er1,r3l
578c2ecf20Sopenharmony_ci	mov.b	r3l,@er0
588c2ecf20Sopenharmony_ci	adds	#1,er1
598c2ecf20Sopenharmony_ci	adds	#1,er0
608c2ecf20Sopenharmony_ci	dec.l	#1,er2
618c2ecf20Sopenharmony_ci	bne	1b
628c2ecf20Sopenharmony_ci3:
638c2ecf20Sopenharmony_ci	mov.l	@sp+,er0
648c2ecf20Sopenharmony_ci	mov.l	@sp+,er4
658c2ecf20Sopenharmony_ci	rts
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	;; odd <- even / even <- odd
688c2ecf20Sopenharmony_ci4:
698c2ecf20Sopenharmony_ci	mov.l	er4,er3
708c2ecf20Sopenharmony_ci	mov.l	er2,er4
718c2ecf20Sopenharmony_ci	mov.l	er5,er2
728c2ecf20Sopenharmony_ci	mov.l	er1,er5
738c2ecf20Sopenharmony_ci	mov.l	er6,er1
748c2ecf20Sopenharmony_ci	mov.l	er0,er6
758c2ecf20Sopenharmony_ci1:
768c2ecf20Sopenharmony_ci	eepmov.w
778c2ecf20Sopenharmony_ci	mov.w	r4,r4
788c2ecf20Sopenharmony_ci	bne	1b
798c2ecf20Sopenharmony_ci	dec.w	#1,e4
808c2ecf20Sopenharmony_ci	bpl	1b
818c2ecf20Sopenharmony_ci	mov.l	er1,er6
828c2ecf20Sopenharmony_ci	mov.l	er2,er5
838c2ecf20Sopenharmony_ci	mov.l	er3,er4
848c2ecf20Sopenharmony_ci	rts
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci	.end
87