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