/* OpenRISC exception, interrupts, syscall and trap support
   Copyright (C) 2017-2021 Free Software Foundation, Inc.

   This file is part of GDB, the GNU debugger.

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

/* This must come before any other includes.  */
#include "defs.h"

#define WANT_CPU_OR1K32BF
#define WANT_CPU

#include "sim-main.h"
#include "sim-signal.h"
#include "cgen-ops.h"

/* Implement the sim invalid instruction function.  This will set the error
   effective address to that of the invalid instruction then call the
   exception handler.  */

SEM_PC
sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
{
  SET_H_SYS_EEAR0 (cia);

#ifdef WANT_CPU_OR1K32BF
  or1k32bf_exception (current_cpu, cia, EXCEPT_ILLEGAL);
#endif

  return vpc;
}

/* Generate the appropriate OpenRISC fpu exception based on the status code from
   the sim fpu.  */
void
or1k32bf_fpu_error (CGEN_FPU* fpu, int status)
{
  SIM_CPU *current_cpu = (SIM_CPU *)fpu->owner;

  /* If floating point exceptions are enabled.  */
  if (GET_H_SYS_FPCSR_FPEE() != 0)
    {
      /* Set all of the status flag bits.  */
      if (status
	  & (sim_fpu_status_invalid_snan
	     | sim_fpu_status_invalid_qnan
	     | sim_fpu_status_invalid_isi
	     | sim_fpu_status_invalid_idi
	     | sim_fpu_status_invalid_zdz
	     | sim_fpu_status_invalid_imz
	     | sim_fpu_status_invalid_cvi
	     | sim_fpu_status_invalid_cmp
	     | sim_fpu_status_invalid_sqrt))
	SET_H_SYS_FPCSR_IVF (1);

      if (status & sim_fpu_status_invalid_snan)
	SET_H_SYS_FPCSR_SNF (1);

      if (status & sim_fpu_status_invalid_qnan)
	SET_H_SYS_FPCSR_QNF (1);

      if (status & sim_fpu_status_overflow)
	SET_H_SYS_FPCSR_OVF (1);

      if (status & sim_fpu_status_underflow)
	SET_H_SYS_FPCSR_UNF (1);

      if (status
	  & (sim_fpu_status_invalid_isi
	     | sim_fpu_status_invalid_idi))
	SET_H_SYS_FPCSR_INF (1);

      if (status & sim_fpu_status_invalid_div0)
	SET_H_SYS_FPCSR_DZF (1);

      if (status & sim_fpu_status_inexact)
	SET_H_SYS_FPCSR_IXF (1);

      /* If any of the exception bits were actually set.  */
      if (GET_H_SYS_FPCSR()
	  & (SPR_FIELD_MASK_SYS_FPCSR_IVF
	     | SPR_FIELD_MASK_SYS_FPCSR_SNF
	     | SPR_FIELD_MASK_SYS_FPCSR_QNF
	     | SPR_FIELD_MASK_SYS_FPCSR_OVF
	     | SPR_FIELD_MASK_SYS_FPCSR_UNF
	     | SPR_FIELD_MASK_SYS_FPCSR_INF
	     | SPR_FIELD_MASK_SYS_FPCSR_DZF
	     | SPR_FIELD_MASK_SYS_FPCSR_IXF))
	{
	  SIM_DESC sd = CPU_STATE (current_cpu);

	  /* If the sim is running in fast mode, i.e. not profiling,
	     per-instruction callbacks are not triggered which would allow
	     us to track the PC.  This means we cannot track which
	     instruction caused the FPU error.  */
	  if (!PROFILE_ANY_P (current_cpu) && !TRACE_ANY_P (current_cpu))
	    sim_io_eprintf
	      (sd, "WARNING: ignoring fpu error caught in fast mode.\n");
	  else
	    or1k32bf_exception (current_cpu, GET_H_SYS_PPC (), EXCEPT_FPE);
	}
    }
}


/* Implement the OpenRISC exception function.  This is mostly used by the
   CGEN generated files.  For example, this is used when handling a
   overflow exception during a multiplication instruction. */

