Complete 64-bit division support.
* grub-core/kern/misc.c (grub_divmod64): Rename to ... (grub_divmod64_full): ... this. Support 64-bit divisor and reminder. * include/grub/misc.h (grub_divmod64): Rename to ... (grub_divmod64_full): ... this. (grub_divmod64): New inline function.
This commit is contained in:
parent
a5102d9433
commit
93a777e388
3 changed files with 31 additions and 9 deletions
|
@ -597,23 +597,23 @@ grub_reverse (char *str)
|
|||
|
||||
/* Divide N by D, return the quotient, and store the remainder in *R. */
|
||||
grub_uint64_t
|
||||
grub_divmod64 (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r)
|
||||
grub_divmod64_full (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r)
|
||||
{
|
||||
/* This algorithm is typically implemented by hardware. The idea
|
||||
is to get the highest bit in N, 64 times, by keeping
|
||||
upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
|
||||
upper(N * 2^i) = (Q * D + M), where upper
|
||||
represents the high 64 bits in 128-bits space. */
|
||||
unsigned bits = 64;
|
||||
unsigned long long q = 0;
|
||||
unsigned m = 0;
|
||||
grub_uint64_t q = 0;
|
||||
grub_uint64_t m = 0;
|
||||
|
||||
/* Skip the slow computation if 32-bit arithmetic is possible. */
|
||||
if (n < 0xffffffff)
|
||||
if (n < 0xffffffff && d < 0xffffffff)
|
||||
{
|
||||
if (r)
|
||||
*r = ((grub_uint32_t) n) % d;
|
||||
*r = ((grub_uint32_t) n) % (grub_uint32_t) d;
|
||||
|
||||
return ((grub_uint32_t) n) / d;
|
||||
return ((grub_uint32_t) n) / (grub_uint32_t) d;
|
||||
}
|
||||
|
||||
while (bits--)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue