diff options
author | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2008-06-12 04:47:56 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-12 04:47:56 -0400 |
commit | f595ec964daf7f99668039d7303ddedd09a75142 (patch) | |
tree | 4ee6679105f0437995ff200f10885598921ae1cd /lib | |
parent | 5e70b7f3c24468bb1635b295945edb48ecd9656a (diff) |
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 <jeremy.fitzhardinge@citrix.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Segher Boessenkool <segher@kernel.crashing.org>
Cc: Christian Kujau <lists@nerdbynature.de>
Cc: Robert Hancock <hancockr@shaw.ca>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/div64.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/lib/div64.c b/lib/div64.c index bb5bd0c0f030..76c01542d3e1 100644 --- a/lib/div64.c +++ b/lib/div64.c | |||
@@ -98,3 +98,26 @@ EXPORT_SYMBOL(div64_u64); | |||
98 | #endif | 98 | #endif |
99 | 99 | ||
100 | #endif /* BITS_PER_LONG == 32 */ | 100 | #endif /* BITS_PER_LONG == 32 */ |
101 | |||
102 | /* | ||
103 | * Iterative div/mod for use when dividend is not expected to be much | ||
104 | * bigger than divisor. | ||
105 | */ | ||
106 | u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder) | ||
107 | { | ||
108 | u32 ret = 0; | ||
109 | |||
110 | while (dividend >= divisor) { | ||
111 | /* The following asm() prevents the compiler from | ||
112 | optimising this loop into a modulo operation. */ | ||
113 | asm("" : "+rm"(dividend)); | ||
114 | |||
115 | dividend -= divisor; | ||
116 | ret++; | ||
117 | } | ||
118 | |||
119 | *remainder = dividend; | ||
120 | |||
121 | return ret; | ||
122 | } | ||
123 | EXPORT_SYMBOL(iter_div_u64_rem); | ||