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	name	"memcpy.S"
18
19	.text
20	even
21global	_memcpy
22global	memmove_entry
23
24_memcpy:
25
26#ifdef __Z8001__
27	segm
28
29#ifdef __STD_CALL__
30	ldl	rr6,rr14(#4)
31	ldl	rr4,rr14(#8)
32	ldl	rr2,rr14(#12)
33#else
34	pushl	@rr14,rr6
35#endif
36
37/* rr2  - length	(high word ignored)
38 * rr4  - src
39 * rr6  - dest
40 */
41
42	testl	rr2
43	jr	z,finish
44
45memmove_entry:		/* external entry point from memmove */
46
47	bitb	rl7,#0		/* odd destination address? */
48	jr	nz,testsrc
49	bitb	rl5,#0		/* odd source address? */
50	jr	nz,odd_copy
51	jr	t,even_copy	/* dest even, src odd */
52
53testsrc:
54	bitb	rl5,#0
55	jr	z,odd_copy	/* src even, dest odd */
56	ldib	@rr6,@rr4,r3
57	jr	ov,finish	/* jump if r3 is zero now */
58
59/* copy words */
60even_copy:
61	ld	r2,r3		/* remember length */
62	srl	r3,#1
63	jr	z,no_words
64
65	ldir	@rr6,@rr4,r3
66
67no_words:
68	bitb	rl2,#0		/* odd length? */
69	jr	z,finish
70	ldib	@rr6,@rr4,r2	/* yes, copy last byte */
71	jr	finish
72
73/* copy bytes */
74odd_copy:
75	ldirb	@rr6,@rr4,r3
76
77finish:
78#ifdef __STD_CALL__
79	ldl	rr6,rr14(#4)
80#else
81	popl	rr2,@rr14
82#endif
83
84
85#else		/* above Z8001, below Z8002 */
86
87
88	unsegm
89
90#ifdef __STD_CALL__
91	ld	r7,r15(#2)
92	ld	r6,r15(#4)
93	ld	r5,r15(#6)
94#else
95	ld	r2,r7		/* buffer pointer return value */
96#endif
97
98/* r5  - length
99 * r6  - src
100 * r7  - dest
101 */
102	test	r5
103	jr	z,finish
104
105memmove_entry:		/* external entry point from memmove */
106
107	bitb	rl7,#0		/* odd destination address? */
108	jr	nz,testsrc
109	bitb	rl6,#0		/* odd source address? */
110	jr	nz,odd_copy
111	jr	t,even_copy	/* dest even, src odd */
112
113testsrc:
114	bitb	rl6,#0
115	jr	z,odd_copy	/* src even, dest odd */
116	ldib	@r7,@r6,r5
117	jr	ov,finish	/* jump if r5 is zero now */
118
119/* copy words */
120even_copy:
121	ld	r4,r5		/* remember length */
122	srl	r5,#1
123	jr	z,no_words
124
125	ldir	@r7,@r6,r5
126
127no_words:
128	bitb	rl4,#0		/* odd length? */
129	jr	z,finish
130	ldib	@r7,@r6,r4	/* yes, copy last byte */
131	jr	finish
132
133/* copy bytes */
134odd_copy:
135	ldirb	@r7,@r6,r5
136
137finish:
138#ifdef __STD_CALL__
139	ld	r7,r15(#2)
140#endif
141
142#endif	/* Z8002 */
143
144	ret
145	.end
146