123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- #ifndef _MULTIPLY_H
- #define _MULTIPLY_H
- #include "common.h"
- /**
- * Double-precision multiplication
- */
- #if defined(HAVE_UINT128)
- #define DP_MULT(a,b,ol,oh) do { \
- __uint128_t pr; \
- pr = (__uint128_t)(a)*(b); \
- ol = (uint64_t)pr; \
- oh = (uint64_t)(pr >> 64); \
- } while (0)
- #elif defined(_MSC_VER) && defined(_WIN64)
- #include <windows.h>
- #define DP_MULT(a,b,ol,oh) do { ol = UnsignedMultiply128(a,b,&oh); } while (0)
- #else
- uint64_t static inline dp_mult_128_32(uint64_t a, uint64_t b, uint64_t *oh);
- uint64_t static inline dp_mult_128_32(uint64_t a, uint64_t b, uint64_t *oh)
- {
- uint32_t al = (uint32_t) a;
- uint32_t ah = (uint32_t)(a >> 32);
- uint32_t bl = (uint32_t) b;
- uint32_t bh = (uint32_t)(b >> 32);
- uint64_t sum0, sum1a, sum1b, sum2, sum3;
- sum0 = (uint64_t)al*bl;
- sum1a = (uint64_t)al*bh;
- sum1b = (uint64_t)ah*bl;
- sum2 = (uint64_t)ah*bh;
- sum1a += sum0 >> 32;
- sum1b += sum1a;
- sum3 = sum1b < sum1a;
- sum2 += sum1b >> 32;
- sum3 += sum2 >> 32;
- *oh = (sum3 << 32) + (uint32_t)sum2;
- return (sum1b << 32) + (uint32_t)sum0;
- }
- #define DP_MULT(a,b,ol,oh) do { ol = dp_mult_128_32(a,b,&oh); } while (0)
- #endif
- /*
- * Square an integer a[].
- *
- * @param t Location where the result is stored, 2*nw words.
- * @param scratchpad Temporary space, 3*nw words.
- * @param a Integer to square, nw words.
- * @param nw Size of the integer a[], in 64-bit words.
- */
- void square(uint64_t *t, uint64_t *scratchpad, const uint64_t *a, size_t nw);
- /*
- * Multiply an integer a[] by a 128-bit scalar, and add the result to integer t[].
- *
- * @param t Integer where the result of the multiplication is added
- * to, t_nw words.
- * @param scratchpad Temporary space, with t_nw+a_nw words.
- * @param a Integer to multiply by the scalar, a_nw words.
- * @param b0 Lower 64 bits of the scalar
- * @param b1 Higher 64 bits of the scalar
- * @param t_nw Size of integer t[], in 64-bit words. It must be at least a_nw+2.
- * @param a_nw Size of integer a[], in 64-bit words.
- */
- void addmul128(uint64_t *t, uint64_t *scratchpad, const uint64_t * a, uint64_t b0, uint64_t b1, size_t t_nw, size_t a_nw);
- #endif
|