/* Target-dependent code for the VAX.

   Copyright (C) 1986-2025 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 "arch-utils.h"
#include "dis-asm.h"
#include "extract-store-integer.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 const char *register_names[] =
  {
    "r0", "r1", "r2",  "r3",  "r4", "r5", "r6", "r7",
    "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc",
    "ps",
  };

  static_assert (VAX_NUM_REGS == ARRAY_SIZE (register_names));
  return register_names[regnum];
}

/* 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 = (const gdb_byte *) gregs;
  int i;

  for (i = 0; i < VAX_NUM_REGS; i++)
    {
      if (regnum == i || regnum == -1)
	regcache->raw_supply (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_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 = regcache->arch ();
  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 = args[i]->enclosing_type ()->length ();

      sp -= (len + 3) & ~3;
      count += (len + 3) / 4;
      write_memory (sp, args[i]->contents_all ().data (), 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 (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,
		     function_call_return_method return_method,
		     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 (return_method == return_method_struct)
    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 (VAX_SP_REGNUM, buf);
  regcache->cooked_write (VAX_FP_REGNUM, buf);

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

static struct frame_id
vax_dummy_id (struct gdbarch *gdbarch, const frame_info_ptr &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 ();
  gdb_byte buf[8];

  if (type->code () == TYPE_CODE_STRUCT
      || type->code () == TYPE_CODE_UNION
      || type->code () == 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 (VAX_R0_REGNUM, buf);
      if (len > 4)
	regcache->cooked_read (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 (VAX_R0_REGNUM, buf);
      if (len > 4)
	regcache->cooked_write (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.  */

constexpr gdb_byte vax_break_insn[] = { 3 };

typedef BP_MANIPULATION (vax_break_insn) vax_breakpoint;

/* 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.  */
  trad_frame_saved_reg *saved_regs;
};

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

  if (*this_cache)
    return (struct vax_frame_cache *) *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].set_addr (cache->base + 16);
  cache->saved_regs[VAX_FP_REGNUM].set_addr (cache->base + 12);
  cache->saved_regs[VAX_AP_REGNUM].set_addr (cache->base + 8);
  cache->saved_regs[VAX_PS_REGNUM].set_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].set_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.  */
  cache->saved_regs[VAX_SP_REGNUM].set_value (addr + (mask >> 14));

  return cache;
}

static void
vax_frame_this_id (const frame_info_ptr &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 (const frame_info_ptr &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_legacy vax_frame_unwind (
  "vax prologue",
  NORMAL_FRAME,
  FRAME_UNWIND_ARCH,
  default_frame_unwind_stop_reason,
  vax_frame_this_id,
  vax_frame_prev_register,
  NULL,
  default_frame_sniffer
);


static CORE_ADDR
vax_frame_base_address (const frame_info_ptr &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 (const frame_info_ptr &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 (const frame_info_ptr &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);
}



/* Initialize the current architecture based on INFO.  If possible, reuse 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_kind_from_pc (gdbarch, vax_breakpoint::kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch, vax_breakpoint::bp_from_kind);

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

  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);
}

INIT_GDB_FILE (vax_tdep)
{
  gdbarch_register (bfd_arch_vax, vax_gdbarch_init, NULL);
}
