/* The common simulator framework for GDB, the GNU Debugger.

   Copyright 2002, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.

   Contributed by Andrew Cagney and Red Hat.

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


#ifndef N
#error "N must be #defined"
#endif
#ifndef M
#define M N
#endif

/* N: The number of bytes of data to transfer.
   M: The number of bytes in the type used to transfer the data */

#if (N > M)
#error "N (nr bytes of data) must be <= M (nr of bytes in data type)"
#endif


#include "symcat.h"

/* NOTE: see end of file for #undef of these macros */

#define unsigned_M XCONCAT2(unsigned_,M)

#define T2H_M XCONCAT2(T2H_,M)
#define H2T_M XCONCAT2(H2T_,M)
#define SWAP_M XCONCAT2(SWAP_,M)

#define sim_core_read_aligned_N XCONCAT2(sim_core_read_aligned_,N)
#define sim_core_read_unaligned_N XCONCAT2(sim_core_read_unaligned_,N)
#define sim_core_read_misaligned_N XCONCAT2(sim_core_read_misaligned_,N)
#define sim_core_write_aligned_N XCONCAT2(sim_core_write_aligned_,N)
#define sim_core_write_unaligned_N XCONCAT2(sim_core_write_unaligned_,N)
#define sim_core_write_misaligned_N XCONCAT2(sim_core_write_misaligned_,N)
#define sim_core_trace_M XCONCAT2(sim_core_trace_,M)
#define sim_core_dummy_M XCONCAT2(sim_core_dummy_,M)


#if (M == N && N > 1)
/* dummy variable used as a return value when nothing else is
   available and the compiler is complaining */
static unsigned_M sim_core_dummy_M;
#endif


/* TAGS: sim_core_trace_1 sim_core_trace_2 */
/* TAGS: sim_core_trace_4 sim_core_trace_8 */
/* TAGS: sim_core_trace_16 */

#if (M == N)
STATIC_SIM_CORE(void)
sim_core_trace_M (sim_cpu *cpu,
		  sim_cia cia,
		  int line_nr,
		  transfer_type type,
		  unsigned map,
		  address_word addr,
		  unsigned_M val,
		  int nr_bytes)
{
  const char *transfer = (type == read_transfer ? "read" : "write");
  const char *direction = (type == read_transfer ? "->" : "<-");

  if (TRACE_DEBUG_P (cpu))
    trace_printf (CPU_STATE (cpu), cpu, "sim-n-core.h:%d: ", line_nr);

#if (M == 16)
  trace_printf (CPU_STATE (cpu), cpu,
		"%s-%d %s:0x%08lx %s 0x%08lx%08lx%08lx%08lx\n",
		transfer, nr_bytes,
		map_to_str (map),
		(unsigned long) addr,
		direction,
		(unsigned long) V4_16 (val, 0),
		(unsigned long) V4_16 (val, 1),
		(unsigned long) V4_16 (val, 2),
		(unsigned long) V4_16 (val, 3));
#endif
#if (M == 8)
  trace_printf (CPU_STATE (cpu), cpu,
		"%s-%d %s:0x%08lx %s 0x%08lx%08lx\n",
		transfer, nr_bytes,
		map_to_str (map),
		(unsigned long) addr,
		direction,
		(unsigned long) V4_8 (val, 0),
		(unsigned long) V4_8 (val, 1));
#endif
#if (M == 4)
  trace_printf (CPU_STATE (cpu), cpu,
		"%s-%d %s:0x%08lx %s 0x%08lx\n",
		transfer,
		nr_bytes,
		map_to_str (map),
		(unsigned long) addr,
		direction,
		(unsigned long) val);
#endif
#if (M == 2)
  trace_printf (CPU_STATE (cpu), cpu,
		"%s-%d %s:0x%08lx %s 0x%04lx\n",
		transfer,
		nr_bytes,
		map_to_str (map),
		(unsigned long) addr,
		direction,
		(unsigned long) val);
#endif
#if (M == 1)
  trace_printf (CPU_STATE (cpu), cpu,
		"%s-%d %s:0x%08lx %s 0x%02lx\n",
		transfer,
		nr_bytes,
		map_to_str (map),
		(unsigned long) addr,
		direction,
		(unsigned long) val);
#endif
}
#endif


