/* IQ2000 simulator support code
   Copyright (C) 2000, 2004, 2007-2012 Free Software Foundation, Inc.
   Contributed by Cygnus Support.

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

#define WANT_CPU
#define WANT_CPU_IQ2000BF

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

enum
{
  GPR0_REGNUM = 0,
  NR_GPR = 32,
  PC_REGNUM = 32
};

enum libgloss_syscall
{
  SYS_exit = 1,
  SYS_open = 2, 
  SYS_close = 3, 
  SYS_read = 4,
  SYS_write = 5, 
  SYS_lseek = 6, 
  SYS_unlink = 7,
  SYS_getpid = 8,
  SYS_kill = 9,
  SYS_fstat = 10, 
  SYS_argvlen = 12, 
  SYS_argv = 13,
  SYS_chdir = 14, 
  SYS_stat = 15, 
  SYS_chmod = 16, 
  SYS_utime = 17,
  SYS_time = 18,
  SYS_gettimeofday = 19,
  SYS_times = 20
};

/* Read a null terminated string from memory, return in a buffer */
static char *
fetch_str (current_cpu, pc, addr)
     SIM_CPU *current_cpu;
     PCADDR pc;
     DI addr;
{
  char *buf;
  int nr = 0;
  while (sim_core_read_1 (current_cpu,
                          pc, read_map, CPU2DATA(addr + nr)) != 0)
    nr++;
  buf = NZALLOC (char, nr + 1);
  sim_read (CPU_STATE (current_cpu), CPU2DATA(addr), buf, nr);
  return buf;
}

void
do_syscall (SIM_CPU *current_cpu, PCADDR pc)
{
#if 0
  int syscall = H2T_4 (iq2000bf_h_gr_get (current_cpu, 11));
#endif
  int syscall_function = iq2000bf_h_gr_get (current_cpu, 4);
  int i;
  char *buf;
  int PARM1 = iq2000bf_h_gr_get (current_cpu, 5);
  int PARM2 = iq2000bf_h_gr_get (current_cpu, 6);
  int PARM3 = iq2000bf_h_gr_get (current_cpu, 7);
  const int ret_reg = 2;
	
  switch (syscall_function)
    {
    case 0:
      switch (H2T_4 (iq2000bf_h_gr_get (current_cpu, 11)))
	{
	case 0:
	  /* Pass.  */
	  puts ("pass");
	  exit (0);
	case 1:
	  /* Fail.  */
	  puts ("fail");
	  exit (1);
	}

    case SYS_write:
      buf = zalloc (PARM3);
      sim_read (CPU_STATE (current_cpu), CPU2DATA(PARM2), buf, PARM3);
      SET_H_GR (ret_reg,
		sim_io_write (CPU_STATE (current_cpu),
			      PARM1, buf, PARM3));
      free (buf);
      break;

    case SYS_lseek:
      SET_H_GR (ret_reg,
		sim_io_lseek (CPU_STATE (current_cpu),
			      PARM1, PARM2, PARM3));
      break;
	    
    case SYS_exit:
      sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
		       NULL, pc, sim_exited, PARM1);
      break;

    case SYS_read:
      buf = zalloc (PARM3);
      SET_H_GR (ret_reg,
		sim_io_read (CPU_STATE (current_cpu),
			     PARM1, buf, PARM3));
      sim_write (CPU_STATE (current_cpu), CPU2DATA(PARM2), buf, PARM3);
      free (buf);
      break;
	    
    case SYS_open:
      buf = fetch_str (current_cpu, pc, PARM1);
      SET_H_GR (ret_reg,
		sim_io_open (CPU_STATE (current_cpu),
			     buf, PARM2));
      free (buf);
      break;

    case SYS_close:
      SET_H_GR (ret_reg,
		sim_io_close (CPU_STATE (current_cpu), PARM1));
      break;

    case SYS_time:
      SET_H_GR (ret_reg, time (0));
      break;

    default:
      SET_H_GR (ret_reg, -1);
    }
}

void 
do_break (SIM_CPU *current_cpu, PCADDR pc)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
}

/* The semantic code invokes this for invalid (unrecognized) instructions.  */

SEM_PC
sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);

  return vpc;
}


/* Process an address exception.  */

void
iq2000_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
                  unsigned int map, int nr_bytes, address_word addr,
                  transfer_type transfer, sim_core_signals sig)
{
  sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
		   transfer, sig);
}


/* Initialize cycle counting for an insn.
   FIRST_P is non-zero if this is the first insn in a set of parallel
   insns.  */

void
iq2000bf_model_insn_before (SIM_CPU *cpu, int first_p)
{
  /* Do nothing.  */
}


/* Record the cycles computed for an insn.
   LAST_P is non-zero if this is the last insn in a set of parallel insns,
   and we update the total cycle count.
   CYCLES is the cycle count of the insn.  */

void
iq2000bf_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
{
  /* Do nothing.  */
}


int
iq2000bf_model_iq2000_u_exec (SIM_CPU *cpu, const IDESC *idesc,
			    int unit_num, int referenced)
{
  return idesc->timing->units[unit_num].done;
}

PCADDR
get_h_pc (SIM_CPU *cpu)
{
  return CPU_CGEN_HW(cpu)->h_pc;
}

void
set_h_pc (SIM_CPU *cpu, PCADDR addr)
{
  CPU_CGEN_HW(cpu)->h_pc = addr | IQ2000_INSN_MASK;
}

int
iq2000bf_fetch_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
{
  if (nr >= GPR0_REGNUM
      && nr < (GPR0_REGNUM + NR_GPR)
      && len == 4)
    {
      *((unsigned32*)buf) =
	H2T_4 (iq2000bf_h_gr_get (cpu, nr - GPR0_REGNUM));
      return 4;
    }
  else if (nr == PC_REGNUM
	   && len == 4)
    {
      *((unsigned32*)buf) = H2T_4 (get_h_pc (cpu));
      return 4;
    }
  else
    return 0;
}

int
iq2000bf_store_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
{
  if (nr >= GPR0_REGNUM
      && nr < (GPR0_REGNUM + NR_GPR)
      && len == 4)
    {
      iq2000bf_h_gr_set (cpu, nr - GPR0_REGNUM, T2H_4 (*((unsigned32*)buf)));
      return 4;
    }
  else if (nr == PC_REGNUM
	   && len == 4)
    {
      set_h_pc (cpu, T2H_4 (*((unsigned32*)buf)));
      return 4;
    }
  else
    return 0;
}
