1/*
2 * ====================================================
3 * Copyright (C) 1998, 2002 by Red Hat Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this
6 * software is freely granted, provided that this notice
7 * is preserved.
8 * ====================================================
9 */
10
11	#include "i386mach.h"
12
13	.global SYM (memmove)
14       SOTYPE_FUNCTION(memmove)
15
16SYM (memmove):
17
18#ifdef __iamcu__
19	pushl esi
20	pushl edi
21	movl eax,edi
22	movl edx,esi
23	cmp esi,edi
24	ja .Lcopy_backward
25	je .Lbwd_write_0bytes
26
27	rep movsb
28
29	popl edi
30	popl esi
31	ret
32
33.Lcopy_backward:
34	lea -1(edi,ecx),edi
35	lea -1(esi,ecx),esi
36	std
37	rep movsb
38	cld
39
40.Lbwd_write_0bytes:
41	popl edi
42	popl esi
43#else
44	pushl ebp
45	movl esp,ebp
46	pushl esi
47	pushl edi
48	pushl ebx
49	movl 8(ebp),edi
50	movl 16(ebp),ecx
51	movl 12(ebp),esi
52
53/*  check for destructive overlap (src < dst && dst < src + length) */
54
55	cld
56	cmpl edi,esi
57	jae  .L2
58	leal -1(ecx,esi),ebx
59	cmpl ebx,edi
60	ja   .L2
61
62/* IF:	 destructive overlap, must copy backwards */
63
64	addl ecx,esi
65	addl ecx,edi
66	std
67
68#ifndef __OPTIMIZE_SIZE__
69
70	cmpl $8,ecx
71	jbe .L13
72.L18:
73
74/* move trailing bytes in reverse until destination address is long word aligned */
75
76	movl edi,edx
77	movl ecx,ebx
78	andl $3,edx
79	jz .L21
80
81	movl edx,ecx
82	decl esi
83	decl edi
84	subl ecx,ebx
85	rep
86	movsb
87
88	mov ebx,ecx
89	incl esi
90	incl edi
91
92.L21:
93
94/* move bytes in reverse, a long word at a time */
95
96	shrl $2,ecx
97	subl $4,esi
98	subl $4,edi
99	rep
100	movsl
101
102	addl $4,esi
103	addl $4,edi
104	movl ebx,ecx
105	andl $3,ecx
106
107#endif /* !__OPTIMIZE_SIZE__ */
108
109/* handle any remaining bytes not on a long word boundary */
110
111.L13:
112	decl esi
113	decl edi
114
115.L15:
116	rep
117	movsb
118	jmp .L5
119	.p2align 4,,7
120
121/* ELSE:   no destructive overlap so we copy forwards */
122
123.L2:
124
125#ifndef __OPTIMIZE_SIZE__
126
127	cmpl $8,ecx
128	jbe .L3
129
130/* move any preceding bytes until destination address is long word aligned */
131
132	movl edi,edx
133	movl ecx,ebx
134	andl $3,edx
135	jz .L11
136	movl $4,ecx
137	subl edx,ecx
138	andl $3,ecx
139	subl ecx,ebx
140	rep
141	movsb
142
143	mov ebx,ecx
144
145/* move bytes a long word at a time */
146
147.L11:
148	shrl $2,ecx
149	.p2align 2
150	rep
151	movsl
152
153	movl ebx,ecx
154	andl $3,ecx
155
156#endif /* !__OPTIMIZE_SIZE__ */
157
158/* handle any remaining bytes */
159
160.L3:
161	rep
162	movsb
163.L5:
164	movl 8(ebp),eax
165	cld
166
167	leal -12(ebp),esp
168	popl ebx
169	popl edi
170	popl esi
171	leave
172#endif
173	ret
174
175#if defined(__linux__) && defined(__ELF__)
176.section .note.GNU-stack,"",%progbits
177#endif
178