/*
 *  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 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;
    }
}
