/* Target-dependent code for NetBSD/powerpc.

   Copyright (C) 2002-2023 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 "gdbtypes.h"
#include "osabi.h"
#include "regcache.h"
#include "regset.h"
#include "trad-frame.h"
#include "tramp-frame.h"

#include "ppc-tdep.h"
#include "netbsd-tdep.h"
#include "ppc-tdep.h"
#include "solib-svr4.h"

/* Register offsets from <machine/reg.h>.  */
static ppc_reg_offsets ppcnbsd_reg_offsets;


/* Core file support.  */

/* NetBSD/powerpc register sets.  */

const struct regset ppcnbsd_gregset =
{
  &ppcnbsd_reg_offsets,
  ppc_supply_gregset
};

const struct regset ppcnbsd_fpregset =
{
  &ppcnbsd_reg_offsets,
  ppc_supply_fpregset
};

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

static void
ppcnbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
				      iterate_over_regset_sections_cb *cb,
				      void *cb_data,
				      const struct regcache *regcache)
{
  cb (".reg", 148, 148, &ppcnbsd_gregset, NULL, cb_data);
  cb (".reg2", 264, 264, &ppcnbsd_fpregset, NULL, cb_data);
}


/* NetBSD is confused.  It appears that 1.5 was using the correct SVR4
   convention but, 1.6 switched to the below broken convention.  For
   the moment use the broken convention.  Ulgh!  */

static enum return_value_convention
ppcnbsd_return_value (struct gdbarch *gdbarch, struct value *function,
		      struct type *valtype, struct regcache *regcache,
		      gdb_byte *readbuf, const gdb_byte *writebuf)
{
#if 0
  if ((valtype->code () == TYPE_CODE_STRUCT
       || valtype->code () == TYPE_CODE_UNION)
      && !((valtype->length () == 16 || valtype->length () == 8)
	    && valtype->is_vector ())
      && !(valtype->length () == 1
	   || valtype->length () == 2
	   || valtype->length () == 4
	   || valtype->length () == 8))
    return RETURN_VALUE_STRUCT_CONVENTION;
  else
#endif
    return ppc_sysv_abi_broken_return_value (gdbarch, function, valtype,
					     regcache, readbuf, writebuf);
}


/* Signal trampolines.  */

extern const struct tramp_frame ppcnbsd2_sigtramp;

static void
ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self,
			     frame_info_ptr this_frame,
			     struct trad_frame_cache *this_cache,
			     CORE_ADDR func)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
  CORE_ADDR addr, base;
  int i;

  base = get_frame_register_unsigned (this_frame,
				      gdbarch_sp_regnum (gdbarch));
  if (self == &ppcnbsd2_sigtramp)
    addr = base + 0x10 + 2 * tdep->wordsize;
  else
    addr = base + 0x18 + 2 * tdep->wordsize;
  for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
    {
      int regnum = i + tdep->ppc_gp0_regnum;
      trad_frame_set_reg_addr (this_cache, regnum, addr);
    }
  trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (this_cache, gdbarch_pc_regnum (gdbarch),
			   addr); /* SRR0?  */
  addr += tdep->wordsize;

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

static const struct tramp_frame ppcnbsd_sigtramp =
{
  SIGTRAMP_FRAME,
  4,
  {
    { 0x3821fff0, ULONGEST_MAX },		/* add r1,r1,-16 */
    { 0x4e800021, ULONGEST_MAX },		/* blrl */
    { 0x38610018, ULONGEST_MAX },		/* addi r3,r1,24 */
    { 0x38000127, ULONGEST_MAX },		/* li r0,295 */
    { 0x44000002, ULONGEST_MAX },		/* sc */
    { 0x38000001, ULONGEST_MAX },		/* li r0,1 */
    { 0x44000002, ULONGEST_MAX },		/* sc */
    { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
  },
  ppcnbsd_sigtramp_cache_init
};

/* NetBSD 2.0 introduced a slightly different signal trampoline.  */

const struct tramp_frame ppcnbsd2_sigtramp =
{
  SIGTRAMP_FRAME,
  4,
  {
    { 0x3821fff0, ULONGEST_MAX },		/* add r1,r1,-16 */
    { 0x4e800021, ULONGEST_MAX },		/* blrl */
    { 0x38610010, ULONGEST_MAX },		/* addi r3,r1,16 */
    { 0x38000127, ULONGEST_MAX },		/* li r0,295 */
    { 0x44000002, ULONGEST_MAX },		/* sc */
    { 0x38000001, ULONGEST_MAX },		/* li r0,1 */
    { 0x44000002, ULONGEST_MAX },		/* sc */
    { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
  },
  ppcnbsd_sigtramp_cache_init
};


static void
ppcnbsd_init_abi (struct gdbarch_info info,
		  struct gdbarch *gdbarch)
{
  nbsd_init_abi (info, gdbarch);

  /* For NetBSD, this is an on again, off again thing.  Some systems
     do use the broken struct convention, and some don't.  */
  set_gdbarch_return_value (gdbarch, ppcnbsd_return_value);

  /* NetBSD uses SVR4-style shared libraries.  */
  set_solib_svr4_fetch_link_map_offsets
    (gdbarch, svr4_ilp32_fetch_link_map_offsets);

  set_gdbarch_iterate_over_regset_sections
    (gdbarch, ppcnbsd_iterate_over_regset_sections);

  tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd_sigtramp);
  tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd2_sigtramp);
}

void _initialize_ppcnbsd_tdep ();
void
_initialize_ppcnbsd_tdep ()
{
  gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD,
			  ppcnbsd_init_abi);

  /* Avoid initializing the register offsets again if they were
     already initialized by ppc-netbsd-nat.c.  */
  if (ppcnbsd_reg_offsets.pc_offset == 0)
    {
      /* General-purpose registers.  */
      ppcnbsd_reg_offsets.r0_offset = 0;
      ppcnbsd_reg_offsets.gpr_size = 4;
      ppcnbsd_reg_offsets.xr_size = 4;
      ppcnbsd_reg_offsets.lr_offset = 128;
      ppcnbsd_reg_offsets.cr_offset = 132;
      ppcnbsd_reg_offsets.xer_offset = 136;
      ppcnbsd_reg_offsets.ctr_offset = 140;
      ppcnbsd_reg_offsets.pc_offset = 144;
      ppcnbsd_reg_offsets.ps_offset = -1;
      ppcnbsd_reg_offsets.mq_offset = -1;

      /* Floating-point registers.  */
      ppcnbsd_reg_offsets.f0_offset = 0;
      ppcnbsd_reg_offsets.fpscr_offset = 256;
      ppcnbsd_reg_offsets.fpscr_size = 4;

    }
}
