/* Target-dependent code for NetBSD/hppa

   Copyright (C) 2008-2015 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/>.  */

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

#include "trad-frame.h"
#include "tramp-frame.h"

#include "hppa-tdep.h"
#include "hppabsd-tdep.h"

/* From <machine/mcontext.h>.  */
static int hppanbsd_mc_reg_offset[] =
{
  /* r0 ... r31 */
      -1,   1 * 4,   2 * 4,   3 * 4,
   4 * 4,   5 * 4,   6 * 4,   7 * 4,
   8 * 4,   9 * 4,  10 * 4,  11 * 4, 
  12 * 4,  13 * 4,  14 * 4,  15 * 4,
  16 * 4,  17 * 4,  18 * 4,  19 * 4,
  20 * 4,  21 * 4,  22 * 4,  23 * 4,
  24 * 4,  25 * 4,  26 * 4,  27 * 4,
  28 * 4,  29 * 4,  30 * 4,  31 * 4,

  32 * 4,	/* HPPA_SAR_REGNUM */
  35 * 4,	/* HPPA_PCOQ_HEAD_REGNUM */
  33 * 4,	/* HPPA_PCSQ_HEAD_REGNUM */
  36 * 4,	/* HPPA_PCOQ_TAIL_REGNUM */
  34 * 4,	/* HPPA_PCSQ_TAIL_REGNUM */
  -1,		/* HPPA_EIEM_REGNUM */
  -1,		/* HPPA_IIR_REGNUM */
  -1,		/* HPPA_ISR_REGNUM */
  -1,		/* HPPA_IOR_REGNUM */
  0 * 4,	/* HPPA_IPSW_REGNUM */
  -1,		/* spare? */
  41 * 4,	/* HPPA_SR4_REGNUM */
  37 * 4,	/* sr0 */
  38 * 4,	/* sr1 */
  39 * 4,	/* sr2 */
  40 * 4,	/* sr3 */

  /* more tbd */
};

static void hppanbsd_sigtramp_cache_init (const struct tramp_frame *,
                                         struct frame_info *,
                                         struct trad_frame_cache *,
                                         CORE_ADDR);

static const struct tramp_frame hppanbsd_sigtramp_si4 =
{
  SIGTRAMP_FRAME,
  4,
  {
    { 0xc7d7c012, -1 },	/*	bb,>=,n %arg3, 30, 1f		*/
    { 0xd6e01c1e, -1 },	/*	 depwi 0,31,2,%arg3		*/
    { 0x0ee81093, -1 },	/*	ldw 4(%arg3), %r19		*/
    { 0x0ee01097, -1 },	/*	ldw 0(%arg3), %arg3		*/
			/* 1: 					*/
    { 0xe8404000, -1 },	/* 	blr %r0, %rp			*/
    { 0xeae0c002, -1 },	/*	bv,n %r0(%arg3)			*/
    { 0x08000240, -1 },	/*	 nop				*/

    { 0x0803025a, -1 },	/*	copy %r3, %arg0			*/
    { 0x20200801, -1 },	/*	ldil -40000000, %r1		*/
    { 0xe420e008, -1 },	/*	be,l 4(%sr7, %r1), %sr0, %r31	*/
    { 0x34160268, -1 },	/*	 ldi 134, %t1 ; SYS_setcontext	*/

    { 0x081c025a, -1 },	/*	copy ret0, %arg0		*/
    { 0x20200801, -1 },	/*	ldil -40000000, %r1		*/
    { 0xe420e008, -1 },	/*	be,l 4(%sr7, %r1), %sr0, %r31	*/
    { 0x34160002, -1 },	/*	 ldi 1, %t1 ; SYS_exit		*/
    { TRAMP_SENTINEL_INSN, -1 }
  },
  hppanbsd_sigtramp_cache_init
};


