/*
 * Helpers for HPPA instructions.
 *
 * Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"
#include "exec/cpu_ldst.h"
#include "qemu/timer.h"
#include "trace.h"

G_NORETURN void HELPER(excp)(CPUHPPAState *env, int excp)
{
    CPUState *cs = env_cpu(env);

    cs->exception_index = excp;
    cpu_loop_exit(cs);
}

G_NORETURN void hppa_dynamic_excp(CPUHPPAState *env, int excp, uintptr_t ra)
{
    CPUState *cs = env_cpu(env);

    cs->exception_index = excp;
    cpu_loop_exit_restore(cs, ra);
}

void HELPER(tsv)(CPUHPPAState *env, target_ulong cond)
{
    if (unlikely((target_long)cond < 0)) {
        hppa_dynamic_excp(env, EXCP_OVERFLOW, GETPC());
    }
}

void HELPER(tcond)(CPUHPPAState *env, target_ulong cond)
{
    if (unlikely(cond)) {
        hppa_dynamic_excp(env, EXCP_COND, GETPC());
    }
}

static void atomic_store_mask32(CPUHPPAState *env, target_ulong addr,
                                uint32_t val, uint32_t mask, uintptr_t ra)
{
    int mmu_idx = cpu_mmu_index(env_cpu(env), 0);
    uint32_t old, new, cmp, *haddr;
    void *vaddr;

    vaddr = probe_access(env, addr, 3, MMU_DATA_STORE, mmu_idx, ra);
    if (vaddr == NULL) {
        cpu_loop_exit_atomic(env_cpu(env), ra);
    }
    haddr = (uint32_t *)((uintptr_t)vaddr & -4);
    mask = addr & 1 ? 0x00ffffffu : 0xffffff00u;

    old = *haddr;
    while (1) {
        new = be32_to_cpu((cpu_to_be32(old) & ~mask) | (val & mask));
        cmp = qatomic_cmpxchg(haddr, old, new);
        if (cmp == old) {
            return;
        }
        old = cmp;
    }
}

static void atomic_store_mask64(CPUHPPAState *env, target_ulong addr,
                                uint64_t val, uint64_t mask,
                                int size, uintptr_t ra)
{
#ifdef CONFIG_ATOMIC64
    int mmu_idx = cpu_mmu_index(env_cpu(env), 0);
    uint64_t old, new, cmp, *haddr;
    void *vaddr;

    vaddr = probe_access(env, addr, size, MMU_DATA_STORE, mmu_idx, ra);
    if (vaddr == NULL) {
        cpu_loop_exit_atomic(env_cpu(env), ra);
    }
    haddr = (uint64_t *)((uintptr_t)vaddr & -8);

    old = *haddr;
    while (1) {
        new = be32_to_cpu((cpu_to_be32(old) & ~mask) | (val & mask));
        cmp = qatomic_cmpxchg__nocheck(haddr, old, new);
        if (cmp == old) {
            return;
        }
        old = cmp;
    }
#else
    cpu_loop_exit_atomic(env_cpu(env), ra);
#endif
}

static void do_stby_b(CPUHPPAState *env, target_ulong addr, target_ulong val,
                      bool parallel, uintptr_t ra)
{
    switch (addr & 3) {
    case 3:
        cpu_stb_data_ra(env, addr, val, ra);
        break;
    case 2:
        cpu_stw_data_ra(env, addr, val, ra);
        break;
    case 1:
        /* The 3 byte store must appear atomic.  */
        if (parallel) {
            atomic_store_mask32(env, addr, val, 0x00ffffffu, ra);
        } else {
            cpu_stb_data_ra(env, addr, val >> 16, ra);
            cpu_stw_data_ra(env, addr + 1, val, ra);
        }
        break;
    default:
        cpu_stl_data_ra(env, addr, val, ra);
        break;
    }
}