/* TAGS: sim_core_read_aligned_1 sim_core_read_aligned_2 */
/* TAGS: sim_core_read_aligned_4 sim_core_read_aligned_8 */
/* TAGS: sim_core_read_aligned_16 */

#if (M == N)
INLINE_SIM_CORE(unsigned_M)
sim_core_read_aligned_N(sim_cpu *cpu,
			sim_cia cia,
			unsigned map,
			address_word xaddr)
{
  sim_cpu_core *cpu_core = CPU_CORE (cpu);
  sim_core_common *core = &cpu_core->common;
  unsigned_M val;
  sim_core_mapping *mapping;
  address_word addr;
#if WITH_XOR_ENDIAN != 0
  if (WITH_XOR_ENDIAN)
    addr = xaddr ^ cpu_core->xor[(N - 1) % WITH_XOR_ENDIAN];
  else
#endif
    addr = xaddr;
  mapping = sim_core_find_mapping (core, map, addr, N, read_transfer, 1 /*abort*/, cpu, cia);
  do
    {
#if (WITH_DEVICES)
      if (WITH_CALLBACK_MEMORY && mapping->device != NULL)
	{
	  unsigned_M data;
	  if (device_io_read_buffer (mapping->device, &data, mapping->space, addr, N, CPU_STATE (cpu), cpu, cia) != N)
	    device_error (mapping->device, "internal error - %s - io_read_buffer should not fail",
			  XSTRING (sim_core_read_aligned_N));
	  val = T2H_M (data);
	  break;
	}
#endif
#if (WITH_HW)
      if (WITH_CALLBACK_MEMORY && mapping->device != NULL)
	{
	  unsigned_M data;
	  sim_cpu_hw_io_read_buffer (cpu, cia, mapping->device, &data, mapping->space, addr, N);
	  val = T2H_M (data);
	  break;
	}
#endif
      val = T2H_M (*(unsigned_M*) sim_core_translate (mapping, addr));
    }
  while (0);
  PROFILE_COUNT_CORE (cpu, addr, N, map);
  if (TRACE_P (cpu, TRACE_CORE_IDX))
    sim_core_trace_M (cpu, cia, __LINE__, read_transfer, map, addr, val, N);
  return val;
}
#endif

/* TAGS: sim_core_read_unaligned_1 sim_core_read_unaligned_2 */
/* TAGS: sim_core_read_unaligned_4 sim_core_read_unaligned_8 */
/* TAGS: sim_core_read_unaligned_16 */

#if (M == N && N > 1)
INLINE_SIM_CORE(unsigned_M)
sim_core_read_unaligned_N(sim_cpu *cpu,
			  sim_cia cia,
			  unsigned map,
			  address_word addr)
{
  int alignment = N - 1;
  /* if hardwired to forced alignment just do it */
  if (WITH_ALIGNMENT == FORCED_ALIGNMENT)
    return sim_core_read_aligned_N (cpu, cia, map, addr & ~alignment);
  else if ((addr & alignment) == 0)
    return sim_core_read_aligned_N (cpu, cia, map, addr);
  else
    switch (CURRENT_ALIGNMENT)
      {
      case STRICT_ALIGNMENT:
	SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
			 read_transfer, sim_core_unaligned_signal);
      case NONSTRICT_ALIGNMENT:
	{
	  unsigned_M val;
	  if (sim_core_xor_read_buffer (CPU_STATE (cpu), cpu, map, &val, addr, N) != N)
	    SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
			     read_transfer, sim_core_unaligned_signal);
	  val = T2H_M(val);
	  PROFILE_COUNT_CORE (cpu, addr, N, map);
	  if (TRACE_P (cpu, TRACE_CORE_IDX))
	    sim_core_trace_M (cpu, cia, __LINE__, read_transfer, map, addr, val, N);
	  return val;
	}
      case FORCED_ALIGNMENT:
	return sim_core_read_aligned_N (cpu, cia, map, addr & ~alignment);
      case MIXED_ALIGNMENT:
	sim_engine_abort (CPU_STATE (cpu), cpu, cia,
			  "internal error - %s - mixed alignment",
			  XSTRING (sim_core_read_unaligned_N));
      default:
	sim_engine_abort (CPU_STATE (cpu), cpu, cia,
			  "internal error - %s - bad switch",
			  XSTRING (sim_core_read_unaligned_N));
	/* to keep some compilers happy, we return a dummy */
	return sim_core_dummy_M;
      }
}
#endif

