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

Reply via email to