/* Target-dependent code for the VAX.

   Copyright (C) 1986-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 "arch-utils.h"
#include "dis-asm.h"
#include "floatformat.h"
#include "frame.h"
#include "frame-base.h"
#include "frame-unwind.h"
#include "gdbcore.h"
#include "gdbtypes.h"
#include "osabi.h"
#include "regcache.h"
#include "regset.h"
#include "trad-frame.h"
#include "value.h"

#include "vax-tdep.h"

/* Return the name of register REGNUM.  */

static const char *
vax_register_name (struct gdbarch *gdbarch, int regnum)
{
  static char *register_names[] =
  {
    "r0", "r1", "r2",  "r3",  "r4", "r5", "r6", "r7",
    "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc",
    "ps",
  };

  if (regnum >= 0 && regnum < ARRAY_SIZE (register_names))
    return register_names[regnum];

  return NULL;
}

/* Return the GDB type object for the "standard" data type of data in
   register REGNUM.  */

static struct type *
vax_register_type (struct gdbarch *gdbarch, int regnum)
{
  return builtin_type (gdbarch)->builtin_int;
}

/* Core file support.  */

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

  for (i = 0; i < VAX_NUM_REGS; i++)
    {
      if (regnum == i || regnum == -1)
	regcache_raw_supply (regcache, i, regs + i * 4);
    }
}

/* VAX register set.  */

static const struct regset vax_gregset =
{
  NULL,
  vax_supply_gregset
};

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

static void
vax_iterate_over_regset_sections (struct gdbarch *gdbarch,
				  iterate_over_regset_sections_cb *cb,
				  void *cb_data,
				  const struct regcache *regcache)
{
  cb (".reg", VAX_NUM_REGS * 4, &vax_gregset, NULL, cb_data);
}

/* The VAX UNIX calling convention uses R1 to pass a structure return
   value address instead of passing it as a first (hidden) argument as
   the VMS calling convention suggests.  */

static CORE_ADDR
vax_store_arguments (struct regcache *regcache, int nargs,
		     struct value **args, CORE_ADDR sp)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte buf[4];
  int count = 0;
  int i;

  /* We create an argument list on the stack, and make the argument
     pointer to it.  */

  /* Push arguments in reverse order.  */
  for (i = nargs - 1; i >= 0; i--)
    {
      int len = TYPE_LENGTH (value_enclosing_type (args[i]));

      sp -= (len + 3) & ~3;
      count += (len + 3) / 4;
      write_memory (sp, value_contents_all (args[i]), len);
    }

  /* Push argument count.  */
  sp -= 4;
  store_unsigned_integer (buf, 4, byte_order, count);
  write_memory (sp, buf, 4);

  /* Update the argument pointer.  */
  store_unsigned_integer (buf, 4, byte_order, sp);
  regcache_cooked_write (regcache, VAX_AP_REGNUM, buf);

  return sp;
}

static CORE_ADDR
vax_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
		     struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
		     struct value **args, CORE_ADDR sp, int struct_return,
		     CORE_ADDR struct_addr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR fp = sp;
  gdb_byte buf[4];

  /* Set up the function arguments.  */
  sp = vax_store_arguments (regcache, nargs, args, sp);

  /* Store return value address.  */
  if (struct_return)
    regcache_cooked_write_unsigned (regcache, VAX_R1_REGNUM, struct_addr);

  /* Store return address in the PC slot.  */
  sp -= 4;
  store_unsigned_integer (buf, 4, byte_order, bp_addr);
  write_memory (sp, buf, 4);

  /* Store the (fake) frame pointer in the FP slot.  */
  sp -= 4;
  store_unsigned_integer (buf, 4, byte_order, fp);
  write_memory (sp, buf, 4);

  /* Skip the AP slot.  */
  sp -= 4;

  /* Store register save mask and control bits.  */
  sp -= 4;
  store_unsigned_integer (buf, 4, byte_order, 0);
  write_memory (sp, buf, 4);

  /* Store condition handler.  */
  sp -= 4;
  store_unsigned_integer (buf, 4, byte_order, 0);
  write_memory (sp, buf, 4);

  /* Update the stack pointer and frame pointer.  */
  store_unsigned_integer (buf, 4, byte_order, sp);
  regcache_cooked_write (regcache, VAX_SP_REGNUM, buf);
  regcache_cooked_write (regcache, VAX_FP_REGNUM, buf);

  /* Return the saved (fake) frame pointer.  */
  return fp;
}