/* TAGS: sim_core_read_misaligned_3 sim_core_read_misaligned_5 */
/* TAGS: sim_core_read_misaligned_6 sim_core_read_misaligned_7 */

#if (M != N)
INLINE_SIM_CORE(unsigned_M)
sim_core_read_misaligned_N(sim_cpu *cpu,
			  sim_cia cia,
			  unsigned map,
			  address_word addr)
{
  unsigned_M val = 0;
  if (sim_core_xor_read_buffer (CPU_STATE (cpu), cpu, map, &val, addr, N) != N)
    SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
		     read_transfer, sim_core_unaligned_signal);
  if (CURRENT_HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER)
    val = SWAP_M (val);
  if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
    val >>= (M - N) * 8;
  PROFILE_COUNT_CORE (cpu, addr, N, map);
  if (TRACE_P (cpu, TRACE_CORE_IDX))
    sim_core_trace_M (cpu, cia, __LINE__, read_transfer, map, addr, val, N);
  return val;
}
#endif

/* TAGS: sim_core_write_aligned_1 sim_core_write_aligned_2 */
/* TAGS: sim_core_write_aligned_4 sim_core_write_aligned_8 */
/* TAGS: sim_core_write_aligned_16 */

#if (M == N)
INLINE_SIM_CORE(void)
sim_core_write_aligned_N(sim_cpu *cpu,
			 sim_cia cia,
			 unsigned map,
			 address_word xaddr,
			 unsigned_M val)
{
  sim_cpu_core *cpu_core = CPU_CORE (cpu);
  sim_core_common *core = &cpu_core->common;
  sim_core_mapping *mapping;
  address_word addr;
#if WITH_XOR_ENDIAN != 0
  if (WITH_XOR_ENDIAN)
    addr = xaddr ^ cpu_core->xor[(N - 1) % WITH_XOR_ENDIAN];
  else
#endif
    addr = xaddr;
  mapping = sim_core_find_mapping (core, map, addr, N, write_transfer, 1 /*abort*/, cpu, cia);
  do
    {
#if (WITH_DEVICES)
      if (WITH_CALLBACK_MEMORY && mapping->device != NULL)
	{
	  unsigned_M data = H2T_M (val);
	  if (device_io_write_buffer (mapping->device, &data, mapping->space, addr, N, CPU_STATE (cpu), cpu, cia) != N)
	    device_error (mapping->device, "internal error - %s - io_write_buffer should not fail",
			  XSTRING (sim_core_write_aligned_N));
	  break;
	}
#endif
#if (WITH_HW)
      if (WITH_CALLBACK_MEMORY && mapping->device != NULL)
	{
	  unsigned_M data = H2T_M (val);
	  sim_cpu_hw_io_write_buffer (cpu, cia, mapping->device, &data, mapping->space, addr, N);
	  break;
	}
#endif
      *(unsigned_M*) sim_core_translate (mapping, addr) = H2T_M (val);
    }
  while (0);
  PROFILE_COUNT_CORE (cpu, addr, N, map);
  if (TRACE_P (cpu, TRACE_CORE_IDX))
    sim_core_trace_M (cpu, cia, __LINE__, write_transfer, map, addr, val, N);
}
#endif

