home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-arm / div64.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  1.1 KB  |  49 lines

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