]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/x86/lib/div64.c
2 * This file is copied from the coreboot repository as part of
3 * the libpayload project:
5 * Copyright 2014 Google Inc.
7 * SPDX-License-Identifier: BSD-3-Clause
20 u64
__ashldi3(u64 num
, unsigned int shift
)
22 union overlay64 output
;
26 output
.words
.higher
= output
.words
.lower
<< (shift
- 32);
27 output
.words
.lower
= 0;
31 output
.words
.higher
= (output
.words
.higher
<< shift
) |
32 (output
.words
.lower
>> (32 - shift
));
33 output
.words
.lower
= output
.words
.lower
<< shift
;
38 u64
__lshrdi3(u64 num
, unsigned int shift
)
40 union overlay64 output
;
44 output
.words
.lower
= output
.words
.higher
>> (shift
- 32);
45 output
.words
.higher
= 0;
49 output
.words
.lower
= output
.words
.lower
>> shift
|
50 (output
.words
.higher
<< (32 - shift
));
51 output
.words
.higher
= output
.words
.higher
>> shift
;
56 #define MAX_32BIT_UINT ((((u64)1) << 32) - 1)
58 static u64
_64bit_divide(u64 dividend
, u64 divider
, u64
*rem_p
)
63 * If divider is zero - let the rest of the system care about the
67 return 1 / (u32
)divider
;
69 /* As an optimization, let's not use 64 bit division unless we must. */
70 if (dividend
<= MAX_32BIT_UINT
) {
71 if (divider
> MAX_32BIT_UINT
) {
76 result
= (u32
)dividend
/ (u32
)divider
;
78 *rem_p
= (u32
)dividend
% (u32
)divider
;
83 while (divider
<= dividend
) {
85 u64 limit
= __lshrdi3(dividend
, 1);
88 while (locald
<= limit
) {
90 locald
= locald
+ locald
;
92 result
|= __ashldi3(1, shifts
);
102 u64
__udivdi3(u64 num
, u64 den
)
104 return _64bit_divide(num
, den
, NULL
);
107 u64
__umoddi3(u64 num
, u64 den
)
111 _64bit_divide(num
, den
, &v
);