From: Heiko Stuebner <heiko@sntech.de>
To: linux-riscv@lists.infradead.org, palmer@dabbelt.com
Cc: christoph.muellner@vrull.eu, prabhakar.csengg@gmail.com,
conor@kernel.org, philipp.tomsich@vrull.eu,
ajones@ventanamicro.com, heiko@sntech.de,
emil.renner.berthing@canonical.com,
Heiko Stuebner <heiko.stuebner@vrull.eu>
Subject: [PATCH 6/7] RISC-V: add infrastructure to allow different str* implementations
Date: Thu, 10 Nov 2022 17:49:23 +0100 [thread overview]
Message-ID: <20221110164924.529386-7-heiko@sntech.de> (raw)
In-Reply-To: <20221110164924.529386-1-heiko@sntech.de>
From: Heiko Stuebner <heiko.stuebner@vrull.eu>
Depending on supported extensions on specific RISC-V cores,
optimized str* functions might make sense.
This adds basic infrastructure to allow patching the function calls
via alternatives later on.
The main idea is to have the core str* functions be inline functions
which then call the most optimized variant and this call then be
replaced via alternatives.
The big advantage is that we don't need additional calls.
Though we need to duplicate the generic functions as the main code
expects either itself or the architecture to provide the str* functions.
The added *_generic functions are done in assembler (taken from
disassembling the main-kernel functions for now) to allow us to control
the used registers.
Signed-off-by: Heiko Stuebner <heiko.stuebner@vrull.eu>
---
arch/riscv/include/asm/string.h | 66 +++++++++++++++++++++++++++++++++
arch/riscv/kernel/image-vars.h | 6 +--
arch/riscv/lib/Makefile | 3 ++
arch/riscv/lib/strcmp.S | 39 +++++++++++++++++++
arch/riscv/lib/strlen.S | 29 +++++++++++++++
arch/riscv/lib/strncmp.S | 41 ++++++++++++++++++++
6 files changed, 181 insertions(+), 3 deletions(-)
create mode 100644 arch/riscv/lib/strcmp.S
create mode 100644 arch/riscv/lib/strlen.S
create mode 100644 arch/riscv/lib/strncmp.S
diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h
index 909049366555..b98481d2d154 100644
--- a/arch/riscv/include/asm/string.h
+++ b/arch/riscv/include/asm/string.h
@@ -18,6 +18,72 @@ extern asmlinkage void *__memcpy(void *, const void *, size_t);
#define __HAVE_ARCH_MEMMOVE
extern asmlinkage void *memmove(void *, const void *, size_t);
extern asmlinkage void *__memmove(void *, const void *, size_t);
+
+#define __HAVE_ARCH_STRCMP
+extern asmlinkage int __strcmp_generic(const char *cs, const char *ct);
+
+static inline int strcmp(const char *cs, const char *ct)
+{
+#ifdef RISCV_EFISTUB
+ return __strcmp_generic(cs, ct);
+#else
+ register const char *a0 asm("a0") = cs;
+ register const char *a1 asm("a1") = ct;
+ register int a0_out asm("a0");
+
+ asm volatile("call __strcmp_generic\n\t"
+ : "=r"(a0_out)
+ : "r"(a0), "r"(a1)
+ : "ra", "t0", "t1", "t2");
+
+ return a0_out;
+#endif
+}
+
+#define __HAVE_ARCH_STRNCMP
+extern asmlinkage int __strncmp_generic(const char *cs,
+ const char *ct, size_t count);
+
+static inline int strncmp(const char *cs, const char *ct, size_t count)
+{
+#ifdef RISCV_EFISTUB
+ return __strncmp_generic(cs, ct, count);
+#else
+ register const char *a0 asm("a0") = cs;
+ register const char *a1 asm("a1") = ct;
+ register size_t a2 asm("a2") = count;
+ register int a0_out asm("a0");
+
+ asm volatile("call __strncmp_generic\n\t"
+ : "=r"(a0_out)
+ : "r"(a0), "r"(a1), "r"(a2)
+ : "ra", "t0", "t1", "t2");
+
+ return a0_out;
+#endif
+}
+
+#define __HAVE_ARCH_STRLEN
+extern asmlinkage __kernel_size_t __strlen_generic(const char *);
+
+static inline __kernel_size_t strlen(const char *s)
+{
+#ifdef RISCV_EFISTUB
+ return __strlen_generic(s);
+#else
+ register const char *a0 asm("a0") = s;
+ register int a0_out asm("a0");
+
+ asm volatile(
+ "call __strlen_generic\n\t"
+ : "=r"(a0_out)
+ : "r"(a0)
+ : "ra", "t0", "t1");
+
+ return a0_out;
+#endif
+}
+
/* For those files which don't want to check by kasan. */
#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
#define memcpy(dst, src, len) __memcpy(dst, src, len)
diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h
index d6e5f739905e..2f270b9fde63 100644
--- a/arch/riscv/kernel/image-vars.h
+++ b/arch/riscv/kernel/image-vars.h
@@ -25,10 +25,10 @@
*/
__efistub_memcmp = memcmp;
__efistub_memchr = memchr;
-__efistub_strlen = strlen;
+__efistub___strlen_generic = __strlen_generic;
__efistub_strnlen = strnlen;
-__efistub_strcmp = strcmp;
-__efistub_strncmp = strncmp;
+__efistub___strcmp_generic = __strcmp_generic;
+__efistub___strncmp_generic = __strncmp_generic;
__efistub_strrchr = strrchr;
__efistub__start = _start;
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 25d5c9664e57..6c74b0bedd60 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -3,6 +3,9 @@ lib-y += delay.o
lib-y += memcpy.o
lib-y += memset.o
lib-y += memmove.o
+lib-y += strcmp.o
+lib-y += strlen.o
+lib-y += strncmp.o
lib-$(CONFIG_MMU) += uaccess.o
lib-$(CONFIG_64BIT) += tishift.o
diff --git a/arch/riscv/lib/strcmp.S b/arch/riscv/lib/strcmp.S
new file mode 100644
index 000000000000..f23a5c5e39d8
--- /dev/null
+++ b/arch/riscv/lib/strcmp.S
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+#include <asm-generic/export.h>
+
+/* int __strcmp_generic(const char *cs, const char *ct) */
+ENTRY(__strcmp_generic)
+ /*
+ * Returns
+ * a0 - comparison result, like strncmp
+ *
+ * Parameters
+ * a0 - string1
+ * a1 - string2
+ * a2 - number of characters to compare
+ *
+ * Clobbers
+ * t0, t1, t2, t3, t4, t5
+ */
+ mv t2, a1
+1:
+ lbu t1, 0(a0)
+ lbu t0, 0(a1)
+ addi a0, a0, 1
+ addi a1, a1, 1
+ beq t1, t0, 3f
+ li a0, 1
+ bgeu t1, t0, 2f
+ li a0, -1
+2:
+ mv a1, t2
+ ret
+3:
+ bnez t1, 1b
+ li a0, 0
+ j 2b
+END(__strcmp_generic)
+EXPORT_SYMBOL(__strcmp_generic)
diff --git a/arch/riscv/lib/strlen.S b/arch/riscv/lib/strlen.S
new file mode 100644
index 000000000000..e0e7440ac724
--- /dev/null
+++ b/arch/riscv/lib/strlen.S
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+#include <asm-generic/export.h>
+
+/* int __strlen_generic(const char *s) */
+ENTRY(__strlen_generic)
+ /*
+ * Returns
+ * a0 - string length
+ *
+ * Parameters
+ * a0 - String to measure
+ *
+ * Clobbers:
+ * t0, t1
+ */
+ mv t1, a0
+1:
+ lbu t0, 0(t1)
+ bnez t0, 2f
+ sub a0, t1, a0
+ ret
+2:
+ addi t1, t1, 1
+ j 1b
+END(__strlen_generic)
+EXPORT_SYMBOL(__strlen_generic)
diff --git a/arch/riscv/lib/strncmp.S b/arch/riscv/lib/strncmp.S
new file mode 100644
index 000000000000..8d271cd0df72
--- /dev/null
+++ b/arch/riscv/lib/strncmp.S
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+#include <asm-generic/export.h>
+
+/* int __strncmp_generic(const char *cs, const char *ct, size_t count) */
+ENTRY(__strncmp_generic)
+ /*
+ * Returns
+ * a0 - comparison result, like strncmp
+ *
+ * Parameters
+ * a0 - string1
+ * a1 - string2
+ * a2 - number of characters to compare
+ *
+ * Clobbers
+ * t0, t1, t2
+ */
+ li t0, 0
+1:
+ beq a2, t0, 4f
+ add t1, a0, t0
+ add t2, a1, t0
+ lbu t1, 0(t1)
+ lbu t2, 0(t2)
+ beq t1, t2, 3f
+ li a0, 1
+ bgeu t1, t2, 2f
+ li a0, -1
+2:
+ ret
+3:
+ addi t0, t0, 1
+ bnez t1, 1b
+4:
+ li a0, 0
+ j 2b
+END(__strncmp_generic)
+EXPORT_SYMBOL(__strncmp_generic)
--
2.35.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2022-11-10 16:50 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-10 16:49 [PATCH 0/7] Zbb string optimizations and call support in alternatives Heiko Stuebner
2022-11-10 16:49 ` [PATCH 1/7] efi/riscv: libstub: mark when compiling libstub Heiko Stuebner
2022-11-13 17:16 ` Conor Dooley
2022-11-13 17:20 ` Heiko Stübner
2022-11-13 18:06 ` Conor Dooley
2022-11-10 16:49 ` [PATCH 2/7] RISC-V: add auipc elements to parse_asm header Heiko Stuebner
2022-11-13 17:18 ` Conor Dooley
2022-11-10 16:49 ` [PATCH 3/7] RISC-V: add U-type imm parsing " Heiko Stuebner
2022-11-13 19:06 ` Conor Dooley
2022-11-10 16:49 ` [PATCH 4/7] RISC-V: add rd reg " Heiko Stuebner
2022-11-13 19:08 ` Conor Dooley
2022-11-10 16:49 ` [PATCH 5/7] RISC-V: fix auipc-jalr addresses in patched alternatives Heiko Stuebner
2022-11-13 20:31 ` Conor Dooley
2022-11-14 10:57 ` Emil Renner Berthing
2022-11-14 11:35 ` Andrew Jones
2022-11-14 11:38 ` Emil Renner Berthing
2022-11-14 11:38 ` Heiko Stübner
2022-11-14 12:15 ` Andrew Jones
2022-11-14 12:29 ` Emil Renner Berthing
2022-11-14 12:47 ` Philipp Tomsich
2022-11-15 14:28 ` Lad, Prabhakar
2022-11-17 11:51 ` Heiko Stübner
2022-11-21 9:50 ` Lad, Prabhakar
2022-11-21 11:27 ` Heiko Stübner
2022-11-21 15:06 ` Lad, Prabhakar
2022-11-21 21:31 ` Lad, Prabhakar
2022-11-21 22:17 ` Heiko Stübner
2022-11-21 22:38 ` Heiko Stübner
2022-11-22 0:16 ` Lad, Prabhakar
2022-11-21 23:59 ` Lad, Prabhakar
2022-11-22 10:59 ` Lad, Prabhakar
2022-11-22 11:19 ` Heiko Stübner
2022-11-22 11:37 ` Heiko Stübner
2022-11-22 12:28 ` Lad, Prabhakar
2022-11-10 16:49 ` Heiko Stuebner [this message]
2022-11-13 22:07 ` [PATCH 6/7] RISC-V: add infrastructure to allow different str* implementations Conor Dooley
2022-11-10 16:49 ` [PATCH 7/7] RISC-V: add zbb support to string functions Heiko Stuebner
2022-11-13 23:29 ` Conor Dooley
2022-11-13 23:47 ` Heiko Stübner
2022-11-24 22:23 ` Heiko Stübner
2022-11-24 22:32 ` Conor Dooley
2022-11-24 23:51 ` Heiko Stuebner
2022-11-25 7:49 ` Andrew Jones
2022-11-25 8:17 ` Conor.Dooley
[not found] ` <CAEg0e7h9skbWPVDsz9CdB8dATN5XM9eT-uPY0A7xRZmX=qTU6A@mail.gmail.com>
2022-11-25 15:28 ` Andrew Jones
2022-11-25 16:35 ` Christoph Müllner
2022-11-25 16:39 ` Conor Dooley
2022-11-25 17:02 ` Christoph Müllner
2022-11-25 17:11 ` Conor Dooley
2022-11-25 17:42 ` Christoph Müllner
2022-11-25 16:36 ` Conor Dooley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221110164924.529386-7-heiko@sntech.de \
--to=heiko@sntech.de \
--cc=ajones@ventanamicro.com \
--cc=christoph.muellner@vrull.eu \
--cc=conor@kernel.org \
--cc=emil.renner.berthing@canonical.com \
--cc=heiko.stuebner@vrull.eu \
--cc=linux-riscv@lists.infradead.org \
--cc=palmer@dabbelt.com \
--cc=philipp.tomsich@vrull.eu \
--cc=prabhakar.csengg@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.