/*
 *  qemu user cpu loop
 *
 *  Copyright (c) 2003-2008 Fabrice Bellard
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 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 "qemu.h"
#include "user-internals.h"
#include "user/cpu_loop.h"
#include "signal-common.h"
#include "sparc/cpu_loop.h"

#define SPARC64_STACK_BIAS 2047

//#define DEBUG_WIN

/* WARNING: dealing with register windows _is_ complicated. More info
   can be found at http://www.sics.se/~psm/sparcstack.html */
static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
{
    index = (index + cwp * 16) % (16 * env->nwindows);
    /* wrap handling : if cwp is on the last window, then we use the
       registers 'after' the end */
    if (index < 8 && env->cwp == env->nwindows - 1)
        index += 16 * env->nwindows;
    return index;
}

/* save the register window 'cwp1' */
static inline void save_window_offset(CPUSPARCState *env, int cwp1)
{
    unsigned int i;
    abi_ulong sp_ptr;

    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
#ifdef TARGET_SPARC64
    if (sp_ptr & 3)
        sp_ptr += SPARC64_STACK_BIAS;
#endif
#if defined(DEBUG_WIN)
    printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
           sp_ptr, cwp1);
#endif
    for(i = 0; i < 16; i++) {
        /* FIXME - what to do if put_user() fails? */
        put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
        sp_ptr += sizeof(abi_ulong);
    }
}

static void save_window(CPUSPARCState *env)
{
#ifndef TARGET_SPARC64
    unsigned int new_wim;
    new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
        ((1LL << env->nwindows) - 1);
    save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
    env->wim = new_wim;
#else
    /*
     * cansave is zero if the spill trap handler is triggered by `save` and
     * nonzero if triggered by a `flushw`
     */
    save_window_offset(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
    env->cansave++;
    env->canrestore--;
#endif
}

static void restore_window(CPUSPARCState *env)
{
#ifndef TARGET_SPARC64
    unsigned int new_wim;
#endif
    unsigned int i, cwp1;
    abi_ulong sp_ptr;

#ifndef TARGET_SPARC64
    new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
        ((1LL << env->nwindows) - 1);
#endif

    /* restore the invalid window */
    cwp1 = cpu_cwp_inc(env, env->cwp + 1);
    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
#ifdef TARGET_SPARC64
    if (sp_ptr & 3)
        sp_ptr += SPARC64_STACK_BIAS;
#endif
#if defined(DEBUG_WIN)
    printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
           sp_ptr, cwp1);
#endif
    for(i = 0; i < 16; i++) {
        /* FIXME - what to do if get_user() fails? */
        get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
        sp_ptr += sizeof(abi_ulong);
    }
#ifdef TARGET_SPARC64
    env->canrestore++;
    if (env->cleanwin < env->nwindows - 1)
        env->cleanwin++;
    env->cansave--;
#else
    env->wim = new_wim;
#endif
}

void flush_windows(CPUSPARCState *env)
{
    int offset, cwp1;

    offset = 1;
    for(;;) {
        /* if restore would invoke restore_window(), then we can stop */
        cwp1 = cpu_cwp_inc(env, env->cwp + offset);
#ifndef TARGET_SPARC64
        if (env->wim & (1 << cwp1))
            break;
#else
        if (env->canrestore == 0)
            break;
        env->cansave++;
        env->canrestore--;
#endif
        save_window_offset(env, cwp1);
        offset++;
    }
    cwp1 = cpu_cwp_inc(env, env->cwp + 1);
#ifndef TARGET_SPARC64
    /* set wim so that restore will reload the registers */
    env->wim = 1 << cwp1;
#endif
#if defined(DEBUG_WIN)
    printf("flush_windows: nb=%d\n", offset - 1);
#endif
}

static void next_instruction(CPUSPARCState *env)
{
    env->pc = env->npc;
    env->npc = env->npc + 4;
}

static uint32_t do_getcc(CPUSPARCState *env)
{
#ifdef TARGET_SPARC64
    return cpu_get_ccr(env) & 0xf;
#else
    return extract32(cpu_get_psr(env), 20, 4);
#endif
}

static void do_setcc(CPUSPARCState *env, uint32_t icc)
{
#ifdef TARGET_SPARC64
    cpu_put_ccr(env, (cpu_get_ccr(env) & 0xf0) | (icc & 0xf));
#else
    cpu_put_psr(env, deposit32(cpu_get_psr(env), 20, 4, icc));
#endif
}

static uint32_t do_getpsr(CPUSPARCState *env)
{
#ifdef TARGET_SPARC64
    const uint64_t TSTATE_CWP = 0x1f;
    const uint64_t TSTATE_ICC = 0xfull << 32;
    const uint64_t TSTATE_XCC = 0xfull << 36;
    const uint32_t PSR_S      = 0x00000080u;
    const uint32_t PSR_V8PLUS = 0xff000000u;
    uint64_t tstate = sparc64_tstate(env);

    /* See <asm/psrcompat.h>, tstate_to_psr. */
    return ((tstate & TSTATE_CWP)                   |
            PSR_S                                   |
            ((tstate & TSTATE_ICC) >> 12)           |
            ((tstate & TSTATE_XCC) >> 20)           |
            PSR_V8PLUS);
#else
    return (cpu_get_psr(env) & (PSR_ICC | PSR_CWP)) | PSR_S;
#endif
}

