mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
riscv: lib: add strchr() implementation
Add an assembly implementation of strchr() for RISC-V. By eliminating stack frame management (prologue/epilogue) and optimizing the function entries, the assembly version provides significant relative gains for short strings where the fixed overhead of the C function is most prominent. As string length increases, performance converges with the generic C implementation. Benchmark results (QEMU TCG, rv64): Length | Original (MB/s) | Optimized (MB/s) | Improvement -------|-----------------|------------------|------------ 1 B | 21 | 22 | +4.8% 7 B | 113 | 121 | +7.1% 16 B | 195 | 202 | +3.6% 512 B | 376 | 389 | +3.5% 4096 B | 394 | 393 | -0.3% Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn> Tested-by: Joel Stanley <joel@jms.id.au> Link: https://patch.msgid.link/20260130025018.172925-8-jiangfeng@kylinos.cn Signed-off-by: Paul Walmsley <pjw@kernel.org>
This commit is contained in:
committed by
Paul Walmsley
parent
5ba15d419f
commit
adf5421339
@@ -31,6 +31,9 @@ extern asmlinkage int strncmp(const char *cs, const char *ct, size_t count);
|
||||
|
||||
#define __HAVE_ARCH_STRNLEN
|
||||
extern asmlinkage __kernel_size_t strnlen(const char *, size_t);
|
||||
|
||||
#define __HAVE_ARCH_STRCHR
|
||||
extern asmlinkage char *strchr(const char *, int);
|
||||
#endif
|
||||
|
||||
/* For those files which don't want to check by kasan. */
|
||||
|
||||
@@ -8,6 +8,7 @@ lib-y += strcmp.o
|
||||
lib-y += strlen.o
|
||||
lib-y += strncmp.o
|
||||
lib-y += strnlen.o
|
||||
lib-y += strchr.o
|
||||
endif
|
||||
lib-y += csum.o
|
||||
ifeq ($(CONFIG_MMU), y)
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 Feng Jiang <jiangfeng@kylinos.cn>
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/asm.h>
|
||||
|
||||
/* char *strchr(const char *s, int c) */
|
||||
SYM_FUNC_START(strchr)
|
||||
/*
|
||||
* Parameters
|
||||
* a0 - The string to be searched
|
||||
* a1 - The character to search for
|
||||
*
|
||||
* Returns
|
||||
* a0 - Address of first occurrence of 'c' or 0
|
||||
*
|
||||
* Clobbers
|
||||
* t0
|
||||
*/
|
||||
andi a1, a1, 0xff
|
||||
1:
|
||||
lbu t0, 0(a0)
|
||||
beq t0, a1, 2f
|
||||
addi a0, a0, 1
|
||||
bnez t0, 1b
|
||||
li a0, 0
|
||||
2:
|
||||
ret
|
||||
SYM_FUNC_END(strchr)
|
||||
|
||||
SYM_FUNC_ALIAS_WEAK(__pi_strchr, strchr)
|
||||
EXPORT_SYMBOL(strchr)
|
||||
@@ -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
|
||||
purgatory-y += strcmp.o strlen.o strncmp.o strnlen.o strchr.o
|
||||
endif
|
||||
|
||||
targets += $(purgatory-y)
|
||||
@@ -35,6 +35,9 @@ $(obj)/sha256.o: $(srctree)/lib/crypto/sha256.c FORCE
|
||||
$(obj)/strnlen.o: $(srctree)/arch/riscv/lib/strnlen.S FORCE
|
||||
$(call if_changed_rule,as_o_S)
|
||||
|
||||
$(obj)/strchr.o: $(srctree)/arch/riscv/lib/strchr.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
|
||||
|
||||
Reference in New Issue
Block a user