]> Pileus Git - ~andy/linux/blobdiff - lib/div64.c
Merge branch 'slab/next' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg...
[~andy/linux] / lib / div64.c
index 3af5728d95fda3c2aa740deec3f6de69cc847e94..4382ad77777ebcb17bc4b25fe606f4371b563a5d 100644 (file)
@@ -79,16 +79,15 @@ EXPORT_SYMBOL(div_s64_rem);
 #endif
 
 /**
- * div64_u64_rem - unsigned 64bit divide with 64bit divisor and 64bit remainder
+ * div64_u64_rem - unsigned 64bit divide with 64bit divisor and remainder
  * @dividend:  64bit dividend
  * @divisor:   64bit divisor
  * @remainder:  64bit remainder
  *
- * This implementation is a modified version of the algorithm proposed
- * by the book 'Hacker's Delight'.  The original source and full proof
- * can be found here and is available for use without restriction.
- *
- * 'http://www.hackersdelight.org/HDcode/newCode/divDouble.c.txt'
+ * This implementation is a comparable to algorithm used by div64_u64.
+ * But this operation, which includes math for calculating the remainder,
+ * is kept distinct to avoid slowing down the div64_u64 operation on 32bit
+ * systems.
  */
 #ifndef div64_u64_rem
 u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder)
@@ -119,6 +118,40 @@ u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder)
 EXPORT_SYMBOL(div64_u64_rem);
 #endif
 
+/**
+ * div64_u64 - unsigned 64bit divide with 64bit divisor
+ * @dividend:  64bit dividend
+ * @divisor:   64bit divisor
+ *
+ * This implementation is a modified version of the algorithm proposed
+ * by the book 'Hacker's Delight'.  The original source and full proof
+ * can be found here and is available for use without restriction.
+ *
+ * 'http://www.hackersdelight.org/HDcode/newCode/divDouble.c.txt'
+ */
+#ifndef div64_u64
+u64 div64_u64(u64 dividend, u64 divisor)
+{
+       u32 high = divisor >> 32;
+       u64 quot;
+
+       if (high == 0) {
+               quot = div_u64(dividend, divisor);
+       } else {
+               int n = 1 + fls(high);
+               quot = div_u64(dividend >> n, divisor >> n);
+
+               if (quot != 0)
+                       quot--;
+               if ((dividend - quot * divisor) >= divisor)
+                       quot++;
+       }
+
+       return quot;
+}
+EXPORT_SYMBOL(div64_u64);
+#endif
+
 /**
  * div64_s64 - signed 64bit divide with 64bit divisor
  * @dividend:  64bit dividend