/* Target-dependent code for NetBSD/sh.

   Copyright (C) 2002, 2003, 2006, 2007, 2008 Free Software Foundation, Inc.

   Contributed by Wasabi Systems, 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/>.  */

#include "defs.h"
#include "gdbcore.h"
#include "regcache.h"
#include "regset.h"
#include "value.h"
#include "osabi.h"

#include "gdb_assert.h"
#include "gdb_string.h"

#include "sh-tdep.h"
#include "shnbsd-tdep.h"
#include "solib-svr4.h"

/* Convert an r0-r15 register number into an offset into a ptrace
   register structure.  */
static const int regmap[] =
{
  (20 * 4),	/* r0 */
  (19 * 4),	/* r1 */
  (18 * 4),	/* r2 */ 
  (17 * 4),	/* r3 */ 
  (16 * 4),	/* r4 */
  (15 * 4),	/* r5 */
  (14 * 4),	/* r6 */
  (13 * 4),	/* r7 */
  (12 * 4),	/* r8 */ 
  (11 * 4),	/* r9 */
  (10 * 4),	/* r10 */
  ( 9 * 4),	/* r11 */
  ( 8 * 4),	/* r12 */
  ( 7 * 4),	/* r13 */
  ( 6 * 4),	/* r14 */
  ( 5 * 4),	/* r15 */
};

/* Sizeof `struct reg' in <machine/reg.h>.  */
#define SHNBSD_SIZEOF_GREGS	(21 * 4)

/* Supply register REGNUM from the buffer specified by GREGS and LEN
   in the general-purpose register set REGSET to register cache
   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */

static void
shnbsd_supply_gregset (const struct regset *regset,
		       struct regcache *regcache,
		       int regnum, const void *gregs, size_t len)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  const gdb_byte *regs = gregs;
  int i;

  gdb_assert (len >= SHNBSD_SIZEOF_GREGS);

  if (regnum == gdbarch_pc_regnum (gdbarch) || regnum == -1)
    regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch),
			 regs + (0 * 4));

  if (regnum == SR_REGNUM || regnum == -1)
    regcache_raw_supply (regcache, SR_REGNUM, regs + (1 * 4));

  if (regnum == PR_REGNUM || regnum == -1)
    regcache_raw_supply (regcache, PR_REGNUM, regs + (2 * 4));

  if (regnum == MACH_REGNUM || regnum == -1)
    regcache_raw_supply (regcache, MACH_REGNUM, regs + (3 * 4));

  if (regnum == MACL_REGNUM || regnum == -1)
    regcache_raw_supply (regcache, MACL_REGNUM, regs + (4 * 4));

  for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++)
    {
      if (regnum == i || regnum == -1)
	regcache_raw_supply (regcache, i, regs + regmap[i - R0_REGNUM]);
    }
}

/* Collect register REGNUM in the general-purpose register set
   REGSET. from register cache REGCACHE into the buffer specified by
   GREGS and LEN.  If REGNUM is -1, do this for all registers in
   REGSET.  */

static void
shnbsd_collect_gregset (const struct regset *regset,
			const struct regcache *regcache,
			int regnum, void *gregs, size_t len)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  gdb_byte *regs = gregs;
  int i;

  gdb_assert (len >= SHNBSD_SIZEOF_GREGS);

  if (regnum == gdbarch_pc_regnum (gdbarch) || regnum == -1)
    regcache_raw_collect (regcache, gdbarch_pc_regnum (gdbarch),
			  regs + (0 * 4));

  if (regnum == SR_REGNUM || regnum == -1)
    regcache_raw_collect (regcache, SR_REGNUM, regs + (1 * 4));

  if (regnum == PR_REGNUM || regnum == -1)
    regcache_raw_collect (regcache, PR_REGNUM, regs + (2 * 4));

  if (regnum == MACH_REGNUM || regnum == -1)
    regcache_raw_collect (regcache, MACH_REGNUM, regs + (3 * 4));

  if (regnum == MACL_REGNUM || regnum == -1)
    regcache_raw_collect (regcache, MACL_REGNUM, regs + (4 * 4));

  for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++)
    {
      if (regnum == i || regnum == -1)
	regcache_raw_collect (regcache, i, regs + regmap[i - R0_REGNUM]);
    }
}

/* SH register sets.  */

static struct regset shnbsd_gregset =
{
  NULL,
  shnbsd_supply_gregset,
  shnbsd_collect_gregset
};

/* Return the appropriate register set for the core section identified
   by SECT_NAME and SECT_SIZE.  */

const struct regset *
shnbsd_regset_from_core_section (struct gdbarch *gdbarch,
				 const char *sect_name, size_t sect_size)
{
  if (strcmp (sect_name, ".reg") == 0 && sect_size >= SHNBSD_SIZEOF_GREGS)
    return &shnbsd_gregset;

  return NULL;
}

void
shnbsd_supply_reg (struct regcache *regcache, const char *regs, int regnum)
{
  shnbsd_supply_gregset (&shnbsd_gregset, regcache, regnum,
			 regs, SHNBSD_SIZEOF_GREGS);
}

void
shnbsd_fill_reg (const struct regcache *regcache, char *regs, int regnum)
{
  shnbsd_collect_gregset (&shnbsd_gregset, regcache, regnum,
			  regs, SHNBSD_SIZEOF_GREGS);
}


static void
shnbsd_init_abi (struct gdbarch_info info,
                  struct gdbarch *gdbarch)
{
  set_gdbarch_regset_from_core_section
    (gdbarch, shnbsd_regset_from_core_section);

  set_solib_svr4_fetch_link_map_offsets
    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
}


/* OpenBSD uses uses the traditional NetBSD core file format, even for
   ports that use ELF.  */
#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF

static enum gdb_osabi
shnbsd_core_osabi_sniffer (bfd *abfd)
{
  if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
    return GDB_OSABI_NETBSD_CORE;

  return GDB_OSABI_UNKNOWN;
}

void
_initialize_shnbsd_tdep (void)
{
  /* BFD doesn't set a flavour for NetBSD style a.out core files.  */
  gdbarch_register_osabi_sniffer (bfd_arch_sh, bfd_target_unknown_flavour,
                                  shnbsd_core_osabi_sniffer);

  gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD_ELF,
			  shnbsd_init_abi);
  gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_OPENBSD_ELF,
			  shnbsd_init_abi);
}
