/*
 * Utility compute operations used by translated code.
 *
 * Copyright (c) 2003 Fabrice Bellard
 * Copyright (c) 2007 Aurelien Jarno
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "qemu/host-utils.h"

/* Long integer helpers */
static inline void mul64(uint64_t *plow, uint64_t *phigh,
                         uint64_t a, uint64_t b)
{
    typedef union {
        uint64_t ll;
        struct {
#ifdef HOST_WORDS_BIGENDIAN
            uint32_t high, low;
#else
            uint32_t low, high;
#endif
        } l;
    } LL;
    LL rl, rm, rn, rh, a0, b0;
    uint64_t c;

    a0.ll = a;
    b0.ll = b;

    rl.ll = (uint64_t)a0.l.low * b0.l.low;
    rm.ll = (uint64_t)a0.l.low * b0.l.high;
    rn.ll = (uint64_t)a0.l.high * b0.l.low;
    rh.ll = (uint64_t)a0.l.high * b0.l.high;

    c = (uint64_t)rl.l.high + rm.l.low + rn.l.low;
    rl.l.high = c;
    c >>= 32;
    c = c + rm.l.high + rn.l.high + rh.l.low;
    rh.l.low = c;
    rh.l.high += (uint32_t)(c >> 32);

    *plow = rl.ll;
    *phigh = rh.ll;
}

/* Unsigned 64x64 -> 128 multiplication */
void mulu64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
{
    mul64(plow, phigh, a, b);
}

/* Signed 64x64 -> 128 multiplication */
void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)
{
    uint64_t rh;

    mul64(plow, &rh, a, b);

    /* Adjust for signs.  */
    if (b < 0) {
        rh -= a;
    }
    if (a < 0) {
        rh -= b;
    }
    *phigh = rh;
}

/* Unsigned 128x64 division.  Returns 1 if overflow (divide by zero or */
/* quotient exceeds 64 bits).  Otherwise returns quotient via plow and */
/* remainder via phigh. */
int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
{
    uint64_t dhi = *phigh;
    uint64_t dlo = *plow;
    unsigned i;
    uint64_t carry = 0;

    if (divisor == 0) {
        return 1;
    } else if (dhi == 0) {
        *plow  = dlo / divisor;
        *phigh = dlo % divisor;
        return 0;
    } else if (dhi > divisor) {
        return 1;
    } else {

        for (i = 0; i < 64; i++) {
            carry = dhi >> 63;
            dhi = (dhi << 1) | (dlo >> 63);
            if (carry || (dhi >= divisor)) {
                dhi -= divisor;
                carry = 1;
            } else {
                carry = 0;
            }
            dlo = (dlo << 1) | carry;
        }

        *plow = dlo;
        *phigh = dhi;
        return 0;
    }
}

int divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
{
    int sgn_dvdnd = *phigh < 0;
    int sgn_divsr = divisor < 0;
    int overflow = 0;

    if (sgn_dvdnd) {
        *plow = ~(*plow);
        *phigh = ~(*phigh);
        if (*plow == (int64_t)-1) {
            *plow = 0;
            (*phigh)++;
         } else {
            (*plow)++;
         }
    }

    if (sgn_divsr) {
        divisor = 0 - divisor;
    }

    overflow = divu128((uint64_t *)plow, (uint64_t *)phigh, (uint64_t)divisor);

    if (sgn_dvdnd  ^ sgn_divsr) {
        *plow = 0 - *plow;
    }

    if (!overflow) {
        if ((*plow < 0) ^ (sgn_dvdnd ^ sgn_divsr)) {
            overflow = 1;
        }
    }

    return overflow;
}