/* Avoid ifdefs below for the abi32 and abi64 paths. */
#ifdef TARGET_ABI32
#define TARGET_TT_SYSCALL  (TT_TRAP + 0x10) /* t_linux */
#else
#define TARGET_TT_SYSCALL  (TT_TRAP + 0x6d) /* tl0_linux64 */
#endif

/* Avoid ifdefs below for the v9 and pre-v9 hw traps. */
#ifdef TARGET_SPARC64
#define TARGET_TT_SPILL  TT_SPILL
#define TARGET_TT_FILL   TT_FILL
#else
#define TARGET_TT_SPILL  TT_WIN_OVF
#define TARGET_TT_FILL   TT_WIN_UNF
#endif

void cpu_loop (CPUSPARCState *env)
{
    CPUState *cs = env_cpu(env);
    int trapnr;
    abi_long ret;

    while (1) {
        cpu_exec_start(cs);
        trapnr = cpu_exec(cs);
        cpu_exec_end(cs);
        qemu_process_cpu_events(cs);

        switch (trapnr) {
        case TARGET_TT_SYSCALL:
            ret = do_syscall (env, env->gregs[1],
                              env->regwptr[0], env->regwptr[1],
                              env->regwptr[2], env->regwptr[3],
                              env->regwptr[4], env->regwptr[5],
                              0, 0);
            if (ret == -QEMU_ERESTARTSYS ||
                ret == -QEMU_ESIGRETURN ||
                ret == -QEMU_ESETPC) {
                break;
            }
            if ((abi_ulong)ret >= (abi_ulong)(-515)) {
                set_syscall_C(env, 1);
                ret = -ret;
            } else {
                set_syscall_C(env, 0);
            }
            env->regwptr[0] = ret;
            /* next instruction */
            env->pc = env->npc;
            env->npc = env->npc + 4;
            break;

        case TT_TRAP + 0x01: /* breakpoint */
        case EXCP_DEBUG:
            force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
            break;

        case TT_TRAP + 0x02: /* div0 */
        case TT_DIV_ZERO:
            force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTDIV, env->pc);
            break;

        case TT_TRAP + 0x03: /* flush windows */
            flush_windows(env);
            next_instruction(env);
            break;

        case TT_TRAP + 0x20: /* getcc */
            env->gregs[1] = do_getcc(env);
            next_instruction(env);
            break;
        case TT_TRAP + 0x21: /* setcc */
            do_setcc(env, env->gregs[1]);
            next_instruction(env);
            break;
        case TT_TRAP + 0x22: /* getpsr */
            env->gregs[1] = do_getpsr(env);
            next_instruction(env);
            break;

#ifdef TARGET_SPARC64
        case TT_TRAP + 0x6e:
            flush_windows(env);
            sparc64_get_context(env);
            break;
        case TT_TRAP + 0x6f:
            flush_windows(env);
            sparc64_set_context(env);
            break;
#endif

        case TARGET_TT_SPILL: /* window overflow */
            save_window(env);
            break;
        case TARGET_TT_FILL:  /* window underflow */
            restore_window(env);
            break;

        case TT_FP_EXCP:
            {
                int code = TARGET_FPE_FLTUNK;
                target_ulong fsr = cpu_get_fsr(env);

                if ((fsr & FSR_FTT_MASK) == FSR_FTT_IEEE_EXCP) {
                    if (fsr & FSR_NVC) {
                        code = TARGET_FPE_FLTINV;
                    } else if (fsr & FSR_OFC) {
                        code = TARGET_FPE_FLTOVF;
                    } else if (fsr & FSR_UFC) {
                        code = TARGET_FPE_FLTUND;
                    } else if (fsr & FSR_DZC) {
                        code = TARGET_FPE_FLTDIV;
                    } else if (fsr & FSR_NXC) {
                        code = TARGET_FPE_FLTRES;
                    }
                }
                force_sig_fault(TARGET_SIGFPE, code, env->pc);
            }
            break;

        case EXCP_INTERRUPT:
            /* just indicate that signals should be handled asap */
            break;
        case TT_ILL_INSN:
            force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->pc);
            break;
        case TT_PRIV_INSN:
            force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVOPC, env->pc);
            break;
        case TT_TOVF:
            force_sig_fault(TARGET_SIGEMT, TARGET_EMT_TAGOVF, env->pc);
            break;
#ifdef TARGET_SPARC64
        case TT_PRIV_ACT:
            /* Note do_privact defers to do_privop. */
            force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVOPC, env->pc);
            break;
#else
        case TT_NCP_INSN:
            force_sig_fault(TARGET_SIGILL, TARGET_ILL_COPROC, env->pc);
            break;
        case TT_UNIMP_FLUSH:
            next_instruction(env);
            break;
#endif
        case EXCP_ATOMIC:
            cpu_exec_step_atomic(cs);
            break;
        default:
            /*
             * Most software trap numbers vector to BAD_TRAP.
             * Handle anything not explicitly matched above.
             */
            if (trapnr >= TT_TRAP && trapnr <= TT_TRAP + 0x7f) {
                force_sig_fault(TARGET_SIGILL, ILL_ILLTRP, env->pc);
                break;
            }
            fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr);
            cpu_dump_state(cs, stderr, 0);
            exit(EXIT_FAILURE);
        }
        process_pending_signals (env);
    }
}

void init_main_thread(CPUState *cs, struct image_info *info)
{
    CPUArchState *env = cpu_env(cs);

    env->pc = info->entry;
    env->npc = env->pc + 4;
    env->regwptr[WREG_SP] = (info->start_stack - 16 * sizeof(abi_ulong)
                             - TARGET_STACK_BIAS);
}
