* 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:
@@ -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 {
|
||||
|
||||
@@ -5,7 +5,6 @@ local librootFunctions =
|
||||
ctype.o
|
||||
qsort.o
|
||||
kernel_vsprintf.o
|
||||
memset.o
|
||||
memcmp.o
|
||||
memmove.o
|
||||
strdup.o
|
||||
|
||||
@@ -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 :
|
||||
|
||||
@@ -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 :
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,6 @@ KernelMergeObject kernel_lib_posix.o :
|
||||
memchr.c
|
||||
memcmp.c
|
||||
memmove.c
|
||||
memset.c
|
||||
strcasecmp.c
|
||||
strcasestr.c
|
||||
strcat.c
|
||||
|
||||
@@ -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)
|
||||
;
|
||||
|
||||
@@ -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)
|
||||
;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user