void
or1k32bf_exception (sim_cpu *current_cpu, USI pc, USI exnum)
{
  SIM_DESC sd = CPU_STATE (current_cpu);

  if (exnum == EXCEPT_TRAP)
    {
      /* Trap, used for breakpoints, sends control back to gdb breakpoint
	 handling.  */
      sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
    }
  else
    {
      IADDR handler_pc;

      /* Calculate the exception program counter.  */
      switch (exnum)
	{
	case EXCEPT_RESET:
	  break;

	case EXCEPT_FPE:
	case EXCEPT_SYSCALL:
	  SET_H_SYS_EPCR0 (pc + 4 - (current_cpu->delay_slot ? 4 : 0));
	  break;

	case EXCEPT_BUSERR:
	case EXCEPT_ALIGN:
	case EXCEPT_ILLEGAL:
	case EXCEPT_RANGE:
	  SET_H_SYS_EPCR0 (pc - (current_cpu->delay_slot ? 4 : 0));
	  break;

	default:
	  sim_io_error (sd, "unexpected exception 0x%x raised at PC 0x%08x",
			exnum, pc);
	  break;
	}

      /* Store the current SR into ESR0.  */
      SET_H_SYS_ESR0 (GET_H_SYS_SR ());

      /* Indicate in SR if the failed instruction is in delay slot or not.  */
      SET_H_SYS_SR_DSX (current_cpu->delay_slot);

      current_cpu->next_delay_slot = 0;

      /* Jump program counter into handler.  */
      handler_pc =
	(GET_H_SYS_SR_EPH () ? 0xf0000000 : 0x00000000) + (exnum << 8);

      sim_engine_restart (sd, current_cpu, NULL, handler_pc);
    }
}

/* Implement the return from exception instruction.  This is used to return
   the CPU to its previous state from within an exception handler.  */

void
or1k32bf_rfe (sim_cpu *current_cpu)
{
  SET_H_SYS_SR (GET_H_SYS_ESR0 ());
  SET_H_SYS_SR_FO (1);

  current_cpu->next_delay_slot = 0;

  sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
		      GET_H_SYS_EPCR0 ());
}

/* Implement the move from SPR instruction.  This is used to read from the
   CPU's special purpose registers.  */

USI
or1k32bf_mfspr (sim_cpu *current_cpu, USI addr)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  SI val;

  if (!GET_H_SYS_SR_SM () && !GET_H_SYS_SR_SUMRA ())
    {
      sim_io_eprintf (sd, "WARNING: l.mfspr in user mode (SR 0x%x)\n",
		      GET_H_SYS_SR ());
      return 0;
    }

  if (addr >= NUM_SPR)
    goto bad_address;

  val = GET_H_SPR (addr);

  switch (addr)
    {

    case SPR_ADDR (SYS, VR):
    case SPR_ADDR (SYS, UPR):
    case SPR_ADDR (SYS, CPUCFGR):
    case SPR_ADDR (SYS, SR):
    case SPR_ADDR (SYS, PPC):
    case SPR_ADDR (SYS, FPCSR):
    case SPR_ADDR (SYS, EPCR0):
    case SPR_ADDR (MAC, MACLO):
    case SPR_ADDR (MAC, MACHI):
      break;

    default:
      if (addr < SPR_ADDR (SYS, GPR0) || addr > SPR_ADDR (SYS, GPR511))
	goto bad_address;
      break;

    }

  return val;

bad_address:
  sim_io_eprintf (sd, "WARNING: l.mfspr with invalid SPR address 0x%x\n", addr);
  return 0;

}

/* Implement the move to SPR instruction.  This is used to write too the
   CPU's special purpose registers.  */

void
or1k32bf_mtspr (sim_cpu *current_cpu, USI addr, USI val)
{
  SIM_DESC sd = CPU_STATE (current_cpu);

  if (!GET_H_SYS_SR_SM () && !GET_H_SYS_SR_SUMRA ())
    {
      sim_io_eprintf
	(sd, "WARNING: l.mtspr with address 0x%x in user mode (SR 0x%x)\n",
	 addr, GET_H_SYS_SR ());
      return;
    }

  if (addr >= NUM_SPR)
    goto bad_address;

  switch (addr)
    {

    case SPR_ADDR (SYS, FPCSR):
    case SPR_ADDR (SYS, EPCR0):
    case SPR_ADDR (SYS, ESR0):
    case SPR_ADDR (MAC, MACHI):
    case SPR_ADDR (MAC, MACLO):
      SET_H_SPR (addr, val);
      break;

    case SPR_ADDR (SYS, SR):
      SET_H_SPR (addr, val);
      SET_H_SYS_SR_FO (1);
      break;

    case SPR_ADDR (SYS, NPC):
      current_cpu->next_delay_slot = 0;

      sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL, val);
      break;

    case SPR_ADDR (TICK, TTMR):
      /* Allow some registers to be silently cleared.  */
      if (val != 0)
	sim_io_eprintf
	  (sd, "WARNING: l.mtspr to SPR address 0x%x with invalid value 0x%x\n",
	   addr, val);
      break;

    default:
      if (addr >= SPR_ADDR (SYS, GPR0) && addr <= SPR_ADDR (SYS, GPR511))
	SET_H_SPR (addr, val);
      else
	goto bad_address;
      break;

    }

  return;

bad_address:
  sim_io_eprintf (sd, "WARNING: l.mtspr with invalid SPR address 0x%x\n", addr);

}
