New upstream version 18.02
[deb_dpdk.git] / lib / librte_eal / common / include / rte_reciprocal.h
similarity index 56%
rename from lib/librte_sched/rte_reciprocal.h
rename to lib/librte_eal/common/include/rte_reciprocal.h
index 5e21f09..3492c73 100644 (file)
@@ -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, 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_ */