/*
 *  CRIS helper routines
 *
 *  Copyright (c) 2007 AXIS Communications
 *  Written by Edgar E. Iglesias
 *
 * 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 "cpu.h"
#include "mmu.h"
#include "exec/helper-proto.h"
#include "qemu/host-utils.h"
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"

//#define CRIS_OP_HELPER_DEBUG


#ifdef CRIS_OP_HELPER_DEBUG
#define D(x) x
#define D_LOG(...) qemu_log(__VA_ARGS__)
#else
#define D(x)
#define D_LOG(...) do { } while (0)
#endif

void helper_raise_exception(CPUCRISState *env, uint32_t index)
{
    CPUState *cs = env_cpu(env);

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

void helper_tlb_flush_pid(CPUCRISState *env, uint32_t pid)
{
#if !defined(CONFIG_USER_ONLY)
    pid &= 0xff;
    if (pid != (env->pregs[PR_PID] & 0xff)) {
        cris_mmu_flush_pid(env, env->pregs[PR_PID]);
    }
#endif
}

void helper_spc_write(CPUCRISState *env, uint32_t new_spc)
{
#if !defined(CONFIG_USER_ONLY)
    CPUState *cs = env_cpu(env);

    tlb_flush_page(cs, env->pregs[PR_SPC]);
    tlb_flush_page(cs, new_spc);
#endif
}

/* Used by the tlb decoder.  */
#define EXTRACT_FIELD(src, start, end)                  \
    (((src) >> start) & ((1 << (end - start + 1)) - 1))

void helper_movl_sreg_reg(CPUCRISState *env, uint32_t sreg, uint32_t reg)
{
    uint32_t srs;
    srs = env->pregs[PR_SRS];
    srs &= 3;
    env->sregs[srs][sreg] = env->regs[reg];

#if !defined(CONFIG_USER_ONLY)
    if (srs == 1 || srs == 2) {
        if (sreg == 6) {
            /* Writes to tlb-hi write to mm_cause as a side effect.  */
            env->sregs[SFR_RW_MM_TLB_HI] = env->regs[reg];
            env->sregs[SFR_R_MM_CAUSE] = env->regs[reg];
        } else if (sreg == 5) {
            uint32_t set;
            uint32_t idx;
            uint32_t lo, hi;
            uint32_t vaddr;
            int tlb_v;

            idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
            set >>= 4;
            set &= 3;

            idx &= 15;
            /* We've just made a write to tlb_lo.  */
            lo = env->sregs[SFR_RW_MM_TLB_LO];
            /* Writes are done via r_mm_cause.  */
            hi = env->sregs[SFR_R_MM_CAUSE];

            vaddr = EXTRACT_FIELD(env->tlbsets[srs - 1][set][idx].hi, 13, 31);
            vaddr <<= TARGET_PAGE_BITS;
            tlb_v = EXTRACT_FIELD(env->tlbsets[srs - 1][set][idx].lo, 3, 3);
            env->tlbsets[srs - 1][set][idx].lo = lo;
            env->tlbsets[srs - 1][set][idx].hi = hi;

            D_LOG("tlb flush vaddr=%x v=%d pc=%x\n",
                  vaddr, tlb_v, env->pc);
            if (tlb_v) {
                tlb_flush_page(env_cpu(env), vaddr);
            }
        }
    }
#endif
}

void helper_movl_reg_sreg(CPUCRISState *env, uint32_t reg, uint32_t sreg)
{
    uint32_t srs;
    env->pregs[PR_SRS] &= 3;
    srs = env->pregs[PR_SRS];

#if !defined(CONFIG_USER_ONLY)
    if (srs == 1 || srs == 2) {
        uint32_t set;
        uint32_t idx;
        uint32_t lo, hi;

        idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
        set >>= 4;
        set &= 3;
        idx &= 15;

        /* Update the mirror regs.  */
        hi = env->tlbsets[srs - 1][set][idx].hi;
        lo = env->tlbsets[srs - 1][set][idx].lo;
        env->sregs[SFR_RW_MM_TLB_HI] = hi;
        env->sregs[SFR_RW_MM_TLB_LO] = lo;
    }
#endif
    env->regs[reg] = env->sregs[srs][sreg];
}