static struct frame_id
vax_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
  CORE_ADDR fp;

  fp = get_frame_register_unsigned (this_frame, VAX_FP_REGNUM);
  return frame_id_build (fp, get_frame_pc (this_frame));
}


static enum return_value_convention
vax_return_value (struct gdbarch *gdbarch, struct value *function,
		  struct type *type, struct regcache *regcache,
		  gdb_byte *readbuf, const gdb_byte *writebuf)
{
  int len = TYPE_LENGTH (type);
  gdb_byte buf[8];

  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
      || TYPE_CODE (type) == TYPE_CODE_UNION
      || TYPE_CODE (type) == TYPE_CODE_ARRAY)
    {
      /* The default on VAX is to return structures in static memory.
         Consequently a function must return the address where we can
         find the return value.  */

      if (readbuf)
	{
	  ULONGEST addr;

	  regcache_raw_read_unsigned (regcache, VAX_R0_REGNUM, &addr);
	  read_memory (addr, readbuf, len);
	}

      return RETURN_VALUE_ABI_RETURNS_ADDRESS;
    }

  if (readbuf)
    {
      /* Read the contents of R0 and (if necessary) R1.  */
      regcache_cooked_read (regcache, VAX_R0_REGNUM, buf);
      if (len > 4)
	regcache_cooked_read (regcache, VAX_R1_REGNUM, buf + 4);
      memcpy (readbuf, buf, len);
    }
  if (writebuf)
    {
      /* Read the contents to R0 and (if necessary) R1.  */
      memcpy (buf, writebuf, len);
      regcache_cooked_write (regcache, VAX_R0_REGNUM, buf);
      if (len > 4)
	regcache_cooked_write (regcache, VAX_R1_REGNUM, buf + 4);
    }

  return RETURN_VALUE_REGISTER_CONVENTION;
}


/* Use the program counter to determine the contents and size of a
   breakpoint instruction.  Return a pointer to a string of bytes that
   encode a breakpoint instruction, store the length of the string in
   *LEN and optionally adjust *PC to point to the correct memory
   location for inserting the breakpoint.  */
   
static const gdb_byte *
vax_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len)
{
  static gdb_byte break_insn[] = { 3 };

  *len = sizeof (break_insn);
  return break_insn;
}

/* Advance PC across any function entry prologue instructions
   to reach some "real" code.  */

static CORE_ADDR
vax_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte op = read_memory_unsigned_integer (pc, 1, byte_order);

  if (op == 0x11)
    pc += 2;			/* skip brb */
  if (op == 0x31)
    pc += 3;			/* skip brw */
  if (op == 0xC2
      && read_memory_unsigned_integer (pc + 2, 1, byte_order) == 0x5E)
    pc += 3;			/* skip subl2 */
  if (op == 0x9E
      && read_memory_unsigned_integer (pc + 1, 1, byte_order) == 0xAE
      && read_memory_unsigned_integer (pc + 3, 1, byte_order) == 0x5E)
    pc += 4;			/* skip movab */
  if (op == 0x9E
      && read_memory_unsigned_integer (pc + 1, 1, byte_order) == 0xCE
      && read_memory_unsigned_integer (pc + 4, 1, byte_order) == 0x5E)
    pc += 5;			/* skip movab */
  if (op == 0x9E
      && read_memory_unsigned_integer (pc + 1, 1, byte_order) == 0xEE
      && read_memory_unsigned_integer (pc + 6, 1, byte_order) == 0x5E)
    pc += 7;			/* skip movab */

  return pc;
}


