/*
 *  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 "cpu.h"
#include "mmu.h"
#include "exec/helper-proto.h"
#include "qemu/host-utils.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

#if !defined(CONFIG_USER_ONLY)
#include "exec/softmmu_exec.h"

#define MMUSUFFIX _mmu

#define SHIFT 0
#include "exec/softmmu_template.h"

#define SHIFT 1
#include "exec/softmmu_template.h"

#define SHIFT 2
#include "exec/softmmu_template.h"

#define SHIFT 3
#include "exec/softmmu_template.h"

/* Try to fill the TLB and return an exception if error. If retaddr is
   NULL, it means that the function was called in C code (i.e. not
   from generated code or from helper.c) */
void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
              uintptr_t retaddr)
{
    CRISCPU *cpu = CRIS_CPU(cs);
    CPUCRISState *env = &cpu->env;
    int ret;

    D_LOG("%s pc=%x tpc=%x ra=%p\n", __func__,
          env->pc, env->pregs[PR_EDA], (void *)retaddr);
    ret = cris_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
    if (unlikely(ret)) {
        if (retaddr) {
            /* now we have a real cpu fault */
            if (cpu_restore_state(cs, retaddr)) {
		/* Evaluate flags after retranslation.  */
                helper_top_evaluate_flags(env);
            }
        }
        cpu_loop_exit(cs);
    }
}

#endif

void helper_raise_exception(CPUCRISState *env, uint32_t index)
{
    CPUState *cs = CPU(cris_env_get_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)
    CRISCPU *cpu = cris_env_get_cpu(env);
    CPUState *cs = CPU(cpu);

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

void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2)
{
	qemu_log("%s: a0=%x a1=%x\n", __func__, a0, a1);
}

/* 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)
{
#if !defined(CONFIG_USER_ONLY)
    CRISCPU *cpu = cris_env_get_cpu(env);
#endif
	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(CPU(cpu), 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_lz(uint32_t t0)
{
	return clz32(t0);
}

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