/*
 * RISC-V Emulation Helpers for QEMU.
 *
 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
 * Copyright (c) 2017-2018 SiFive, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"

target_ulong HELPER(divu_i128)(CPURISCVState *env,
                               target_ulong ul, target_ulong uh,
                               target_ulong vl, target_ulong vh)
{
    target_ulong ql, qh;
    Int128 q;

    if (vl == 0 && vh == 0) { /* Handle special behavior on div by zero */
        ql = ~0x0;
        qh = ~0x0;
    } else {
        q = int128_divu(int128_make128(ul, uh), int128_make128(vl, vh));
        ql = int128_getlo(q);
        qh = int128_gethi(q);
    }

    env->retxh = qh;
    return ql;
}

target_ulong HELPER(remu_i128)(CPURISCVState *env,
                               target_ulong ul, target_ulong uh,
                               target_ulong vl, target_ulong vh)
{
    target_ulong rl, rh;
    Int128 r;

    if (vl == 0 && vh == 0) {
        rl = ul;
        rh = uh;
    } else {
        r = int128_remu(int128_make128(ul, uh), int128_make128(vl, vh));
        rl = int128_getlo(r);
        rh = int128_gethi(r);
    }

    env->retxh = rh;
    return rl;
}

target_ulong HELPER(divs_i128)(CPURISCVState *env,
                               target_ulong ul, target_ulong uh,
                               target_ulong vl, target_ulong vh)
{
    target_ulong qh, ql;
    Int128 q;

    if (vl == 0 && vh == 0) { /* Div by zero check */
        ql = ~0x0;
        qh = ~0x0;
    } else if (uh == (1ULL << (TARGET_LONG_BITS - 1)) && ul == 0 &&
               vh == ~0x0 && vl == ~0x0) {
        /* Signed div overflow check (-2**127 / -1) */
        ql = ul;
        qh = uh;
    } else {
        q = int128_divs(int128_make128(ul, uh), int128_make128(vl, vh));
        ql = int128_getlo(q);
        qh = int128_gethi(q);
    }

    env->retxh = qh;
    return ql;
}

target_ulong HELPER(rems_i128)(CPURISCVState *env,
                               target_ulong ul, target_ulong uh,
                               target_ulong vl, target_ulong vh)
{
    target_ulong rh, rl;
    Int128 r;

    if (vl == 0 && vh == 0) {
        rl = ul;
        rh = uh;
    } else {
        r = int128_rems(int128_make128(ul, uh), int128_make128(vl, vh));
        rl = int128_getlo(r);
        rh = int128_gethi(r);
    }

    env->retxh = rh;
    return rl;
}
