/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* Multiplication performance enhancements for sparc v8+vis CPUs. */

#include "mpi-priv.h"
#include <stddef.h>
#include <sys/systeminfo.h>
#include <strings.h>

/* In the functions below, */
/* vector y must be 8-byte aligned, and n must be even */
/* returns carry out of high order word of result */
/* maximum n is 256 */

/* vector x += vector y * scaler a; where y is of length n words. */
extern mp_digit mul_add_inp(mp_digit *x, const mp_digit *y, int n, mp_digit a);

/* vector z = vector x + vector y * scaler a; where y is of length n words. */
extern mp_digit mul_add(mp_digit *z, const mp_digit *x, const mp_digit *y,
                        int n, mp_digit a);

/* v8 versions of these functions run on any Sparc v8 CPU. */

/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
#define MP_MUL_DxD(a, b, Phi, Plo)                              \
    {                                                           \
        unsigned long long product = (unsigned long long)a * b; \
        Plo = (mp_digit)product;                                \
        Phi = (mp_digit)(product >> MP_DIGIT_BIT);              \
    }

/* c = a * b */
static void
v8_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
{
#if !defined(MP_NO_MP_WORD)
    mp_digit d = 0;

    /* Inner product:  Digits of a */
    while (a_len--) {
        mp_word w = ((mp_word)b * *a++) + d;
        *c++ = ACCUM(w);
        d = CARRYOUT(w);
    }
    *c = d;
#else
    mp_digit carry = 0;
    while (a_len--) {
        mp_digit a_i = *a++;
        mp_digit a0b0, a1b1;

        MP_MUL_DxD(a_i, b, a1b1, a0b0);

        a0b0 += carry;
        if (a0b0 < carry)
            ++a1b1;
        *c++ = a0b0;
        carry = a1b1;
    }
    *c = carry;
#endif
}

/* c += a * b */
static void
v8_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
{
#if !defined(MP_NO_MP_WORD)
    mp_digit d = 0;

    /* Inner product:  Digits of a */
    while (a_len--) {
        mp_word w = ((mp_word)b * *a++) + *c + d;
        *c++ = ACCUM(w);
        d = CARRYOUT(w);
    }
    *c = d;
#else
    mp_digit carry = 0;
    while (a_len--) {
        mp_digit a_i = *a++;
        mp_digit a0b0, a1b1;

        MP_MUL_DxD(a_i, b, a1b1, a0b0);

        a0b0 += carry;
        if (a0b0 < carry)
            ++a1b1;
        a0b0 += a_i = *c;
        if (a0b0 < a_i)
            ++a1b1;
        *c++ = a0b0;
        carry = a1b1;
    }
    *c = carry;
#endif
}

/* Presently, this is only used by the Montgomery arithmetic code. */
/* c += a * b */
static void
v8_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
{
#if !defined(MP_NO_MP_WORD)
    mp_digit d = 0;

    /* Inner product:  Digits of a */
    while (a_len--) {
        mp_word w = ((mp_word)b * *a++) + *c + d;
        *c++ = ACCUM(w);
        d = CARRYOUT(w);
    }

    while (d) {
        mp_word w = (mp_word)*c + d;
        *c++ = ACCUM(w);
        d = CARRYOUT(w);
    }
#else
    mp_digit carry = 0;
    while (a_len--) {
        mp_digit a_i = *a++;
        mp_digit a0b0, a1b1;

        MP_MUL_DxD(a_i, b, a1b1, a0b0);

        a0b0 += carry;
        if (a0b0 < carry)
            ++a1b1;

        a0b0 += a_i = *c;
        if (a0b0 < a_i)
            ++a1b1;

        *c++ = a0b0;
        carry = a1b1;
    }
    while (carry) {
        mp_digit c_i = *c;
        carry += c_i;
        *c++ = carry;
        carry = carry < c_i;
    }
#endif
}

/* These functions run only on v8plus+vis or v9+vis CPUs. */

/* c = a * b */
void
s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
{
    mp_digit d;
    mp_digit x[258];
    if (a_len <= 256) {
        if (a == c || ((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) {
            mp_digit *px;
            px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x;
            memcpy(px, a, a_len * sizeof(*a));
            a = px;
            if (a_len & 1) {
                px[a_len] = 0;
            }
        }
        s_mp_setz(c, a_len + 1);
        d = mul_add_inp(c, a, a_len, b);
        c[a_len] = d;
    } else {
        v8_mpv_mul_d(a, a_len, b, c);
    }
}

/* c += a * b, where a is a_len words long. */
void
s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
{
    mp_digit d;
    mp_digit x[258];
    if (a_len <= 256) {
        if (((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) {
            mp_digit *px;
            px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x;
            memcpy(px, a, a_len * sizeof(*a));
            a = px;
            if (a_len & 1) {
                px[a_len] = 0;
            }
        }
        d = mul_add_inp(c, a, a_len, b);
        c[a_len] = d;
    } else {
        v8_mpv_mul_d_add(a, a_len, b, c);
    }
}

/* c += a * b, where a is y words long. */
void
s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
{
    mp_digit d;
    mp_digit x[258];
    if (a_len <= 256) {
        if (((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) {
            mp_digit *px;
            px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x;
            memcpy(px, a, a_len * sizeof(*a));
            a = px;
            if (a_len & 1) {
                px[a_len] = 0;
            }
        }
        d = mul_add_inp(c, a, a_len, b);
        if (d) {
            c += a_len;
            do {
                mp_digit sum = d + *c;
                *c++ = sum;
                d = sum < d;
            } while (d);
        }
    } else {
        v8_mpv_mul_d_add_prop(a, a_len, b, c);
    }
}