static void do_stdby_b(CPUHPPAState *env, target_ulong addr, uint64_t val,
                       bool parallel, uintptr_t ra)
{
    switch (addr & 7) {
    case 7:
        cpu_stb_data_ra(env, addr, val, ra);
        break;
    case 6:
        cpu_stw_data_ra(env, addr, val, ra);
        break;
    case 5:
        /* The 3 byte store must appear atomic.  */
        if (parallel) {
            atomic_store_mask32(env, addr, val, 0x00ffffffu, ra);
        } else {
            cpu_stb_data_ra(env, addr, val >> 16, ra);
            cpu_stw_data_ra(env, addr + 1, val, ra);
        }
        break;
    case 4:
        cpu_stl_data_ra(env, addr, val, ra);
        break;
    case 3:
        /* The 5 byte store must appear atomic.  */
        if (parallel) {
            atomic_store_mask64(env, addr, val, 0x000000ffffffffffull, 5, ra);
        } else {
            cpu_stb_data_ra(env, addr, val >> 32, ra);
            cpu_stl_data_ra(env, addr + 1, val, ra);
        }
        break;
    case 2:
        /* The 6 byte store must appear atomic.  */
        if (parallel) {
            atomic_store_mask64(env, addr, val, 0x0000ffffffffffffull, 6, ra);
        } else {
            cpu_stw_data_ra(env, addr, val >> 32, ra);
            cpu_stl_data_ra(env, addr + 2, val, ra);
        }
        break;
    case 1:
        /* The 7 byte store must appear atomic.  */
        if (parallel) {
            atomic_store_mask64(env, addr, val, 0x00ffffffffffffffull, 7, ra);
        } else {
            cpu_stb_data_ra(env, addr, val >> 48, ra);
            cpu_stw_data_ra(env, addr + 1, val >> 32, ra);
            cpu_stl_data_ra(env, addr + 3, val, ra);
        }
        break;
    default:
        cpu_stq_data_ra(env, addr, val, ra);
        break;
    }
}

void HELPER(stby_b)(CPUHPPAState *env, target_ulong addr, target_ulong val)
{
    do_stby_b(env, addr, val, false, GETPC());
}

void HELPER(stby_b_parallel)(CPUHPPAState *env, target_ulong addr,
                             target_ulong val)
{
    do_stby_b(env, addr, val, true, GETPC());
}

void HELPER(stdby_b)(CPUHPPAState *env, target_ulong addr, target_ulong val)
{
    do_stdby_b(env, addr, val, false, GETPC());
}

void HELPER(stdby_b_parallel)(CPUHPPAState *env, target_ulong addr,
                              target_ulong val)
{
    do_stdby_b(env, addr, val, true, GETPC());
}

static void do_stby_e(CPUHPPAState *env, target_ulong addr, target_ulong val,
                      bool parallel, uintptr_t ra)
{
    switch (addr & 3) {
    case 3:
        /* The 3 byte store must appear atomic.  */
        if (parallel) {
            atomic_store_mask32(env, addr - 3, val, 0xffffff00u, ra);
        } else {
            cpu_stw_data_ra(env, addr - 3, val >> 16, ra);
            cpu_stb_data_ra(env, addr - 1, val >> 8, ra);
        }
        break;
    case 2:
        cpu_stw_data_ra(env, addr - 2, val >> 16, ra);
        break;
    case 1:
        cpu_stb_data_ra(env, addr - 1, val >> 24, ra);
        break;
    default:
        /* Nothing is stored, but protection is checked and the
           cacheline is marked dirty.  */
        probe_write(env, addr, 0, cpu_mmu_index(env_cpu(env), 0), ra);
        break;
    }
}

