revert between 56095 -> 55830 in arch
[AROS.git] / arch / arm-all / arm-aeabi / uldiv.c
blobadd8c1d8fdeb19f3d153fd59ecd3bc4ee4e5e833
1 /*
2 Copyright © 2009-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <inttypes.h>
8 void __attribute__((noreturn)) __aeabi_ldiv0(uint64_t);
10 uint64_t __uldiv(uint64_t a, uint64_t b)
12 uint64_t ret = 0;
13 if (b == 0)
15 __aeabi_ldiv0(a);
17 else if (b > a)
19 return 0;
21 else
23 int first_bit_a = __builtin_clz(a >> 32);
24 int first_bit_b = __builtin_clz(b >> 32);
26 if (first_bit_a == 32)
27 first_bit_a += __builtin_clz(a & 0xffffffff);
28 if (first_bit_b == 32)
29 first_bit_b += __builtin_clz(b & 0xffffffff);
31 uint64_t mask = 0x00000001ULL << (first_bit_b-first_bit_a);
32 b <<= (first_bit_b - first_bit_a);
36 if (a >= b)
38 ret |= mask;
39 a -= b;
42 mask >>=1;
43 b >>=1;
44 } while(mask);
46 return ret;
49 uint64_t __uldivmod_helper(uint64_t a, uint64_t b, uint64_t *remainder)
51 uint64_t quotient;
53 quotient = __uldiv(a, b);
55 *remainder = a - b * quotient;
57 return quotient;