summaryrefslogtreecommitdiff
path: root/com32/lib/memmove.S
blob: e97299f24c1f35a51afb75da6110783ba9384d4c (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
/* ----------------------------------------------------------------------- *
 *
 *   Copyright 2008 H. Peter Anvin - All Rights Reserved
 *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
 *
 *   Permission is hereby granted, free of charge, to any person
 *   obtaining a copy of this software and associated documentation
 *   files (the "Software"), to deal in the Software without
 *   restriction, including without limitation the rights to use,
 *   copy, modify, merge, publish, distribute, sublicense, and/or
 *   sell copies of the Software, and to permit persons to whom
 *   the Software is furnished to do so, subject to the following
 *   conditions:
 *
 *   The above copyright notice and this permission notice shall
 *   be included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 *
 * ----------------------------------------------------------------------- */

/*
 * memmove.S
 *
 * Reasonably efficient memmove, using aligned transfers at least
 * for the destination operand.
 */

	.globl	memmove
	.type	memmove,@function
	.text
memmove:
	jecxz	4f

	pushl	%esi
	pushl	%edi
	pushl	%eax		/* Return value */

	movl	%eax,%edi
	movl	%edx,%esi

	cmpl	%edi,%esi
	jb	2f

	/* source >= dest, forwards move */

	/* Initial alignment */
1:
	movl	%edi,%edx
	shrl	$1,%edx
	jnc	11f
	movsb
	decl	%ecx
11:
	movb	%cl,%al
	cmpl	$2,%ecx
	jb	13f

	shrl	$1,%edx
	jnc	12f
	movsw
	subl	$2,%ecx
12:
	/* Bulk transfer */
	movb	%cl,%al
	shrl	$2,%ecx
	rep; movsl

	/* Final alignment */
	testb	$2,%al
	jz	14f
	movsw
13:
14:
	testb	$1,%al
	jz	15f
	movsb
15:
	/* Common exit stub */
3:
	popl	%eax		/* Return value */
	popl	%edi
	popl	%esi
4:
	ret


2:
	/* source < dest, backwards move if overlap */
	leal	-1(%ecx,%esi),%eax
	cmpl	%eax,%edi
	ja	1b			/* No overlap, after all... */

	std
	leal	-1(%ecx,%edi),%edi
	movl	%eax,%esi

	/* Initial alignment */
	movl	%edi,%edx
	shrl	$1,%edx
	jc	21f
	movsb
	decl	%ecx
21:
	decl	%esi
	decl	%edi
	movb	%cl,%al
	cmpl	$2,%ecx
	jb	23f
	shrl	$1,%edx
	jc	22f
	movsw
	subl	$2,%ecx
22:
	/* Bulk transfer */
	subl	$2,%esi
	subl	$2,%edi
	movb	%cl,%al
	shrl	$2,%ecx
	rep; movsl

	/* Final alignment */
	addl	$2,%esi
	addl	$2,%edi
	testb	$2,%al
	jz	24f
	movsw
23:
24:
	incl	%esi
	incl	%edi
	testb	$1,%al
	jz	25f
	movsb
25:
	cld
	jmp	3b

	.size	memmove, .-memmove