* Implemented x86 assembly version of memset().

* memset() is now available through the commpage.
* CPU modules can provide a model-optimized memset().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27952 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-10-10 18:43:46 +00:00
parent 609bc8ca47
commit b18c9b97ae
18 changed files with 119 additions and 16 deletions
@@ -100,6 +100,8 @@
typedef struct x86_optimized_functions {
void (*memcpy)(void* dest, const void* source, size_t count);
void* memcpy_end;
void (*memset)(void* dest, int value, size_t count);
void* memset_end;
} x86_optimized_functions;
typedef struct x86_cpu_module_info {
-1
View File
@@ -5,7 +5,6 @@ local librootFunctions =
ctype.o
qsort.o
kernel_vsprintf.o
memset.o
memcmp.o
memmove.o
strdup.o
+1
View File
@@ -10,6 +10,7 @@ local librootArchObjects =
local kernelLibArchObjects =
<src!system!kernel!lib!arch!$(TARGET_ARCH)>byteorder.o
<src!system!kernel!lib!arch!$(TARGET_ARCH)>memset.o
;
KernelMergeObject boot_arch_$(TARGET_ARCH).o :
+1
View File
@@ -5,6 +5,7 @@ DEFINES += _BOOT_MODE ;
local kernelLibArchObjects =
<src!system!kernel!lib!arch!$(TARGET_ARCH)>byteorder.o
<src!system!kernel!lib!arch!$(TARGET_ARCH)>memcpy.o
<src!system!kernel!lib!arch!$(TARGET_ARCH)>memset.o
;
KernelMergeObject boot_arch_$(TARGET_ARCH).o :
+17 -1
View File
@@ -87,10 +87,14 @@ static x86_cpu_module_info *sCpuModule;
extern "C" void memcpy_generic(void* dest, const void* source, size_t count);
extern int memcpy_generic_end;
extern "C" void memset_generic(void* dest, int value, size_t count);
extern int memset_generic_end;
x86_optimized_functions gOptimizedFunctions = {
memcpy_generic,
&memcpy_generic_end
&memcpy_generic_end,
memset_generic,
&memset_generic_end
};
@@ -605,6 +609,11 @@ arch_cpu_init_post_modules(kernel_args *args)
gOptimizedFunctions.memcpy = functions.memcpy;
gOptimizedFunctions.memcpy_end = functions.memcpy_end;
}
if (functions.memset != NULL) {
gOptimizedFunctions.memset = functions.memset;
gOptimizedFunctions.memset_end = functions.memset_end;
}
}
// put the optimized functions into the commpage
@@ -612,12 +621,19 @@ arch_cpu_init_post_modules(kernel_args *args)
- (addr_t)gOptimizedFunctions.memcpy;
fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMCPY,
(const void*)gOptimizedFunctions.memcpy, memcpyLen);
size_t memsetLen = (addr_t)gOptimizedFunctions.memset_end
- (addr_t)gOptimizedFunctions.memset;
fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMSET,
(const void*)gOptimizedFunctions.memset, memsetLen);
// add the functions to the commpage image
image_id image = get_commpage_image();
elf_add_memory_image_symbol(image, "commpage_memcpy",
((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_MEMCPY], memcpyLen,
B_SYMBOL_TYPE_TEXT);
elf_add_memory_image_symbol(image, "commpage_memset",
((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_MEMSET], memsetLen,
B_SYMBOL_TYPE_TEXT);
return B_OK;
}
@@ -57,4 +57,6 @@ dummy()
// struct x86_optimized_functions
DEFINE_OFFSET_MACRO(X86_OPTIMIZED_FUNCTIONS, x86_optimized_functions,
memcpy);
DEFINE_OFFSET_MACRO(X86_OPTIMIZED_FUNCTIONS, x86_optimized_functions,
memset);
}
-1
View File
@@ -86,7 +86,6 @@ KernelMergeObject kernel_lib_posix.o :
memchr.c
memcmp.c
memmove.c
memset.c
strcasecmp.c
strcasestr.c
strcat.c
+1
View File
@@ -27,6 +27,7 @@ KernelMergeObject kernel_lib_posix_arch_$(TARGET_ARCH).o :
kernel_setjmp_save_sigs.c
arch_string.S
memset.c
: $(TARGET_KERNEL_PIC_CCFLAGS)
;
+1
View File
@@ -26,6 +26,7 @@ KernelMergeObject kernel_lib_posix_arch_$(TARGET_ARCH).o :
kernel_setjmp_save_sigs.c
memcpy.c
memset.c
: $(TARGET_KERNEL_PIC_CCFLAGS)
;
+79 -2
View File
@@ -1,6 +1,9 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#if !_BOOT_MODE
@@ -13,6 +16,7 @@
// We don't need the indirection in the boot loader.
#if _BOOT_MODE
# define memcpy_generic memcpy
# define memset_generic memset
#endif
@@ -26,6 +30,7 @@ FUNCTION(memcpy_generic):
movl 20(%esp),%ecx /* count */
/* move by words */
// TODO: The addresses might not be aligned!
cld
shrl $2,%ecx
rep
@@ -40,13 +45,85 @@ FUNCTION(memcpy_generic):
popl %edi
popl %esi
ret
FUNCTION_END(memcpy_generic)
SYMBOL(memcpy_generic_end):
/* void *memset(void *dest, int value, size_t length); */
.align 4
FUNCTION(memset_generic):
push %ebp
mov %esp, %ebp
// %eax, %ecx, and %edx are scratch registers -- we only have to save %edi
push %edi
// get the parameters
mov 16(%ebp), %ecx
mov 12(%ebp), %eax
mov 8(%ebp), %edi
// When touching less than 12 bytes, we just do it bytewise. We might be
// able to process one or two lwords lwordwise, but the additional overhead
// isn't worth it.
cmp $12, %ecx
jl 2f
// buffer address lword-aligned?
mov %edi, %edx
and $0x3, %edx
jz 1f
// the buffer is unaligned -- copy the first bytes bytewise
mov $4, %ecx
sub %edx, %ecx
rep stosb
mov 16(%ebp), %ecx
sub $4, %ecx
add %edx, %ecx
1: // lwordwise
// prepare %eax -- the low byte must be copied to the other bytes
mov %al, %ah
mov %ax, %dx
shl $16, %eax
mov %dx, %ax
// get the unaligned remainder into %edx
mov %ecx, %edx
and $0x3, %edx
// write words
shr $2, %ecx
rep stosl
mov %edx, %ecx
2: // bytewise (remaining bytes)
rep stosb
pop %edi
// return value is the value passed in
mov 12(%ebp), %eax
mov %ebp, %esp
pop %ebp
ret
FUNCTION_END(memset_generic)
SYMBOL(memset_generic_end):
#if !_BOOT_MODE
.align 4
FUNCTION(memcpy):
jmp *(gOptimizedFunctions + X86_OPTIMIZED_FUNCTIONS_memcpy)
FUNCTION_END(memcpy)
FUNCTION(memset):
jmp *(gOptimizedFunctions + X86_OPTIMIZED_FUNCTIONS_memset)
FUNCTION_END(memset)
#endif // !_BOOT_MODE
-1
View File
@@ -9,7 +9,6 @@ MergeObject posix_string.o :
memchr.c
memcmp.c
memmove.c
memset.c
stpcpy.c
strcasecmp.c
strcasestr.c
@@ -2,6 +2,9 @@ SubDir HAIKU_TOP src system libroot posix string arch m68k ;
UsePrivateSystemHeaders ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
MergeObject posix_string_arch_$(TARGET_ARCH).o :
arch_string.S
memset.c
;
@@ -6,4 +6,5 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
MergeObject posix_string_arch_$(TARGET_ARCH).o :
memcpy.c
memset.c
;
@@ -1,18 +1,18 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#if !_KERNEL_MODE
// TODO: This should not even be compiled for the kernel. Fix the TODO in
// src/system/kernel/lib/Jamfile!
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include <asm_defs.h>
#include <commpage_defs.h>
#define FUNCTION(x) .global x; .type x,@function; x
.align 4
FUNCTION(memcpy):
jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_MEMCPY * 4)
FUNCTION_END(memcpy)
#endif // !_KERNEL_MODE
FUNCTION(memset):
jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_MEMSET * 4)
FUNCTION_END(memset)
-1
View File
@@ -36,7 +36,6 @@ StaticLibrary libruntime_loader.a :
<src!system!libroot!posix!string>memchr.o
<src!system!libroot!posix!string>memcmp.o
<src!system!libroot!posix!string>memmove.o
<src!system!libroot!posix!string>memset.o
<src!system!libroot!posix!string>strcasecmp.o
<src!system!libroot!posix!string>strcat.o
<src!system!libroot!posix!string>strchr.o
@@ -12,4 +12,5 @@ StaticLibrary libruntime_loader_$(TARGET_ARCH).a :
<src!system!libroot!os!arch!$(TARGET_ARCH)>thread.o
<src!system!libroot!posix!string!arch!$(TARGET_ARCH)>arch_string.o
<src!system!libroot!posix!string!arch!$(TARGET_ARCH)>memset.o
;
@@ -12,4 +12,5 @@ StaticLibrary libruntime_loader_$(TARGET_ARCH).a :
<src!system!libroot!os!arch!$(TARGET_ARCH)>thread.o
<src!system!libroot!posix!string!arch!$(TARGET_ARCH)>memcpy.o
<src!system!libroot!posix!string!arch!$(TARGET_ARCH)>memset.o
;