div64.h 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. #ifndef __ASM_ARM_DIV64
  2. #define __ASM_ARM_DIV64
  3. #include <asm/system.h>
  4. /*
  5. * The semantics of do_div() are:
  6. *
  7. * uint32_t do_div(uint64_t *n, uint32_t base)
  8. * {
  9. * uint32_t remainder = *n % base;
  10. * *n = *n / base;
  11. * return remainder;
  12. * }
  13. *
  14. * In other words, a 64-bit dividend with a 32-bit divisor producing
  15. * a 64-bit result and a 32-bit remainder. To accomplish this optimally
  16. * we call a special __do_div64 helper with completely non standard
  17. * calling convention for arguments and results (beware).
  18. */
  19. #ifdef __ARMEB__
  20. #define __xh "r0"
  21. #define __xl "r1"
  22. #else
  23. #define __xl "r0"
  24. #define __xh "r1"
  25. #endif
  26. #define do_div(n,base) \
  27. ({ \
  28. register unsigned int __base asm("r4") = base; \
  29. register unsigned long long __n asm("r0") = n; \
  30. register unsigned long long __res asm("r2"); \
  31. register unsigned int __rem asm(__xh); \
  32. asm( __asmeq("%0", __xh) \
  33. __asmeq("%1", "r2") \
  34. __asmeq("%2", "r0") \
  35. __asmeq("%3", "r4") \
  36. "bl __do_div64" \
  37. : "=r" (__rem), "=r" (__res) \
  38. : "r" (__n), "r" (__base) \
  39. : "ip", "lr", "cc"); \
  40. n = __res; \
  41. __rem; \
  42. })
  43. #endif