Welcome to mirror list, hosted at ThFree Co, Russian Federation.

memmove.S « z8k « machine « libc « newlib - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c4d0c73f8823438374f449144cdf7513b4ab0920 (plain)
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
 * memmove routine for Z8000
 * Copyright (C) 2004 Christian Groessler <chris@groessler.org>
 *
 * Permission to use, copy, modify, and distribute this file
 * for any purpose is hereby granted without fee, provided that
 * the above copyright notice and this notice appears in all
 * copies.
 *
 * This file is distributed WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

/* void *memmove(void *dest, const void *src, size_t length);
 */

	name	"memmove.S"

	.text
	even
global	_memmove

_memmove:

#ifdef __Z8001__
	segm

#ifdef __STD_CALL__
	ldl	rr6,rr14(#4)
	ldl	rr4,rr14(#8)
	ldl	rr2,rr14(#12)
#else
	pushl	@rr14,rr6
#endif

/* rr2  - length	(high word ignored)
 * rr4  - src
 * rr6  - dest
 */

	testl	rr2
	jr	z,finish

/*  check for destructive overlap (src < dest && dest < src + length) */

	cpl	rr6,rr4
	jp	ule,memmove_entry	/* non-destructive, let memcpy do the work */
	ldl	rr0,rr2
	addl	rr0,rr4			/* rr0 = src + length */
	cpl	rr0,rr6
	jp	ult,memmove_entry	/* non-destructive, let memcpy do the work */

/* set-up pointers to copy backwards, add (length - 1) */
	addl	rr4,rr2			/* src + length */
	addl	rr6,rr2			/* dest + length */
	subl	rr4,#1
	subl	rr6,#1

/* check alignment */
	bitb	rl7,#0		/* odd destination address? */
	jr	z,testsrc
	bitb	rl5,#0		/* odd source address? */
	jr	z,odd_copy
	jr	even_copy

testsrc:
	bitb	rl5,#0
	jr	nz,odd_copy	/* src even, dest odd */
	lddb	@rr6,@rr4,r3
	jr	ov,finish	/* jump if r5 is zero now */

/* copy words */
even_copy:
	ld	r2,r3			/* remember length */
	srl	r3,#1
/*	jr	z,no_words	   it cannot be zero here */

	dec	r5,#1
	dec	r7,#1
	lddr	@rr6,@rr4,r3

no_words:
	bitb	rl2,#0		/* odd length? */
	jr	z,finish
	inc	r5,#1
	inc	r7,#1
	lddb	@rr6,@rr4,r2	/* yes, copy last byte */
	jr	finish

/* copy bytes */
odd_copy:
	lddrb	@rr6,@rr4,r3

finish:
#ifdef __STD_CALL__
	ldl	rr6,rr14(#4)
#else
	popl	rr2,@rr14
#endif


#else		/* above Z8001, below Z8002 */


	unsegm

#ifdef __STD_CALL__
	ld	r7,r15(#2)
	ld	r6,r15(#4)
	ld	r5,r15(#6)
#else
	ld	r2,r7		/* buffer pointer return value */
#endif

/* r5  - length
 * r6  - src
 * r7  - dest
 */
	test	r5
	jr	z,finish

/*  check for destructive overlap (src < dest && dest < src + length) */

	cp	r7,r6
	jp	ule,memmove_entry	/* non-destructive, let memcpy do the work */
	ld	r0,r5
	add	r0,r6			/* r0 = src + length */
	cp	r0,r7
	jp	ult,memmove_entry	/* non-destructive, let memcpy do the work */

/* set-up pointers to copy backwards, add (length - 1) */
	add	r6,r5			/* src + length */
	add	r7,r5			/* dest + length */
	dec	r6,#1
	dec	r7,#1

/* check alignment */
	bitb	rl7,#0		/* odd destination address? */
	jr	z,testsrc
	bitb	rl6,#0		/* odd source address? */
	jr	z,odd_copy
	jr	even_copy

testsrc:
	bitb	rl6,#0
	jr	nz,odd_copy	/* src even, dest odd */
	lddb	@r7,@r6,r5
	jr	ov,finish	/* jump if r5 is zero now */

/* copy words */
even_copy:
	ld	r4,r5		/* remember length */
	srl	r5,#1
/*	jr	z,no_words	   it cannot be zero here */

	dec	r6,#1
	dec	r7,#1
	lddr	@r7,@r6,r5

no_words:
	bitb	rl4,#0		/* odd length? */
	jr	z,finish
	inc	r6,#1
	inc	r7,#1
	lddb	@r7,@r6,r4	/* yes, copy last byte */
	jr	finish

/* copy bytes */
odd_copy:
	lddrb	@r7,@r6,r5

finish:
#ifdef __STD_CALL__
	ld	r7,r15(#2)
#endif

#endif	/* Z8002 */

	ret
	.end