X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=lib%2Flibrte_eal%2Fcommon%2Finclude%2Frte_reciprocal.h;h=63e16fde0aa864f4c5a9777e67d715269d39bc82;hb=df3ff6be2b33faea3edf3c112b9bdc5b74d6f684;hp=5e21f096fa8d808d80df1a8753ad07955c487070;hpb=0b037e8b02b7ced8c18a650b708f2fd6e3364d83;p=dpdk.git diff --git a/lib/librte_eal/common/include/rte_reciprocal.h b/lib/librte_eal/common/include/rte_reciprocal.h index 5e21f096fa..63e16fde0a 100644 --- a/lib/librte_eal/common/include/rte_reciprocal.h +++ b/lib/librte_eal/common/include/rte_reciprocal.h @@ -1,3 +1,6 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Cavium, Inc + */ /* * Reciprocal divide * @@ -29,6 +32,11 @@ struct rte_reciprocal { uint8_t sh1, sh2; }; +struct rte_reciprocal_u64 { + uint64_t m; + uint8_t sh1, sh2; +}; + static inline uint32_t rte_reciprocal_divide(uint32_t a, struct rte_reciprocal R) { uint32_t t = (uint32_t)(((uint64_t)a * R.m) >> 32); @@ -36,6 +44,47 @@ static inline uint32_t rte_reciprocal_divide(uint32_t a, struct rte_reciprocal R return (t + ((a - t) >> R.sh1)) >> R.sh2; } +static __rte_always_inline uint64_t +mullhi_u64(uint64_t x, uint64_t y) +{ +#ifdef __SIZEOF_INT128__ + __uint128_t xl = x; + __uint128_t rl = xl * y; + + return (rl >> 64); +#else + uint64_t u0, u1, v0, v1, k, t; + uint64_t w1, w2; + uint64_t whi; + + u1 = x >> 32; u0 = x & 0xFFFFFFFF; + v1 = y >> 32; v0 = y & 0xFFFFFFFF; + + t = u0*v0; + k = t >> 32; + + t = u1*v0 + k; + w1 = t & 0xFFFFFFFF; + w2 = t >> 32; + + t = u0*v1 + w1; + k = t >> 32; + + whi = u1*v1 + w2 + k; + + return whi; +#endif +} + +static __rte_always_inline uint64_t +rte_reciprocal_divide_u64(uint64_t a, const struct rte_reciprocal_u64 *R) +{ + uint64_t t = mullhi_u64(a, R->m); + + return (t + ((a - t) >> R->sh1)) >> R->sh2; +} + struct rte_reciprocal rte_reciprocal_value(uint32_t d); +struct rte_reciprocal_u64 rte_reciprocal_value_u64(uint64_t d); #endif /* _RTE_RECIPROCAL_H_ */