]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Complete 64-bit division support.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 18 Apr 2011 21:03:52 +0000 (23:03 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 18 Apr 2011 21:03:52 +0000 (23:03 +0200)
* 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
grub-core/kern/misc.c
include/grub/misc.h

index f9cfcdb4670cd7ea4be41512b1671ac78f53601d..f4627740531f1020c8d7745e040aee94650ebd0b 100644 (file)
--- a/ChangeLog
+++ b/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.
index 37ce8decdc9d5951637345cbcc5c410169eb3069..1b4cdec66f12f8a103e75630a1e2b11145b054cc 100644 (file)
@@ -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--)
index 6fcaa148ba3ef5a30b8b01df427db1b442c7aaa6..80588be33ab9c276c0606bde828a63068ad2429a 100644 (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));
 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);