1/*
2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2018, Haiku, Inc. All rights reserved.
4 * Distributed under the terms of the MIT License.
5 *
6 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
7 * Distributed under the terms of the NewOS License.
8 */
9
10
11#include <asm_defs.h>
12
13
14.align 4
15FUNCTION(memcpy):
16	pushl	%esi
17	pushl	%edi
18	movl	12(%esp),%edi	/* dest */
19	movl	%edi,%eax	/* save dest ptr as return address */
20	movl	16(%esp),%esi	/* source */
21	movl	20(%esp),%ecx	/* count */
22
23	/* (count == 0 || dest == src) -> quick way out */
24	testl	%ecx, %ecx
25	je		.tail
26	cmpl	%edi, %esi
27	je		.tail
28
29	/* move by words */
30	// TODO: The addresses might not be aligned!
31	cld
32	shrl	$2,%ecx
33	rep
34	movsl
35
36	/* move any remaining data by bytes */
37	movl	20(%esp),%ecx
38	andl	$3,%ecx
39	rep
40	movsb
41
42.tail:
43	popl	%edi
44	popl	%esi
45	ret
46FUNCTION_END(memcpy)
47SYMBOL(memcpy_end):
48
49
50/* void *memset(void *dest, int value, size_t length); */
51.align 4
52FUNCTION(memset):
53	push	%ebp
54	mov		%esp, %ebp
55
56	// %eax, %ecx, and %edx are scratch registers -- we only have to save %edi
57	push	%edi
58
59	// get the parameters
60	mov		16(%ebp), %ecx
61	mov		12(%ebp), %eax
62	mov		8(%ebp), %edi
63
64	// When touching less than 12 bytes, we just do it bytewise. We might be
65	// able to process one or two lwords lwordwise, but the additional overhead
66	// isn't worth it.
67	cmp		$12, %ecx
68	jl		2f
69
70	// buffer address lword-aligned?
71	mov		%edi, %edx
72	and		$0x3, %edx
73	jz		1f
74
75	// the buffer is unaligned -- copy the first bytes bytewise
76	mov		$4, %ecx
77	sub		%edx, %ecx
78	rep 	stosb
79
80	mov		16(%ebp), %ecx
81	sub		$4, %ecx
82	add		%edx, %ecx
83
841:	// lwordwise
85	// prepare %eax -- the low byte must be copied to the other bytes
86	mov		%al, %ah
87	mov		%eax, %edx
88	shl		$16, %eax
89	mov		%dx, %ax
90
91	// get the unaligned remainder into %edx
92	mov		%ecx, %edx
93	and		$0x3, %edx
94
95	// write words
96	shr		$2, %ecx
97	rep		stosl
98
99	mov		%edx, %ecx
100
1012:	// bytewise (remaining bytes)
102	rep 	stosb
103
104	pop		%edi
105
106	// return value is the value passed in
107	mov		8(%ebp), %eax
108
109	mov		%ebp, %esp
110	pop		%ebp
111	ret
112FUNCTION_END(memset)
113SYMBOL(memset_end):
114
115