* [PATCH 0/2] add riscv32 double-word shifts and library test
@ 2026-04-07 5:28 Dmitry Antipov
2026-04-07 5:28 ` [PATCH 1/2] riscv: add platform-specific double word shifts for riscv32 Dmitry Antipov
2026-04-07 5:28 ` [PATCH 2/2] lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3() Dmitry Antipov
0 siblings, 2 replies; 11+ messages in thread
From: Dmitry Antipov @ 2026-04-07 5:28 UTC (permalink / raw)
To: Andrew Morton, Andy Shevchenko
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Ard Biesheuvel,
linux-riscv, Dmitry Antipov
This series should immediately follow v8 of lib and lib/cmdline enhancements,
see https://patchew.org/linux/20260212164413.889625-1-dmantipov@yandex.ru.
Started from riscv32 build quirk, now it aims to provide platform-specific
double-word shifts and corresponding KUnit test (known to work on ARM too).
Dmitry Antipov (2):
riscv: add platform-specific double word shifts for riscv32
lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3()
arch/riscv/Kconfig | 3 -
arch/riscv/kernel/image-vars.h | 7 ++
arch/riscv/lib/Makefile | 1 +
arch/riscv/lib/ashldi3.S | 36 +++++++
arch/riscv/lib/ashrdi3.S | 37 +++++++
arch/riscv/lib/lshrdi3.S | 36 +++++++
lib/Kconfig.debug | 10 ++
lib/tests/Makefile | 1 +
lib/tests/shdi3_kunit.c | 174 +++++++++++++++++++++++++++++++++
9 files changed, 302 insertions(+), 3 deletions(-)
create mode 100644 arch/riscv/lib/ashldi3.S
create mode 100644 arch/riscv/lib/ashrdi3.S
create mode 100644 arch/riscv/lib/lshrdi3.S
create mode 100644 lib/tests/shdi3_kunit.c
--
2.53.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/2] riscv: add platform-specific double word shifts for riscv32
2026-04-07 5:28 [PATCH 0/2] add riscv32 double-word shifts and library test Dmitry Antipov
@ 2026-04-07 5:28 ` Dmitry Antipov
2026-04-07 5:28 ` [PATCH 2/2] lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3() Dmitry Antipov
1 sibling, 0 replies; 11+ messages in thread
From: Dmitry Antipov @ 2026-04-07 5:28 UTC (permalink / raw)
To: Andrew Morton, Andy Shevchenko
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Ard Biesheuvel,
linux-riscv, Dmitry Antipov, kernel test robot
Add riscv32-specific '__ashldi3()', '__ashrdi3()', and '__lshrdi3()'.
This is mostly intended to fix the following link error observed
when building EFI-enabled kernel with CONFIG_EFI_STUB=y and
CONFIG_EFI_GENERIC_STUB=y:
riscv32-linux-gnu-ld: ./drivers/firmware/efi/libstub/lib-cmdline.stub.o: in function `__efistub_.L49':
__efistub_cmdline.c:(.init.text+0x1f2): undefined reference to `__efistub___ashldi3'
riscv32-linux-gnu-ld: __efistub_cmdline.c:(.init.text+0x202): undefined reference to `__efistub___lshrdi3'
Tested with 'qemu-system-riscv32 -M virt' only.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202603041925.KLKqpK6N-lkp@intel.com
Suggested-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
arch/riscv/Kconfig | 3 ---
arch/riscv/kernel/image-vars.h | 7 +++++++
arch/riscv/lib/Makefile | 1 +
arch/riscv/lib/ashldi3.S | 36 +++++++++++++++++++++++++++++++++
arch/riscv/lib/ashrdi3.S | 37 ++++++++++++++++++++++++++++++++++
arch/riscv/lib/lshrdi3.S | 36 +++++++++++++++++++++++++++++++++
6 files changed, 117 insertions(+), 3 deletions(-)
create mode 100644 arch/riscv/lib/ashldi3.S
create mode 100644 arch/riscv/lib/ashrdi3.S
create mode 100644 arch/riscv/lib/lshrdi3.S
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 90c531e6abf5..515254720da5 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -407,9 +407,6 @@ config ARCH_RV32I
bool "RV32I"
depends on NONPORTABLE
select 32BIT
- select GENERIC_LIB_ASHLDI3
- select GENERIC_LIB_ASHRDI3
- select GENERIC_LIB_LSHRDI3
select GENERIC_LIB_UCMPDI2
config ARCH_RV64I
diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h
index 3bd9d06a8b8f..d66e06daf13e 100644
--- a/arch/riscv/kernel/image-vars.h
+++ b/arch/riscv/kernel/image-vars.h
@@ -32,6 +32,13 @@ __efistub___init_text_end = __init_text_end;
__efistub_sysfb_primary_display = sysfb_primary_display;
#endif
+/*
+ * These double-word integer shifts are used
+ * by the library code and so EFI stub as well.
+ */
+PROVIDE(__efistub___lshrdi3 = __lshrdi3);
+PROVIDE(__efistub___ashldi3 = __ashldi3);
+
#endif
#endif /* __RISCV_KERNEL_IMAGE_VARS_H */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index bbc031124974..7cee3da80c68 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -13,6 +13,7 @@ ifeq ($(CONFIG_MMU), y)
lib-$(CONFIG_RISCV_ISA_V) += uaccess_vector.o
endif
lib-$(CONFIG_MMU) += uaccess.o
+lib-$(CONFIG_32BIT) += ashldi3.o ashrdi3.o lshrdi3.o
lib-$(CONFIG_64BIT) += tishift.o
lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
diff --git a/arch/riscv/lib/ashldi3.S b/arch/riscv/lib/ashldi3.S
new file mode 100644
index 000000000000..c3408862e2f6
--- /dev/null
+++ b/arch/riscv/lib/ashldi3.S
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/**
+ * Adopted for the Linux kernel from IPXE project, see
+ * https://github.com/ipxe/ipxe/blob/master/src/arch/riscv32/libgcc/llshift.S
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+
+/**
+ * Shift left
+ *
+ * @v a1:a0 Value to shift
+ * @v a2 Shift amount
+ * @ret a1:a0 Shifted value
+ */
+
+SYM_FUNC_START(__ashldi3)
+
+ /* Perform shift by 32 bits, if applicable */
+ li t0, 32
+ sub t1, t0, a2
+ bgtz t1, 1f
+ mv a1, a0
+ mv a0, zero
+1: /* Perform shift by modulo-32 bits, if applicable */
+ andi a2, a2, 0x1f
+ beqz a2, 2f
+ srl t2, a0, t1
+ sll a0, a0, a2
+ sll a1, a1, a2
+ or a1, a1, t2
+2: ret
+
+SYM_FUNC_END(__ashldi3)
+EXPORT_SYMBOL(__ashldi3)
diff --git a/arch/riscv/lib/ashrdi3.S b/arch/riscv/lib/ashrdi3.S
new file mode 100644
index 000000000000..dd42b3cbb173
--- /dev/null
+++ b/arch/riscv/lib/ashrdi3.S
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/**
+ * Adopted for the Linux kernel from IPXE project, see
+ * https://github.com/ipxe/ipxe/blob/master/src/arch/riscv32/libgcc/llshift.S
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+
+/**
+ * Arithmetic shift right
+ *
+ * @v a1:a0 Value to shift
+ * @v a2 Shift amount
+ * @ret a1:a0 Shifted value
+ */
+
+SYM_FUNC_START(__ashrdi3)
+
+ /* Perform shift by 32 bits, if applicable */
+ li t0, 32
+ sub t1, t0, a2
+ bgtz t1, 1f
+ mv a0, a1
+ srai a1, a1, 16
+ srai a1, a1, 16
+1: /* Perform shift by modulo-32 bits, if applicable */
+ andi a2, a2, 0x1f
+ beqz a2, 2f
+ sll t2, a1, t1
+ sra a1, a1, a2
+ srl a0, a0, a2
+ or a0, a0, t2
+2: ret
+
+SYM_FUNC_END(__ashrdi3)
+EXPORT_SYMBOL(__ashrdi3)
diff --git a/arch/riscv/lib/lshrdi3.S b/arch/riscv/lib/lshrdi3.S
new file mode 100644
index 000000000000..1af03985ccb7
--- /dev/null
+++ b/arch/riscv/lib/lshrdi3.S
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/**
+ * Adopted for the Linux kernel from IPXE project, see
+ * https://github.com/ipxe/ipxe/blob/master/src/arch/riscv32/libgcc/llshift.S
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+
+/**
+ * Logical shift right
+ *
+ * @v a1:a0 Value to shift
+ * @v a2 Shift amount
+ * @ret a1:a0 Shifted value
+ */
+
+SYM_FUNC_START(__lshrdi3)
+
+ /* Perform shift by 32 bits, if applicable */
+ li t0, 32
+ sub t1, t0, a2
+ bgtz t1, 1f
+ mv a0, a1
+ mv a1, zero
+1: /* Perform shift by modulo-32 bits, if applicable */
+ andi a2, a2, 0x1f
+ beqz a2, 2f
+ sll t2, a1, t1
+ srl a1, a1, a2
+ srl a0, a0, a2
+ or a0, a0, t2
+2: ret
+
+SYM_FUNC_END(__lshrdi3)
+EXPORT_SYMBOL(__lshrdi3)
--
2.53.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/2] lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3()
2026-04-07 5:28 [PATCH 0/2] add riscv32 double-word shifts and library test Dmitry Antipov
2026-04-07 5:28 ` [PATCH 1/2] riscv: add platform-specific double word shifts for riscv32 Dmitry Antipov
@ 2026-04-07 5:28 ` Dmitry Antipov
2026-04-08 19:41 ` Andy Shevchenko
1 sibling, 1 reply; 11+ messages in thread
From: Dmitry Antipov @ 2026-04-07 5:28 UTC (permalink / raw)
To: Andrew Morton, Andy Shevchenko
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Ard Biesheuvel,
linux-riscv, Dmitry Antipov
Add KUnit tests for '__ashldi3()', '__ashrdi3()', and '__lshrdi3()'
helper functions used to implement 64-bit arithmetic shift left,
arithmetic shift right and logical shift right, respectively,
on a 32-bit CPUs.
Tested with 'qemu-system-riscv32 -M virt' and 'qemu-system-arm -M virt'.
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
lib/Kconfig.debug | 10 +++
lib/tests/Makefile | 1 +
lib/tests/shdi3_kunit.c | 174 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 185 insertions(+)
create mode 100644 lib/tests/shdi3_kunit.c
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 93f356d2b3d9..b68b1325379b 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2942,6 +2942,16 @@ config BITS_TEST
If unsure, say N.
+config SHDI3_KUNIT_TEST
+ tristate "KUnit test for __ashldi3(), __ashrdi3(), and __lshrdi3()"
+ depends on KUNIT
+ depends on (32BIT || ARM)
+ help
+ This builds the unit test for __ashldi3(), __ashrdi3(), and
+ __lshrdi3() helper functions used to implement 64-bit arithmetic
+ shift left, arithmetic shift right and logical shift right,
+ respectively, on a 32-bit CPUs.
+
config SLUB_KUNIT_TEST
tristate "KUnit test for SLUB cache error detection" if !KUNIT_ALL_TESTS
depends on SLUB_DEBUG && KUNIT
diff --git a/lib/tests/Makefile b/lib/tests/Makefile
index 05f74edbc62b..db678ccdd8b1 100644
--- a/lib/tests/Makefile
+++ b/lib/tests/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_BASE64_KUNIT) += base64_kunit.o
obj-$(CONFIG_BITOPS_KUNIT) += bitops_kunit.o
obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o
obj-$(CONFIG_BITS_TEST) += test_bits.o
+obj-$(CONFIG_SHDI3_KUNIT_TEST) += shdi3_kunit.o
obj-$(CONFIG_BLACKHOLE_DEV_KUNIT_TEST) += blackhole_dev_kunit.o
obj-$(CONFIG_CHECKSUM_KUNIT) += checksum_kunit.o
obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o
diff --git a/lib/tests/shdi3_kunit.c b/lib/tests/shdi3_kunit.c
new file mode 100644
index 000000000000..6fa411554d6c
--- /dev/null
+++ b/lib/tests/shdi3_kunit.c
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR Apache-2.0
+/*
+ * Test cases for __ashldi3(), __ashrdi3(), and __lshrdi3().
+ */
+
+#include <linux/kernel.h>
+#include <linux/libgcc.h>
+#include <kunit/test.h>
+
+struct shdi3_test_entry {
+ long long input;
+ int shift;
+ long long result;
+};
+
+static const struct shdi3_test_entry ashldi3_testdata[] = {
+ /* https://github.com/llvm/llvm-project/compiler-rt/test/builtins/Unit/ashldi3_test.c */
+ { 0x0123456789ABCDEFLL, 0, 0x123456789ABCDEFLL },
+ { 0x0123456789ABCDEFLL, 1, 0x2468ACF13579BDELL },
+ { 0x0123456789ABCDEFLL, 2, 0x48D159E26AF37BCLL },
+ { 0x0123456789ABCDEFLL, 3, 0x91A2B3C4D5E6F78LL },
+ { 0x0123456789ABCDEFLL, 4, 0x123456789ABCDEF0LL },
+ { 0x0123456789ABCDEFLL, 28, 0x789ABCDEF0000000LL },
+ { 0x0123456789ABCDEFLL, 29, 0xF13579BDE0000000LL },
+ { 0x0123456789ABCDEFLL, 30, 0xE26AF37BC0000000LL },
+ { 0x0123456789ABCDEFLL, 31, 0xC4D5E6F780000000LL },
+ { 0x0123456789ABCDEFLL, 32, 0x89ABCDEF00000000LL },
+ { 0x0123456789ABCDEFLL, 33, 0x13579BDE00000000LL },
+ { 0x0123456789ABCDEFLL, 34, 0x26AF37BC00000000LL },
+ { 0x0123456789ABCDEFLL, 35, 0x4D5E6F7800000000LL },
+ { 0x0123456789ABCDEFLL, 36, 0x9ABCDEF000000000LL },
+ { 0x0123456789ABCDEFLL, 60, 0xF000000000000000LL },
+ { 0x0123456789ABCDEFLL, 61, 0xE000000000000000LL },
+ { 0x0123456789ABCDEFLL, 62, 0xC000000000000000LL },
+ { 0x0123456789ABCDEFLL, 63, 0x8000000000000000LL },
+};
+
+static void shdi3_test_ashldi3(struct kunit *test)
+{
+ const struct shdi3_test_entry *e;
+ long long ret;
+
+ for (e = ashldi3_testdata;
+ e < ashldi3_testdata + ARRAY_SIZE(ashldi3_testdata); e++) {
+ ret = __ashldi3(e->input, e->shift);
+ KUNIT_EXPECT_EQ_MSG(test, ret, e->result,
+ " when evaluating __ashldi3(%lld, %d)",
+ e->input, e->shift);
+ }
+}
+
+static const struct shdi3_test_entry ashrdi3_testdata[] = {
+ /* https://github.com/llvm/llvm-project/compiler-rt/test/builtins/Unit/ashrdi3_test.c */
+ { 0x0123456789ABCDEFLL, 0, 0x123456789ABCDEFLL },
+ { 0x0123456789ABCDEFLL, 1, 0x91A2B3C4D5E6F7LL },
+ { 0x0123456789ABCDEFLL, 2, 0x48D159E26AF37BLL },
+ { 0x0123456789ABCDEFLL, 3, 0x2468ACF13579BDLL },
+ { 0x0123456789ABCDEFLL, 4, 0x123456789ABCDELL },
+ { 0x0123456789ABCDEFLL, 28, 0x12345678LL },
+ { 0x0123456789ABCDEFLL, 29, 0x91A2B3CLL },
+ { 0x0123456789ABCDEFLL, 30, 0x48D159ELL },
+ { 0x0123456789ABCDEFLL, 31, 0x2468ACFLL },
+ { 0x0123456789ABCDEFLL, 32, 0x1234567LL },
+ { 0x0123456789ABCDEFLL, 33, 0x91A2B3LL },
+ { 0x0123456789ABCDEFLL, 34, 0x48D159LL },
+ { 0x0123456789ABCDEFLL, 35, 0x2468ACLL },
+ { 0x0123456789ABCDEFLL, 36, 0x123456LL },
+ { 0x0123456789ABCDEFLL, 60, 0 },
+ { 0x0123456789ABCDEFLL, 61, 0 },
+ { 0x0123456789ABCDEFLL, 62, 0 },
+ { 0x0123456789ABCDEFLL, 63, 0 },
+ { 0xFEDCBA9876543210LL, 0, 0xFEDCBA9876543210LL },
+ { 0xFEDCBA9876543210LL, 1, 0xFF6E5D4C3B2A1908LL },
+ { 0xFEDCBA9876543210LL, 2, 0xFFB72EA61D950C84LL },
+ { 0xFEDCBA9876543210LL, 3, 0xFFDB97530ECA8642LL },
+ { 0xFEDCBA9876543210LL, 4, 0xFFEDCBA987654321LL },
+ { 0xFEDCBA9876543210LL, 28, 0xFFFFFFFFEDCBA987LL },
+ { 0xFEDCBA9876543210LL, 29, 0xFFFFFFFFF6E5D4C3LL },
+ { 0xFEDCBA9876543210LL, 30, 0xFFFFFFFFFB72EA61LL },
+ { 0xFEDCBA9876543210LL, 31, 0xFFFFFFFFFDB97530LL },
+ { 0xFEDCBA9876543210LL, 32, 0xFFFFFFFFFEDCBA98LL },
+ { 0xFEDCBA9876543210LL, 33, 0xFFFFFFFFFF6E5D4CLL },
+ { 0xFEDCBA9876543210LL, 34, 0xFFFFFFFFFFB72EA6LL },
+ { 0xFEDCBA9876543210LL, 35, 0xFFFFFFFFFFDB9753LL },
+ { 0xFEDCBA9876543210LL, 36, 0xFFFFFFFFFFEDCBA9LL },
+ { 0xAEDCBA9876543210LL, 60, 0xFFFFFFFFFFFFFFFALL },
+ { 0xAEDCBA9876543210LL, 61, 0xFFFFFFFFFFFFFFFDLL },
+ { 0xAEDCBA9876543210LL, 62, 0xFFFFFFFFFFFFFFFELL },
+ { 0xAEDCBA9876543210LL, 63, 0xFFFFFFFFFFFFFFFFLL },
+};
+
+static void shdi3_test_ashrdi3(struct kunit *test)
+{
+ const struct shdi3_test_entry *e;
+ long long ret;
+
+ for (e = ashrdi3_testdata;
+ e < ashrdi3_testdata + ARRAY_SIZE(ashrdi3_testdata); e++) {
+ ret = __ashrdi3(e->input, e->shift);
+ KUNIT_EXPECT_EQ_MSG(test, ret, e->result,
+ " when evaluating __ashrdi3(%lld, %d)",
+ e->input, e->shift);
+ }
+}
+
+static const struct shdi3_test_entry lshrdi3_testdata[] = {
+ /* https://github.com/llvm/llvm-project/compiler-rt/test/builtins/Unit/lshrdi3_test.c */
+ { 0x0123456789ABCDEFLL, 0, 0x123456789ABCDEFLL },
+ { 0x0123456789ABCDEFLL, 1, 0x91A2B3C4D5E6F7LL },
+ { 0x0123456789ABCDEFLL, 2, 0x48D159E26AF37BLL },
+ { 0x0123456789ABCDEFLL, 3, 0x2468ACF13579BDLL },
+ { 0x0123456789ABCDEFLL, 4, 0x123456789ABCDELL },
+ { 0x0123456789ABCDEFLL, 28, 0x12345678LL },
+ { 0x0123456789ABCDEFLL, 29, 0x91A2B3CLL },
+ { 0x0123456789ABCDEFLL, 30, 0x48D159ELL },
+ { 0x0123456789ABCDEFLL, 31, 0x2468ACFLL },
+ { 0x0123456789ABCDEFLL, 32, 0x1234567LL },
+ { 0x0123456789ABCDEFLL, 33, 0x91A2B3LL },
+ { 0x0123456789ABCDEFLL, 34, 0x48D159LL },
+ { 0x0123456789ABCDEFLL, 35, 0x2468ACLL },
+ { 0x0123456789ABCDEFLL, 36, 0x123456LL },
+ { 0x0123456789ABCDEFLL, 60, 0 },
+ { 0x0123456789ABCDEFLL, 61, 0 },
+ { 0x0123456789ABCDEFLL, 62, 0 },
+ { 0x0123456789ABCDEFLL, 63, 0 },
+ { 0xFEDCBA9876543210LL, 0, 0xFEDCBA9876543210LL },
+ { 0xFEDCBA9876543210LL, 1, 0x7F6E5D4C3B2A1908LL },
+ { 0xFEDCBA9876543210LL, 2, 0x3FB72EA61D950C84LL },
+ { 0xFEDCBA9876543210LL, 3, 0x1FDB97530ECA8642LL },
+ { 0xFEDCBA9876543210LL, 4, 0xFEDCBA987654321LL },
+ { 0xFEDCBA9876543210LL, 28, 0xFEDCBA987LL },
+ { 0xFEDCBA9876543210LL, 29, 0x7F6E5D4C3LL },
+ { 0xFEDCBA9876543210LL, 30, 0x3FB72EA61LL },
+ { 0xFEDCBA9876543210LL, 31, 0x1FDB97530LL },
+ { 0xFEDCBA9876543210LL, 32, 0xFEDCBA98LL },
+ { 0xFEDCBA9876543210LL, 33, 0x7F6E5D4CLL },
+ { 0xFEDCBA9876543210LL, 34, 0x3FB72EA6LL },
+ { 0xFEDCBA9876543210LL, 35, 0x1FDB9753LL },
+ { 0xFEDCBA9876543210LL, 36, 0xFEDCBA9LL },
+ { 0xAEDCBA9876543210LL, 60, 0xALL },
+ { 0xAEDCBA9876543210LL, 61, 0x5LL },
+ { 0xAEDCBA9876543210LL, 62, 0x2LL },
+ { 0xAEDCBA9876543210LL, 63, 0x1LL },
+};
+
+static void shdi3_test_lshrdi3(struct kunit *test)
+{
+ const struct shdi3_test_entry *e;
+ long long ret;
+
+ for (e = lshrdi3_testdata;
+ e < lshrdi3_testdata + ARRAY_SIZE(lshrdi3_testdata); e++) {
+ ret = __lshrdi3(e->input, e->shift);
+ KUNIT_EXPECT_EQ_MSG(test, ret, e->result,
+ " when evaluating __lshrdi3(%lld, %d)",
+ e->input, e->shift);
+ }
+}
+
+static struct kunit_case shdi3_test_cases[] = {
+ KUNIT_CASE(shdi3_test_ashldi3),
+ KUNIT_CASE(shdi3_test_ashrdi3),
+ KUNIT_CASE(shdi3_test_lshrdi3),
+ {}
+};
+
+static struct kunit_suite shdi3_test_suite = {
+ .name = "shdi3",
+ .test_cases = shdi3_test_cases,
+};
+kunit_test_suite(shdi3_test_suite);
+
+MODULE_DESCRIPTION("Test cases for __ashldi3(), __ashrdi3(), and __lshrdi3()");
+MODULE_LICENSE("GPL");
--
2.53.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3()
2026-04-07 5:28 ` [PATCH 2/2] lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3() Dmitry Antipov
@ 2026-04-08 19:41 ` Andy Shevchenko
2026-04-09 3:38 ` [PATCH v2 0/2] add riscv32 double-word shifts and library test Dmitry Antipov
0 siblings, 1 reply; 11+ messages in thread
From: Andy Shevchenko @ 2026-04-08 19:41 UTC (permalink / raw)
To: Dmitry Antipov
Cc: Andrew Morton, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Ard Biesheuvel, linux-riscv
On Tue, Apr 07, 2026 at 08:28:24AM +0300, Dmitry Antipov wrote:
> Add KUnit tests for '__ashldi3()', '__ashrdi3()', and '__lshrdi3()'
> helper functions used to implement 64-bit arithmetic shift left,
> arithmetic shift right and logical shift right, respectively,
> on a 32-bit CPUs.
>
> Tested with 'qemu-system-riscv32 -M virt' and 'qemu-system-arm -M virt'.
...
> +#include <linux/kernel.h>
> +#include <linux/libgcc.h>
> +#include <kunit/test.h>
Always try to follow IWYU principle. The kernel.h is a niche header and rarely
should be included. I do not see any use of it here. OTOH module.h and
array_size.h are missing.
With that being addressed, I'm always in love with new test cases!
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
--
With Best Regards,
Andy Shevchenko
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 0/2] add riscv32 double-word shifts and library test
2026-04-08 19:41 ` Andy Shevchenko
@ 2026-04-09 3:38 ` Dmitry Antipov
2026-04-09 3:38 ` [PATCH v2 1/2] riscv: add platform-specific double word shifts for riscv32 Dmitry Antipov
2026-04-09 3:38 ` [PATCH v2 2/2] lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3() Dmitry Antipov
0 siblings, 2 replies; 11+ messages in thread
From: Dmitry Antipov @ 2026-04-09 3:38 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Andrew Morton, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Ard Biesheuvel, linux-riscv, Dmitry Antipov
This series should immediately follow v8 of lib and lib/cmdline enhancements,
see https://patchew.org/linux/20260212164413.889625-1-dmantipov@yandex.ru.
Started from riscv32 build quirk, now it aims to provide platform-specific
double-word shifts and corresponding KUnit test (tested on ARM as well).
Dmitry Antipov (2):
riscv: add platform-specific double word shifts for riscv32
lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3()
arch/riscv/Kconfig | 3 -
arch/riscv/kernel/image-vars.h | 7 ++
arch/riscv/lib/Makefile | 1 +
arch/riscv/lib/ashldi3.S | 36 +++++++
arch/riscv/lib/ashrdi3.S | 37 +++++++
arch/riscv/lib/lshrdi3.S | 36 +++++++
lib/Kconfig.debug | 10 ++
lib/tests/Makefile | 1 +
lib/tests/shdi3_kunit.c | 175 +++++++++++++++++++++++++++++++++
9 files changed, 303 insertions(+), 3 deletions(-)
create mode 100644 arch/riscv/lib/ashldi3.S
create mode 100644 arch/riscv/lib/ashrdi3.S
create mode 100644 arch/riscv/lib/lshrdi3.S
create mode 100644 lib/tests/shdi3_kunit.c
--
2.53.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 1/2] riscv: add platform-specific double word shifts for riscv32
2026-04-09 3:38 ` [PATCH v2 0/2] add riscv32 double-word shifts and library test Dmitry Antipov
@ 2026-04-09 3:38 ` Dmitry Antipov
2026-04-09 23:22 ` Charlie Jenkins
2026-04-09 3:38 ` [PATCH v2 2/2] lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3() Dmitry Antipov
1 sibling, 1 reply; 11+ messages in thread
From: Dmitry Antipov @ 2026-04-09 3:38 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Andrew Morton, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Ard Biesheuvel, linux-riscv, Dmitry Antipov, kernel test robot
Add riscv32-specific '__ashldi3()', '__ashrdi3()', and '__lshrdi3()'.
Initially it was intended to fix the following link error observed
when building EFI-enabled kernel with CONFIG_EFI_STUB=y and
CONFIG_EFI_GENERIC_STUB=y:
riscv32-linux-gnu-ld: ./drivers/firmware/efi/libstub/lib-cmdline.stub.o: in function `__efistub_.L49':
__efistub_cmdline.c:(.init.text+0x1f2): undefined reference to `__efistub___ashldi3'
riscv32-linux-gnu-ld: __efistub_cmdline.c:(.init.text+0x202): undefined reference to `__efistub___lshrdi3'
Reported at [1] trying to build https://patchew.org/linux/20260212164413.889625-1-dmantipov@yandex.ru,
tested with 'qemu-system-riscv32 -M virt' only.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202603041925.KLKqpK6N-lkp@intel.com [1]
Suggested-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
v2: adjust commit message
---
arch/riscv/Kconfig | 3 ---
arch/riscv/kernel/image-vars.h | 7 +++++++
arch/riscv/lib/Makefile | 1 +
arch/riscv/lib/ashldi3.S | 36 +++++++++++++++++++++++++++++++++
arch/riscv/lib/ashrdi3.S | 37 ++++++++++++++++++++++++++++++++++
arch/riscv/lib/lshrdi3.S | 36 +++++++++++++++++++++++++++++++++
6 files changed, 117 insertions(+), 3 deletions(-)
create mode 100644 arch/riscv/lib/ashldi3.S
create mode 100644 arch/riscv/lib/ashrdi3.S
create mode 100644 arch/riscv/lib/lshrdi3.S
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 90c531e6abf5..515254720da5 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -407,9 +407,6 @@ config ARCH_RV32I
bool "RV32I"
depends on NONPORTABLE
select 32BIT
- select GENERIC_LIB_ASHLDI3
- select GENERIC_LIB_ASHRDI3
- select GENERIC_LIB_LSHRDI3
select GENERIC_LIB_UCMPDI2
config ARCH_RV64I
diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h
index 3bd9d06a8b8f..d66e06daf13e 100644
--- a/arch/riscv/kernel/image-vars.h
+++ b/arch/riscv/kernel/image-vars.h
@@ -32,6 +32,13 @@ __efistub___init_text_end = __init_text_end;
__efistub_sysfb_primary_display = sysfb_primary_display;
#endif
+/*
+ * These double-word integer shifts are used
+ * by the library code and so EFI stub as well.
+ */
+PROVIDE(__efistub___lshrdi3 = __lshrdi3);
+PROVIDE(__efistub___ashldi3 = __ashldi3);
+
#endif
#endif /* __RISCV_KERNEL_IMAGE_VARS_H */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index bbc031124974..7cee3da80c68 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -13,6 +13,7 @@ ifeq ($(CONFIG_MMU), y)
lib-$(CONFIG_RISCV_ISA_V) += uaccess_vector.o
endif
lib-$(CONFIG_MMU) += uaccess.o
+lib-$(CONFIG_32BIT) += ashldi3.o ashrdi3.o lshrdi3.o
lib-$(CONFIG_64BIT) += tishift.o
lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
diff --git a/arch/riscv/lib/ashldi3.S b/arch/riscv/lib/ashldi3.S
new file mode 100644
index 000000000000..c3408862e2f6
--- /dev/null
+++ b/arch/riscv/lib/ashldi3.S
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/**
+ * Adopted for the Linux kernel from IPXE project, see
+ * https://github.com/ipxe/ipxe/blob/master/src/arch/riscv32/libgcc/llshift.S
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+
+/**
+ * Shift left
+ *
+ * @v a1:a0 Value to shift
+ * @v a2 Shift amount
+ * @ret a1:a0 Shifted value
+ */
+
+SYM_FUNC_START(__ashldi3)
+
+ /* Perform shift by 32 bits, if applicable */
+ li t0, 32
+ sub t1, t0, a2
+ bgtz t1, 1f
+ mv a1, a0
+ mv a0, zero
+1: /* Perform shift by modulo-32 bits, if applicable */
+ andi a2, a2, 0x1f
+ beqz a2, 2f
+ srl t2, a0, t1
+ sll a0, a0, a2
+ sll a1, a1, a2
+ or a1, a1, t2
+2: ret
+
+SYM_FUNC_END(__ashldi3)
+EXPORT_SYMBOL(__ashldi3)
diff --git a/arch/riscv/lib/ashrdi3.S b/arch/riscv/lib/ashrdi3.S
new file mode 100644
index 000000000000..dd42b3cbb173
--- /dev/null
+++ b/arch/riscv/lib/ashrdi3.S
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/**
+ * Adopted for the Linux kernel from IPXE project, see
+ * https://github.com/ipxe/ipxe/blob/master/src/arch/riscv32/libgcc/llshift.S
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+
+/**
+ * Arithmetic shift right
+ *
+ * @v a1:a0 Value to shift
+ * @v a2 Shift amount
+ * @ret a1:a0 Shifted value
+ */
+
+SYM_FUNC_START(__ashrdi3)
+
+ /* Perform shift by 32 bits, if applicable */
+ li t0, 32
+ sub t1, t0, a2
+ bgtz t1, 1f
+ mv a0, a1
+ srai a1, a1, 16
+ srai a1, a1, 16
+1: /* Perform shift by modulo-32 bits, if applicable */
+ andi a2, a2, 0x1f
+ beqz a2, 2f
+ sll t2, a1, t1
+ sra a1, a1, a2
+ srl a0, a0, a2
+ or a0, a0, t2
+2: ret
+
+SYM_FUNC_END(__ashrdi3)
+EXPORT_SYMBOL(__ashrdi3)
diff --git a/arch/riscv/lib/lshrdi3.S b/arch/riscv/lib/lshrdi3.S
new file mode 100644
index 000000000000..1af03985ccb7
--- /dev/null
+++ b/arch/riscv/lib/lshrdi3.S
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/**
+ * Adopted for the Linux kernel from IPXE project, see
+ * https://github.com/ipxe/ipxe/blob/master/src/arch/riscv32/libgcc/llshift.S
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+
+/**
+ * Logical shift right
+ *
+ * @v a1:a0 Value to shift
+ * @v a2 Shift amount
+ * @ret a1:a0 Shifted value
+ */
+
+SYM_FUNC_START(__lshrdi3)
+
+ /* Perform shift by 32 bits, if applicable */
+ li t0, 32
+ sub t1, t0, a2
+ bgtz t1, 1f
+ mv a0, a1
+ mv a1, zero
+1: /* Perform shift by modulo-32 bits, if applicable */
+ andi a2, a2, 0x1f
+ beqz a2, 2f
+ sll t2, a1, t1
+ srl a1, a1, a2
+ srl a0, a0, a2
+ or a0, a0, t2
+2: ret
+
+SYM_FUNC_END(__lshrdi3)
+EXPORT_SYMBOL(__lshrdi3)
--
2.53.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 2/2] lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3()
2026-04-09 3:38 ` [PATCH v2 0/2] add riscv32 double-word shifts and library test Dmitry Antipov
2026-04-09 3:38 ` [PATCH v2 1/2] riscv: add platform-specific double word shifts for riscv32 Dmitry Antipov
@ 2026-04-09 3:38 ` Dmitry Antipov
2026-04-09 21:02 ` Charlie Jenkins
1 sibling, 1 reply; 11+ messages in thread
From: Dmitry Antipov @ 2026-04-09 3:38 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Andrew Morton, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Ard Biesheuvel, linux-riscv, Dmitry Antipov
Add KUnit tests for '__ashldi3()', '__ashrdi3()', and '__lshrdi3()'
helper functions used to implement 64-bit arithmetic shift left,
arithmetic shift right and logical shift right, respectively,
on a 32-bit CPUs.
Tested with 'qemu-system-riscv32 -M virt' and 'qemu-system-arm -M virt'.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
v2: include test-specific headers rather than generic linux/kernel.h
---
lib/Kconfig.debug | 10 +++
lib/tests/Makefile | 1 +
lib/tests/shdi3_kunit.c | 175 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 186 insertions(+)
create mode 100644 lib/tests/shdi3_kunit.c
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 93f356d2b3d9..b68b1325379b 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2942,6 +2942,16 @@ config BITS_TEST
If unsure, say N.
+config SHDI3_KUNIT_TEST
+ tristate "KUnit test for __ashldi3(), __ashrdi3(), and __lshrdi3()"
+ depends on KUNIT
+ depends on (32BIT || ARM)
+ help
+ This builds the unit test for __ashldi3(), __ashrdi3(), and
+ __lshrdi3() helper functions used to implement 64-bit arithmetic
+ shift left, arithmetic shift right and logical shift right,
+ respectively, on a 32-bit CPUs.
+
config SLUB_KUNIT_TEST
tristate "KUnit test for SLUB cache error detection" if !KUNIT_ALL_TESTS
depends on SLUB_DEBUG && KUNIT
diff --git a/lib/tests/Makefile b/lib/tests/Makefile
index 05f74edbc62b..db678ccdd8b1 100644
--- a/lib/tests/Makefile
+++ b/lib/tests/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_BASE64_KUNIT) += base64_kunit.o
obj-$(CONFIG_BITOPS_KUNIT) += bitops_kunit.o
obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o
obj-$(CONFIG_BITS_TEST) += test_bits.o
+obj-$(CONFIG_SHDI3_KUNIT_TEST) += shdi3_kunit.o
obj-$(CONFIG_BLACKHOLE_DEV_KUNIT_TEST) += blackhole_dev_kunit.o
obj-$(CONFIG_CHECKSUM_KUNIT) += checksum_kunit.o
obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o
diff --git a/lib/tests/shdi3_kunit.c b/lib/tests/shdi3_kunit.c
new file mode 100644
index 000000000000..44f65e66512b
--- /dev/null
+++ b/lib/tests/shdi3_kunit.c
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR Apache-2.0
+/*
+ * Test cases for __ashldi3(), __ashrdi3(), and __lshrdi3().
+ */
+
+#include <linux/array_size.h>
+#include <linux/module.h>
+#include <linux/libgcc.h>
+#include <kunit/test.h>
+
+struct shdi3_test_entry {
+ long long input;
+ int shift;
+ long long result;
+};
+
+static const struct shdi3_test_entry ashldi3_testdata[] = {
+ /* https://github.com/llvm/llvm-project/compiler-rt/test/builtins/Unit/ashldi3_test.c */
+ { 0x0123456789ABCDEFLL, 0, 0x123456789ABCDEFLL },
+ { 0x0123456789ABCDEFLL, 1, 0x2468ACF13579BDELL },
+ { 0x0123456789ABCDEFLL, 2, 0x48D159E26AF37BCLL },
+ { 0x0123456789ABCDEFLL, 3, 0x91A2B3C4D5E6F78LL },
+ { 0x0123456789ABCDEFLL, 4, 0x123456789ABCDEF0LL },
+ { 0x0123456789ABCDEFLL, 28, 0x789ABCDEF0000000LL },
+ { 0x0123456789ABCDEFLL, 29, 0xF13579BDE0000000LL },
+ { 0x0123456789ABCDEFLL, 30, 0xE26AF37BC0000000LL },
+ { 0x0123456789ABCDEFLL, 31, 0xC4D5E6F780000000LL },
+ { 0x0123456789ABCDEFLL, 32, 0x89ABCDEF00000000LL },
+ { 0x0123456789ABCDEFLL, 33, 0x13579BDE00000000LL },
+ { 0x0123456789ABCDEFLL, 34, 0x26AF37BC00000000LL },
+ { 0x0123456789ABCDEFLL, 35, 0x4D5E6F7800000000LL },
+ { 0x0123456789ABCDEFLL, 36, 0x9ABCDEF000000000LL },
+ { 0x0123456789ABCDEFLL, 60, 0xF000000000000000LL },
+ { 0x0123456789ABCDEFLL, 61, 0xE000000000000000LL },
+ { 0x0123456789ABCDEFLL, 62, 0xC000000000000000LL },
+ { 0x0123456789ABCDEFLL, 63, 0x8000000000000000LL },
+};
+
+static void shdi3_test_ashldi3(struct kunit *test)
+{
+ const struct shdi3_test_entry *e;
+ long long ret;
+
+ for (e = ashldi3_testdata;
+ e < ashldi3_testdata + ARRAY_SIZE(ashldi3_testdata); e++) {
+ ret = __ashldi3(e->input, e->shift);
+ KUNIT_EXPECT_EQ_MSG(test, ret, e->result,
+ " when evaluating __ashldi3(%lld, %d)",
+ e->input, e->shift);
+ }
+}
+
+static const struct shdi3_test_entry ashrdi3_testdata[] = {
+ /* https://github.com/llvm/llvm-project/compiler-rt/test/builtins/Unit/ashrdi3_test.c */
+ { 0x0123456789ABCDEFLL, 0, 0x123456789ABCDEFLL },
+ { 0x0123456789ABCDEFLL, 1, 0x91A2B3C4D5E6F7LL },
+ { 0x0123456789ABCDEFLL, 2, 0x48D159E26AF37BLL },
+ { 0x0123456789ABCDEFLL, 3, 0x2468ACF13579BDLL },
+ { 0x0123456789ABCDEFLL, 4, 0x123456789ABCDELL },
+ { 0x0123456789ABCDEFLL, 28, 0x12345678LL },
+ { 0x0123456789ABCDEFLL, 29, 0x91A2B3CLL },
+ { 0x0123456789ABCDEFLL, 30, 0x48D159ELL },
+ { 0x0123456789ABCDEFLL, 31, 0x2468ACFLL },
+ { 0x0123456789ABCDEFLL, 32, 0x1234567LL },
+ { 0x0123456789ABCDEFLL, 33, 0x91A2B3LL },
+ { 0x0123456789ABCDEFLL, 34, 0x48D159LL },
+ { 0x0123456789ABCDEFLL, 35, 0x2468ACLL },
+ { 0x0123456789ABCDEFLL, 36, 0x123456LL },
+ { 0x0123456789ABCDEFLL, 60, 0 },
+ { 0x0123456789ABCDEFLL, 61, 0 },
+ { 0x0123456789ABCDEFLL, 62, 0 },
+ { 0x0123456789ABCDEFLL, 63, 0 },
+ { 0xFEDCBA9876543210LL, 0, 0xFEDCBA9876543210LL },
+ { 0xFEDCBA9876543210LL, 1, 0xFF6E5D4C3B2A1908LL },
+ { 0xFEDCBA9876543210LL, 2, 0xFFB72EA61D950C84LL },
+ { 0xFEDCBA9876543210LL, 3, 0xFFDB97530ECA8642LL },
+ { 0xFEDCBA9876543210LL, 4, 0xFFEDCBA987654321LL },
+ { 0xFEDCBA9876543210LL, 28, 0xFFFFFFFFEDCBA987LL },
+ { 0xFEDCBA9876543210LL, 29, 0xFFFFFFFFF6E5D4C3LL },
+ { 0xFEDCBA9876543210LL, 30, 0xFFFFFFFFFB72EA61LL },
+ { 0xFEDCBA9876543210LL, 31, 0xFFFFFFFFFDB97530LL },
+ { 0xFEDCBA9876543210LL, 32, 0xFFFFFFFFFEDCBA98LL },
+ { 0xFEDCBA9876543210LL, 33, 0xFFFFFFFFFF6E5D4CLL },
+ { 0xFEDCBA9876543210LL, 34, 0xFFFFFFFFFFB72EA6LL },
+ { 0xFEDCBA9876543210LL, 35, 0xFFFFFFFFFFDB9753LL },
+ { 0xFEDCBA9876543210LL, 36, 0xFFFFFFFFFFEDCBA9LL },
+ { 0xAEDCBA9876543210LL, 60, 0xFFFFFFFFFFFFFFFALL },
+ { 0xAEDCBA9876543210LL, 61, 0xFFFFFFFFFFFFFFFDLL },
+ { 0xAEDCBA9876543210LL, 62, 0xFFFFFFFFFFFFFFFELL },
+ { 0xAEDCBA9876543210LL, 63, 0xFFFFFFFFFFFFFFFFLL },
+};
+
+static void shdi3_test_ashrdi3(struct kunit *test)
+{
+ const struct shdi3_test_entry *e;
+ long long ret;
+
+ for (e = ashrdi3_testdata;
+ e < ashrdi3_testdata + ARRAY_SIZE(ashrdi3_testdata); e++) {
+ ret = __ashrdi3(e->input, e->shift);
+ KUNIT_EXPECT_EQ_MSG(test, ret, e->result,
+ " when evaluating __ashrdi3(%lld, %d)",
+ e->input, e->shift);
+ }
+}
+
+static const struct shdi3_test_entry lshrdi3_testdata[] = {
+ /* https://github.com/llvm/llvm-project/compiler-rt/test/builtins/Unit/lshrdi3_test.c */
+ { 0x0123456789ABCDEFLL, 0, 0x123456789ABCDEFLL },
+ { 0x0123456789ABCDEFLL, 1, 0x91A2B3C4D5E6F7LL },
+ { 0x0123456789ABCDEFLL, 2, 0x48D159E26AF37BLL },
+ { 0x0123456789ABCDEFLL, 3, 0x2468ACF13579BDLL },
+ { 0x0123456789ABCDEFLL, 4, 0x123456789ABCDELL },
+ { 0x0123456789ABCDEFLL, 28, 0x12345678LL },
+ { 0x0123456789ABCDEFLL, 29, 0x91A2B3CLL },
+ { 0x0123456789ABCDEFLL, 30, 0x48D159ELL },
+ { 0x0123456789ABCDEFLL, 31, 0x2468ACFLL },
+ { 0x0123456789ABCDEFLL, 32, 0x1234567LL },
+ { 0x0123456789ABCDEFLL, 33, 0x91A2B3LL },
+ { 0x0123456789ABCDEFLL, 34, 0x48D159LL },
+ { 0x0123456789ABCDEFLL, 35, 0x2468ACLL },
+ { 0x0123456789ABCDEFLL, 36, 0x123456LL },
+ { 0x0123456789ABCDEFLL, 60, 0 },
+ { 0x0123456789ABCDEFLL, 61, 0 },
+ { 0x0123456789ABCDEFLL, 62, 0 },
+ { 0x0123456789ABCDEFLL, 63, 0 },
+ { 0xFEDCBA9876543210LL, 0, 0xFEDCBA9876543210LL },
+ { 0xFEDCBA9876543210LL, 1, 0x7F6E5D4C3B2A1908LL },
+ { 0xFEDCBA9876543210LL, 2, 0x3FB72EA61D950C84LL },
+ { 0xFEDCBA9876543210LL, 3, 0x1FDB97530ECA8642LL },
+ { 0xFEDCBA9876543210LL, 4, 0xFEDCBA987654321LL },
+ { 0xFEDCBA9876543210LL, 28, 0xFEDCBA987LL },
+ { 0xFEDCBA9876543210LL, 29, 0x7F6E5D4C3LL },
+ { 0xFEDCBA9876543210LL, 30, 0x3FB72EA61LL },
+ { 0xFEDCBA9876543210LL, 31, 0x1FDB97530LL },
+ { 0xFEDCBA9876543210LL, 32, 0xFEDCBA98LL },
+ { 0xFEDCBA9876543210LL, 33, 0x7F6E5D4CLL },
+ { 0xFEDCBA9876543210LL, 34, 0x3FB72EA6LL },
+ { 0xFEDCBA9876543210LL, 35, 0x1FDB9753LL },
+ { 0xFEDCBA9876543210LL, 36, 0xFEDCBA9LL },
+ { 0xAEDCBA9876543210LL, 60, 0xALL },
+ { 0xAEDCBA9876543210LL, 61, 0x5LL },
+ { 0xAEDCBA9876543210LL, 62, 0x2LL },
+ { 0xAEDCBA9876543210LL, 63, 0x1LL },
+};
+
+static void shdi3_test_lshrdi3(struct kunit *test)
+{
+ const struct shdi3_test_entry *e;
+ long long ret;
+
+ for (e = lshrdi3_testdata;
+ e < lshrdi3_testdata + ARRAY_SIZE(lshrdi3_testdata); e++) {
+ ret = __lshrdi3(e->input, e->shift);
+ KUNIT_EXPECT_EQ_MSG(test, ret, e->result,
+ " when evaluating __lshrdi3(%lld, %d)",
+ e->input, e->shift);
+ }
+}
+
+static struct kunit_case shdi3_test_cases[] = {
+ KUNIT_CASE(shdi3_test_ashldi3),
+ KUNIT_CASE(shdi3_test_ashrdi3),
+ KUNIT_CASE(shdi3_test_lshrdi3),
+ {}
+};
+
+static struct kunit_suite shdi3_test_suite = {
+ .name = "shdi3",
+ .test_cases = shdi3_test_cases,
+};
+kunit_test_suite(shdi3_test_suite);
+
+MODULE_DESCRIPTION("Test cases for __ashldi3(), __ashrdi3(), and __lshrdi3()");
+MODULE_LICENSE("GPL");
--
2.53.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/2] lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3()
2026-04-09 3:38 ` [PATCH v2 2/2] lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3() Dmitry Antipov
@ 2026-04-09 21:02 ` Charlie Jenkins
0 siblings, 0 replies; 11+ messages in thread
From: Charlie Jenkins @ 2026-04-09 21:02 UTC (permalink / raw)
To: Dmitry Antipov
Cc: Andy Shevchenko, Andrew Morton, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Ard Biesheuvel, linux-riscv
On Thu, Apr 09, 2026 at 06:38:24AM +0300, Dmitry Antipov wrote:
> Add KUnit tests for '__ashldi3()', '__ashrdi3()', and '__lshrdi3()'
> helper functions used to implement 64-bit arithmetic shift left,
> arithmetic shift right and logical shift right, respectively,
> on a 32-bit CPUs.
>
> Tested with 'qemu-system-riscv32 -M virt' and 'qemu-system-arm -M virt'.
>
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
> Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
I was able to reproduce these three tests passing on riscv32 qemu.
Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
> ---
> v2: include test-specific headers rather than generic linux/kernel.h
> ---
> lib/Kconfig.debug | 10 +++
> lib/tests/Makefile | 1 +
> lib/tests/shdi3_kunit.c | 175 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 186 insertions(+)
> create mode 100644 lib/tests/shdi3_kunit.c
>
> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> index 93f356d2b3d9..b68b1325379b 100644
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -2942,6 +2942,16 @@ config BITS_TEST
>
> If unsure, say N.
>
> +config SHDI3_KUNIT_TEST
> + tristate "KUnit test for __ashldi3(), __ashrdi3(), and __lshrdi3()"
> + depends on KUNIT
> + depends on (32BIT || ARM)
> + help
> + This builds the unit test for __ashldi3(), __ashrdi3(), and
> + __lshrdi3() helper functions used to implement 64-bit arithmetic
> + shift left, arithmetic shift right and logical shift right,
> + respectively, on a 32-bit CPUs.
> +
> config SLUB_KUNIT_TEST
> tristate "KUnit test for SLUB cache error detection" if !KUNIT_ALL_TESTS
> depends on SLUB_DEBUG && KUNIT
> diff --git a/lib/tests/Makefile b/lib/tests/Makefile
> index 05f74edbc62b..db678ccdd8b1 100644
> --- a/lib/tests/Makefile
> +++ b/lib/tests/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_BASE64_KUNIT) += base64_kunit.o
> obj-$(CONFIG_BITOPS_KUNIT) += bitops_kunit.o
> obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o
> obj-$(CONFIG_BITS_TEST) += test_bits.o
> +obj-$(CONFIG_SHDI3_KUNIT_TEST) += shdi3_kunit.o
> obj-$(CONFIG_BLACKHOLE_DEV_KUNIT_TEST) += blackhole_dev_kunit.o
> obj-$(CONFIG_CHECKSUM_KUNIT) += checksum_kunit.o
> obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o
> diff --git a/lib/tests/shdi3_kunit.c b/lib/tests/shdi3_kunit.c
> new file mode 100644
> index 000000000000..44f65e66512b
> --- /dev/null
> +++ b/lib/tests/shdi3_kunit.c
> @@ -0,0 +1,175 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later OR Apache-2.0
> +/*
> + * Test cases for __ashldi3(), __ashrdi3(), and __lshrdi3().
> + */
> +
> +#include <linux/array_size.h>
> +#include <linux/module.h>
> +#include <linux/libgcc.h>
> +#include <kunit/test.h>
> +
> +struct shdi3_test_entry {
> + long long input;
> + int shift;
> + long long result;
> +};
> +
> +static const struct shdi3_test_entry ashldi3_testdata[] = {
> + /* https://github.com/llvm/llvm-project/compiler-rt/test/builtins/Unit/ashldi3_test.c */
> + { 0x0123456789ABCDEFLL, 0, 0x123456789ABCDEFLL },
> + { 0x0123456789ABCDEFLL, 1, 0x2468ACF13579BDELL },
> + { 0x0123456789ABCDEFLL, 2, 0x48D159E26AF37BCLL },
> + { 0x0123456789ABCDEFLL, 3, 0x91A2B3C4D5E6F78LL },
> + { 0x0123456789ABCDEFLL, 4, 0x123456789ABCDEF0LL },
> + { 0x0123456789ABCDEFLL, 28, 0x789ABCDEF0000000LL },
> + { 0x0123456789ABCDEFLL, 29, 0xF13579BDE0000000LL },
> + { 0x0123456789ABCDEFLL, 30, 0xE26AF37BC0000000LL },
> + { 0x0123456789ABCDEFLL, 31, 0xC4D5E6F780000000LL },
> + { 0x0123456789ABCDEFLL, 32, 0x89ABCDEF00000000LL },
> + { 0x0123456789ABCDEFLL, 33, 0x13579BDE00000000LL },
> + { 0x0123456789ABCDEFLL, 34, 0x26AF37BC00000000LL },
> + { 0x0123456789ABCDEFLL, 35, 0x4D5E6F7800000000LL },
> + { 0x0123456789ABCDEFLL, 36, 0x9ABCDEF000000000LL },
> + { 0x0123456789ABCDEFLL, 60, 0xF000000000000000LL },
> + { 0x0123456789ABCDEFLL, 61, 0xE000000000000000LL },
> + { 0x0123456789ABCDEFLL, 62, 0xC000000000000000LL },
> + { 0x0123456789ABCDEFLL, 63, 0x8000000000000000LL },
> +};
> +
> +static void shdi3_test_ashldi3(struct kunit *test)
> +{
> + const struct shdi3_test_entry *e;
> + long long ret;
> +
> + for (e = ashldi3_testdata;
> + e < ashldi3_testdata + ARRAY_SIZE(ashldi3_testdata); e++) {
> + ret = __ashldi3(e->input, e->shift);
> + KUNIT_EXPECT_EQ_MSG(test, ret, e->result,
> + " when evaluating __ashldi3(%lld, %d)",
> + e->input, e->shift);
> + }
> +}
> +
> +static const struct shdi3_test_entry ashrdi3_testdata[] = {
> + /* https://github.com/llvm/llvm-project/compiler-rt/test/builtins/Unit/ashrdi3_test.c */
> + { 0x0123456789ABCDEFLL, 0, 0x123456789ABCDEFLL },
> + { 0x0123456789ABCDEFLL, 1, 0x91A2B3C4D5E6F7LL },
> + { 0x0123456789ABCDEFLL, 2, 0x48D159E26AF37BLL },
> + { 0x0123456789ABCDEFLL, 3, 0x2468ACF13579BDLL },
> + { 0x0123456789ABCDEFLL, 4, 0x123456789ABCDELL },
> + { 0x0123456789ABCDEFLL, 28, 0x12345678LL },
> + { 0x0123456789ABCDEFLL, 29, 0x91A2B3CLL },
> + { 0x0123456789ABCDEFLL, 30, 0x48D159ELL },
> + { 0x0123456789ABCDEFLL, 31, 0x2468ACFLL },
> + { 0x0123456789ABCDEFLL, 32, 0x1234567LL },
> + { 0x0123456789ABCDEFLL, 33, 0x91A2B3LL },
> + { 0x0123456789ABCDEFLL, 34, 0x48D159LL },
> + { 0x0123456789ABCDEFLL, 35, 0x2468ACLL },
> + { 0x0123456789ABCDEFLL, 36, 0x123456LL },
> + { 0x0123456789ABCDEFLL, 60, 0 },
> + { 0x0123456789ABCDEFLL, 61, 0 },
> + { 0x0123456789ABCDEFLL, 62, 0 },
> + { 0x0123456789ABCDEFLL, 63, 0 },
> + { 0xFEDCBA9876543210LL, 0, 0xFEDCBA9876543210LL },
> + { 0xFEDCBA9876543210LL, 1, 0xFF6E5D4C3B2A1908LL },
> + { 0xFEDCBA9876543210LL, 2, 0xFFB72EA61D950C84LL },
> + { 0xFEDCBA9876543210LL, 3, 0xFFDB97530ECA8642LL },
> + { 0xFEDCBA9876543210LL, 4, 0xFFEDCBA987654321LL },
> + { 0xFEDCBA9876543210LL, 28, 0xFFFFFFFFEDCBA987LL },
> + { 0xFEDCBA9876543210LL, 29, 0xFFFFFFFFF6E5D4C3LL },
> + { 0xFEDCBA9876543210LL, 30, 0xFFFFFFFFFB72EA61LL },
> + { 0xFEDCBA9876543210LL, 31, 0xFFFFFFFFFDB97530LL },
> + { 0xFEDCBA9876543210LL, 32, 0xFFFFFFFFFEDCBA98LL },
> + { 0xFEDCBA9876543210LL, 33, 0xFFFFFFFFFF6E5D4CLL },
> + { 0xFEDCBA9876543210LL, 34, 0xFFFFFFFFFFB72EA6LL },
> + { 0xFEDCBA9876543210LL, 35, 0xFFFFFFFFFFDB9753LL },
> + { 0xFEDCBA9876543210LL, 36, 0xFFFFFFFFFFEDCBA9LL },
> + { 0xAEDCBA9876543210LL, 60, 0xFFFFFFFFFFFFFFFALL },
> + { 0xAEDCBA9876543210LL, 61, 0xFFFFFFFFFFFFFFFDLL },
> + { 0xAEDCBA9876543210LL, 62, 0xFFFFFFFFFFFFFFFELL },
> + { 0xAEDCBA9876543210LL, 63, 0xFFFFFFFFFFFFFFFFLL },
> +};
> +
> +static void shdi3_test_ashrdi3(struct kunit *test)
> +{
> + const struct shdi3_test_entry *e;
> + long long ret;
> +
> + for (e = ashrdi3_testdata;
> + e < ashrdi3_testdata + ARRAY_SIZE(ashrdi3_testdata); e++) {
> + ret = __ashrdi3(e->input, e->shift);
> + KUNIT_EXPECT_EQ_MSG(test, ret, e->result,
> + " when evaluating __ashrdi3(%lld, %d)",
> + e->input, e->shift);
> + }
> +}
> +
> +static const struct shdi3_test_entry lshrdi3_testdata[] = {
> + /* https://github.com/llvm/llvm-project/compiler-rt/test/builtins/Unit/lshrdi3_test.c */
> + { 0x0123456789ABCDEFLL, 0, 0x123456789ABCDEFLL },
> + { 0x0123456789ABCDEFLL, 1, 0x91A2B3C4D5E6F7LL },
> + { 0x0123456789ABCDEFLL, 2, 0x48D159E26AF37BLL },
> + { 0x0123456789ABCDEFLL, 3, 0x2468ACF13579BDLL },
> + { 0x0123456789ABCDEFLL, 4, 0x123456789ABCDELL },
> + { 0x0123456789ABCDEFLL, 28, 0x12345678LL },
> + { 0x0123456789ABCDEFLL, 29, 0x91A2B3CLL },
> + { 0x0123456789ABCDEFLL, 30, 0x48D159ELL },
> + { 0x0123456789ABCDEFLL, 31, 0x2468ACFLL },
> + { 0x0123456789ABCDEFLL, 32, 0x1234567LL },
> + { 0x0123456789ABCDEFLL, 33, 0x91A2B3LL },
> + { 0x0123456789ABCDEFLL, 34, 0x48D159LL },
> + { 0x0123456789ABCDEFLL, 35, 0x2468ACLL },
> + { 0x0123456789ABCDEFLL, 36, 0x123456LL },
> + { 0x0123456789ABCDEFLL, 60, 0 },
> + { 0x0123456789ABCDEFLL, 61, 0 },
> + { 0x0123456789ABCDEFLL, 62, 0 },
> + { 0x0123456789ABCDEFLL, 63, 0 },
> + { 0xFEDCBA9876543210LL, 0, 0xFEDCBA9876543210LL },
> + { 0xFEDCBA9876543210LL, 1, 0x7F6E5D4C3B2A1908LL },
> + { 0xFEDCBA9876543210LL, 2, 0x3FB72EA61D950C84LL },
> + { 0xFEDCBA9876543210LL, 3, 0x1FDB97530ECA8642LL },
> + { 0xFEDCBA9876543210LL, 4, 0xFEDCBA987654321LL },
> + { 0xFEDCBA9876543210LL, 28, 0xFEDCBA987LL },
> + { 0xFEDCBA9876543210LL, 29, 0x7F6E5D4C3LL },
> + { 0xFEDCBA9876543210LL, 30, 0x3FB72EA61LL },
> + { 0xFEDCBA9876543210LL, 31, 0x1FDB97530LL },
> + { 0xFEDCBA9876543210LL, 32, 0xFEDCBA98LL },
> + { 0xFEDCBA9876543210LL, 33, 0x7F6E5D4CLL },
> + { 0xFEDCBA9876543210LL, 34, 0x3FB72EA6LL },
> + { 0xFEDCBA9876543210LL, 35, 0x1FDB9753LL },
> + { 0xFEDCBA9876543210LL, 36, 0xFEDCBA9LL },
> + { 0xAEDCBA9876543210LL, 60, 0xALL },
> + { 0xAEDCBA9876543210LL, 61, 0x5LL },
> + { 0xAEDCBA9876543210LL, 62, 0x2LL },
> + { 0xAEDCBA9876543210LL, 63, 0x1LL },
> +};
> +
> +static void shdi3_test_lshrdi3(struct kunit *test)
> +{
> + const struct shdi3_test_entry *e;
> + long long ret;
> +
> + for (e = lshrdi3_testdata;
> + e < lshrdi3_testdata + ARRAY_SIZE(lshrdi3_testdata); e++) {
> + ret = __lshrdi3(e->input, e->shift);
> + KUNIT_EXPECT_EQ_MSG(test, ret, e->result,
> + " when evaluating __lshrdi3(%lld, %d)",
> + e->input, e->shift);
> + }
> +}
> +
> +static struct kunit_case shdi3_test_cases[] = {
> + KUNIT_CASE(shdi3_test_ashldi3),
> + KUNIT_CASE(shdi3_test_ashrdi3),
> + KUNIT_CASE(shdi3_test_lshrdi3),
> + {}
> +};
> +
> +static struct kunit_suite shdi3_test_suite = {
> + .name = "shdi3",
> + .test_cases = shdi3_test_cases,
> +};
> +kunit_test_suite(shdi3_test_suite);
> +
> +MODULE_DESCRIPTION("Test cases for __ashldi3(), __ashrdi3(), and __lshrdi3()");
> +MODULE_LICENSE("GPL");
> --
> 2.53.0
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
>
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/2] riscv: add platform-specific double word shifts for riscv32
2026-04-09 3:38 ` [PATCH v2 1/2] riscv: add platform-specific double word shifts for riscv32 Dmitry Antipov
@ 2026-04-09 23:22 ` Charlie Jenkins
2026-04-10 10:49 ` Dmitry Antipov
0 siblings, 1 reply; 11+ messages in thread
From: Charlie Jenkins @ 2026-04-09 23:22 UTC (permalink / raw)
To: Dmitry Antipov
Cc: Andy Shevchenko, Andrew Morton, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Ard Biesheuvel, linux-riscv, kernel test robot
On Thu, Apr 09, 2026 at 06:38:23AM +0300, Dmitry Antipov wrote:
> Add riscv32-specific '__ashldi3()', '__ashrdi3()', and '__lshrdi3()'.
> Initially it was intended to fix the following link error observed
> when building EFI-enabled kernel with CONFIG_EFI_STUB=y and
> CONFIG_EFI_GENERIC_STUB=y:
>
> riscv32-linux-gnu-ld: ./drivers/firmware/efi/libstub/lib-cmdline.stub.o: in function `__efistub_.L49':
> __efistub_cmdline.c:(.init.text+0x1f2): undefined reference to `__efistub___ashldi3'
> riscv32-linux-gnu-ld: __efistub_cmdline.c:(.init.text+0x202): undefined reference to `__efistub___lshrdi3'
>
> Reported at [1] trying to build https://patchew.org/linux/20260212164413.889625-1-dmantipov@yandex.ru,
> tested with 'qemu-system-riscv32 -M virt' only.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202603041925.KLKqpK6N-lkp@intel.com [1]
> Suggested-by: Ard Biesheuvel <ardb@kernel.org>
> Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
I needed to apply the following to get this to successfully compile for
riscv32 with CONFIG_EFI_ZBOOT. After applying this change, I was able to
successfully EFI boot the vmlinuz.efi in qemu.
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index e386ffd009b7..f83301a19dc5 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -96,7 +96,7 @@ CFLAGS_zboot-decompress-gzip.o += -I$(srctree)/lib/zlib_inflate
zboot-obj-$(CONFIG_KERNEL_ZSTD) := zboot-decompress-zstd.o lib-xxhash.o
CFLAGS_zboot-decompress-zstd.o += -I$(srctree)/lib/zstd
-zboot-obj-$(CONFIG_RISCV) += lib-clz_ctz.o lib-ashldi3.o
+zboot-obj-$(CONFIG_RISCV) += lib-clz_ctz.o lib-ashldi3.o lib-lshrdi3.o
lib-$(CONFIG_EFI_ZBOOT) += zboot.o $(zboot-obj-y)
lib-$(CONFIG_UNACCEPTED_MEMORY) += unaccepted_memory.o bitmap.o find.o
However, this change causes the libstub to bypass these new functions
you have introduced. lib-ashldi3.o and lib-lshrdi3.o use the following
rule to compile the generic arch libs:
$(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
$(call if_changed_rule,cc_o_c)
This is specifically for the efi libstub, the regular kernel (like in
your test case in the next patch) will use these newly introduced
functions.
One solution is to use this change instead:
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index e386ffd009b7..775c34d80179 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -96,7 +96,7 @@ CFLAGS_zboot-decompress-gzip.o += -I$(srctree)/lib/zlib_inflate
zboot-obj-$(CONFIG_KERNEL_ZSTD) := zboot-decompress-zstd.o lib-xxhash.o
CFLAGS_zboot-decompress-zstd.o += -I$(srctree)/lib/zstd
-zboot-obj-$(CONFIG_RISCV) += lib-clz_ctz.o lib-ashldi3.o
+zboot-obj-$(CONFIG_RISCV) += lib-clz_ctz.o ../../../../arch/riscv/lib/ashldi3.o ../../../../arch/riscv/lib/lshrdi3.o
lib-$(CONFIG_EFI_ZBOOT) += zboot.o $(zboot-obj-y)
lib-$(CONFIG_UNACCEPTED_MEMORY) += unaccepted_memory.o bitmap.o find.o
This will link against the correct shifting libraries.
- Charlie
> ---
> v2: adjust commit message
> ---
> arch/riscv/Kconfig | 3 ---
> arch/riscv/kernel/image-vars.h | 7 +++++++
> arch/riscv/lib/Makefile | 1 +
> arch/riscv/lib/ashldi3.S | 36 +++++++++++++++++++++++++++++++++
> arch/riscv/lib/ashrdi3.S | 37 ++++++++++++++++++++++++++++++++++
> arch/riscv/lib/lshrdi3.S | 36 +++++++++++++++++++++++++++++++++
> 6 files changed, 117 insertions(+), 3 deletions(-)
> create mode 100644 arch/riscv/lib/ashldi3.S
> create mode 100644 arch/riscv/lib/ashrdi3.S
> create mode 100644 arch/riscv/lib/lshrdi3.S
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 90c531e6abf5..515254720da5 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -407,9 +407,6 @@ config ARCH_RV32I
> bool "RV32I"
> depends on NONPORTABLE
> select 32BIT
> - select GENERIC_LIB_ASHLDI3
> - select GENERIC_LIB_ASHRDI3
> - select GENERIC_LIB_LSHRDI3
> select GENERIC_LIB_UCMPDI2
>
> config ARCH_RV64I
> diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h
> index 3bd9d06a8b8f..d66e06daf13e 100644
> --- a/arch/riscv/kernel/image-vars.h
> +++ b/arch/riscv/kernel/image-vars.h
> @@ -32,6 +32,13 @@ __efistub___init_text_end = __init_text_end;
> __efistub_sysfb_primary_display = sysfb_primary_display;
> #endif
>
> +/*
> + * These double-word integer shifts are used
> + * by the library code and so EFI stub as well.
> + */
> +PROVIDE(__efistub___lshrdi3 = __lshrdi3);
> +PROVIDE(__efistub___ashldi3 = __ashldi3);
> +
> #endif
>
> #endif /* __RISCV_KERNEL_IMAGE_VARS_H */
> diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
> index bbc031124974..7cee3da80c68 100644
> --- a/arch/riscv/lib/Makefile
> +++ b/arch/riscv/lib/Makefile
> @@ -13,6 +13,7 @@ ifeq ($(CONFIG_MMU), y)
> lib-$(CONFIG_RISCV_ISA_V) += uaccess_vector.o
> endif
> lib-$(CONFIG_MMU) += uaccess.o
> +lib-$(CONFIG_32BIT) += ashldi3.o ashrdi3.o lshrdi3.o
> lib-$(CONFIG_64BIT) += tishift.o
> lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
> obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
> diff --git a/arch/riscv/lib/ashldi3.S b/arch/riscv/lib/ashldi3.S
> new file mode 100644
> index 000000000000..c3408862e2f6
> --- /dev/null
> +++ b/arch/riscv/lib/ashldi3.S
> @@ -0,0 +1,36 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/**
> + * Adopted for the Linux kernel from IPXE project, see
> + * https://github.com/ipxe/ipxe/blob/master/src/arch/riscv32/libgcc/llshift.S
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/asm.h>
> +
> +/**
> + * Shift left
> + *
> + * @v a1:a0 Value to shift
> + * @v a2 Shift amount
> + * @ret a1:a0 Shifted value
> + */
> +
> +SYM_FUNC_START(__ashldi3)
> +
> + /* Perform shift by 32 bits, if applicable */
> + li t0, 32
> + sub t1, t0, a2
> + bgtz t1, 1f
> + mv a1, a0
> + mv a0, zero
> +1: /* Perform shift by modulo-32 bits, if applicable */
> + andi a2, a2, 0x1f
> + beqz a2, 2f
> + srl t2, a0, t1
> + sll a0, a0, a2
> + sll a1, a1, a2
> + or a1, a1, t2
> +2: ret
> +
> +SYM_FUNC_END(__ashldi3)
> +EXPORT_SYMBOL(__ashldi3)
> diff --git a/arch/riscv/lib/ashrdi3.S b/arch/riscv/lib/ashrdi3.S
> new file mode 100644
> index 000000000000..dd42b3cbb173
> --- /dev/null
> +++ b/arch/riscv/lib/ashrdi3.S
> @@ -0,0 +1,37 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/**
> + * Adopted for the Linux kernel from IPXE project, see
> + * https://github.com/ipxe/ipxe/blob/master/src/arch/riscv32/libgcc/llshift.S
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/asm.h>
> +
> +/**
> + * Arithmetic shift right
> + *
> + * @v a1:a0 Value to shift
> + * @v a2 Shift amount
> + * @ret a1:a0 Shifted value
> + */
> +
> +SYM_FUNC_START(__ashrdi3)
> +
> + /* Perform shift by 32 bits, if applicable */
> + li t0, 32
> + sub t1, t0, a2
> + bgtz t1, 1f
> + mv a0, a1
> + srai a1, a1, 16
> + srai a1, a1, 16
> +1: /* Perform shift by modulo-32 bits, if applicable */
> + andi a2, a2, 0x1f
> + beqz a2, 2f
> + sll t2, a1, t1
> + sra a1, a1, a2
> + srl a0, a0, a2
> + or a0, a0, t2
> +2: ret
> +
> +SYM_FUNC_END(__ashrdi3)
> +EXPORT_SYMBOL(__ashrdi3)
> diff --git a/arch/riscv/lib/lshrdi3.S b/arch/riscv/lib/lshrdi3.S
> new file mode 100644
> index 000000000000..1af03985ccb7
> --- /dev/null
> +++ b/arch/riscv/lib/lshrdi3.S
> @@ -0,0 +1,36 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/**
> + * Adopted for the Linux kernel from IPXE project, see
> + * https://github.com/ipxe/ipxe/blob/master/src/arch/riscv32/libgcc/llshift.S
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/asm.h>
> +
> +/**
> + * Logical shift right
> + *
> + * @v a1:a0 Value to shift
> + * @v a2 Shift amount
> + * @ret a1:a0 Shifted value
> + */
> +
> +SYM_FUNC_START(__lshrdi3)
> +
> + /* Perform shift by 32 bits, if applicable */
> + li t0, 32
> + sub t1, t0, a2
> + bgtz t1, 1f
> + mv a0, a1
> + mv a1, zero
> +1: /* Perform shift by modulo-32 bits, if applicable */
> + andi a2, a2, 0x1f
> + beqz a2, 2f
> + sll t2, a1, t1
> + srl a1, a1, a2
> + srl a0, a0, a2
> + or a0, a0, t2
> +2: ret
> +
> +SYM_FUNC_END(__lshrdi3)
> +EXPORT_SYMBOL(__lshrdi3)
> --
> 2.53.0
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
>
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/2] riscv: add platform-specific double word shifts for riscv32
2026-04-09 23:22 ` Charlie Jenkins
@ 2026-04-10 10:49 ` Dmitry Antipov
2026-04-10 19:30 ` Charlie Jenkins
0 siblings, 1 reply; 11+ messages in thread
From: Dmitry Antipov @ 2026-04-10 10:49 UTC (permalink / raw)
To: Charlie Jenkins
Cc: Andy Shevchenko, Andrew Morton, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Ard Biesheuvel, linux-riscv, kernel test robot
On Thu, 2026-04-09 at 16:22 -0700, Charlie Jenkins wrote:
> However, this change causes the libstub to bypass these new functions
> you have introduced. lib-ashldi3.o and lib-lshrdi3.o use the following
> rule to compile the generic arch libs:
>
> $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
> $(call if_changed_rule,cc_o_c)
>
> This is specifically for the efi libstub, the regular kernel (like in
> your test case in the next patch) will use these newly introduced
> functions.
>
> One solution is to use this change instead:
>
> diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
> index e386ffd009b7..775c34d80179 100644
> --- a/drivers/firmware/efi/libstub/Makefile
> +++ b/drivers/firmware/efi/libstub/Makefile
> @@ -96,7 +96,7 @@ CFLAGS_zboot-decompress-gzip.o += -I$(srctree)/lib/zlib_inflate
> zboot-obj-$(CONFIG_KERNEL_ZSTD) := zboot-decompress-zstd.o lib-xxhash.o
> CFLAGS_zboot-decompress-zstd.o += -I$(srctree)/lib/zstd
>
> -zboot-obj-$(CONFIG_RISCV) += lib-clz_ctz.o lib-ashldi3.o
> +zboot-obj-$(CONFIG_RISCV) += lib-clz_ctz.o ../../../../arch/riscv/lib/ashldi3.o ../../../../arch/riscv/lib/lshrdi3.o
> lib-$(CONFIG_EFI_ZBOOT) += zboot.o $(zboot-obj-y)
>
> lib-$(CONFIG_UNACCEPTED_MEMORY) += unaccepted_memory.o bitmap.o find.o
>
> This will link against the correct shifting libraries.
1) This seems wrong for riscv64 which can have CONFIG_EFI_ZBOOT=y as
well but doesn't need these 64-on-32 quirks.
2) IIUC EFI stub executes just once before the kernel is booting, so it
doesn't seem too critical to link arch-specific (optimized) things
against it.
So I'm voting for something like:
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 29e0729299f5..55fb5a20aa25 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -85,6 +85,10 @@ config EFI_ZBOOT
provided that the loader implements the decompression algorithm.
(The compression algorithm used is described in the zboot header)
+config EFI_ZBOOT_EXTRAS
+ bool
+ default y if RISCV && 32BIT
+
config EFI_ARMSTUB_DTB_LOADER
bool "Enable the DTB loader"
depends on EFI_GENERIC_STUB && !RISCV && !LOONGARCH
diff --git a/drivers/firmware/efi/libstub/Makefile
b/drivers/firmware/efi/libstub/Makefile
index f83301a19dc5..8f199b99d0f6 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -96,7 +96,8 @@ CFLAGS_zboot-decompress-gzip.o += -
I$(srctree)/lib/zlib_inflate
zboot-obj-$(CONFIG_KERNEL_ZSTD) := zboot-decompress-zstd.o lib-
xxhash.o
CFLAGS_zboot-decompress-zstd.o += -I$(srctree)/lib/zstd
-zboot-obj-$(CONFIG_RISCV) += lib-clz_ctz.o lib-ashldi3.o lib-lshrdi3.o
+zboot-obj-extras-$(CONFIG_EFI_ZBOOT_EXTRAS) += lib-ashldi3.o lib-lshrdi3.o
+zboot-obj-$(CONFIG_RISCV) += lib-clz_ctz.o $(zboot-obj-extras-y)
lib-$(CONFIG_EFI_ZBOOT) += zboot.o $(zboot-obj-y)
lib-$(CONFIG_UNACCEPTED_MEMORY) += unaccepted_memory.o bitmap.o find.o
Kindly ask you to test this. And it will be even more helpful if you can test
building an running riscv64 as well :-).
Dmitry
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/2] riscv: add platform-specific double word shifts for riscv32
2026-04-10 10:49 ` Dmitry Antipov
@ 2026-04-10 19:30 ` Charlie Jenkins
0 siblings, 0 replies; 11+ messages in thread
From: Charlie Jenkins @ 2026-04-10 19:30 UTC (permalink / raw)
To: Dmitry Antipov
Cc: Andy Shevchenko, Andrew Morton, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Ard Biesheuvel, linux-riscv, kernel test robot
On Fri, Apr 10, 2026 at 01:49:31PM +0300, Dmitry Antipov wrote:
> On Thu, 2026-04-09 at 16:22 -0700, Charlie Jenkins wrote:
>
> > However, this change causes the libstub to bypass these new functions
> > you have introduced. lib-ashldi3.o and lib-lshrdi3.o use the following
> > rule to compile the generic arch libs:
> >
> > $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
> > $(call if_changed_rule,cc_o_c)
> >
> > This is specifically for the efi libstub, the regular kernel (like in
> > your test case in the next patch) will use these newly introduced
> > functions.
> >
> > One solution is to use this change instead:
> >
> > diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
> > index e386ffd009b7..775c34d80179 100644
> > --- a/drivers/firmware/efi/libstub/Makefile
> > +++ b/drivers/firmware/efi/libstub/Makefile
> > @@ -96,7 +96,7 @@ CFLAGS_zboot-decompress-gzip.o += -I$(srctree)/lib/zlib_inflate
> > zboot-obj-$(CONFIG_KERNEL_ZSTD) := zboot-decompress-zstd.o lib-xxhash.o
> > CFLAGS_zboot-decompress-zstd.o += -I$(srctree)/lib/zstd
> >
> > -zboot-obj-$(CONFIG_RISCV) += lib-clz_ctz.o lib-ashldi3.o
> > +zboot-obj-$(CONFIG_RISCV) += lib-clz_ctz.o ../../../../arch/riscv/lib/ashldi3.o ../../../../arch/riscv/lib/lshrdi3.o
> > lib-$(CONFIG_EFI_ZBOOT) += zboot.o $(zboot-obj-y)
> >
> > lib-$(CONFIG_UNACCEPTED_MEMORY) += unaccepted_memory.o bitmap.o find.o
> >
> > This will link against the correct shifting libraries.
>
> 1) This seems wrong for riscv64 which can have CONFIG_EFI_ZBOOT=y as
> well but doesn't need these 64-on-32 quirks.
>
> 2) IIUC EFI stub executes just once before the kernel is booting, so it
> doesn't seem too critical to link arch-specific (optimized) things
> against it.
>
> So I'm voting for something like:
>
> diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
> index 29e0729299f5..55fb5a20aa25 100644
> --- a/drivers/firmware/efi/Kconfig
> +++ b/drivers/firmware/efi/Kconfig
> @@ -85,6 +85,10 @@ config EFI_ZBOOT
> provided that the loader implements the decompression algorithm.
> (The compression algorithm used is described in the zboot header)
>
> +config EFI_ZBOOT_EXTRAS
> + bool
> + default y if RISCV && 32BIT
> +
> config EFI_ARMSTUB_DTB_LOADER
> bool "Enable the DTB loader"
> depends on EFI_GENERIC_STUB && !RISCV && !LOONGARCH
> diff --git a/drivers/firmware/efi/libstub/Makefile
> b/drivers/firmware/efi/libstub/Makefile
> index f83301a19dc5..8f199b99d0f6 100644
> --- a/drivers/firmware/efi/libstub/Makefile
> +++ b/drivers/firmware/efi/libstub/Makefile
> @@ -96,7 +96,8 @@ CFLAGS_zboot-decompress-gzip.o += -
> I$(srctree)/lib/zlib_inflate
> zboot-obj-$(CONFIG_KERNEL_ZSTD) := zboot-decompress-zstd.o lib-
> xxhash.o
> CFLAGS_zboot-decompress-zstd.o += -I$(srctree)/lib/zstd
>
> -zboot-obj-$(CONFIG_RISCV) += lib-clz_ctz.o lib-ashldi3.o lib-lshrdi3.o
> +zboot-obj-extras-$(CONFIG_EFI_ZBOOT_EXTRAS) += lib-ashldi3.o lib-lshrdi3.o
> +zboot-obj-$(CONFIG_RISCV) += lib-clz_ctz.o $(zboot-obj-extras-y)
> lib-$(CONFIG_EFI_ZBOOT) += zboot.o $(zboot-obj-y)
>
> lib-$(CONFIG_UNACCEPTED_MEMORY) += unaccepted_memory.o bitmap.o find.o
>
> Kindly ask you to test this. And it will be even more helpful if you can test
> building an running riscv64 as well :-).
I agree with this solution. With this patch applied, I have tested
EFI booting on riscv32 and riscv64. Thanks for putting this together.
You can add my tags assuming this patch is applied in the next
version.
Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
>
> Dmitry
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-04-10 19:30 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-07 5:28 [PATCH 0/2] add riscv32 double-word shifts and library test Dmitry Antipov
2026-04-07 5:28 ` [PATCH 1/2] riscv: add platform-specific double word shifts for riscv32 Dmitry Antipov
2026-04-07 5:28 ` [PATCH 2/2] lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3() Dmitry Antipov
2026-04-08 19:41 ` Andy Shevchenko
2026-04-09 3:38 ` [PATCH v2 0/2] add riscv32 double-word shifts and library test Dmitry Antipov
2026-04-09 3:38 ` [PATCH v2 1/2] riscv: add platform-specific double word shifts for riscv32 Dmitry Antipov
2026-04-09 23:22 ` Charlie Jenkins
2026-04-10 10:49 ` Dmitry Antipov
2026-04-10 19:30 ` Charlie Jenkins
2026-04-09 3:38 ` [PATCH v2 2/2] lib: kunit: add tests for __ashldi3(), __ashrdi3(), and __lshrdi3() Dmitry Antipov
2026-04-09 21:02 ` Charlie Jenkins
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox