/* CRIS v32 simulator support code
   Copyright (C) 2004-2016 Free Software Foundation, Inc.
   Contributed by Axis Communications.

This file is part of the GNU simulators.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* The infrastructure is based on that of i960.c.  */

#define WANT_CPU_CRISV32F

#define SPECIFIC_U_EXEC_FN
#define SPECIFIC_U_SKIP4_FN
#define SPECIFIC_U_CONST16_FN
#define SPECIFIC_U_CONST32_FN
#define SPECIFIC_U_MEM_FN
#define SPECIFIC_U_MOVEM_FN
#define BASENUM 32
#define CRIS_TLS_REGISTER 2
#include "cris-tmpl.c"

#if WITH_PROFILE_MODEL_P

/* Re-use the bit position for the BZ register, since there are no stall
   cycles for reading or writing it.  */
#define CRIS_BZ_REGNO 16
#define CRIS_MODF_JUMP_MASK (1 << CRIS_BZ_REGNO)
/* Likewise for the WZ register, marking memory writes.  */
#define CRIS_WZ_REGNO 20
#define CRIS_MODF_MEM_WRITE_MASK (1 << CRIS_WZ_REGNO)
#define CRIS_MOF_REGNO (16 + 7)
#define CRIS_ALWAYS_CONDITION 14

/* This macro must only be used in context where there's only one
   dynamic cause for a penalty, except in the u-exec unit.  */

#define PENALIZE1(CNT)					\
  do							\
    {							\
      CPU_CRIS_MISC_PROFILE (current_cpu)->CNT++;	\
      model_data->prev_prev_prev_modf_regs		\
	= model_data->prev_prev_modf_regs;		\
      model_data->prev_prev_modf_regs			\
	= model_data->prev_modf_regs;			\
      model_data->prev_modf_regs = 0;			\
      model_data->prev_prev_prev_movem_dest_regs	\
	= model_data->prev_prev_movem_dest_regs;	\
      model_data->prev_prev_movem_dest_regs		\
	= model_data->prev_movem_dest_regs;		\
      model_data->prev_movem_dest_regs = 0;		\
    }							\
  while (0)


/* Model function for u-skip4 unit.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_skip4)) (SIM_CPU *current_cpu,
			  const IDESC *idesc ATTRIBUTE_UNUSED,
			  int unit_num ATTRIBUTE_UNUSED,
			  int referenced ATTRIBUTE_UNUSED)
{
  /* Handle PC not being updated with pbb.  FIXME: What if not pbb?  */
  CPU (h_pc) += 4;
  return 0;
}

/* Model function for u-exec unit.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_exec)) (SIM_CPU *current_cpu,
			 const IDESC *idesc ATTRIBUTE_UNUSED,
			 int unit_num ATTRIBUTE_UNUSED,
			 int referenced ATTRIBUTE_UNUSED,
			 INT destreg_in,
			 INT srcreg,
			 INT destreg_out)
{
  MODEL_CRISV32_DATA *model_data
    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
  UINT modf_regs
    = ((destreg_out == -1 ? 0 : (1 << destreg_out))
       | model_data->modf_regs);

  if (srcreg != -1)
    {
      if (model_data->prev_movem_dest_regs & (1 << srcreg))
	{
	  PENALIZE1 (movemdst_stall_count);
	  PENALIZE1 (movemdst_stall_count);
	  PENALIZE1 (movemdst_stall_count);
	}
      else if (model_data->prev_prev_movem_dest_regs & (1 << srcreg))
	{
	  PENALIZE1 (movemdst_stall_count);
	  PENALIZE1 (movemdst_stall_count);
	}
      else if (model_data->prev_prev_prev_movem_dest_regs & (1 << srcreg))
	PENALIZE1 (movemdst_stall_count);
    }

  if (destreg_in != -1)
    {
      if (model_data->prev_movem_dest_regs & (1 << destreg_in))
	{
	  PENALIZE1 (movemdst_stall_count);
	  PENALIZE1 (movemdst_stall_count);
	  PENALIZE1 (movemdst_stall_count);
	}
      else if (model_data->prev_prev_movem_dest_regs & (1 << destreg_in))
	{
	  PENALIZE1 (movemdst_stall_count);
	  PENALIZE1 (movemdst_stall_count);
	}
      else if (model_data->prev_prev_prev_movem_dest_regs & (1 << destreg_in))
	PENALIZE1 (movemdst_stall_count);
    }

  model_data->prev_prev_prev_modf_regs
    = model_data->prev_prev_modf_regs;
  model_data->prev_prev_modf_regs = model_data->prev_modf_regs;
  model_data->prev_modf_regs = modf_regs;
  model_data->modf_regs = 0;

  model_data->prev_prev_prev_movem_dest_regs
    = model_data->prev_prev_movem_dest_regs;
  model_data->prev_prev_movem_dest_regs = model_data->prev_movem_dest_regs;
  model_data->prev_movem_dest_regs = model_data->movem_dest_regs;
  model_data->movem_dest_regs = 0;

  /* Handle PC not being updated with pbb.  FIXME: What if not pbb?  */
  CPU (h_pc) += 2;
  return 1;
}

/* Special case used when the destination is a special register.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_exec_to_sr)) (SIM_CPU *current_cpu,
			       const IDESC *idesc ATTRIBUTE_UNUSED,
			       int unit_num ATTRIBUTE_UNUSED,
			       int referenced ATTRIBUTE_UNUSED,
			       INT srcreg,
			       INT specreg)
{
  int specdest;

  if (specreg != -1)
    specdest = specreg + 16;
  else
    abort ();

  return MY (XCONCAT3 (f_model_crisv,BASENUM,_u_exec))
    (current_cpu, NULL, 0, 0, -1, srcreg,
     /* The positions for constant-zero registers BZ and WZ are recycled
	for jump and memory-write markers.  We must take precautions
	here not to add false markers for them.  It might be that the
	hardware inserts stall cycles for instructions that actually try
	and write those registers, but we'll burn that bridge when we
	get to it; we'd have to find other free bits or make new
	model_data variables.  However, it's doubtful that there will
	ever be a need to be cycle-correct for useless code, at least in
	this particular simulator, mainly used for GCC testing.  */
     specdest == CRIS_BZ_REGNO || specdest == CRIS_WZ_REGNO
     ? -1 : specdest);
}


/* Special case for movem.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_exec_movem)) (SIM_CPU *current_cpu,
			       const IDESC *idesc ATTRIBUTE_UNUSED,
			       int unit_num ATTRIBUTE_UNUSED,
			       int referenced ATTRIBUTE_UNUSED,
			       INT srcreg,
			       INT destreg_out)
{
  return MY (XCONCAT3 (f_model_crisv,BASENUM,_u_exec))
    (current_cpu, NULL, 0, 0, -1, srcreg, destreg_out);
}

/* Model function for u-const16 unit.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_const16)) (SIM_CPU *current_cpu,
			    const IDESC *idesc ATTRIBUTE_UNUSED,
			    int unit_num ATTRIBUTE_UNUSED,
			    int referenced ATTRIBUTE_UNUSED)
{
  MODEL_CRISV32_DATA *model_data
    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);

  /* If the previous insn was a jump of some sort and this insn
     straddles a cache-line, there's a one-cycle penalty.
     FIXME: Test-cases for normal const16 and others, like branch.  */
  if ((model_data->prev_modf_regs & CRIS_MODF_JUMP_MASK)
      && (CPU (h_pc) & 0x1e) == 0x1e)
    PENALIZE1 (jumptarget_stall_count);

  /* Handle PC not being updated with pbb.  FIXME: What if not pbb?  */
  CPU (h_pc) += 2;

  return 0;
}

/* Model function for u-const32 unit.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_const32)) (SIM_CPU *current_cpu,
			    const IDESC *idesc ATTRIBUTE_UNUSED,
			    int unit_num ATTRIBUTE_UNUSED,
			    int referenced ATTRIBUTE_UNUSED)
{
  MODEL_CRISV32_DATA *model_data
    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);

  /* If the previous insn was a jump of some sort and this insn
     straddles a cache-line, there's a one-cycle penalty.  */
  if ((model_data->prev_modf_regs & CRIS_MODF_JUMP_MASK)
      && (CPU (h_pc) & 0x1e) == 0x1c)
    PENALIZE1 (jumptarget_stall_count);

  /* Handle PC not being updated with pbb.  FIXME: What if not pbb?  */
  CPU (h_pc) += 4;

  return 0;
}

