/*
 *  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"

//#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 arithmetic, 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;
    }
}
