1/*
2 * memcpy routine for Z8000
3 * Copyright (C) 2004 Christian Groessler <chris@groessler.org>
4 *
5 * Permission to use, copy, modify, and distribute this file
6 * for any purpose is hereby granted without fee, provided that
7 * the above copyright notice and this notice appears in all
8 * copies.
9 *
10 * This file is distributed WITHOUT ANY WARRANTY; without even the implied
11 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 */
13
14/* void *memcpy(void *dest, const void *src, size_t length);
15 */
16
17#include <picolibc.h>
18
19	name	"memcpy.S"
20
21	.text
22	even
23global	_memcpy
24global	memmove_entry
25
26_memcpy:
27
28#ifdef __Z8001__
29	segm
30
31#ifdef __STD_CALL__
32	ldl	rr6,rr14(#4)
33	ldl	rr4,rr14(#8)
34	ldl	rr2,rr14(#12)
35#else
36	pushl	@rr14,rr6
37#endif
38
39/* rr2  - length	(high word ignored)
40 * rr4  - src
41 * rr6  - dest
42 */
43
44	testl	rr2
45	jr	z,finish
46
47memmove_entry:		/* external entry point from memmove */
48
49	bitb	rl7,#0		/* odd destination address? */
50	jr	nz,testsrc
51	bitb	rl5,#0		/* odd source address? */
52	jr	nz,odd_copy
53	jr	t,even_copy	/* dest even, src odd */
54
55testsrc:
56	bitb	rl5,#0
57	jr	z,odd_copy	/* src even, dest odd */
58	ldib	@rr6,@rr4,r3
59	jr	ov,finish	/* jump if r3 is zero now */
60
61/* copy words */
62even_copy:
63	ld	r2,r3		/* remember length */
64	srl	r3,#1
65	jr	z,no_words
66
67	ldir	@rr6,@rr4,r3
68
69no_words:
70	bitb	rl2,#0		/* odd length? */
71	jr	z,finish
72	ldib	@rr6,@rr4,r2	/* yes, copy last byte */
73	jr	finish
74
75/* copy bytes */
76odd_copy:
77	ldirb	@rr6,@rr4,r3
78
79finish:
80#ifdef __STD_CALL__
81	ldl	rr6,rr14(#4)
82#else
83	popl	rr2,@rr14
84#endif
85
86
87#else		/* above Z8001, below Z8002 */
88
89
90	unsegm
91
92#ifdef __STD_CALL__
93	ld	r7,r15(#2)
94	ld	r6,r15(#4)
95	ld	r5,r15(#6)
96#else
97	ld	r2,r7		/* buffer pointer return value */
98#endif
99
100/* r5  - length
101 * r6  - src
102 * r7  - dest
103 */
104	test	r5
105	jr	z,finish
106
107memmove_entry:		/* external entry point from memmove */
108
109	bitb	rl7,#0		/* odd destination address? */
110	jr	nz,testsrc
111	bitb	rl6,#0		/* odd source address? */
112	jr	nz,odd_copy
113	jr	t,even_copy	/* dest even, src odd */
114
115testsrc:
116	bitb	rl6,#0
117	jr	z,odd_copy	/* src even, dest odd */
118	ldib	@r7,@r6,r5
119	jr	ov,finish	/* jump if r5 is zero now */
120
121/* copy words */
122even_copy:
123	ld	r4,r5		/* remember length */
124	srl	r5,#1
125	jr	z,no_words
126
127	ldir	@r7,@r6,r5
128
129no_words:
130	bitb	rl4,#0		/* odd length? */
131	jr	z,finish
132	ldib	@r7,@r6,r4	/* yes, copy last byte */
133	jr	finish
134
135/* copy bytes */
136odd_copy:
137	ldirb	@r7,@r6,r5
138
139finish:
140#ifdef __STD_CALL__
141	ld	r7,r15(#2)
142#endif
143
144#endif	/* Z8002 */
145
146	ret
147	.end
148