2005-04-16 15:20:36 -07:00
# ifndef _ASM_GENERIC_DIV64_H
# define _ASM_GENERIC_DIV64_H
/*
* Copyright ( C ) 2003 Bernardo Innocenti < bernie @ develer . com >
* Based on former asm - ppc / div64 . h and asm - m68knommu / div64 . h
*
* The semantics of do_div ( ) are :
*
* uint32_t do_div ( uint64_t * n , uint32_t base )
* {
* uint32_t remainder = * n % base ;
* * n = * n / base ;
* return remainder ;
* }
*
* NOTE : macro parameter n is evaluated multiple times ,
* beware of side effects !
*/
# include <linux/types.h>
# include <linux/compiler.h>
# if BITS_PER_LONG == 64
# define do_div(n,base) ({ \
uint32_t __base = ( base ) ; \
uint32_t __rem ; \
__rem = ( ( uint64_t ) ( n ) ) % __base ; \
( n ) = ( ( uint64_t ) ( n ) ) / __base ; \
__rem ; \
} )
2007-03-25 19:54:23 -07:00
static inline uint64_t div64_64 ( uint64_t dividend , uint64_t divisor )
{
return dividend / divisor ;
}
2005-04-16 15:20:36 -07:00
# elif BITS_PER_LONG == 32
extern uint32_t __div64_32 ( uint64_t * dividend , uint32_t divisor ) ;
/* The unnecessary pointer compare is there
* to check for type safety ( n must be 64 bit )
*/
# define do_div(n,base) ({ \
uint32_t __base = ( base ) ; \
uint32_t __rem ; \
( void ) ( ( ( typeof ( ( n ) ) * ) 0 ) = = ( ( uint64_t * ) 0 ) ) ; \
if ( likely ( ( ( n ) > > 32 ) = = 0 ) ) { \
__rem = ( uint32_t ) ( n ) % __base ; \
( n ) = ( uint32_t ) ( n ) / __base ; \
} else \
__rem = __div64_32 ( & ( n ) , __base ) ; \
__rem ; \
} )
2007-03-25 19:54:23 -07:00
extern uint64_t div64_64 ( uint64_t dividend , uint64_t divisor ) ;
2005-04-16 15:20:36 -07:00
# else /* BITS_PER_LONG == ?? */
# error do_div() does not yet support the C64
# endif /* BITS_PER_LONG */
# endif /* _ASM_GENERIC_DIV64_H */