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