
Squashfs wasn't compiling because the lldiv() directives turn into __udivdi3 and we are using private libgcc. This is just copied from the Linux kernel v6.6-rc1 arch/mips/include/asm/div64.h and then adjusted for U-Boot.
After this squashfs compiles for MIPS.
Cc: Daniel Schwierzeck daniel.schwierzeck@gmail.com Cc: Mauro Condarelli mc5686@mclink.it Cc: Ralf Baechle ralf@linux-mips.org Signed-off-by: Linus Walleij linus.walleij@linaro.org --- I can't test this because it didn't work for MTD devices as I had expected, but I saw Mauro had this problem before so I think I might have fixed it. I better put the patch out there rather than let it sit on my drive. --- arch/mips/lib/Makefile | 2 +- arch/mips/lib/udivdi3.c | 86 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 arch/mips/lib/udivdi3.c
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 9ee1fcb5c702..1621cc9a1ff9 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -14,4 +14,4 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_GO) += boot.o obj-$(CONFIG_SPL_BUILD) += spl.o
-lib-$(CONFIG_USE_PRIVATE_LIBGCC) += ashldi3.o ashrdi3.o lshrdi3.o +lib-$(CONFIG_USE_PRIVATE_LIBGCC) += ashldi3.o ashrdi3.o lshrdi3.o udivdi3.o diff --git a/arch/mips/lib/udivdi3.c b/arch/mips/lib/udivdi3.c new file mode 100644 index 000000000000..6a4ee5fa46ab --- /dev/null +++ b/arch/mips/lib/udivdi3.c @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2000, 2004, 2021 Maciej W. Rozycki + * Copyright (C) 2003, 07 Ralf Baechle (ralf@linux-mips.org) + */ + +#include "libgcc.h" + +/* + * No traps on overflows for any of these... + */ + +#define do_div64_32(res, high, low, base) ({ \ + unsigned long __cf, __tmp, __tmp2, __i; \ + unsigned long __quot32, __mod32; \ + \ + __asm__( \ + " .set push \n" \ + " .set noat \n" \ + " .set noreorder \n" \ + " move %2, $0 \n" \ + " move %3, $0 \n" \ + " b 1f \n" \ + " li %4, 0x21 \n" \ + "0: \n" \ + " sll $1, %0, 0x1 \n" \ + " srl %3, %0, 0x1f \n" \ + " or %0, $1, %5 \n" \ + " sll %1, %1, 0x1 \n" \ + " sll %2, %2, 0x1 \n" \ + "1: \n" \ + " bnez %3, 2f \n" \ + " sltu %5, %0, %z6 \n" \ + " bnez %5, 3f \n" \ + "2: \n" \ + " addiu %4, %4, -1 \n" \ + " subu %0, %0, %z6 \n" \ + " addiu %2, %2, 1 \n" \ + "3: \n" \ + " bnez %4, 0b \n" \ + " srl %5, %1, 0x1f \n" \ + " .set pop" \ + : "=&r" (__mod32), "=&r" (__tmp), \ + "=&r" (__quot32), "=&r" (__cf), \ + "=&r" (__i), "=&r" (__tmp2) \ + : "Jr" (base), "0" (high), "1" (low)); \ + \ + (res) = __quot32; \ + __mod32; \ +}) + +#define __div64_32(n, base) ({ \ + unsigned long __upper, __low, __high, __radix; \ + unsigned long long __quot; \ + unsigned long long __div; \ + unsigned long __mod; \ + \ + __div = (*n); \ + __radix = (base); \ + \ + __high = __div >> 32; \ + __low = __div; \ + \ + if (__high < __radix) { \ + __upper = __high; \ + __high = 0; \ + } else { \ + __upper = __high % __radix; \ + __high /= __radix; \ + } \ + \ + __mod = do_div64_32(__low, __upper, __low, __radix); \ + \ + __quot = __high; \ + __quot = __quot << 32 | __low; \ + (*n) = __quot; \ + __mod; \ +}) + +long long __udivdi3(long long u, word_type b) +{ + long long ret = u; + + __div64_32(&ret, b); + return ret; +}