mirror of
https://github.com/torvalds/linux.git
synced 2025-11-06 03:29:11 +02:00
tools/nolibc: x86-64: Use rep stosb for memset()
Simplify memset() on the x86-64 arch.
The x86-64 arch has a 'rep stosb' instruction, which can perform
memset() using only a single instruction, given:
%al = value (just like the second argument of memset())
%rdi = destination
%rcx = length
Before this patch:
```
00000000000010c9 <memset>:
10c9: 48 89 f8 mov %rdi,%rax
10cc: 48 85 d2 test %rdx,%rdx
10cf: 74 0e je 10df <memset+0x16>
10d1: 31 c9 xor %ecx,%ecx
10d3: 40 88 34 08 mov %sil,(%rax,%rcx,1)
10d7: 48 ff c1 inc %rcx
10da: 48 39 ca cmp %rcx,%rdx
10dd: 75 f4 jne 10d3 <memset+0xa>
10df: c3 ret
```
After this patch:
```
0000000000001511 <memset>:
1511: 96 xchg %eax,%esi
1512: 48 89 d1 mov %rdx,%rcx
1515: 57 push %rdi
1516: f3 aa rep stos %al,%es:(%rdi)
1518: 58 pop %rax
1519: c3 ret
```
v2:
- Use pushq %rdi / popq %rax (Alviro).
- Use xchg %eax, %esi (Willy).
Link: https://lore.kernel.org/lkml/ZO9e6h2jjVIMpBJP@1wt.eu
Suggested-by: Alviro Iskandar Setiawan <alviro.iskandar@gnuweeb.org>
Suggested-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
Reviewed-by: Alviro Iskandar Setiawan <alviro.iskandar@gnuweeb.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
This commit is contained in:
parent
553845eebd
commit
12108aa8c1
2 changed files with 15 additions and 0 deletions
|
|
@ -179,6 +179,9 @@ void *memmove(void *dst, const void *src, size_t len);
|
|||
#define NOLIBC_ARCH_HAS_MEMCPY
|
||||
void *memcpy(void *dst, const void *src, size_t len);
|
||||
|
||||
#define NOLIBC_ARCH_HAS_MEMSET
|
||||
void *memset(void *dst, int c, size_t len);
|
||||
|
||||
__asm__ (
|
||||
".section .text.nolibc_memmove_memcpy\n"
|
||||
".weak memmove\n"
|
||||
|
|
@ -200,6 +203,16 @@ __asm__ (
|
|||
"rep movsb\n\t"
|
||||
"cld\n\t"
|
||||
"retq\n"
|
||||
|
||||
".section .text.nolibc_memset\n"
|
||||
".weak memset\n"
|
||||
"memset:\n"
|
||||
"xchgl %eax, %esi\n\t"
|
||||
"movq %rdx, %rcx\n\t"
|
||||
"pushq %rdi\n\t"
|
||||
"rep stosb\n\t"
|
||||
"popq %rax\n\t"
|
||||
"retq\n"
|
||||
);
|
||||
|
||||
#endif /* _NOLIBC_ARCH_X86_64_H */
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ void *memcpy(void *dst, const void *src, size_t len)
|
|||
}
|
||||
#endif /* #ifndef NOLIBC_ARCH_HAS_MEMCPY */
|
||||
|
||||
#ifndef NOLIBC_ARCH_HAS_MEMSET
|
||||
/* might be ignored by the compiler without -ffreestanding, then found as
|
||||
* missing.
|
||||
*/
|
||||
|
|
@ -99,6 +100,7 @@ void *memset(void *dst, int b, size_t len)
|
|||
}
|
||||
return dst;
|
||||
}
|
||||
#endif /* #ifndef NOLIBC_ARCH_HAS_MEMSET */
|
||||
|
||||
static __attribute__((unused))
|
||||
char *strchr(const char *s, int c)
|
||||
|
|
|
|||
Loading…
Reference in a new issue