div64.h 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #ifndef _ASM_GENERIC_DIV64_H
  2. #define _ASM_GENERIC_DIV64_H
  3. /*
  4. * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
  5. * Based on former asm-ppc/div64.h and asm-m68knommu/div64.h
  6. *
  7. * The semantics of do_div() are:
  8. *
  9. * u32 do_div(UINT64 *n, u32 base)
  10. * {
  11. * u32 remainder = *n % base;
  12. * *n = *n / base;
  13. * return remainder;
  14. * }
  15. *
  16. * NOTE: macro parameter n is evaluated multiple times,
  17. * beware of side effects!
  18. */
  19. //#include <linux/types.h>
  20. #include <comdef.h>
  21. static unsigned int __div64_32(UINT64 *n, unsigned int base)
  22. {
  23. UINT64 rem = *n;
  24. UINT64 b = base;
  25. UINT64 res, d = 1;
  26. unsigned int high = rem >> 32;
  27. /* Reduce the thing a bit first */
  28. res = 0;
  29. if (high >= base) {
  30. high /= base;
  31. res = (UINT64) high << 32;
  32. rem -= (UINT64) (high*base) << 32;
  33. }
  34. while ((s64)b > 0 && b < rem) {
  35. b = b+b;
  36. d = d+d;
  37. }
  38. do {
  39. if (rem >= b) {
  40. rem -= b;
  41. res += d;
  42. }
  43. b >>= 1;
  44. d >>= 1;
  45. } while (d);
  46. *n = res;
  47. return rem;
  48. }
  49. /* The unnecessary pointer compare is there
  50. * to check for type safety (n must be 64bit)
  51. */
  52. # define do_div(n,base) ({ \
  53. u32 __base = (base); \
  54. u32 __rem; \
  55. (void)(((typeof((n)) *)0) == ((UINT64 *)0)); \
  56. if (((n) >> 32) == 0) { \
  57. __rem = (u32)(n) % __base; \
  58. (n) = (u32)(n) / __base; \
  59. } else \
  60. __rem = __div64_32(&(n), __base); \
  61. __rem; \
  62. })
  63. /* Wrapper for do_div(). Doesn't modify dividend and returns
  64. * the result, not reminder.
  65. */
  66. static inline UINT64 lldiv(UINT64 dividend, u32 divisor)
  67. {
  68. UINT64 __res = dividend;
  69. do_div(__res, divisor);
  70. return(__res);
  71. }
  72. static inline UINT64 div_u64_rem(UINT64 dividend, u32 divisor, u32 *remainder)
  73. {
  74. *remainder = dividend % divisor;
  75. return dividend / divisor;
  76. }
  77. #endif /* _ASM_GENERIC_DIV64_H */