* [PATCH 1/3] nios2: remove usage of libgcc
2026-10-30 15:53 [PATCH 0/3] lib: Add software mul/div helpers and use them from nios2 Simon Schuster
@ 2026-10-30 15:53 ` Simon Schuster
2026-10-30 15:53 ` [PATCH 2/3] nios2: export __divsi3_table Simon Schuster
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Simon Schuster @ 2026-10-30 15:53 UTC (permalink / raw)
To: Dinh Nguyen, Andrew Morton, Arnd Bergmann
Cc: Sasha Levin, linux-kernel, Simon Schuster
From: Dinh Nguyen <dinguyen@kernel.org>
Use the kernel's runtime support for lshrdi3, ashldi3, ashrdi3, muldi3,
and ucmpdi2.
Copy over the math functions from a GPLv2 GCC implementation of divsi3,
udivsi3, mulsi3, umulsi3, modsi3, and gcc_bcmp.
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
Signed-off-by: Simon Schuster <schuster.simon@siemens-energy.com>
---
arch/nios2/Kconfig | 5 ++
arch/nios2/Makefile | 4 +-
arch/nios2/kernel/nios2_ksyms.c | 22 --------
arch/nios2/lib/Makefile | 1 +
arch/nios2/lib/math.c | 119 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 126 insertions(+), 25 deletions(-)
diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig
index 9c0e6eaeb005c..9417bcf583957 100644
--- a/arch/nios2/Kconfig
+++ b/arch/nios2/Kconfig
@@ -14,6 +14,11 @@ config NIOS2
select GENERIC_CPU_DEVICES
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
+ select GENERIC_LIB_LSHRDI3
+ select GENERIC_LIB_ASHLDI3
+ select GENERIC_LIB_ASHRDI3
+ select GENERIC_LIB_MULDI3
+ select GENERIC_LIB_UCMPDI2
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_KGDB
select HAVE_PAGE_SIZE_4KB
diff --git a/arch/nios2/Makefile b/arch/nios2/Makefile
index f1ff4ce0f1a2c..173588c31abf9 100644
--- a/arch/nios2/Makefile
+++ b/arch/nios2/Makefile
@@ -19,8 +19,6 @@ UTS_SYSNAME = Linux
export MMU
-LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) $(KCFLAGS) -print-libgcc-file-name)
-
KBUILD_AFLAGS += -march=r$(CONFIG_NIOS2_ARCH_REVISION)
KBUILD_CFLAGS += -pipe -D__linux__ -D__ELF__
@@ -37,7 +35,7 @@ KBUILD_CFLAGS += -DUTS_SYSNAME=\"$(UTS_SYSNAME)\"
KBUILD_CFLAGS += -fno-builtin
KBUILD_CFLAGS += -G 0
-libs-y += arch/nios2/lib/ $(LIBGCC)
+libs-y += arch/nios2/lib/
INSTALL_PATH ?= /tftpboot
nios2-boot := arch/$(ARCH)/boot
diff --git a/arch/nios2/kernel/nios2_ksyms.c b/arch/nios2/kernel/nios2_ksyms.c
index e8710a269b398..351664e236fac 100644
--- a/arch/nios2/kernel/nios2_ksyms.c
+++ b/arch/nios2/kernel/nios2_ksyms.c
@@ -21,25 +21,3 @@ EXPORT_SYMBOL(memmove);
/* memory management */
EXPORT_SYMBOL(flush_icache_range);
-
-/*
- * libgcc functions - functions that are used internally by the
- * compiler... (prototypes are not correct though, but that
- * doesn't really matter since they're not versioned).
- */
-#define DECLARE_EXPORT(name) extern void name(void); EXPORT_SYMBOL(name)
-
-DECLARE_EXPORT(__gcc_bcmp);
-DECLARE_EXPORT(__divsi3);
-DECLARE_EXPORT(__moddi3);
-DECLARE_EXPORT(__modsi3);
-DECLARE_EXPORT(__udivmoddi4);
-DECLARE_EXPORT(__udivsi3);
-DECLARE_EXPORT(__umoddi3);
-DECLARE_EXPORT(__umodsi3);
-DECLARE_EXPORT(__muldi3);
-DECLARE_EXPORT(__mulsi3);
-DECLARE_EXPORT(__ucmpdi2);
-DECLARE_EXPORT(__lshrdi3);
-DECLARE_EXPORT(__ashldi3);
-DECLARE_EXPORT(__ashrdi3);
diff --git a/arch/nios2/lib/Makefile b/arch/nios2/lib/Makefile
index 9d5bf1df520c1..86433dcaac7e5 100644
--- a/arch/nios2/lib/Makefile
+++ b/arch/nios2/lib/Makefile
@@ -7,3 +7,4 @@ lib-y += delay.o
lib-y += memcpy.o
lib-y += memmove.o
lib-y += memset.o
+lib-y += math.o
diff --git a/arch/nios2/lib/math.c b/arch/nios2/lib/math.c
new file mode 100644
index 0000000000000..9a89fa268a96e
--- /dev/null
+++ b/arch/nios2/lib/math.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright Altera Corporation (C) 2026. All rights reserved.
+ */
+
+#include <linux/export.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+/*
+ * Software 32-bit multiply for cores built without the hardware multiplier.
+ */
+s32 __mulsi3(s32 a, s32 b);
+s32 __divsi3(s32 a, s32 b);
+s32 __udivsi3(s32 a, s32 b);
+s32 __modsi3(s32 a, s32 b);
+s32 __umodsi3(s32 a, s32 b);
+int __gcc_bcmp(const void *s1, const void *s2, size_t len);
+
+static u32 udivmodsi4(u32 num, u32 den, int modwanted)
+{
+ u32 bit = 1;
+ u32 res = 0;
+
+ while (den < num && bit && !(den & (1U << 31))) {
+ den <<= 1;
+ bit <<= 1;
+ }
+
+ while (bit) {
+ if (num >= den) {
+ num -= den;
+ res |= bit;
+ }
+ bit >>= 1;
+ den >>= 1;
+ }
+
+ return modwanted ? num : res;
+}
+
+s32 __mulsi3(s32 a, s32 b)
+{
+ s32 res = 0;
+ u32 cnt = a;
+
+ while (cnt) {
+ if (cnt & 1)
+ res += b;
+
+ b <<= 1;
+ cnt >>= 1;
+ }
+
+ return res;
+}
+EXPORT_SYMBOL(__mulsi3);
+
+s32 __divsi3(s32 a, s32 b)
+{
+ int neg = 0;
+ s32 res;
+
+ if (a < 0) {
+ a = -a;
+ neg = !neg;
+ }
+
+ if (b < 0) {
+ b = -b;
+ neg = !neg;
+ }
+
+ res = udivmodsi4(a, b, 0);
+ if (neg)
+ res = -res;
+
+ return res;
+}
+EXPORT_SYMBOL(__divsi3);
+
+s32 __udivsi3(s32 a, s32 b)
+{
+ return udivmodsi4(a, b, 0);
+}
+EXPORT_SYMBOL(__udivsi3);
+
+s32 __modsi3(s32 a, s32 b)
+{
+ int neg = 0;
+ s32 res;
+
+ if (a < 0) {
+ a = -a;
+ neg = 1;
+ }
+
+ if (b < 0)
+ b = -b;
+
+ res = udivmodsi4(a, b, 1);
+ if (neg)
+ res = -res;
+
+ return res;
+}
+EXPORT_SYMBOL(__modsi3);
+
+s32 __umodsi3(s32 a, s32 b)
+{
+ return udivmodsi4(a, b, 1);
+}
+EXPORT_SYMBOL(__umodsi3);
+
+int __gcc_bcmp(const void *s1, const void *s2, size_t len)
+{
+ return memcmp(s1, s2, len);
+}
+EXPORT_SYMBOL(__gcc_bcmp);
+
--
2.39.5
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 2/3] nios2: export __divsi3_table
2026-10-30 15:53 [PATCH 0/3] lib: Add software mul/div helpers and use them from nios2 Simon Schuster
2026-10-30 15:53 ` [PATCH 1/3] nios2: remove usage of libgcc Simon Schuster
@ 2026-10-30 15:53 ` Simon Schuster
2026-10-30 15:53 ` [PATCH 3/3] lib: extract 32bit mul/div helpers from nios2 into GENERIC_LIB Simon Schuster
2026-10-30 16:50 ` [PATCH 0/3] lib: Add software mul/div helpers and use them from nios2 Arnd Bergmann
3 siblings, 0 replies; 5+ messages in thread
From: Simon Schuster @ 2026-10-30 15:53 UTC (permalink / raw)
To: Dinh Nguyen, Andrew Morton, Arnd Bergmann
Cc: Sasha Levin, linux-kernel, Simon Schuster
As noted in <20261026234452.1086974-1-sashal@kernel.org>, gcc can
occasionally emit references to __divsi3_table, so we need to include
that one in libgcc-less builds, as well.
The definition originates from gcc/config/nios2/lib2-divtable.c that
was distributed in source by Altera as part of the nios2eds in
gcc 3.4.1 (Altera Nios II 6.1 b197) under GPLv2 or later.
lib2-divtable.c does not carry an explicit copyright notice in the gcc
release, the associated nios2.h is: Copyright (C) 2005 Altera.
Nonetheless, the table can also be regenerated by the following snippet:
perl -e 'for my $row (0..15) {
print join(", ", map { $_ == 0 ? 0 : "$row/$_" } 0..15), ",\n";
}'
Signed-off-by: Simon Schuster <schuster.simon@siemens-energy.com>
---
arch/nios2/lib/math.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/nios2/lib/math.c b/arch/nios2/lib/math.c
index 9a89fa268a96e..f4a4e7d1afeee 100644
--- a/arch/nios2/lib/math.c
+++ b/arch/nios2/lib/math.c
@@ -117,3 +117,22 @@ int __gcc_bcmp(const void *s1, const void *s2, size_t len)
}
EXPORT_SYMBOL(__gcc_bcmp);
+u8 __divsi3_table[] = {
+0, 0/1, 0/2, 0/3, 0/4, 0/5, 0/6, 0/7, 0/8, 0/9, 0/10, 0/11, 0/12, 0/13, 0/14, 0/15,
+0, 1/1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, 1/14, 1/15,
+0, 2/1, 2/2, 2/3, 2/4, 2/5, 2/6, 2/7, 2/8, 2/9, 2/10, 2/11, 2/12, 2/13, 2/14, 2/15,
+0, 3/1, 3/2, 3/3, 3/4, 3/5, 3/6, 3/7, 3/8, 3/9, 3/10, 3/11, 3/12, 3/13, 3/14, 3/15,
+0, 4/1, 4/2, 4/3, 4/4, 4/5, 4/6, 4/7, 4/8, 4/9, 4/10, 4/11, 4/12, 4/13, 4/14, 4/15,
+0, 5/1, 5/2, 5/3, 5/4, 5/5, 5/6, 5/7, 5/8, 5/9, 5/10, 5/11, 5/12, 5/13, 5/14, 5/15,
+0, 6/1, 6/2, 6/3, 6/4, 6/5, 6/6, 6/7, 6/8, 6/9, 6/10, 6/11, 6/12, 6/13, 6/14, 6/15,
+0, 7/1, 7/2, 7/3, 7/4, 7/5, 7/6, 7/7, 7/8, 7/9, 7/10, 7/11, 7/12, 7/13, 7/14, 7/15,
+0, 8/1, 8/2, 8/3, 8/4, 8/5, 8/6, 8/7, 8/8, 8/9, 8/10, 8/11, 8/12, 8/13, 8/14, 8/15,
+0, 9/1, 9/2, 9/3, 9/4, 9/5, 9/6, 9/7, 9/8, 9/9, 9/10, 9/11, 9/12, 9/13, 9/14, 9/15,
+0, 10/1, 10/2, 10/3, 10/4, 10/5, 10/6, 10/7, 10/8, 10/9, 10/10, 10/11, 10/12, 10/13, 10/14, 10/15,
+0, 11/1, 11/2, 11/3, 11/4, 11/5, 11/6, 11/7, 11/8, 11/9, 11/10, 11/11, 11/12, 11/13, 11/14, 11/15,
+0, 12/1, 12/2, 12/3, 12/4, 12/5, 12/6, 12/7, 12/8, 12/9, 12/10, 12/11, 12/12, 12/13, 12/14, 12/15,
+0, 13/1, 13/2, 13/3, 13/4, 13/5, 13/6, 13/7, 13/8, 13/9, 13/10, 13/11, 13/12, 13/13, 13/14, 13/15,
+0, 14/1, 14/2, 14/3, 14/4, 14/5, 14/6, 14/7, 14/8, 14/9, 14/10, 14/11, 14/12, 14/13, 14/14, 14/15,
+0, 15/1, 15/2, 15/3, 15/4, 15/5, 15/6, 15/7, 15/8, 15/9, 15/10, 15/11, 15/12, 15/13, 15/14, 15/15,
+};
+EXPORT_SYMBOL(__divsi3_table);
--
2.39.5
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 3/3] lib: extract 32bit mul/div helpers from nios2 into GENERIC_LIB
2026-10-30 15:53 [PATCH 0/3] lib: Add software mul/div helpers and use them from nios2 Simon Schuster
2026-10-30 15:53 ` [PATCH 1/3] nios2: remove usage of libgcc Simon Schuster
2026-10-30 15:53 ` [PATCH 2/3] nios2: export __divsi3_table Simon Schuster
@ 2026-10-30 15:53 ` Simon Schuster
2026-10-30 16:50 ` [PATCH 0/3] lib: Add software mul/div helpers and use them from nios2 Arnd Bergmann
3 siblings, 0 replies; 5+ messages in thread
From: Simon Schuster @ 2026-10-30 15:53 UTC (permalink / raw)
To: Dinh Nguyen, Andrew Morton, Arnd Bergmann
Cc: Sasha Levin, linux-kernel, Simon Schuster
As suggested in 426c73b7-b4dc-4b68-9aa5-6145a13280bc@app.fastmail.com,
the software emulation of div/mul/mod on 32-bit platforms from nios2
might be of use to other smaller architectures as well when trying to
drop their libgcc dependency (e.g., arc, openrisc). The same applies to
__gcc_bcmp.
Therefore, extract and add them to lib/, guarded by respective
CONFIG_GENERIC_LIB_* options.
Symbols covered:
s32 __mulsi3(s32 a, s32 b);
s32 __divsi3(s32 a, s32 b);
s32 __udivsi3(s32 a, s32 b);
s32 __modsi3(s32 a, s32 b);
s32 __umodsi3(s32 a, s32 b);
int __gcc_bcmp(const void *s1, const void *s2, size_t len);
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Simon Schuster <schuster.simon@siemens-energy.com>
---
arch/nios2/Kconfig | 6 +++
arch/nios2/lib/math.c | 112 -------------------------------------------------
include/linux/libgcc.h | 12 ++++++
lib/Kconfig | 18 ++++++++
lib/Makefile | 11 +++++
lib/divmod.c | 94 +++++++++++++++++++++++++++++++++++++++++
lib/gccbcmp.c | 13 ++++++
lib/mulsi3.c | 24 +++++++++++
8 files changed, 178 insertions(+), 112 deletions(-)
diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig
index 9417bcf583957..08db6aa9c396f 100644
--- a/arch/nios2/Kconfig
+++ b/arch/nios2/Kconfig
@@ -19,6 +19,12 @@ config NIOS2
select GENERIC_LIB_ASHRDI3
select GENERIC_LIB_MULDI3
select GENERIC_LIB_UCMPDI2
+ select GENERIC_LIB_DIVSI3
+ select GENERIC_LIB_MODSI3
+ select GENERIC_LIB_UDIVSI3
+ select GENERIC_LIB_UMODSI3
+ select GENERIC_LIB_MULSI3
+ select GENERIC_LIB_GCC_BCMP
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_KGDB
select HAVE_PAGE_SIZE_4KB
diff --git a/arch/nios2/lib/math.c b/arch/nios2/lib/math.c
index f4a4e7d1afeee..ba16b57019227 100644
--- a/arch/nios2/lib/math.c
+++ b/arch/nios2/lib/math.c
@@ -3,120 +3,8 @@
*/
#include <linux/export.h>
-#include <linux/string.h>
#include <linux/types.h>
-/*
- * Software 32-bit multiply for cores built without the hardware multiplier.
- */
-s32 __mulsi3(s32 a, s32 b);
-s32 __divsi3(s32 a, s32 b);
-s32 __udivsi3(s32 a, s32 b);
-s32 __modsi3(s32 a, s32 b);
-s32 __umodsi3(s32 a, s32 b);
-int __gcc_bcmp(const void *s1, const void *s2, size_t len);
-
-static u32 udivmodsi4(u32 num, u32 den, int modwanted)
-{
- u32 bit = 1;
- u32 res = 0;
-
- while (den < num && bit && !(den & (1U << 31))) {
- den <<= 1;
- bit <<= 1;
- }
-
- while (bit) {
- if (num >= den) {
- num -= den;
- res |= bit;
- }
- bit >>= 1;
- den >>= 1;
- }
-
- return modwanted ? num : res;
-}
-
-s32 __mulsi3(s32 a, s32 b)
-{
- s32 res = 0;
- u32 cnt = a;
-
- while (cnt) {
- if (cnt & 1)
- res += b;
-
- b <<= 1;
- cnt >>= 1;
- }
-
- return res;
-}
-EXPORT_SYMBOL(__mulsi3);
-
-s32 __divsi3(s32 a, s32 b)
-{
- int neg = 0;
- s32 res;
-
- if (a < 0) {
- a = -a;
- neg = !neg;
- }
-
- if (b < 0) {
- b = -b;
- neg = !neg;
- }
-
- res = udivmodsi4(a, b, 0);
- if (neg)
- res = -res;
-
- return res;
-}
-EXPORT_SYMBOL(__divsi3);
-
-s32 __udivsi3(s32 a, s32 b)
-{
- return udivmodsi4(a, b, 0);
-}
-EXPORT_SYMBOL(__udivsi3);
-
-s32 __modsi3(s32 a, s32 b)
-{
- int neg = 0;
- s32 res;
-
- if (a < 0) {
- a = -a;
- neg = 1;
- }
-
- if (b < 0)
- b = -b;
-
- res = udivmodsi4(a, b, 1);
- if (neg)
- res = -res;
-
- return res;
-}
-EXPORT_SYMBOL(__modsi3);
-
-s32 __umodsi3(s32 a, s32 b)
-{
- return udivmodsi4(a, b, 1);
-}
-EXPORT_SYMBOL(__umodsi3);
-
-int __gcc_bcmp(const void *s1, const void *s2, size_t len)
-{
- return memcmp(s1, s2, len);
-}
-EXPORT_SYMBOL(__gcc_bcmp);
-
u8 __divsi3_table[] = {
0, 0/1, 0/2, 0/3, 0/4, 0/5, 0/6, 0/7, 0/8, 0/9, 0/10, 0/11, 0/12, 0/13, 0/14, 0/15,
0, 1/1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, 1/14, 1/15,
diff --git a/include/linux/libgcc.h b/include/linux/libgcc.h
index 0d68f9d6a6a7e..85d7b7b0f1949 100644
--- a/include/linux/libgcc.h
+++ b/include/linux/libgcc.h
@@ -7,6 +7,7 @@
#define __LIB_LIBGCC_H
#include <asm/byteorder.h>
+#include <linux/types.h>
typedef int word_type __attribute__ ((mode (__word__)));
@@ -34,6 +35,17 @@ long long notrace __lshrdi3(long long u, word_type b);
long long notrace __muldi3(long long u, long long v);
word_type notrace __ucmpdi2(unsigned long long a, unsigned long long b);
+/*
+ * Software 32-bit multiply for cores built without the hardware multiplier.
+ */
+s32 notrace __mulsi3(s32 a, s32 b);
+s32 notrace __divsi3(s32 a, s32 b);
+s32 notrace __udivsi3(s32 a, s32 b);
+s32 notrace __modsi3(s32 a, s32 b);
+s32 notrace __umodsi3(s32 a, s32 b);
+
+int __gcc_bcmp(const void *s1, const void *s2, size_t len);
+
#ifdef CONFIG_HAVE_ARCH_LIBGCC_H
#include <asm/libgcc.h>
#endif
diff --git a/lib/Kconfig b/lib/Kconfig
index 1e42f5167c68b..91a36aad2e625 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -611,6 +611,24 @@ config GENERIC_LIB_CMPDI2
config GENERIC_LIB_UCMPDI2
bool
+config GENERIC_LIB_DIVSI3
+ bool
+
+config GENERIC_LIB_MODSI3
+ bool
+
+config GENERIC_LIB_UDIVSI3
+ bool
+
+config GENERIC_LIB_UMODSI3
+ bool
+
+config GENERIC_LIB_MULSI3
+ bool
+
+config GENERIC_LIB_GCC_BCMP
+ bool
+
config GENERIC_LIB_DEVMEM_IS_ALLOWED
bool
diff --git a/lib/Makefile b/lib/Makefile
index a2afe954805cb..671ff5de1c397 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -337,6 +337,17 @@ obj-$(CONFIG_GENERIC_LIB_LSHRDI3) += lshrdi3.o
obj-$(CONFIG_GENERIC_LIB_MULDI3) += muldi3.o
obj-$(CONFIG_GENERIC_LIB_CMPDI2) += cmpdi2.o
obj-$(CONFIG_GENERIC_LIB_UCMPDI2) += ucmpdi2.o
+obj-$(CONFIG_GENERIC_LIB_MULSI3) += mulsi3.o
+obj-$(CONFIG_GENERIC_LIB_GCC_BCMP) += gccbcmp.o
+
+divmod-needed := $(or \
+ $(CONFIG_GENERIC_LIB_DIVSI3),\
+ $(CONFIG_GENERIC_LIB_MODSI3),\
+ $(CONFIG_GENERIC_LIB_UDIVSI3),\
+ $(CONFIG_GENERIC_LIB_UMODSI3))
+obj-$(divmod-needed) += divmod.o
+
+
obj-$(CONFIG_OBJAGG) += objagg.o
# pldmfw library
diff --git a/lib/divmod.c b/lib/divmod.c
new file mode 100644
index 0000000000000..cc1df6f9978ce
--- /dev/null
+++ b/lib/divmod.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright Altera Corporation (C) 2026. All rights reserved.
+ */
+
+#include <linux/libgcc.h>
+#include <linux/export.h>
+#include <linux/types.h>
+
+static u32 udivmodsi4(u32 num, u32 den, int modwanted)
+{
+ u32 bit = 1;
+ u32 res = 0;
+
+ while (den < num && bit && !(den & (1U << 31))) {
+ den <<= 1;
+ bit <<= 1;
+ }
+
+ while (bit) {
+ if (num >= den) {
+ num -= den;
+ res |= bit;
+ }
+ bit >>= 1;
+ den >>= 1;
+ }
+
+ return modwanted ? num : res;
+}
+
+
+#ifdef CONFIG_GENERIC_LIB_DIVSI3
+s32 __divsi3(s32 a, s32 b)
+{
+ int neg = 0;
+ s32 res;
+
+ if (a < 0) {
+ a = -a;
+ neg = !neg;
+ }
+
+ if (b < 0) {
+ b = -b;
+ neg = !neg;
+ }
+
+ res = udivmodsi4(a, b, 0);
+ if (neg)
+ res = -res;
+
+ return res;
+}
+EXPORT_SYMBOL(__divsi3);
+#endif
+
+#ifdef CONFIG_GENERIC_LIB_MODSI3
+s32 __modsi3(s32 a, s32 b)
+{
+ int neg = 0;
+ s32 res;
+
+ if (a < 0) {
+ a = -a;
+ neg = 1;
+ }
+
+ if (b < 0)
+ b = -b;
+
+ res = udivmodsi4(a, b, 1);
+ if (neg)
+ res = -res;
+
+ return res;
+}
+EXPORT_SYMBOL(__modsi3);
+#endif
+
+#ifdef CONFIG_GENERIC_LIB_UDIVSI3
+s32 __udivsi3(s32 a, s32 b)
+{
+ return udivmodsi4(a, b, 0);
+}
+EXPORT_SYMBOL(__udivsi3);
+#endif
+
+#ifdef CONFIG_GENERIC_LIB_UMODSI3
+s32 __umodsi3(s32 a, s32 b)
+{
+ return udivmodsi4(a, b, 1);
+}
+EXPORT_SYMBOL(__umodsi3);
+#endif
diff --git a/lib/gccbcmp.c b/lib/gccbcmp.c
new file mode 100644
index 0000000000000..7037176b04b35
--- /dev/null
+++ b/lib/gccbcmp.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright Altera Corporation (C) 2026. All rights reserved.
+ */
+
+#include <linux/libgcc.h>
+#include <linux/export.h>
+#include <linux/string.h>
+
+int __gcc_bcmp(const void *s1, const void *s2, size_t len)
+{
+ return memcmp(s1, s2, len);
+}
+EXPORT_SYMBOL(__gcc_bcmp);
diff --git a/lib/mulsi3.c b/lib/mulsi3.c
new file mode 100644
index 0000000000000..6596a6598de05
--- /dev/null
+++ b/lib/mulsi3.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright Altera Corporation (C) 2026. All rights reserved.
+ */
+
+#include <linux/libgcc.h>
+#include <linux/export.h>
+#include <linux/types.h>
+
+s32 __mulsi3(s32 a, s32 b)
+{
+ s32 res = 0;
+ u32 cnt = a;
+
+ while (cnt) {
+ if (cnt & 1)
+ res += b;
+
+ b <<= 1;
+ cnt >>= 1;
+ }
+
+ return res;
+}
+EXPORT_SYMBOL(__mulsi3);
--
2.39.5
^ permalink raw reply [flat|nested] 5+ messages in thread