1*1da177e4SLinus Torvalds #ifndef _ASM_GENERIC_DIV64_H 2*1da177e4SLinus Torvalds #define _ASM_GENERIC_DIV64_H 3*1da177e4SLinus Torvalds /* 4*1da177e4SLinus Torvalds * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com> 5*1da177e4SLinus Torvalds * Based on former asm-ppc/div64.h and asm-m68knommu/div64.h 6*1da177e4SLinus Torvalds * 7*1da177e4SLinus Torvalds * The semantics of do_div() are: 8*1da177e4SLinus Torvalds * 9*1da177e4SLinus Torvalds * uint32_t do_div(uint64_t *n, uint32_t base) 10*1da177e4SLinus Torvalds * { 11*1da177e4SLinus Torvalds * uint32_t remainder = *n % base; 12*1da177e4SLinus Torvalds * *n = *n / base; 13*1da177e4SLinus Torvalds * return remainder; 14*1da177e4SLinus Torvalds * } 15*1da177e4SLinus Torvalds * 16*1da177e4SLinus Torvalds * NOTE: macro parameter n is evaluated multiple times, 17*1da177e4SLinus Torvalds * beware of side effects! 18*1da177e4SLinus Torvalds */ 19*1da177e4SLinus Torvalds 20*1da177e4SLinus Torvalds #include <linux/types.h> 21*1da177e4SLinus Torvalds #include <linux/compiler.h> 22*1da177e4SLinus Torvalds 23*1da177e4SLinus Torvalds #if BITS_PER_LONG == 64 24*1da177e4SLinus Torvalds 25*1da177e4SLinus Torvalds # define do_div(n,base) ({ \ 26*1da177e4SLinus Torvalds uint32_t __base = (base); \ 27*1da177e4SLinus Torvalds uint32_t __rem; \ 28*1da177e4SLinus Torvalds __rem = ((uint64_t)(n)) % __base; \ 29*1da177e4SLinus Torvalds (n) = ((uint64_t)(n)) / __base; \ 30*1da177e4SLinus Torvalds __rem; \ 31*1da177e4SLinus Torvalds }) 32*1da177e4SLinus Torvalds 33*1da177e4SLinus Torvalds #elif BITS_PER_LONG == 32 34*1da177e4SLinus Torvalds 35*1da177e4SLinus Torvalds extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor); 36*1da177e4SLinus Torvalds 37*1da177e4SLinus Torvalds /* The unnecessary pointer compare is there 38*1da177e4SLinus Torvalds * to check for type safety (n must be 64bit) 39*1da177e4SLinus Torvalds */ 40*1da177e4SLinus Torvalds # define do_div(n,base) ({ \ 41*1da177e4SLinus Torvalds uint32_t __base = (base); \ 42*1da177e4SLinus Torvalds uint32_t __rem; \ 43*1da177e4SLinus Torvalds (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \ 44*1da177e4SLinus Torvalds if (likely(((n) >> 32) == 0)) { \ 45*1da177e4SLinus Torvalds __rem = (uint32_t)(n) % __base; \ 46*1da177e4SLinus Torvalds (n) = (uint32_t)(n) / __base; \ 47*1da177e4SLinus Torvalds } else \ 48*1da177e4SLinus Torvalds __rem = __div64_32(&(n), __base); \ 49*1da177e4SLinus Torvalds __rem; \ 50*1da177e4SLinus Torvalds }) 51*1da177e4SLinus Torvalds 52*1da177e4SLinus Torvalds #else /* BITS_PER_LONG == ?? */ 53*1da177e4SLinus Torvalds 54*1da177e4SLinus Torvalds # error do_div() does not yet support the C64 55*1da177e4SLinus Torvalds 56*1da177e4SLinus Torvalds #endif /* BITS_PER_LONG */ 57*1da177e4SLinus Torvalds 58*1da177e4SLinus Torvalds #endif /* _ASM_GENERIC_DIV64_H */ 59