static void
hppanbsd_sigtramp_cache_init (const struct tramp_frame *self,
                             struct frame_info *this_frame,
                             struct trad_frame_cache *this_cache,
                             CORE_ADDR func)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, HPPA_SP_REGNUM);
  CORE_ADDR base;
  int *reg_offset;
  int num_regs;
  int i;

  reg_offset = hppanbsd_mc_reg_offset;
  num_regs = ARRAY_SIZE (hppanbsd_mc_reg_offset);

  /* frame pointer */
  base = sp - 0x280;
  /* offsetof(struct sigframe_siginfo, sf_uc) = 128 */
  base += 128;
  /* offsetof(ucontext_t, uc_mcontext) == 40 */
  base += 40;

  for (i = 0; i < num_regs; i++)
    if (reg_offset[i] != -1)
      trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);

  /* Construct the frame ID using the function start.  */
  trad_frame_set_id (this_cache, frame_id_build (sp, func));
}

/* Core file support.  */

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

static int hppanbsd_reg_offset[] =
{
  /* r0 ... r31 */
      -1,   1 * 4,   2 * 4,   3 * 4,
   4 * 4,   5 * 4,   6 * 4,   7 * 4,
   8 * 4,   9 * 4,  10 * 4,  11 * 4, 
  12 * 4,  13 * 4,  14 * 4,  15 * 4,
  16 * 4,  17 * 4,  18 * 4,  19 * 4,
  20 * 4,  21 * 4,  22 * 4,  23 * 4,
  24 * 4,  25 * 4,  26 * 4,  27 * 4,
  28 * 4,  29 * 4,  30 * 4,  31 * 4,

  32 * 4,	/* HPPA_SAR_REGNUM */
  35 * 4,	/* HPPA_PCOQ_HEAD_REGNUM */
  33 * 4,	/* HPPA_PCSQ_HEAD_REGNUM */
  36 * 4,	/* HPPA_PCOQ_TAIL_REGNUM */
  34 * 4,	/* HPPA_PCSQ_TAIL_REGNUM */
  -1,		/* HPPA_EIEM_REGNUM */
  -1,		/* HPPA_IIR_REGNUM */
  -1,		/* HPPA_ISR_REGNUM */
  -1,		/* HPPA_IOR_REGNUM */
  0 * 4,	/* HPPA_IPSW_REGNUM */
};

/* 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
hppanbsd_supply_gregset (const struct regset *regset,
			 struct regcache *regcache,
			 int regnum, const void *gregs, size_t len)
{
  const gdb_byte *regs = gregs;
  int i;

  gdb_assert (len >= HPPANBSD_SIZEOF_GREGS);

  for (i = 0; i < ARRAY_SIZE (hppanbsd_reg_offset); i++)
    if (hppanbsd_reg_offset[i] != -1)
      if (regnum == -1 || regnum == i)
	regcache_raw_supply (regcache, i, regs + hppanbsd_reg_offset[i]);
}

/* NetBSD/hppa register set.  */

static const struct regset hppanbsd_gregset =
{
  NULL,
  hppanbsd_supply_gregset
};

/* Iterate over supported core file register note sections. */

static void
hppanbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
				       iterate_over_regset_sections_cb *cb,
				       void *cb_data,
				       const struct regcache *regcache)
{
  cb (".reg", HPPANBSD_SIZEOF_GREGS, &hppanbsd_gregset, NULL, cb_data);
}

static void
hppanbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  /* Obviously NetBSD is BSD-based.  */
  hppabsd_init_abi (info, gdbarch);

  /* Core file support.  */
  set_gdbarch_iterate_over_regset_sections
    (gdbarch, hppanbsd_iterate_over_regset_sections);

  tramp_frame_prepend_unwinder (gdbarch, &hppanbsd_sigtramp_si4);
}


/* Provide a prototype to silence -Wmissing-prototypes.  */
extern initialize_file_ftype _initialize_hppanbsd_tdep;

void
_initialize_hppanbsd_tdep (void)
{
  gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_NETBSD_ELF,
			  hppanbsd_init_abi);
}