static void cris_ccs_rshift(CPUCRISState *env)
{
    uint32_t ccs;

    /* Apply the ccs shift.  */
    ccs = env->pregs[PR_CCS];
    ccs = (ccs & 0xc0000000) | ((ccs & 0x0fffffff) >> 10);
    if (ccs & U_FLAG) {
        /* Enter user mode.  */
        env->ksp = env->regs[R_SP];
        env->regs[R_SP] = env->pregs[PR_USP];
    }

    env->pregs[PR_CCS] = ccs;
}

void helper_rfe(CPUCRISState *env)
{
    int rflag = env->pregs[PR_CCS] & R_FLAG;

    D_LOG("rfe: erp=%x pid=%x ccs=%x btarget=%x\n",
          env->pregs[PR_ERP], env->pregs[PR_PID],
          env->pregs[PR_CCS],
          env->btarget);

    cris_ccs_rshift(env);

    /* RFE sets the P_FLAG only if the R_FLAG is not set.  */
    if (!rflag) {
        env->pregs[PR_CCS] |= P_FLAG;
    }
}

void helper_rfn(CPUCRISState *env)
{
    int rflag = env->pregs[PR_CCS] & R_FLAG;

    D_LOG("rfn: erp=%x pid=%x ccs=%x btarget=%x\n",
          env->pregs[PR_ERP], env->pregs[PR_PID],
          env->pregs[PR_CCS],
          env->btarget);

    cris_ccs_rshift(env);

    /* Set the P_FLAG only if the R_FLAG is not set.  */
    if (!rflag) {
        env->pregs[PR_CCS] |= P_FLAG;
    }

    /* Always set the M flag.  */
    env->pregs[PR_CCS] |= M_FLAG_V32;
}

uint32_t helper_btst(CPUCRISState *env, uint32_t t0, uint32_t t1, uint32_t ccs)
{
    /* FIXME: clean this up.  */

    /*
     * des ref:
     *  The N flag is set according to the selected bit in the dest reg.
     *  The Z flag is set if the selected bit and all bits to the right are
     *  zero.
     *  The X flag is cleared.
     *  Other flags are left untouched.
     *  The destination reg is not affected.
     */
    unsigned int fz, sbit, bset, mask, masked_t0;

    sbit = t1 & 31;
    bset = !!(t0 & (1 << sbit));
    mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1;
    masked_t0 = t0 & mask;
    fz = !(masked_t0 | bset);

    /* Clear the X, N and Z flags.  */
    ccs = ccs & ~(X_FLAG | N_FLAG | Z_FLAG);
    if (env->pregs[PR_VR] < 32) {
        ccs &= ~(V_FLAG | C_FLAG);
    }
    /* Set the N and Z flags accordingly.  */
    ccs |= (bset << 3) | (fz << 2);
    return ccs;
}

static inline uint32_t evaluate_flags_writeback(CPUCRISState *env,
                                                uint32_t flags, uint32_t ccs)
{
    unsigned int x, z, mask;

    /* Extended arithmetics, leave the z flag alone.  */
    x = env->cc_x;
    mask = env->cc_mask | X_FLAG;
    if (x) {
        z = flags & Z_FLAG;
        mask = mask & ~z;
    }
    flags &= mask;

    /* all insn clear the x-flag except setf or clrf.  */
    ccs &= ~mask;
    ccs |= flags;
    return ccs;
}

uint32_t helper_evaluate_flags_muls(CPUCRISState *env,
                                    uint32_t ccs, uint32_t res, uint32_t mof)
{
    uint32_t flags = 0;
    int64_t tmp;
    int dneg;

    dneg = ((int32_t)res) < 0;

    tmp = mof;
    tmp <<= 32;
    tmp |= res;
    if (tmp == 0) {
        flags |= Z_FLAG;
    } else if (tmp < 0) {
        flags |= N_FLAG;
    }
    if ((dneg && mof != -1) || (!dneg && mof != 0)) {
        flags |= V_FLAG;
    }
    return evaluate_flags_writeback(env, flags, ccs);
}

uint32_t helper_evaluate_flags_mulu(CPUCRISState *env,
                                    uint32_t ccs, uint32_t res, uint32_t mof)
{
    uint32_t flags = 0;
    uint64_t tmp;

    tmp = mof;
    tmp <<= 32;
    tmp |= res;
    if (tmp == 0) {
        flags |= Z_FLAG;
    } else if (tmp >> 63) {
        flags |= N_FLAG;
    }
    if (mof) {
        flags |= V_FLAG;
    }

    return evaluate_flags_writeback(env, flags, ccs);
}

