#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) ({					\
	__u32 __base = (base);				\
	__u32 __rem;						\
	__rem = ((__u64)(n)) % __base;			\
	(n) = ((__u64)(n)) / __base;				\
	__rem;							\
 })

#elif BITS_PER_LONG == 32

extern __u32 __div64_32(__u64 *dividend, __u32 divisor);

/* The unnecessary pointer compare is there
 * to check for type safety (n must be 64bit)
 */
# define do_div(n,base) ({				\
	__u32 __base = (base);			\
	__u32 __rem;					\
	(void)(((typeof((n)) *)0) == ((__u64 *)0));	\
	if (likely(((n) >> 32) == 0)) {			\
		__rem = (__u32)(n) % __base;		\
		(n) = (__u32)(n) / __base;		\
	} else 						\
		__rem = __div64_32(&(n), __base);	\
	__rem;						\
 })

#else /* BITS_PER_LONG == ?? */
# ifdef __KERNEL__
#  error do_div() does not yet support the C64
# endif
#endif /* BITS_PER_LONG */

#endif /* _ASM_GENERIC_DIV64_H */
