/* OpenRISC exception, interrupts, syscall and trap support
   Copyright (C) 2017-2023 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-fpu.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);
  struct or1k_sim_cpu *or1k_cpu = OR1K_SIM_CPU (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 - (or1k_cpu->delay_slot ? 4 : 0));
	  break;

	case EXCEPT_BUSERR:
	case EXCEPT_ALIGN:
	case EXCEPT_ILLEGAL:
	case EXCEPT_RANGE:
	  SET_H_SYS_EPCR0 (pc - (or1k_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 (or1k_cpu->delay_slot);

      or1k_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)
{
  struct or1k_sim_cpu *or1k_cpu = OR1K_SIM_CPU (current_cpu);

  SET_H_SYS_SR (GET_H_SYS_ESR0 ());
  SET_H_SYS_SR_FO (1);

  or1k_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);
  struct or1k_sim_cpu *or1k_cpu = OR1K_SIM_CPU (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):
      or1k_cpu->next_delay_slot = 0;

      sim_engine_restart (sd, 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);

}