uint32_t helper_evaluate_flags_mcp(CPUCRISState *env, uint32_t ccs,
				   uint32_t src, uint32_t dst, uint32_t res)
{
    uint32_t flags = 0;

    src = src & 0x80000000;
    dst = dst & 0x80000000;

    if ((res & 0x80000000L) != 0L) {
        flags |= N_FLAG;
        if (!src && !dst) {
            flags |= V_FLAG;
        } else if (src & dst) {
            flags |= R_FLAG;
        }
    } else {
        if (res == 0L) {
            flags |= Z_FLAG;
        }
        if (src & dst) {
            flags |= V_FLAG;
        }
        if (dst | src) {
            flags |= R_FLAG;
        }
    }

    return evaluate_flags_writeback(env, flags, ccs);
}

uint32_t helper_evaluate_flags_alu_4(CPUCRISState *env, uint32_t ccs,
				     uint32_t src, uint32_t dst, uint32_t res)
{
    uint32_t flags = 0;

    src = src & 0x80000000;
    dst = dst & 0x80000000;

    if ((res & 0x80000000L) != 0L) {
        flags |= N_FLAG;
        if (!src && !dst) {
            flags |= V_FLAG;
        } else if (src & dst) {
            flags |= C_FLAG;
        }
    } else {
        if (res == 0L) {
            flags |= Z_FLAG;
        }
        if (src & dst) {
            flags |= V_FLAG;
        }
        if (dst | src) {
            flags |= C_FLAG;
        }
    }

    return evaluate_flags_writeback(env, flags, ccs);
}

uint32_t helper_evaluate_flags_sub_4(CPUCRISState *env, uint32_t ccs,
				     uint32_t src, uint32_t dst, uint32_t res)
{
    uint32_t flags = 0;

    src = (~src) & 0x80000000;
    dst = dst & 0x80000000;

    if ((res & 0x80000000L) != 0L) {
        flags |= N_FLAG;
        if (!src && !dst) {
            flags |= V_FLAG;
        } else if (src & dst) {
            flags |= C_FLAG;
        }
    } else {
        if (res == 0L) {
            flags |= Z_FLAG;
        }
        if (src & dst) {
            flags |= V_FLAG;
        }
        if (dst | src) {
            flags |= C_FLAG;
        }
    }

    flags ^= C_FLAG;
    return evaluate_flags_writeback(env, flags, ccs);
}

uint32_t helper_evaluate_flags_move_4(CPUCRISState *env,
                                      uint32_t ccs, uint32_t res)
{
    uint32_t flags = 0;

    if ((int32_t)res < 0) {
        flags |= N_FLAG;
    } else if (res == 0L) {
        flags |= Z_FLAG;
    }

    return evaluate_flags_writeback(env, flags, ccs);
}

uint32_t helper_evaluate_flags_move_2(CPUCRISState *env,
                                      uint32_t ccs, uint32_t res)
{
    uint32_t flags = 0;

    if ((int16_t)res < 0L) {
        flags |= N_FLAG;
    } else if (res == 0) {
        flags |= Z_FLAG;
    }

    return evaluate_flags_writeback(env, flags, ccs);
}

/*
 * TODO: This is expensive. We could split things up and only evaluate part of
 * CCR on a need to know basis. For now, we simply re-evaluate everything.
 */
