>From 16d35a92b0fa18df9986117db5135b4161210fe0 Mon Sep 17 00:00:00 2001 From: Balazs Kezes Date: Mon, 22 Aug 2016 17:58:09 +0100 Subject: [PATCH 1/2] Fix slow unsigned long long division on ARM The macro AEABI_UXDIVMOD expands to this bit: #define AEABI_UXDIVMOD(name,type, rettype, typemacro) \ ... while (num >= den) { \ ... while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \ q <<= 1; \ ... With the current ULONG_MAX version the inner loop goes only until 4 billion so the outer loop will progress very slowly if num is large. With ULLONG_MAX the inner loop works as expected. The current version is probably a result of a typo. The following bash snippet demonstrates the bug: $ uname -a Linux eper 4.4.16-2-ARCH #1 Wed Aug 10 20:03:13 MDT 2016 armv6l GNU/Linux $ cat div.c int printf(const char *, ...); int main(void) { unsigned long long num, denom; num = 12345678901234567ULL; denom = 7; printf("%lld\n", num / denom); return 0; } $ time tcc -run div.c 1763668414462081 real 0m16.291s user 0m15.860s sys 0m0.020s --- lib/armeabi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/armeabi.c b/lib/armeabi.c index 0d1217b..b12d164 100644 --- a/lib/armeabi.c +++ b/lib/armeabi.c @@ -399,7 +399,7 @@ REGS_RETURN(ulldiv_t, ulldiv_t) REGS_RETURN(idiv_t, idiv_t) REGS_RETURN(uidiv_t, uidiv_t) -AEABI_UXDIVMOD(uldivmod, unsigned long long, ulldiv_t, ULONG) +AEABI_UXDIVMOD(uldivmod, unsigned long long, ulldiv_t, ULLONG) __AEABI_XDIVMOD(ldivmod, long long, uldivmod, lldiv_t, ulldiv_t, LLONG) -- 2.9.3