On 18 October 2026 09:35:06 BST, Josef Schlehofer <[email protected]> wrote: >On 32-bit PowerPC, GCC lowers '/' and '%' on unsigned 64-bit operands >to calls to __udivdi3() and __umoddi3(). U-Boot's private libgcc lacks >these routines, so turris_1x_sdcard fails to link with >CONFIG_USE_PRIVATE_LIBGCC=y: > > undefined reference to `__udivdi3' > >Implement both with a copy of __div64_32() from lib/div64.c whose >divisor is widened to 64 bits. The copy keeps the private libgcc >independent of lib/, which not every xPL phase links. > >Build the file without LTO, as ARM does for eabi_compat.o: LTO can >drop these functions before GCC generates the calls that need them. > >Signed-off-by: Josef Schlehofer <[email protected]> >Cc: Tom Rini <[email protected]> >Cc: Marek BehĂșn <[email protected]>
I see. Let's crack on and review thid >--- >Changes in v2: >- new patch > >At -Os the two take 300 bytes, against 1036 and 992 bytes of >_udivdi3.o and _umoddi3.o in Debian's libgcc 14.2. >--- > arch/powerpc/lib/Makefile | 3 +- > arch/powerpc/lib/udivdi3.c | 82 ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 84 insertions(+), 1 deletion(-) > create mode 100644 arch/powerpc/lib/udivdi3.c > >diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile >index 90f0e1e5fa9..23e62996701 100644 >--- a/arch/powerpc/lib/Makefile >+++ b/arch/powerpc/lib/Makefile >@@ -6,7 +6,8 @@ > ## Build a couple of necessary functions into a private libgcc > ## if the user asked for it > lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _ashldi3.o _ashrdi3.o _lshrdi3.o \ >- crtsavres.o >+ crtsavres.o udivdi3.o >+CFLAGS_REMOVE_udivdi3.o := $(LTO_CFLAGS) > > MINIMAL= > >diff --git a/arch/powerpc/lib/udivdi3.c b/arch/powerpc/lib/udivdi3.c >new file mode 100644 >index 00000000000..deb0b5d49e1 >--- /dev/null >+++ b/arch/powerpc/lib/udivdi3.c >@@ -0,0 +1,82 @@ >+// SPDX-License-Identifier: GPL-2.0 >+/* >+ * 64-bit unsigned division and modulo for the private libgcc >+ * >+ * GCC calls __udivdi3() and __umoddi3() for '/' and '%' on unsigned 64-bit >+ * operands on 32-bit PowerPC. udivmod64() is __div64_32() from lib/div64.c >+ * with a 64-bit divisor: its shift-and-subtract loop already works on one, >+ * and the step that first divides the high word now only runs when the >+ * divisor fits into 32 bits. Like __div64_32(), the functions are not >+ * instrumented, as tracing code may divide. The source file copyrights are >+ * as follows: >+ * >+ * Copyright (C) 2003 Bernardo Innocenti <[email protected]> What's your source? Maybe cite it? >+ * >+ * Based on former do_div() implementation from asm-parisc/div64.h: >+ * Copyright (C) 1999 Hewlett-Packard Co >+ * Copyright (C) 1999 David Mosberger-Tang <[email protected]> >+ */ >+ >+#include <linux/types.h> >+ >+static notrace u64 udivmod64(u64 n, u64 base, u64 *rem) >+{ >+ u64 b = base; >+ u64 res, d = 1; >+ u32 high = n >> 32; >+ >+ /* Reduce the thing a bit first */ Could we clarify that better? >+ res = 0; >+ if (!(base >> 32) && high >= base) { >+ high /= (u32)base; >+ res = (u64)high << 32; >+ n -= (u64)(high * (u32)base) << 32; >+ } >+ >+ while ((s64)b > 0 && b < n) { >+ b = b + b; >+ d = d + d; >+ } >+ >+ do { >+ if (n >= b) { >+ n -= b; >+ res += d; >+ } >+ b >>= 1; >+ d >>= 1; >+ } while (d); >+ >+ *rem = n; >+ return res; >+} >+ >+/** >+ * __udivdi3() - divide two 64-bit unsigned integers >+ * >+ * @n: dividend >+ * @d: divisor >+ * Return: quotient >+ */ >+notrace u64 __udivdi3(u64 n, u64 d) >+{ >+ u64 rem; >+ >+ return udivmod64(n, d, &rem); >+} >+ >+/** >+ * __umoddi3() - remainder of the division of two 64-bit unsigned integers >+ * >+ * @n: dividend >+ * @d: divisor >+ * Return: remainder >+ */ >+notrace u64 __umoddi3(u64 n, u64 d) >+{ >+ u64 rem; >+ >+ udivmod64(n, d, &rem); >+ >+ return rem; >+} > Ok, the code looks *sane* to me, I'd be comfortable adding Reviewed-by: Bradley Morgan <[email protected]> /shrug --- Thanks! "I'm not a very positive person" - Linus torvalds
