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
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2011-04-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
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.
|
||||
|
||||
2011-04-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* util/grub-mkimage.c (generate_image): Add forgotten comma.
|
||||
|
|
|
@ -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--)
|
||||
|
|
|
@ -287,8 +287,20 @@ char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...)
|
|||
char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) __attribute__ ((warn_unused_result));
|
||||
void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
|
||||
void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn));
|
||||
grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
|
||||
grub_uint32_t d, grub_uint32_t *r);
|
||||
grub_uint64_t EXPORT_FUNC(grub_divmod64_full) (grub_uint64_t n,
|
||||
grub_uint64_t d,
|
||||
grub_uint64_t *r);
|
||||
static inline grub_uint64_t grub_divmod64 (grub_uint64_t n,
|
||||
grub_uint32_t d,
|
||||
grub_uint32_t *r)
|
||||
{
|
||||
grub_uint64_t ret, rr;
|
||||
|
||||
ret = grub_divmod64_full (n, d, &rr);
|
||||
if (r)
|
||||
*r = rr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if NEED_ENABLE_EXECUTE_STACK && !defined(GRUB_UTIL)
|
||||
void EXPORT_FUNC(__enable_execute_stack) (void *addr);
|
||||
|
|
Loading…
Reference in a new issue