* [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
* 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
* [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
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