static void do_stdby_e(CPUHPPAState *env, target_ulong addr, uint64_t val,
                       bool parallel, uintptr_t ra)
{
    switch (addr & 7) {
    case 7:
        /* The 7 byte store must appear atomic.  */
        if (parallel) {
            atomic_store_mask64(env, addr - 7, val,
                                0xffffffffffffff00ull, 7, ra);
        } else {
            cpu_stl_data_ra(env, addr - 7, val >> 32, ra);
            cpu_stw_data_ra(env, addr - 3, val >> 16, ra);
            cpu_stb_data_ra(env, addr - 1, val >> 8, ra);
        }
        break;
    case 6:
        /* The 6 byte store must appear atomic.  */
        if (parallel) {
            atomic_store_mask64(env, addr - 6, val,
                                0xffffffffffff0000ull, 6, ra);
        } else {
            cpu_stl_data_ra(env, addr - 6, val >> 32, ra);
            cpu_stw_data_ra(env, addr - 2, val >> 16, ra);
        }
        break;
    case 5:
        /* The 5 byte store must appear atomic.  */
        if (parallel) {
            atomic_store_mask64(env, addr - 5, val,
                                0xffffffffff000000ull, 5, ra);
        } else {
            cpu_stl_data_ra(env, addr - 5, val >> 32, ra);
            cpu_stb_data_ra(env, addr - 1, val >> 24, ra);
        }
        break;
    case 4:
        cpu_stl_data_ra(env, addr - 4, val >> 32, ra);
        break;
    case 3:
        /* The 3 byte store must appear atomic.  */
        if (parallel) {
            atomic_store_mask32(env, addr - 3, val >> 32, 0xffffff00u, ra);
        } else {
            cpu_stw_data_ra(env, addr - 3, val >> 48, ra);
            cpu_stb_data_ra(env, addr - 1, val >> 40, ra);
        }
        break;
    case 2:
        cpu_stw_data_ra(env, addr - 2, val >> 48, ra);
        break;
    case 1:
        cpu_stb_data_ra(env, addr - 1, val >> 56, ra);
        break;
    default:
        /* Nothing is stored, but protection is checked and the
           cacheline is marked dirty.  */
        probe_write(env, addr, 0, cpu_mmu_index(env_cpu(env), 0), ra);
        break;
    }
}

void HELPER(stby_e)(CPUHPPAState *env, target_ulong addr, target_ulong val)
{
    do_stby_e(env, addr, val, false, GETPC());
}

void HELPER(stby_e_parallel)(CPUHPPAState *env, target_ulong addr,
                             target_ulong val)
{
    do_stby_e(env, addr, val, true, GETPC());
}

void HELPER(stdby_e)(CPUHPPAState *env, target_ulong addr, target_ulong val)
{
    do_stdby_e(env, addr, val, false, GETPC());
}

void HELPER(stdby_e_parallel)(CPUHPPAState *env, target_ulong addr,
                              target_ulong val)
{
    do_stdby_e(env, addr, val, true, GETPC());
}

void HELPER(ldc_check)(target_ulong addr)
{
    if (unlikely(addr & 0xf)) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "Undefined ldc to unaligned address mod 16: "
                      TARGET_FMT_lx "\n", addr);
    }
}

target_ulong HELPER(probe)(CPUHPPAState *env, target_ulong addr,
                          uint32_t level, uint32_t want)
{
#ifdef CONFIG_USER_ONLY
    return page_check_range(addr, 1, want);
#else
    int prot, excp, mmu_idx;
    hwaddr phys;

    trace_hppa_tlb_probe(addr, level, want);
    /* Fail if the requested privilege level is higher than current.  */
    if (level < (env->iaoq_f & 3)) {
        return 0;
    }

    mmu_idx = PRIV_P_TO_MMU_IDX(level, env->psw & PSW_P);
    excp = hppa_get_physical_address(env, addr, mmu_idx, 0, &phys,
                                     &prot, NULL);
    if (excp >= 0) {
        cpu_restore_state(env_cpu(env), GETPC());
        hppa_set_ior_and_isr(env, addr, MMU_IDX_MMU_DISABLED(mmu_idx));
        if (excp == EXCP_DTLB_MISS) {
            excp = EXCP_NA_DTLB_MISS;
        }
        helper_excp(env, excp);
    }
    return (want & prot) != 0;
#endif
}

