/* Lattice Mico32 exception and system call support.
   Contributed by Jon Beniston <jon@beniston.com>

   Copyright (C) 2009-2013 Free Software Foundation, Inc.

   This file is part of GDB.

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

#define WANT_CPU lm32bf
#define WANT_CPU_LM32BF

#include "sim-main.h"
#include "lm32-sim.h"
#include "targ-vals.h"

/* Read memory function for system call interface.  */

static int
syscall_read_mem (host_callback * cb, struct cb_syscall *sc,
		  unsigned long taddr, char *buf, int bytes)
{
  SIM_DESC sd = (SIM_DESC) sc->p1;
  SIM_CPU *cpu = (SIM_CPU *) sc->p2;

  return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
}

/* Write memory function for system call interface.  */

static int
syscall_write_mem (host_callback * cb, struct cb_syscall *sc,
		   unsigned long taddr, const char *buf, int bytes)
{
  SIM_DESC sd = (SIM_DESC) sc->p1;
  SIM_CPU *cpu = (SIM_CPU *) sc->p2;

  return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
}

/* Handle invalid instructions.  */

SEM_PC
sim_engine_invalid_insn (SIM_CPU * current_cpu, IADDR cia, SEM_PC pc)
{
  SIM_DESC sd = CPU_STATE (current_cpu);

  sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);

  return pc;
}

/* Handle divide instructions. */

USI
lm32bf_divu_insn (SIM_CPU * current_cpu, IADDR pc, USI r0, USI r1, USI r2)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  host_callback *cb = STATE_CALLBACK (sd);

  /* Check for divide by zero */
  if (GET_H_GR (r1) == 0)
    {
      if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
	sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGFPE);
      else
	{
	  /* Save PC in exception address register.  */
	  SET_H_GR (30, pc);
	  /* Save and clear interrupt enable.  */
	  SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
	  /* Branch to divide by zero exception handler.  */
	  return GET_H_CSR (LM32_CSR_EBA) + LM32_EID_DIVIDE_BY_ZERO * 32;
	}
    }
  else
    {
      SET_H_GR (r2, (USI) GET_H_GR (r0) / (USI) GET_H_GR (r1));
      return pc + 4;
    }
}

USI
lm32bf_modu_insn (SIM_CPU * current_cpu, IADDR pc, USI r0, USI r1, USI r2)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  host_callback *cb = STATE_CALLBACK (sd);

  /* Check for divide by zero.  */
  if (GET_H_GR (r1) == 0)
    {
      if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
	sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGFPE);
      else
	{
	  /* Save PC in exception address register.  */
	  SET_H_GR (30, pc);
	  /* Save and clear interrupt enable.  */
	  SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
	  /* Branch to divide by zero exception handler.  */
	  return GET_H_CSR (LM32_CSR_EBA) + LM32_EID_DIVIDE_BY_ZERO * 32;
	}
    }
  else
    {
      SET_H_GR (r2, (USI) GET_H_GR (r0) % (USI) GET_H_GR (r1));
      return pc + 4;
    }
}

/* Handle break instructions.  */

USI
lm32bf_break_insn (SIM_CPU * current_cpu, IADDR pc)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  host_callback *cb = STATE_CALLBACK (sd);
  /* Breakpoint.  */
  if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
    {
      sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
      return pc;
    }
  else
    {
      /* Save PC in breakpoint address register.  */
      SET_H_GR (31, pc);
      /* Save and clear interrupt enable.  */
      SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 2);
      /* Branch to breakpoint exception handler.  */
      return GET_H_CSR (LM32_CSR_DEBA) + LM32_EID_BREAKPOINT * 32;
    }
}

/* Handle scall instructions.  */

