/* Target-dependent code for Fuchsia AArch64.

   Copyright (C) 2017 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 <ctype.h>

#include "gdbarch.h"
#include "arch-utils.h"
#include "fuchsia-tdep.h"
#include "aarch64-tdep.h"
#include "aarch64-fuchsia-tdep.h"
#include "osabi.h"
#include "solib-svr4.h"
#include "symtab.h"
#include "regcache.h"
#include "regset.h"
#include "cli/cli-utils.h"
#include "parser-defs.h"
#include "user-regs.h"

/* Register maps.  */

static const struct regcache_map_entry aarch64_fuchsia_gregmap[] =
  {
    { 31, AARCH64_X0_REGNUM, 8 }, /* x0 ... x30 */
    { 1, AARCH64_SP_REGNUM, 8 },
    { 1, AARCH64_PC_REGNUM, 8 },
    { 1, AARCH64_CPSR_REGNUM, 8 },
    { 0 }
  };

static const struct regcache_map_entry aarch64_fuchsia_fpregmap[] =
  {
    { 32, AARCH64_V0_REGNUM, 16 }, /* v0 ... v31 */
    { 1, AARCH64_FPSR_REGNUM, 4 },
    { 1, AARCH64_FPCR_REGNUM, 4 },
    { 0 }
  };

/* Register set definitions.  */

const struct regset aarch64_fuchsia_gregset =
  {
    aarch64_fuchsia_gregmap,
    regcache_supply_regset, regcache_collect_regset
  };

const struct regset aarch64_fuchsia_fpregset =
  {
    aarch64_fuchsia_fpregmap,
    regcache_supply_regset, regcache_collect_regset
  };

static void
aarch64_fuchsia_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  tdep->lowest_pc = 0x8000;

  fuchsia_init_abi (info, gdbarch);

  /* Enable longjmp.  */
  tdep->jb_pc = 11;

  /* Displaced stepping.  */
  set_gdbarch_max_insn_length (gdbarch, 4 * DISPLACED_MODIFIED_INSNS);
  set_gdbarch_displaced_step_copy_insn (gdbarch,
					aarch64_displaced_step_copy_insn);
  set_gdbarch_displaced_step_fixup (gdbarch, aarch64_displaced_step_fixup);
  set_gdbarch_displaced_step_free_closure (gdbarch,
					   simple_displaced_step_free_closure);
  set_gdbarch_displaced_step_location (gdbarch, fuchsia_displaced_step_location);
  set_gdbarch_displaced_step_hw_singlestep (gdbarch,
					    aarch64_displaced_step_hw_singlestep);
}

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

void
_initialize_aarch64_fuchsia_tdep (void)
{
  gdbarch_register_osabi_sniffer (bfd_arch_aarch64, bfd_target_elf_flavour,
				  fuchsia_osabi_sniffer);
  gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_FUCHSIA,
			  aarch64_fuchsia_init_abi);
}