void helper_evaluate_flags(CPUCRISState *env)
{
    uint32_t src, dst, res;
    uint32_t flags = 0;

    src = env->cc_src;
    dst = env->cc_dest;
    res = env->cc_result;

    if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP) {
        src = ~src;
    }

    /*
     * Now, evaluate the flags. This stuff is based on
     * Per Zander's CRISv10 simulator.
     */
    switch (env->cc_size) {
    case 1:
        if ((res & 0x80L) != 0L) {
            flags |= N_FLAG;
            if (((src & 0x80L) == 0L) && ((dst & 0x80L) == 0L)) {
                flags |= V_FLAG;
            } else if (((src & 0x80L) != 0L) && ((dst & 0x80L) != 0L)) {
                flags |= C_FLAG;
            }
        } else {
            if ((res & 0xFFL) == 0L) {
                flags |= Z_FLAG;
            }
            if (((src & 0x80L) != 0L) && ((dst & 0x80L) != 0L)) {
                flags |= V_FLAG;
            }
            if ((dst & 0x80L) != 0L || (src & 0x80L) != 0L) {
                flags |= C_FLAG;
            }
        }
        break;
    case 2:
        if ((res & 0x8000L) != 0L) {
            flags |= N_FLAG;
            if (((src & 0x8000L) == 0L) && ((dst & 0x8000L) == 0L)) {
                flags |= V_FLAG;
            } else if (((src & 0x8000L) != 0L) && ((dst & 0x8000L) != 0L)) {
                flags |= C_FLAG;
            }
        } else {
            if ((res & 0xFFFFL) == 0L) {
                flags |= Z_FLAG;
            }
            if (((src & 0x8000L) != 0L) && ((dst & 0x8000L) != 0L)) {
                flags |= V_FLAG;
            }
            if ((dst & 0x8000L) != 0L || (src & 0x8000L) != 0L) {
                flags |= C_FLAG;
            }
        }
        break;
    case 4:
        if ((res & 0x80000000L) != 0L) {
            flags |= N_FLAG;
            if (((src & 0x80000000L) == 0L) && ((dst & 0x80000000L) == 0L)) {
                flags |= V_FLAG;
            } else if (((src & 0x80000000L) != 0L) &&
                       ((dst & 0x80000000L) != 0L)) {
                flags |= C_FLAG;
            }
        } else {
            if (res == 0L) {
                flags |= Z_FLAG;
            }
            if (((src & 0x80000000L) != 0L) && ((dst & 0x80000000L) != 0L)) {
                flags |= V_FLAG;
            }
            if ((dst & 0x80000000L) != 0L || (src & 0x80000000L) != 0L) {
                flags |= C_FLAG;
            }
        }
        break;
    default:
        break;
    }

    if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP) {
        flags ^= C_FLAG;
    }

    env->pregs[PR_CCS] = evaluate_flags_writeback(env, flags,
                                                  env->pregs[PR_CCS]);
}

void helper_top_evaluate_flags(CPUCRISState *env)
{
    switch (env->cc_op) {
    case CC_OP_MCP:
        env->pregs[PR_CCS]
            = helper_evaluate_flags_mcp(env, env->pregs[PR_CCS],
                                        env->cc_src, env->cc_dest,
                                        env->cc_result);
        break;
    case CC_OP_MULS:
        env->pregs[PR_CCS]
            = helper_evaluate_flags_muls(env, env->pregs[PR_CCS],
                                         env->cc_result, env->pregs[PR_MOF]);
        break;
    case CC_OP_MULU:
        env->pregs[PR_CCS]
            = helper_evaluate_flags_mulu(env, env->pregs[PR_CCS],
                                         env->cc_result, env->pregs[PR_MOF]);
        break;
    case CC_OP_MOVE:
    case CC_OP_AND:
    case CC_OP_OR:
    case CC_OP_XOR:
    case CC_OP_ASR:
    case CC_OP_LSR:
    case CC_OP_LSL:
        switch (env->cc_size) {
        case 4:
            env->pregs[PR_CCS] =
                helper_evaluate_flags_move_4(env,
                                             env->pregs[PR_CCS],
                                             env->cc_result);
            break;
        case 2:
            env->pregs[PR_CCS] =
                helper_evaluate_flags_move_2(env,
                                             env->pregs[PR_CCS],
                                             env->cc_result);
            break;
        default:
            helper_evaluate_flags(env);
            break;
        }
        break;
    case CC_OP_FLAGS:
        /* live.  */
        break;
    case CC_OP_SUB:
    case CC_OP_CMP:
        if (env->cc_size == 4) {
            env->pregs[PR_CCS] =
                helper_evaluate_flags_sub_4(env,
                                            env->pregs[PR_CCS],
                                            env->cc_src, env->cc_dest,
                                            env->cc_result);
        } else {
            helper_evaluate_flags(env);
        }
        break;
    default:
        switch (env->cc_size) {
        case 4:
            env->pregs[PR_CCS] =
                helper_evaluate_flags_alu_4(env,
                                            env->pregs[PR_CCS],
                                            env->cc_src, env->cc_dest,
                                            env->cc_result);
            break;
        default:
            helper_evaluate_flags(env);
            break;
        }
        break;
    }
}