target_ulong HELPER(read_interval_timer)(void)
{
#ifdef CONFIG_USER_ONLY
    /* In user-mode, QEMU_CLOCK_VIRTUAL doesn't exist.
       Just pass through the host cpu clock ticks.  */
    return cpu_get_host_ticks();
#else
    /* In system mode we have access to a decent high-resolution clock.
       In order to make OS-level time accounting work with the cr16,
       present it with a well-timed clock fixed at 250MHz.  */
    return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >> 2;
#endif
}

uint64_t HELPER(hadd_ss)(uint64_t r1, uint64_t r2)
{
    uint64_t ret = 0;

    for (int i = 0; i < 64; i += 16) {
        int f1 = sextract64(r1, i, 16);
        int f2 = sextract64(r2, i, 16);
        int fr = f1 + f2;

        fr = MIN(fr, INT16_MAX);
        fr = MAX(fr, INT16_MIN);
        ret = deposit64(ret, i, 16, fr);
    }
    return ret;
}

uint64_t HELPER(hadd_us)(uint64_t r1, uint64_t r2)
{
    uint64_t ret = 0;

    for (int i = 0; i < 64; i += 16) {
        int f1 = extract64(r1, i, 16);
        int f2 = sextract64(r2, i, 16);
        int fr = f1 + f2;

        fr = MIN(fr, UINT16_MAX);
        fr = MAX(fr, 0);
        ret = deposit64(ret, i, 16, fr);
    }
    return ret;
}

uint64_t HELPER(havg)(uint64_t r1, uint64_t r2)
{
    uint64_t ret = 0;

    for (int i = 0; i < 64; i += 16) {
        int f1 = extract64(r1, i, 16);
        int f2 = extract64(r2, i, 16);
        int fr = f1 + f2;

        ret = deposit64(ret, i, 16, (fr >> 1) | (fr & 1));
    }
    return ret;
}

uint64_t HELPER(hsub_ss)(uint64_t r1, uint64_t r2)
{
    uint64_t ret = 0;

    for (int i = 0; i < 64; i += 16) {
        int f1 = sextract64(r1, i, 16);
        int f2 = sextract64(r2, i, 16);
        int fr = f1 - f2;

        fr = MIN(fr, INT16_MAX);
        fr = MAX(fr, INT16_MIN);
        ret = deposit64(ret, i, 16, fr);
    }
    return ret;
}

uint64_t HELPER(hsub_us)(uint64_t r1, uint64_t r2)
{
    uint64_t ret = 0;

    for (int i = 0; i < 64; i += 16) {
        int f1 = extract64(r1, i, 16);
        int f2 = sextract64(r2, i, 16);
        int fr = f1 - f2;

        fr = MIN(fr, UINT16_MAX);
        fr = MAX(fr, 0);
        ret = deposit64(ret, i, 16, fr);
    }
    return ret;
}

uint64_t HELPER(hshladd)(uint64_t r1, uint64_t r2, uint32_t sh)
{
    uint64_t ret = 0;

    for (int i = 0; i < 64; i += 16) {
        int f1 = sextract64(r1, i, 16);
        int f2 = sextract64(r2, i, 16);
        int fr = (f1 << sh) + f2;

        fr = MIN(fr, INT16_MAX);
        fr = MAX(fr, INT16_MIN);
        ret = deposit64(ret, i, 16, fr);
    }
    return ret;
}

uint64_t HELPER(hshradd)(uint64_t r1, uint64_t r2, uint32_t sh)
{
    uint64_t ret = 0;

    for (int i = 0; i < 64; i += 16) {
        int f1 = sextract64(r1, i, 16);
        int f2 = sextract64(r2, i, 16);
        int fr = (f1 >> sh) + f2;

        fr = MIN(fr, INT16_MAX);
        fr = MAX(fr, INT16_MIN);
        ret = deposit64(ret, i, 16, fr);
    }
    return ret;
}