/* TAGS: sim_core_write_unaligned_1 sim_core_write_unaligned_2 */
/* TAGS: sim_core_write_unaligned_4 sim_core_write_unaligned_8 */
/* TAGS: sim_core_write_unaligned_16 */

#if (M == N && N > 1)
INLINE_SIM_CORE(void)
sim_core_write_unaligned_N(sim_cpu *cpu,
			   sim_cia cia,
			   unsigned map,
			   address_word addr,
			   unsigned_M val)
{
  int alignment = N - 1;
  /* if hardwired to forced alignment just do it */
  if (WITH_ALIGNMENT == FORCED_ALIGNMENT)
    sim_core_write_aligned_N (cpu, cia, map, addr & ~alignment, val);
  else if ((addr & alignment) == 0)
    sim_core_write_aligned_N (cpu, cia, map, addr, val);
  else
    switch (CURRENT_ALIGNMENT)
      {
      case STRICT_ALIGNMENT:
	SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
			 write_transfer, sim_core_unaligned_signal);
	break;
      case NONSTRICT_ALIGNMENT:
	{
	  unsigned_M data = H2T_M (val);
	  if (sim_core_xor_write_buffer (CPU_STATE (cpu), cpu, map, &data, addr, N) != N)
	    SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
			     write_transfer, sim_core_unaligned_signal);
	  PROFILE_COUNT_CORE (cpu, addr, N, map);
	  if (TRACE_P (cpu, TRACE_CORE_IDX))
	    sim_core_trace_M (cpu, cia, __LINE__, write_transfer, map, addr, val, N);
	  break;
	}
      case FORCED_ALIGNMENT:
	sim_core_write_aligned_N (cpu, cia, map, addr & ~alignment, val);
	break;
      case MIXED_ALIGNMENT:
	sim_engine_abort (CPU_STATE (cpu), cpu, cia,
			  "internal error - %s - mixed alignment",
			  XSTRING (sim_core_write_unaligned_N));
	break;
      default:
	sim_engine_abort (CPU_STATE (cpu), cpu, cia,
			  "internal error - %s - bad switch",
			  XSTRING (sim_core_write_unaligned_N));
	break;
      }
}
#endif

/* TAGS: sim_core_write_misaligned_3 sim_core_write_misaligned_5 */
/* TAGS: sim_core_write_misaligned_6 sim_core_write_misaligned_7 */

#if (M != N)
INLINE_SIM_CORE(void)
sim_core_write_misaligned_N(sim_cpu *cpu,
			   sim_cia cia,
			   unsigned map,
			   address_word addr,
			   unsigned_M val)
{
  unsigned_M data = val;
  if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
    data <<= (M - N) * 8;
  if (CURRENT_HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER)
    data = SWAP_M (data);
  if (sim_core_xor_write_buffer (CPU_STATE (cpu), cpu, map, &data, addr, N) != N)
    SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
		     write_transfer, sim_core_unaligned_signal);
  PROFILE_COUNT_CORE (cpu, addr, N, map);
  if (TRACE_P (cpu, TRACE_CORE_IDX))
    sim_core_trace_M (cpu, cia, __LINE__, write_transfer, map, addr, val, N);
}
#endif


/* NOTE: see start of file for #define of these macros */
#undef unsigned_M
#undef T2H_M
#undef H2T_M
#undef SWAP_M
#undef sim_core_read_aligned_N
#undef sim_core_read_unaligned_N
#undef sim_core_read_misaligned_N
#undef sim_core_write_aligned_N
#undef sim_core_write_unaligned_N
#undef sim_core_write_misaligned_N
#undef sim_core_trace_M
#undef sim_core_dummy_M
#undef M
#undef N