/* Unwinding the stack is relatively easy since the VAX has a
   dedicated frame pointer, and frames are set up automatically as the
   result of a function call.  Most of the relevant information can be
   inferred from the documentation of the Procedure Call Instructions
   in the VAX MACRO and Instruction Set Reference Manual.  */

struct vax_frame_cache
{
  /* Base address.  */
  CORE_ADDR base;

  /* Table of saved registers.  */
  struct trad_frame_saved_reg *saved_regs;
};

static struct vax_frame_cache *
vax_frame_cache (struct frame_info *this_frame, void **this_cache)
{
  struct vax_frame_cache *cache;
  CORE_ADDR addr;
  ULONGEST mask;
  int regnum;

  if (*this_cache)
    return *this_cache;

  /* Allocate a new cache.  */
  cache = FRAME_OBSTACK_ZALLOC (struct vax_frame_cache);
  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  /* The frame pointer is used as the base for the frame.  */
  cache->base = get_frame_register_unsigned (this_frame, VAX_FP_REGNUM);
  if (cache->base == 0)
    return cache;

  /* The register save mask and control bits determine the layout of
     the stack frame.  */
  mask = get_frame_memory_unsigned (this_frame, cache->base + 4, 4) >> 16;

  /* These are always saved.  */
  cache->saved_regs[VAX_PC_REGNUM].addr = cache->base + 16;
  cache->saved_regs[VAX_FP_REGNUM].addr = cache->base + 12;
  cache->saved_regs[VAX_AP_REGNUM].addr = cache->base + 8;
  cache->saved_regs[VAX_PS_REGNUM].addr = cache->base + 4;

  /* Scan the register save mask and record the location of the saved
     registers.  */
  addr = cache->base + 20;
  for (regnum = 0; regnum < VAX_AP_REGNUM; regnum++)
    {
      if (mask & (1 << regnum))
	{
	  cache->saved_regs[regnum].addr = addr;
	  addr += 4;
	}
    }

  /* The CALLS/CALLG flag determines whether this frame has a General
     Argument List or a Stack Argument List.  */
  if (mask & (1 << 13))
    {
      ULONGEST numarg;

      /* This is a procedure with Stack Argument List.  Adjust the
         stack address for the arguments that were pushed onto the
         stack.  The return instruction will automatically pop the
         arguments from the stack.  */
      numarg = get_frame_memory_unsigned (this_frame, addr, 1);
      addr += 4 + numarg * 4;
    }

  /* Bits 1:0 of the stack pointer were saved in the control bits.  */
  trad_frame_set_value (cache->saved_regs, VAX_SP_REGNUM, addr + (mask >> 14));

  return cache;
}

static void
vax_frame_this_id (struct frame_info *this_frame, void **this_cache,
		   struct frame_id *this_id)
{
  struct vax_frame_cache *cache = vax_frame_cache (this_frame, this_cache);

  /* This marks the outermost frame.  */
  if (cache->base == 0)
    return;

  (*this_id) = frame_id_build (cache->base, get_frame_func (this_frame));
}

static struct value *
vax_frame_prev_register (struct frame_info *this_frame,
			 void **this_cache, int regnum)
{
  struct vax_frame_cache *cache = vax_frame_cache (this_frame, this_cache);

  return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
}

static const struct frame_unwind vax_frame_unwind =
{
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  vax_frame_this_id,
  vax_frame_prev_register,
  NULL,
  default_frame_sniffer
};


static CORE_ADDR
vax_frame_base_address (struct frame_info *this_frame, void **this_cache)
{
  struct vax_frame_cache *cache = vax_frame_cache (this_frame, this_cache);

  return cache->base;
}

