common implementation of iterative div/mod

We have a few instances of the open-coded iterative div/mod loop, used
when we don't expcet the dividend to be much bigger than the divisor.
Unfortunately modern gcc's have the tendency to strength "reduce" this
into a full mod operation, which isn't necessarily any faster, and
even if it were, doesn't exist if gcc implements it in libgcc.

The workaround is to put a dummy asm statement in the loop to prevent
gcc from performing the transformation.

This patch creates a single implementation of this loop, and uses it
to replace the open-coded versions I know about.

Signed-off-by: Jeremy Fitzhardinge <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: john stultz <[email protected]>
Cc: Segher Boessenkool <[email protected]>
Cc: Christian Kujau <[email protected]>
Cc: Robert Hancock <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
This commit is contained in:
Jeremy Fitzhardinge 2008-06-12 10:47:56 +02:00 • committed by Ingo Molnar
commit f595ec964d
4 changed files with 30 additions and 19 deletions

View file

@ -98,3 +98,26 @@ EXPORT_SYMBOL(div64_u64);
#endif
#endif /* BITS_PER_LONG == 32 */
/*
* Iterative div/mod for use when dividend is not expected to be much
* bigger than divisor.
*/
u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder)
{
u32 ret = 0;
while (dividend >= divisor) {
/* The following asm() prevents the compiler from
optimising this loop into a modulo operation. */
asm("" : "+rm"(dividend));
dividend -= divisor;
ret++;
}
*remainder = dividend;
return ret;
}
EXPORT_SYMBOL(iter_div_u64_rem);