+ /**
+ * Compute 128-bit result of 64-bit unsigned integer multiplication
+ * followed by addition
+ */
+ inline std::tuple<uint64_t, uint64_t>
+ multiplyAdd(uint64_t ra, uint64_t rb, uint64_t rc) const
+ {
+ uint64_t rlo, rhi;
+ #if defined(__SIZEOF_INT128__)
+ __uint128_t res = ((__uint128_t)ra * rb) + rc;
+ rlo = res;
+ rhi = res >> 64;
+ #else
+ uint64_t plo, phi;
+ std::tie(plo, phi) = multiply(ra, rb);
+ std::tie(rlo, rhi) = add(plo, phi, rc);
+ #endif
+ return std::make_tuple(rlo, rhi);
+ }
+
+ /**
+ * Compute 128-bit result of 64-bit signed integer multiplication
+ * followed by addition
+ */
+ inline std::tuple<uint64_t, int64_t>
+ multiplyAdd(int64_t ra, int64_t rb, int64_t rc) const
+ {
+ uint64_t rlo;
+ int64_t rhi;
+ #if defined(__SIZEOF_INT128__)
+ __int128_t res = (__int128_t)ra * rb + rc;
+ rlo = res;
+ rhi = res >> 64;
+ #else
+ uint64_t plo;
+ int64_t phi;
+ std::tie(plo, phi) = multiply(ra, rb);
+ std::tie(rlo, rhi) = add(plo, phi, rc);
+ #endif
+ return std::make_tuple(rlo, rhi);
+ }
+