USI
lm32bf_scall_insn (SIM_CPU * current_cpu, IADDR pc)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  host_callback *cb = STATE_CALLBACK (sd);

  if ((STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
      || (GET_H_GR (8) == TARGET_SYS_exit))
    {
      /* Delegate system call to host O/S.  */
      CB_SYSCALL s;
      CB_SYSCALL_INIT (&s);
      s.p1 = (PTR) sd;
      s.p2 = (PTR) current_cpu;
      s.read_mem = syscall_read_mem;
      s.write_mem = syscall_write_mem;
      /* Extract parameters.  */
      s.func = GET_H_GR (8);
      s.arg1 = GET_H_GR (1);
      s.arg2 = GET_H_GR (2);
      s.arg3 = GET_H_GR (3);
      /* Halt the simulator if the requested system call is _exit.  */
      if (s.func == TARGET_SYS_exit)
	sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1);
      /* Perform the system call.  */
      cb_syscall (cb, &s);
      /* Store the return value in the CPU's registers.  */
      SET_H_GR (1, s.result);
      SET_H_GR (2, s.result2);
      SET_H_GR (3, s.errcode);
      /* Skip over scall instruction.  */
      return pc + 4;
    }
  else
    {
      /* Save PC in exception address register.  */
      SET_H_GR (30, pc);
      /* Save and clear interrupt enable */
      SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
      /* Branch to system call exception handler.  */
      return GET_H_CSR (LM32_CSR_EBA) + LM32_EID_SYSTEM_CALL * 32;
    }
}

/* Handle b instructions.  */

USI
lm32bf_b_insn (SIM_CPU * current_cpu, USI r0, USI f_r0)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  host_callback *cb = STATE_CALLBACK (sd);

  /* Restore interrupt enable.  */
  if (f_r0 == 30)
    SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 2) >> 1);
  else if (f_r0 == 31)
    SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 4) >> 2);
  return r0;
}

/* Handle wcsr instructions.  */

void
lm32bf_wcsr_insn (SIM_CPU * current_cpu, USI f_csr, USI r1)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  host_callback *cb = STATE_CALLBACK (sd);

  /* Writing a 1 to IP CSR clears a bit, writing 0 has no effect.  */
  if (f_csr == LM32_CSR_IP)
    SET_H_CSR (f_csr, GET_H_CSR (f_csr) & ~r1);
  else
    SET_H_CSR (f_csr, r1);
}

/* Handle signals.  */

void
lm32_core_signal (SIM_DESC sd,
		  sim_cpu * cpu,
		  sim_cia cia,
		  unsigned map,
		  int nr_bytes,
		  address_word addr,
		  transfer_type transfer, sim_core_signals sig)
{
  const char *copy = (transfer == read_transfer ? "read" : "write");
  address_word ip = CIA_ADDR (cia);
  SIM_CPU *current_cpu = cpu;

  switch (sig)
    {
    case sim_core_unmapped_signal:
      sim_io_eprintf (sd,
		      "core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
		      nr_bytes, copy, (unsigned long) addr,
		      (unsigned long) ip);
      SET_H_GR (30, ip);
      /* Save and clear interrupt enable.  */
      SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
      CIA_SET (cpu, GET_H_CSR (LM32_CSR_EBA) + LM32_EID_DATA_BUS_ERROR * 32);
      sim_engine_halt (sd, cpu, NULL, LM32_EID_DATA_BUS_ERROR * 32,
		       sim_stopped, SIM_SIGSEGV);
      break;
    case sim_core_unaligned_signal:
      sim_io_eprintf (sd,
		      "core: %d byte misaligned %s to address 0x%lx at 0x%lx\n",
		      nr_bytes, copy, (unsigned long) addr,
		      (unsigned long) ip);
      SET_H_GR (30, ip);
      /* Save and clear interrupt enable.  */
      SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
      CIA_SET (cpu, GET_H_CSR (LM32_CSR_EBA) + LM32_EID_DATA_BUS_ERROR * 32);
      sim_engine_halt (sd, cpu, NULL, LM32_EID_DATA_BUS_ERROR * 32,
		       sim_stopped, SIM_SIGBUS);
      break;
    default:
      sim_engine_abort (sd, cpu, cia,
			"sim_core_signal - internal error - bad switch");
    }
}
