diff options
| author | Peter Tyser <ptyser@xes-inc.com> | 2010-04-12 22:28:05 -0500 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2010-04-13 09:13:04 +0200 | 
| commit | 78acc472d9719316f22e002a009a998d9ceec29d (patch) | |
| tree | aa99461b3d693cf3691869abea485091860a66d0 /lib/div64.c | |
| parent | ea0364f1bbfed1e3ea711147420875cf338fe77a (diff) | |
| download | olio-uboot-2014.01-78acc472d9719316f22e002a009a998d9ceec29d.tar.xz olio-uboot-2014.01-78acc472d9719316f22e002a009a998d9ceec29d.zip | |
Rename lib_generic/ to lib/
Now that the other architecture-specific lib directories have been
moved out of the top-level directory there's not much reason to have the
'_generic' suffix on the common lib directory.
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
Diffstat (limited to 'lib/div64.c')
| -rw-r--r-- | lib/div64.c | 52 | 
1 files changed, 52 insertions, 0 deletions
| diff --git a/lib/div64.c b/lib/div64.c new file mode 100644 index 000000000..d9951b597 --- /dev/null +++ b/lib/div64.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com> + * + * Based on former do_div() implementation from asm-parisc/div64.h: + *	Copyright (C) 1999 Hewlett-Packard Co + *	Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com> + * + * + * Generic C version of 64bit/32bit division and modulo, with + * 64bit result and 32bit remainder. + * + * The fast case for (n>>32 == 0) is handled inline by do_div(). + * + * Code generated for this function might be very inefficient + * for some CPUs. __div64_32() can be overridden by linking arch-specific + * assembly versions such as arch/ppc/lib/div64.S and arch/sh/lib/div64.S. + */ + +#include <linux/types.h> + +uint32_t __div64_32(uint64_t *n, uint32_t base) +{ +	uint64_t rem = *n; +	uint64_t b = base; +	uint64_t res, d = 1; +	uint32_t high = rem >> 32; + +	/* Reduce the thing a bit first */ +	res = 0; +	if (high >= base) { +		high /= base; +		res = (uint64_t) high << 32; +		rem -= (uint64_t) (high*base) << 32; +	} + +	while ((int64_t)b > 0 && b < rem) { +		b = b+b; +		d = d+d; +	} + +	do { +		if (rem >= b) { +			rem -= b; +			res += d; +		} +		b >>= 1; +		d >>= 1; +	} while (d); + +	*n = res; +	return rem; +} |