From 93a777e38840ad59105cd6552c9a787e61b6f338 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 18 Apr 2011 23:03:52 +0200 Subject: [PATCH] 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. --- ChangeLog | 10 ++++++++++ grub-core/kern/misc.c | 14 +++++++------- include/grub/misc.h | 16 ++++++++++++++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index f9cfcdb46..f46277405 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-04-18 Vladimir Serbinenko + + 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 * util/grub-mkimage.c (generate_image): Add forgotten comma. diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 37ce8decd..1b4cdec66 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -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--) diff --git a/include/grub/misc.h b/include/grub/misc.h index 6fcaa148b..80588be33 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -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);