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