mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
riscv: lib: add strrchr() implementation
Add an assembly implementation of strrchr() for RISC-V. This implementation minimizes instruction count and avoids unnecessary memory access to the stack. The performance benefits are most visible on small workloads (1-16 bytes) where the architectural savings in function overhead outweigh the execution time of the scan loop. Benchmark results (QEMU TCG, rv64): Length | Original (MB/s) | Optimized (MB/s) | Improvement -------|-----------------|------------------|------------ 1 B | 20 | 21 | +5.0% 7 B | 111 | 120 | +8.1% 16 B | 189 | 199 | +5.3% 512 B | 361 | 382 | +5.8% 4096 B | 388 | 391 | +0.8% Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn> Tested-by: Joel Stanley <joel@jms.id.au> Link: https://patch.msgid.link/20260130025018.172925-9-jiangfeng@kylinos.cn Signed-off-by: Paul Walmsley <pjw@kernel.org>
This commit is contained in:
parent
adf5421339
commit
bef64bcb94
|
|
@ -34,6 +34,9 @@ extern asmlinkage __kernel_size_t strnlen(const char *, size_t);
|
|||
|
||||
#define __HAVE_ARCH_STRCHR
|
||||
extern asmlinkage char *strchr(const char *, int);
|
||||
|
||||
#define __HAVE_ARCH_STRRCHR
|
||||
extern asmlinkage char *strrchr(const char *, int);
|
||||
#endif
|
||||
|
||||
/* For those files which don't want to check by kasan. */
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ lib-y += strlen.o
|
|||
lib-y += strncmp.o
|
||||
lib-y += strnlen.o
|
||||
lib-y += strchr.o
|
||||
lib-y += strrchr.o
|
||||
endif
|
||||
lib-y += csum.o
|
||||
ifeq ($(CONFIG_MMU), y)
|
||||
|
|
|
|||
37
arch/riscv/lib/strrchr.S
Normal file
37
arch/riscv/lib/strrchr.S
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 Feng Jiang <jiangfeng@kylinos.cn>
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/asm.h>
|
||||
|
||||
/* char *strrchr(const char *s, int c) */
|
||||
SYM_FUNC_START(strrchr)
|
||||
/*
|
||||
* Parameters
|
||||
* a0 - The string to be searched
|
||||
* a1 - The character to seaerch for
|
||||
*
|
||||
* Returns
|
||||
* a0 - Address of last occurrence of 'c' or 0
|
||||
*
|
||||
* Clobbers
|
||||
* t0, t1
|
||||
*/
|
||||
andi a1, a1, 0xff
|
||||
mv t1, a0
|
||||
li a0, 0
|
||||
1:
|
||||
lbu t0, 0(t1)
|
||||
bne t0, a1, 2f
|
||||
mv a0, t1
|
||||
2:
|
||||
addi t1, t1, 1
|
||||
bnez t0, 1b
|
||||
ret
|
||||
SYM_FUNC_END(strrchr)
|
||||
|
||||
SYM_FUNC_ALIAS_WEAK(__pi_strrchr, strrchr)
|
||||
EXPORT_SYMBOL(strrchr)
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o memcpy.o memset.o
|
||||
ifeq ($(CONFIG_KASAN_GENERIC)$(CONFIG_KASAN_SW_TAGS),)
|
||||
purgatory-y += strcmp.o strlen.o strncmp.o strnlen.o strchr.o
|
||||
purgatory-y += strcmp.o strlen.o strncmp.o strnlen.o strchr.o strrchr.o
|
||||
endif
|
||||
|
||||
targets += $(purgatory-y)
|
||||
|
|
@ -38,6 +38,9 @@ $(obj)/strnlen.o: $(srctree)/arch/riscv/lib/strnlen.S FORCE
|
|||
$(obj)/strchr.o: $(srctree)/arch/riscv/lib/strchr.S FORCE
|
||||
$(call if_changed_rule,as_o_S)
|
||||
|
||||
$(obj)/strrchr.o: $(srctree)/arch/riscv/lib/strrchr.S FORCE
|
||||
$(call if_changed_rule,as_o_S)
|
||||
|
||||
CFLAGS_sha256.o := -D__DISABLE_EXPORTS -D__NO_FORTIFY
|
||||
CFLAGS_string.o := -D__DISABLE_EXPORTS
|
||||
CFLAGS_ctype.o := -D__DISABLE_EXPORTS
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user