/* Model function for u-mem unit.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_mem)) (SIM_CPU *current_cpu,
			const IDESC *idesc ATTRIBUTE_UNUSED,
			int unit_num ATTRIBUTE_UNUSED,
			int referenced ATTRIBUTE_UNUSED,
			INT srcreg)
{
  MODEL_CRISV32_DATA *model_data
    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);

  if (srcreg == -1)
    abort ();

  /* If srcreg references a register modified in the previous cycle
     through other than autoincrement, then there's a penalty: one
     cycle.  */
  if (model_data->prev_modf_regs & (1 << srcreg))
    PENALIZE1 (memsrc_stall_count);

  return 0;
}

/* Model function for u-mem-r unit.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_mem_r)) (SIM_CPU *current_cpu,
			  const IDESC *idesc ATTRIBUTE_UNUSED,
			  int unit_num ATTRIBUTE_UNUSED,
			  int referenced ATTRIBUTE_UNUSED)
{
  MODEL_CRISV32_DATA *model_data
    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);

  /* There's a two-cycle penalty for read after a memory write in any of
     the two previous cycles, known as a cache read-after-write hazard.

     This model function (the model_data member access) depends on being
     executed before the u-exec unit.  */
  if ((model_data->prev_modf_regs & CRIS_MODF_MEM_WRITE_MASK)
      || (model_data->prev_prev_modf_regs & CRIS_MODF_MEM_WRITE_MASK))
    {
      PENALIZE1 (memraw_stall_count);
      PENALIZE1 (memraw_stall_count);
    }

  return 0;
}

/* Model function for u-mem-w unit.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_mem_w)) (SIM_CPU *current_cpu,
			  const IDESC *idesc ATTRIBUTE_UNUSED,
			  int unit_num ATTRIBUTE_UNUSED,
			  int referenced ATTRIBUTE_UNUSED)
{
  MODEL_CRISV32_DATA *model_data
    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);

  /* Mark that memory has been written.  This model function (the
     model_data member access) depends on being executed after the
     u-exec unit.  */
  model_data->prev_modf_regs |= CRIS_MODF_MEM_WRITE_MASK;

  return 0;
}

/* Model function for u-movem-rtom unit.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_movem_rtom)) (SIM_CPU *current_cpu,
			       const IDESC *idesc ATTRIBUTE_UNUSED,
			       int unit_num ATTRIBUTE_UNUSED,
			       int referenced ATTRIBUTE_UNUSED,
			       /* Deliberate order.  */
			       INT addrreg, INT limreg)
{
  USI addr;
  MODEL_CRISV32_DATA *model_data
    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);

  if (limreg == -1 || addrreg == -1)
    abort ();

  addr = GET_H_GR (addrreg);

  /* The movem-to-memory instruction must not move a register modified
     in one of the previous two cycles.  Enforce by adding penalty
     cycles.  */
  if (model_data->prev_modf_regs & ((1 << (limreg + 1)) - 1))
    {
      PENALIZE1 (movemsrc_stall_count);
      PENALIZE1 (movemsrc_stall_count);
    }
  else if (model_data->prev_prev_modf_regs & ((1 << (limreg + 1)) - 1))
    PENALIZE1 (movemsrc_stall_count);

  /* One-cycle penalty for each cache-line straddled.  Use the
     documented expressions.  Unfortunately no penalty cycles are
     eliminated by any penalty cycles above.  We file these numbers
     separately, since they aren't schedulable for all cases.  */
  if ((addr >> 5) == (((addr + 4 * (limreg + 1)) - 1) >> 5))
    ;
  else if ((addr >> 5) == (((addr + 4 * (limreg + 1)) - 1) >> 5) - 1)
    PENALIZE1 (movemaddr_stall_count);
  else if ((addr >> 5) == (((addr + 4 * (limreg + 1)) - 1) >> 5) - 2)
    {
      PENALIZE1 (movemaddr_stall_count);
      PENALIZE1 (movemaddr_stall_count);
    }
  else
    abort ();

  return 0;
}

