* 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>
+
+ 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.
/* 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--)
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);