summaryrefslogtreecommitdiff
path: root/lib/libc/arch/ns32k/string/memcpy.S
blob: 066a4770f03d6cfe19d038cd345d3d8aa630e921 (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
/*	$NetBSD: memcpy.S,v 1.6 1998/05/28 22:07:22 matthias Exp $	*/

/* 
 * Written by Matthias Pfaller, 1996
 * Public domain.
 */

#include <machine/asm.h>

#if defined(LIBC_SCCS)
	RCSID("$NetBSD: memcpy.S,v 1.6 1998/05/28 22:07:22 matthias Exp $")
# if defined(BCOPY)
	RCSID("$Masqueraded: as bcopy $")
# endif
# if defined(MEMMOVE)
	RCSID("$Masqueraded: as memmove $")
# endif
#endif

#if !defined(BCOPY) && !defined(MEMMOVE)
/*
 * void *
 * memcpy (void *d, const void *s, size_t len)
 *	copy len bytes from the string s to d.
 */

KENTRY(memcpy, 12)
#elif defined(BCOPY)
/*
 * void
 * bcopy (void *s, const void *d, size_t len)
 *	copy len bytes from the string s to d.
 *	s and d may overlap.
 */

# if defined(_KERNEL)
ALTENTRY(ovbcopy,bcopy)
# endif

KENTRY(bcopy, 12)
#else
/*
 * void *
 * memmove (void *d, const void *s, size_t len)
 *	copy len bytes from the string s to d.
 *	s and d may overlap.
 */

KENTRY(memmove, 12)
#endif
	enter	[r3],0
	movd	B_ARG2,r0
#if defined(BCOPY)
	movd	B_ARG0,r1
	movd	B_ARG1,r2
#else
	movd	B_ARG1,r1
	movd	B_ARG0,r2
#endif
#if defined(MEMMOVE) || defined(BCOPY)
	cmpd	r2,r1
	bls	0f
	movd	r1,r3
	addd	r0,r3
	cmpd	r2,r3
	bls	2f
#endif
0:	cmpqd	4,r0
	bhi	1f

	/*
	 * Align destination address.
	 */
	movd	3,r3
	andd	r2,r3
	movd	0(r1),tos	/* Delay write in case src-dst < 4 */
	negd	r3,r3
	addqd	4,r3
	addd	r3,r1
	addd	r3,r2
	subd	r3,r0

	movqd	3,r3
	andd	r0,r3
	lshd	-2,r0
	movsd

	movd	r3,r0
	movsb
#if !defined(BCOPY)
	movd	B_ARG0,r0
	movd	tos,0(r0)
#else
	movd	tos,0(B_ARG1)
#endif
	exit	[r3]
	ret	ARGS

1:	movsb
#if !defined(BCOPY)
	movd	B_ARG0,r0
#endif
	exit	[r3]
	ret	ARGS

#if defined(MEMMOVE) || defined(BCOPY)
2:	addd	r0,r1
	addd	r0,r2
	addqd	-1,r1
	addqd	-1,r2
	cmpqd	4,r0
	bhi	0f

	/*
	 * Align destination address.
	 */
	movd	r0,r3
	movqd	1,r0
	addd	r2,r0
	andd	3,r0
	subd	r0,r3
	movsb	b
	movd	r3,r0
	andd	3,r3

	addqd	-3,r1
	addqd	-3,r2
	lshd	-2,r0
	movsd	b

	movd	r3,r0
	addqd	3,r1
	addqd	3,r2
0:	movsb	b
#if !defined(BCOPY)
	movd	B_ARG0,r0
#endif
	exit	[r3]
	ret	ARGS
#endif