| // SPDX-License-Identifier: GPL-2.0 |
| #include <linux/kernel.h> |
| #include <linux/reciprocal_div.h> |
| #include <linux/export.h> |
| * For a description of the algorithm please have a look at |
| * include/linux/reciprocal_div.h |
| struct reciprocal_value reciprocal_value(u32 d) |
| struct reciprocal_value R; |
| m = ((1ULL << 32) * ((1ULL << l) - d)); |
| EXPORT_SYMBOL(reciprocal_value); |
| struct reciprocal_value_adv reciprocal_value_adv(u32 d, u8 prec) |
| struct reciprocal_value_adv R; |
| /* NOTE: mlow/mhigh could overflow u64 when l == 32. This case needs to |
| * be handled before calling "reciprocal_value_adv", please see the |
| * comment at include/linux/reciprocal_div.h. |
| "ceil(log2(0x%08x)) == 32, %s doesn't support such divisor", |
| mhigh = (1ULL << (32 + l)) + (1ULL << (32 + l - prec)); |
| for (; post_shift > 0; post_shift--) { |
| u64 lo = mlow >> 1, hi = mhigh >> 1; |
| R.is_wide_m = mhigh > U32_MAX; |
| EXPORT_SYMBOL(reciprocal_value_adv); |