/* Model function for u-movem-mtor unit.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_movem_mtor)) (SIM_CPU *current_cpu,
			       const IDESC *idesc ATTRIBUTE_UNUSED,
			       int unit_num ATTRIBUTE_UNUSED,
			       int referenced ATTRIBUTE_UNUSED,
			       /* Deliberate order.  */
			       INT addrreg, INT limreg)
{
  USI addr;
  int nregs = limreg + 1;
  MODEL_CRISV32_DATA *model_data
    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);

  if (limreg == -1 || addrreg == -1)
    abort ();

  addr = GET_H_GR (addrreg);

  /* One-cycle penalty for each cache-line straddled.  Use the
     documented expressions.  One cycle is the norm; more cycles are
     counted as penalties.  Unfortunately no penalty cycles here
     eliminate penalty cycles indicated in ->movem_dest_regs.  */
  if ((addr >> 5) == (((addr + 4 * nregs) - 1) >> 5) - 1)
    PENALIZE1 (movemaddr_stall_count);
  else if ((addr >> 5) == (((addr + 4 * nregs) - 1) >> 5) - 2)
    {
      PENALIZE1 (movemaddr_stall_count);
      PENALIZE1 (movemaddr_stall_count);
    }

  model_data->modf_regs |= ((1 << nregs) - 1);
  model_data->movem_dest_regs  |= ((1 << nregs) - 1);
  return 0;
}


/* Model function for u-branch unit.
   FIXME: newpc and cc are always wrong.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,_u_branch)) (SIM_CPU *current_cpu,
						 const IDESC *idesc,
						 int unit_num, int referenced)
{
  CRIS_MISC_PROFILE *profp = CPU_CRIS_MISC_PROFILE (current_cpu);
  USI pc = profp->old_pc;
  MODEL_CRISV32_DATA *model_data
    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
  int taken = profp->branch_taken;
  int branch_index = (pc & (N_CRISV32_BRANCH_PREDICTORS - 1)) >> 1;
  int pred_taken = (profp->branch_predictors[branch_index] & 2) != 0;

  if (taken != pred_taken)
    {
      PENALIZE1 (branch_stall_count);
      PENALIZE1 (branch_stall_count);
    }

  if (taken)
    {
      if (profp->branch_predictors[branch_index] < 3)
	profp->branch_predictors[branch_index]++;

      return MY (XCONCAT3 (f_model_crisv,BASENUM,_u_jump))
	(current_cpu, idesc, unit_num, referenced, -1);
    }

  if (profp->branch_predictors[branch_index] != 0)
    profp->branch_predictors[branch_index]--;

  return 0;
}

/* Model function for u-jump-r unit.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_jump_r)) (SIM_CPU *current_cpu,
			   const IDESC *idesc ATTRIBUTE_UNUSED,
			   int unit_num ATTRIBUTE_UNUSED,
			   int referenced ATTRIBUTE_UNUSED,
			   int regno)
{
  MODEL_CRISV32_DATA *model_data
    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);

  if (regno == -1)
    abort ();

  /* For jump-to-register, the register must not have been modified the
     last two cycles.  Penalty: two cycles from the modifying insn.  */
  if ((1 << regno) & model_data->prev_modf_regs)
    {
      PENALIZE1 (jumpsrc_stall_count);
      PENALIZE1 (jumpsrc_stall_count);
    }
  else if ((1 << regno) & model_data->prev_prev_modf_regs)
    PENALIZE1 (jumpsrc_stall_count);

  return 0;
}

/* Model function for u-jump-sr unit.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,_u_jump_sr)) (SIM_CPU *current_cpu,
						  const IDESC *idesc,
						  int unit_num, int referenced,
						  int sr_regno)
{
  int regno;

  MODEL_CRISV32_DATA *model_data
    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);

  if (sr_regno == -1)
    abort ();

  regno = sr_regno + 16;

  /* For jump-to-register, the register must not have been modified the
     last two cycles.  Penalty: two cycles from the modifying insn.  */
  if ((1 << regno) & model_data->prev_modf_regs)
    {
      PENALIZE1 (jumpsrc_stall_count);
      PENALIZE1 (jumpsrc_stall_count);
    }
  else if ((1 << regno) & model_data->prev_prev_modf_regs)
    PENALIZE1 (jumpsrc_stall_count);

  return
    MY (XCONCAT3 (f_model_crisv,BASENUM,_u_jump)) (current_cpu, idesc,
						   unit_num, referenced, -1);
}