static CORE_ADDR
vax_frame_args_address (struct frame_info *this_frame, void **this_cache)
{
  return get_frame_register_unsigned (this_frame, VAX_AP_REGNUM);
}

static const struct frame_base vax_frame_base =
{
  &vax_frame_unwind,
  vax_frame_base_address,
  vax_frame_base_address,
  vax_frame_args_address
};

/* Return number of arguments for FRAME.  */

static int
vax_frame_num_args (struct frame_info *frame)
{
  CORE_ADDR args;

  /* Assume that the argument pointer for the outermost frame is
     hosed, as is the case on NetBSD/vax ELF.  */
  if (get_frame_base_address (frame) == 0)
    return 0;

  args = get_frame_register_unsigned (frame, VAX_AP_REGNUM);
  return get_frame_memory_unsigned (frame, args, 1);
}

static CORE_ADDR
vax_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  return frame_unwind_register_unsigned (next_frame, VAX_PC_REGNUM);
}


/* Initialize the current architecture based on INFO.  If possible, re-use an
   architecture from ARCHES, which is a list of architectures already created
   during this debugging session.

   Called e.g. at program startup, when reading a core file, and when reading
   a binary file.  */

static struct gdbarch *
vax_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;

  /* If there is already a candidate, use it.  */
  arches = gdbarch_list_lookup_by_info (arches, &info);
  if (arches != NULL)
    return arches->gdbarch;

  gdbarch = gdbarch_alloc (&info, NULL);

  set_gdbarch_float_format (gdbarch, floatformats_vax_f);
  set_gdbarch_double_format (gdbarch, floatformats_vax_d);
  set_gdbarch_long_double_format (gdbarch, floatformats_vax_d);
  set_gdbarch_long_double_bit (gdbarch, 64);

  /* Register info */
  set_gdbarch_num_regs (gdbarch, VAX_NUM_REGS);
  set_gdbarch_register_name (gdbarch, vax_register_name);
  set_gdbarch_register_type (gdbarch, vax_register_type);
  set_gdbarch_sp_regnum (gdbarch, VAX_SP_REGNUM);
  set_gdbarch_pc_regnum (gdbarch, VAX_PC_REGNUM);
  set_gdbarch_ps_regnum (gdbarch, VAX_PS_REGNUM);

  set_gdbarch_iterate_over_regset_sections
    (gdbarch, vax_iterate_over_regset_sections);

  /* Frame and stack info */
  set_gdbarch_skip_prologue (gdbarch, vax_skip_prologue);
  set_gdbarch_frame_num_args (gdbarch, vax_frame_num_args);
  set_gdbarch_frame_args_skip (gdbarch, 4);

  /* Stack grows downward.  */
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);

  /* Return value info */
  set_gdbarch_return_value (gdbarch, vax_return_value);

  /* Call dummy code.  */
  set_gdbarch_push_dummy_call (gdbarch, vax_push_dummy_call);
  set_gdbarch_dummy_id (gdbarch, vax_dummy_id);

  /* Breakpoint info */
  set_gdbarch_breakpoint_from_pc (gdbarch, vax_breakpoint_from_pc);

  /* Misc info */
  set_gdbarch_deprecated_function_start_offset (gdbarch, 2);
  set_gdbarch_believe_pcc_promotion (gdbarch, 1);

  set_gdbarch_print_insn (gdbarch, print_insn_vax);

  set_gdbarch_unwind_pc (gdbarch, vax_unwind_pc);

  frame_base_set_default (gdbarch, &vax_frame_base);

  /* Hook in ABI-specific overrides, if they have been registered.  */
  gdbarch_init_osabi (info, gdbarch);

  frame_unwind_append_unwinder (gdbarch, &vax_frame_unwind);

  return (gdbarch);
}

/* Provide a prototype to silence -Wmissing-prototypes.  */
void _initialize_vax_tdep (void);

void
_initialize_vax_tdep (void)
{
  gdbarch_register (bfd_arch_vax, vax_gdbarch_init, NULL);
}
