/*
 *  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 "dyngen-exec.h"
#include "mmu.h"
#include "helper.h"
#include "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 "softmmu_exec.h"

#define MMUSUFFIX _mmu

#define SHIFT 0
#include "softmmu_template.h"

#define SHIFT 1
#include "softmmu_template.h"

#define SHIFT 2
#include "softmmu_template.h"

#define SHIFT 3
#include "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) */
/* XXX: fix it to restore all registers */
void tlb_fill(CPUCRISState *env1, target_ulong addr, int is_write, int mmu_idx,
              uintptr_t retaddr)
{
    TranslationBlock *tb;
    CPUCRISState *saved_env;
    int ret;

    saved_env = env;
    env = env1;

    D_LOG("%s pc=%x tpc=%x ra=%p\n", __func__,
          env->pc, env->debug1, (void *)retaddr);
    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx);
    if (unlikely(ret)) {
        if (retaddr) {
            /* now we have a real cpu fault */
            tb = tb_find_pc(retaddr);
            if (tb) {
                /* the PC is inside the translated code. It means that we have
                   a virtual CPU fault */
                cpu_restore_state(tb, env, retaddr);

		/* Evaluate flags after retranslation.  */
                helper_top_evaluate_flags();
            }
        }
        cpu_loop_exit(env);
    }
    env = saved_env;
}

#endif

void helper_raise_exception(uint32_t index)
{
	env->exception_index = index;
        cpu_loop_exit(env);
}

void helper_tlb_flush_pid(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(uint32_t new_spc)
{
#if !defined(CONFIG_USER_ONLY)
	tlb_flush_page(env, env->pregs[PR_SPC]);
	tlb_flush_page(env, 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 (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, vaddr);
			}
		}
	}
#endif
}

void helper_movl_reg_sreg (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(void)
{
	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(void)
{
	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(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(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(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(flags, ccs);
}

uint32_t helper_evaluate_flags_mulu(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(flags, ccs);
}

uint32_t helper_evaluate_flags_mcp(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(flags, ccs);
}

uint32_t helper_evaluate_flags_alu_4(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(flags, ccs);
}

uint32_t helper_evaluate_flags_sub_4(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(flags, ccs);
}

uint32_t helper_evaluate_flags_move_4(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(flags, ccs);
}
uint32_t helper_evaluate_flags_move_2(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(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(void)
{
	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(flags, env->pregs[PR_CCS]);
}

void helper_top_evaluate_flags(void)
{
	switch (env->cc_op)
	{
		case CC_OP_MCP:
			env->pregs[PR_CCS] = helper_evaluate_flags_mcp(
					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->pregs[PR_CCS], env->cc_result,
					env->pregs[PR_MOF]);
			break;
		case CC_OP_MULU:
			env->pregs[PR_CCS] = helper_evaluate_flags_mulu(
					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->pregs[PR_CCS],
							env->cc_result);
				break;
			case 2:
				env->pregs[PR_CCS] =
					helper_evaluate_flags_move_2(
							env->pregs[PR_CCS],
							env->cc_result);
				break;
			default:
				helper_evaluate_flags();
				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->pregs[PR_CCS],
						env->cc_src, env->cc_dest,
						env->cc_result);
			else
				helper_evaluate_flags();
			break;
		default:
		{
			switch (env->cc_size)
			{
			case 4:
				env->pregs[PR_CCS] =
					helper_evaluate_flags_alu_4(
						env->pregs[PR_CCS],
						env->cc_src, env->cc_dest,
						env->cc_result);
				break;
			default:
				helper_evaluate_flags();
				break;
			}
		}
		break;
	}
}
