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:
Vladimir 'phcoder' Serbinenko 2011-04-18 23:03:52 +02:00
parent a5102d9433
commit 93a777e388
3 changed files with 31 additions and 9 deletions

View file

@ -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> 2011-04-18 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-mkimage.c (generate_image): Add forgotten comma. * util/grub-mkimage.c (generate_image): Add forgotten comma.

View file

@ -597,23 +597,23 @@ grub_reverse (char *str)
/* Divide N by D, return the quotient, and store the remainder in *R. */ /* Divide N by D, return the quotient, and store the remainder in *R. */
grub_uint64_t 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 /* This algorithm is typically implemented by hardware. The idea
is to get the highest bit in N, 64 times, by keeping 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. */ represents the high 64 bits in 128-bits space. */
unsigned bits = 64; unsigned bits = 64;
unsigned long long q = 0; grub_uint64_t q = 0;
unsigned m = 0; grub_uint64_t m = 0;
/* Skip the slow computation if 32-bit arithmetic is possible. */ /* Skip the slow computation if 32-bit arithmetic is possible. */
if (n < 0xffffffff) if (n < 0xffffffff && d < 0xffffffff)
{ {
if (r) 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--) while (bits--)

View file

@ -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)); 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_exit) (void) __attribute__ ((noreturn));
void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn));
grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, grub_uint64_t EXPORT_FUNC(grub_divmod64_full) (grub_uint64_t n,
grub_uint32_t d, grub_uint32_t *r); 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) #if NEED_ENABLE_EXECUTE_STACK && !defined(GRUB_UTIL)
void EXPORT_FUNC(__enable_execute_stack) (void *addr); void EXPORT_FUNC(__enable_execute_stack) (void *addr);