/* Model function for u-jump unit.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_jump)) (SIM_CPU *current_cpu,
			 const IDESC *idesc ATTRIBUTE_UNUSED,
			 int unit_num ATTRIBUTE_UNUSED,
			 int referenced ATTRIBUTE_UNUSED,
			 int out_sr_regno)
{
  MODEL_CRISV32_DATA *model_data
    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);

  /* Mark that we made a jump.  */
  model_data->modf_regs
    |= (CRIS_MODF_JUMP_MASK
	| (out_sr_regno == -1 || out_sr_regno == CRIS_BZ_REGNO
	   ? 0 : (1 << (out_sr_regno + 16))));
  return 0;
}

/* Model function for u-multiply unit.  */

int
MY (XCONCAT3 (f_model_crisv,BASENUM,
	      _u_multiply)) (SIM_CPU *current_cpu,
			     const IDESC *idesc ATTRIBUTE_UNUSED,
			     int unit_num ATTRIBUTE_UNUSED,
			     int referenced ATTRIBUTE_UNUSED,
			     int srcreg, int destreg)
{
  MODEL_CRISV32_DATA *model_data
    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);

  /* Sanity-check for cases that should never happen.  */
  if (srcreg == -1 || destreg == -1)
    abort ();

  /* This takes extra cycles when one of the inputs has been modified
     through other than autoincrement in the previous cycle.  Penalty:
     one cycle.  */
  if (((1 << srcreg) | (1 << destreg)) & model_data->prev_modf_regs)
    PENALIZE1 (mulsrc_stall_count);

  /* We modified the multiplication destination (marked in u-exec) and
     the MOF register.  */
  model_data->modf_regs |= (1 << CRIS_MOF_REGNO);
  return 0;
}

#endif /* WITH_PROFILE_MODEL_P */

int
MY (deliver_interrupt) (SIM_CPU *current_cpu,
			enum cris_interrupt_type type,
			unsigned int vec)
{
  unsigned32 old_ccs, shifted_ccs, new_ccs;
  unsigned char entryaddr_le[4];
  int was_user;
  SIM_DESC sd = CPU_STATE (current_cpu);
  unsigned32 entryaddr;

  /* We haven't implemented other interrupt-types yet.  */
  if (type != CRIS_INT_INT)
    abort ();

  /* We're called outside of branch delay slots etc, so we don't check
     for that.  */
  if (!GET_H_IBIT_V32 ())
    return 0;

  old_ccs = GET_H_SR_V32 (H_SR_CCS);
  shifted_ccs = (old_ccs << 10) & ((1 << 30) - 1);

  /* The M bit is handled by code below and the M bit setter function, but
     we need to preserve the Q bit.  */
  new_ccs = shifted_ccs | (old_ccs & (unsigned32) 0x80000000UL);
  was_user = GET_H_UBIT_V32 ();

  /* We need to force kernel mode since the setter method doesn't allow
     it.  Then we can use setter methods at will, since they then
     recognize that we're in kernel mode.  */
  CPU (h_ubit_v32) = 0;

  SET_H_SR (H_SR_CCS, new_ccs);

  if (was_user)
    {
      /* These methods require that user mode is unset.  */
      SET_H_SR (H_SR_USP, GET_H_GR (H_GR_SP));
      SET_H_GR (H_GR_SP, GET_H_KERNEL_SP ());
    }

  /* ERP setting is simplified by not taking interrupts in delay-slots
     or when halting.  */
  /* For all other exceptions than guru and NMI, store the return
     address in ERP and set EXS and EXD here.  */
  SET_H_SR (H_SR_ERP, GET_H_PC ());

  /* Simplified by not having exception types (fault indications).  */
  SET_H_SR_V32 (H_SR_EXS, (vec * 256));
  SET_H_SR_V32 (H_SR_EDA, 0);

  if (sim_core_read_buffer (sd,
			    current_cpu,
			    read_map, entryaddr_le,
			    GET_H_SR (H_SR_EBP) + vec * 4, 4) == 0)
    {
      /* Nothing to do actually; either abort or send a signal.  */
      sim_core_signal (sd, current_cpu, CPU_PC_GET (current_cpu), 0, 4,
		       GET_H_SR (H_SR_EBP) + vec * 4,
		       read_transfer, sim_core_unmapped_signal);
      return 0;
    }

  entryaddr = bfd_getl32 (entryaddr_le);
  SET_H_PC (entryaddr);

  return 1;
}
