/* Print VAX instructions for GDB, the GNU debugger.
   Copyright 1986, 1989, 1991, 1992, 1995, 1996, 1998, 1999, 2000, 2002, 2003
   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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "defs.h"
#include "symtab.h"
#include "opcode/vax.h"
#include "gdbcore.h"
#include "inferior.h"
#include "regcache.h"
#include "frame.h"
#include "value.h"
#include "arch-utils.h"
#include "gdb_string.h"
#include "osabi.h"

#include "vax-tdep.h"

static gdbarch_register_name_ftype vax_register_name;
static gdbarch_register_byte_ftype vax_register_byte;
static gdbarch_register_raw_size_ftype vax_register_raw_size;
static gdbarch_register_virtual_size_ftype vax_register_virtual_size;
static gdbarch_register_virtual_type_ftype vax_register_virtual_type;

static gdbarch_skip_prologue_ftype vax_skip_prologue;
static gdbarch_frame_num_args_ftype vax_frame_num_args;
static gdbarch_deprecated_frame_chain_ftype vax_frame_chain;
static gdbarch_frame_args_address_ftype vax_frame_args_address;
static gdbarch_frame_locals_address_ftype vax_frame_locals_address;

static gdbarch_deprecated_extract_return_value_ftype vax_extract_return_value;
static gdbarch_deprecated_extract_struct_value_address_ftype
    vax_extract_struct_value_address;

static gdbarch_deprecated_push_dummy_frame_ftype vax_push_dummy_frame;
static gdbarch_fix_call_dummy_ftype vax_fix_call_dummy;

/* Return 1 if P points to an invalid floating point value.
   LEN is the length in bytes -- not relevant on the Vax.  */

/* FIXME: cagney/2002-01-19: The macro below was originally defined in
   tm-vax.h and used in values.c.  Two problems.  Firstly this is a
   very non-portable and secondly it is wrong.  The VAX should be
   using floatformat and associated methods to identify and handle
   invalid floating-point values.  Adding to the poor target's woes
   there is no floatformat_vax_{f,d} and no TARGET_FLOAT_FORMAT
   et.al..  */

/* FIXME: cagney/2002-01-19: It turns out that the only thing that
   uses this macro is the vax disassembler code (so how old is this
   target?).  This target should instead be using the opcodes
   disassembler.  That allowing the macro to be eliminated.  */

#define INVALID_FLOAT(p, len) ((*(short *) p & 0xff80) == 0x8000)

/* Vax instructions are never longer than this.  */
#define MAXLEN 62

/* Number of elements in the opcode table.  */
#define NOPCODES (sizeof votstrs / sizeof votstrs[0])

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

  if (regno < 0)
    return (NULL);
  if (regno >= (sizeof(register_names) / sizeof(*register_names)))
    return (NULL);
  return (register_names[regno]);
}

static int
vax_register_byte (int regno)
{
  return (regno * 4);
}

static int
vax_register_raw_size (int regno)
{
  return (4);
}

static int
vax_register_virtual_size (int regno)
{
  return (4);
}

static struct type *
vax_register_virtual_type (int regno)
{
  return (builtin_type_int);
}

static void
vax_frame_init_saved_regs (struct frame_info *frame)
{
  int regnum, regmask;
  CORE_ADDR next_addr;

  if (get_frame_saved_regs (frame))
    return;

  frame_saved_regs_zalloc (frame);

  regmask = read_memory_integer (get_frame_base (frame) + 4, 4) >> 16;

  next_addr = get_frame_base (frame) + 16;

  /* regmask's low bit is for register 0, which is the first one
     what would be pushed.  */
  for (regnum = 0; regnum < VAX_AP_REGNUM; regnum++)
    {
      if (regmask & (1 << regnum))
        get_frame_saved_regs (frame)[regnum] = next_addr += 4;
    }

  get_frame_saved_regs (frame)[SP_REGNUM] = next_addr + 4;
  if (regmask & (1 << FP_REGNUM))
    get_frame_saved_regs (frame)[SP_REGNUM] +=
      4 + (4 * read_memory_integer (next_addr + 4, 4));

  get_frame_saved_regs (frame)[PC_REGNUM] = get_frame_base (frame) + 16;
  get_frame_saved_regs (frame)[FP_REGNUM] = get_frame_base (frame) + 12;
  get_frame_saved_regs (frame)[VAX_AP_REGNUM] = get_frame_base (frame) + 8;
  get_frame_saved_regs (frame)[PS_REGNUM] = get_frame_base (frame) + 4;
}

/* Get saved user PC for sigtramp from sigcontext for BSD style sigtramp.  */

static CORE_ADDR
vax_sigtramp_saved_pc (struct frame_info *frame)
{
  CORE_ADDR sigcontext_addr;
  char *buf;
  int ptrbytes = TYPE_LENGTH (builtin_type_void_func_ptr);
  int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT;

  buf = alloca (ptrbytes);
  /* Get sigcontext address, it is the third parameter on the stack.  */
  if (get_next_frame (frame))
    sigcontext_addr = read_memory_typed_address
      (FRAME_ARGS_ADDRESS (get_next_frame (frame))
       + FRAME_ARGS_SKIP + sigcontext_offs,
       builtin_type_void_data_ptr);
  else
    sigcontext_addr = read_memory_typed_address
      (read_register (SP_REGNUM) + sigcontext_offs, builtin_type_void_data_ptr);

  /* Don't cause a memory_error when accessing sigcontext in case the stack
     layout has changed or the stack is corrupt.  */
  target_read_memory (sigcontext_addr + SIGCONTEXT_PC_OFFSET, buf, ptrbytes);
  return extract_typed_address (buf, builtin_type_void_func_ptr);
}

static CORE_ADDR
vax_frame_saved_pc (struct frame_info *frame)
{
  if ((get_frame_type (frame) == SIGTRAMP_FRAME))
    return (vax_sigtramp_saved_pc (frame)); /* XXXJRT */

  return (read_memory_integer (get_frame_base (frame) + 16, 4));
}

CORE_ADDR
vax_frame_args_address_correct (struct frame_info *frame)
{
  /* Cannot find the AP register value directly from the FP value.  Must
     find it saved in the frame called by this one, or in the AP register
     for the innermost frame.  However, there is no way to tell the
     difference between the innermost frame and a frame for which we
     just don't know the frame that it called (e.g. "info frame 0x7ffec789").
     For the sake of argument, suppose that the stack is somewhat trashed
     (which is one reason that "info frame" exists).  So, return 0 (indicating
     we don't know the address of the arglist) if we don't know what frame
     this frame calls.  */
  if (get_next_frame (frame))
    return (read_memory_integer (get_frame_base (get_next_frame (frame)) + 8, 4));

  return (0);
}

static CORE_ADDR
vax_frame_args_address (struct frame_info *frame)
{
  /* In most of GDB, getting the args address is too important to
     just say "I don't know".  This is sometimes wrong for functions
     that aren't on top of the stack, but c'est la vie.  */
  if (get_next_frame (frame))
    return (read_memory_integer (get_frame_base (get_next_frame (frame)) + 8, 4));

  return (read_register (VAX_AP_REGNUM));
}

static CORE_ADDR
vax_frame_locals_address (struct frame_info *frame)
{
  return (get_frame_base (frame));
}

static int
vax_frame_num_args (struct frame_info *fi)
{
  return (0xff & read_memory_integer (FRAME_ARGS_ADDRESS (fi), 1));
}

static CORE_ADDR
vax_frame_chain (struct frame_info *frame)
{
  /* In the case of the VAX, the frame's nominal address is the FP value,
     and 12 bytes later comes the saved previous FP value as a 4-byte word.  */
  if (inside_entry_file (get_frame_pc (frame)))
    return (0);

  return (read_memory_integer (get_frame_base (frame) + 12, 4));
}

static void
vax_push_dummy_frame (void)
{
  CORE_ADDR sp = read_register (SP_REGNUM);
  int regnum;

  sp = push_word (sp, 0);	/* arglist */
  for (regnum = 11; regnum >= 0; regnum--)
    sp = push_word (sp, read_register (regnum));
  sp = push_word (sp, read_register (PC_REGNUM));
  sp = push_word (sp, read_register (FP_REGNUM));
  sp = push_word (sp, read_register (VAX_AP_REGNUM));
  sp = push_word (sp, (read_register (PS_REGNUM) & 0xffef) + 0x2fff0000);
  sp = push_word (sp, 0);
  write_register (SP_REGNUM, sp);
  write_register (FP_REGNUM, sp);
  write_register (VAX_AP_REGNUM, sp + (17 * 4));
}

static void
vax_pop_frame (void)
{
  CORE_ADDR fp = read_register (FP_REGNUM);
  int regnum;
  int regmask = read_memory_integer (fp + 4, 4);

  write_register (PS_REGNUM,
		  (regmask & 0xffff)
		  | (read_register (PS_REGNUM) & 0xffff0000));
  write_register (PC_REGNUM, read_memory_integer (fp + 16, 4));
  write_register (FP_REGNUM, read_memory_integer (fp + 12, 4));
  write_register (VAX_AP_REGNUM, read_memory_integer (fp + 8, 4));
  fp += 16;
  for (regnum = 0; regnum < 12; regnum++)
    if (regmask & (0x10000 << regnum))
      write_register (regnum, read_memory_integer (fp += 4, 4));
  fp = fp + 4 + ((regmask >> 30) & 3);
  if (regmask & 0x20000000)
    {
      regnum = read_memory_integer (fp, 4);
      fp += (regnum + 1) * 4;
    }
  write_register (SP_REGNUM, fp);
  flush_cached_frames ();
}

/* The VAX call dummy sequence:

	calls #69, @#32323232
	bpt

   It is 8 bytes long.  The address and argc are patched by
   vax_fix_call_dummy().  */
static LONGEST vax_call_dummy_words[] = { 0x329f69fb, 0x03323232 };
static int sizeof_vax_call_dummy_words = sizeof(vax_call_dummy_words);

static void
vax_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
                    struct value **args, struct type *type, int gcc_p)
{
  dummy[1] = nargs;
  store_unsigned_integer (dummy + 3, 4, fun);
}

static void
vax_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
{
  write_register (1, addr);
}

static void
vax_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
{
  memcpy (valbuf, regbuf + REGISTER_BYTE (0), TYPE_LENGTH (valtype));
}

static void
vax_store_return_value (struct type *valtype, char *valbuf)
{
  deprecated_write_register_bytes (0, valbuf, TYPE_LENGTH (valtype));
}

static CORE_ADDR
vax_extract_struct_value_address (char *regbuf)
{
  return (extract_address (regbuf + REGISTER_BYTE (0), REGISTER_RAW_SIZE (0)));
}

static const unsigned char *
vax_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
{
  static const unsigned char vax_breakpoint[] = { 3 };

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

static CORE_ADDR
vax_skip_prologue (CORE_ADDR pc)
{
  register int op = (unsigned char) read_memory_integer (pc, 1);
  if (op == 0x11)
    pc += 2;			/* skip brb */
  if (op == 0x31)
    pc += 3;			/* skip brw */
  if (op == 0xC2
      && ((unsigned char) read_memory_integer (pc + 2, 1)) == 0x5E)
    pc += 3;			/* skip subl2 */
  if (op == 0x9E
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xAE
      && ((unsigned char) read_memory_integer (pc + 3, 1)) == 0x5E)
    pc += 4;			/* skip movab */
  if (op == 0x9E
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xCE
      && ((unsigned char) read_memory_integer (pc + 4, 1)) == 0x5E)
    pc += 5;			/* skip movab */
  if (op == 0x9E
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xEE
      && ((unsigned char) read_memory_integer (pc + 6, 1)) == 0x5E)
    pc += 7;			/* skip movab */
  return pc;
}

static CORE_ADDR
vax_saved_pc_after_call (struct frame_info *frame)
{
  return (DEPRECATED_FRAME_SAVED_PC(frame));
}

/* Print the vax instruction at address MEMADDR in debugged memory,
   from disassembler info INFO.
   Returns length of the instruction, in bytes.  */

static int
vax_print_insn (CORE_ADDR memaddr, disassemble_info *info)
{
  unsigned char buffer[MAXLEN];
  register int i;
  register unsigned char *p;
  const char *d;

  int status = (*info->read_memory_func) (memaddr, buffer, MAXLEN, info);
  if (status != 0)
    {
      (*info->memory_error_func) (status, memaddr, info);
      return -1;
    }

  for (i = 0; i < NOPCODES; i++)
    if (votstrs[i].detail.code == buffer[0]
	|| votstrs[i].detail.code == *(unsigned short *) buffer)
      break;

  /* Handle undefined instructions.  */
  if (i == NOPCODES)
    {
      (*info->fprintf_func) (info->stream, "0%o", buffer[0]);
      return 1;
    }

  (*info->fprintf_func) (info->stream, "%s", votstrs[i].name);

  /* Point at first byte of argument data,
     and at descriptor for first argument.  */
  p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
  d = votstrs[i].detail.args;

  if (*d)
    (*info->fprintf_func) (info->stream, " ");

  while (*d)
    {
      p = print_insn_arg (d, p, memaddr + (p - buffer), info);
      d += 2;
      if (*d)
	(*info->fprintf_func) (info->stream, ",");
    }
  return p - buffer;
}

static unsigned char *
print_insn_arg (char *d, register char *p, CORE_ADDR addr,
		disassemble_info *info)
{
  register int regnum = *p & 0xf;
  float floatlitbuf;

  if (*d == 'b')
    {
      if (d[1] == 'b')
	(*info->fprintf_func) (info->stream, "0x%x", addr + *p++ + 1);
      else
	{
	  (*info->fprintf_func) (info->stream, "0x%x", addr + *(short *) p + 2);
	  p += 2;
	}
    }
  else
    switch ((*p++ >> 4) & 0xf)
      {
      case 0:
      case 1:
      case 2:
      case 3:			/* Literal mode */
	if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
	  {
	    *(int *) &floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
	    (*info->fprintf_func) (info->stream, "$%f", floatlitbuf);
	  }
	else
	  (*info->fprintf_func) (info->stream, "$%d", p[-1] & 0x3f);
	break;

      case 4:			/* Indexed */
	p = (char *) print_insn_arg (d, p, addr + 1, info);
	(*info->fprintf_func) (info->stream, "[%s]", REGISTER_NAME (regnum));
	break;

      case 5:			/* Register */
	(*info->fprintf_func) (info->stream, REGISTER_NAME (regnum));
	break;

      case 7:			/* Autodecrement */
	(*info->fprintf_func) (info->stream, "-");
      case 6:			/* Register deferred */
	(*info->fprintf_func) (info->stream, "(%s)", REGISTER_NAME (regnum));
	break;

      case 9:			/* Autoincrement deferred */
	(*info->fprintf_func) (info->stream, "@");
	if (regnum == PC_REGNUM)
	  {
	    (*info->fprintf_func) (info->stream, "#");
	    info->target = *(long *) p;
	    (*info->print_address_func) (info->target, info);
	    p += 4;
	    break;
	  }
      case 8:			/* Autoincrement */
	if (regnum == PC_REGNUM)
	  {
	    (*info->fprintf_func) (info->stream, "#");
	    switch (d[1])
	      {
	      case 'b':
		(*info->fprintf_func) (info->stream, "%d", *p++);
		break;

	      case 'w':
		(*info->fprintf_func) (info->stream, "%d", *(short *) p);
		p += 2;
		break;

	      case 'l':
		(*info->fprintf_func) (info->stream, "%d", *(long *) p);
		p += 4;
		break;

	      case 'q':
		(*info->fprintf_func) (info->stream, "0x%x%08x",
				       ((long *) p)[1], ((long *) p)[0]);
		p += 8;
		break;

	      case 'o':
		(*info->fprintf_func) (info->stream, "0x%x%08x%08x%08x",
				       ((long *) p)[3], ((long *) p)[2],
				       ((long *) p)[1], ((long *) p)[0]);
		p += 16;
		break;

	      case 'f':
		if (INVALID_FLOAT (p, 4))
		  (*info->fprintf_func) (info->stream,
					 "<<invalid float 0x%x>>",
					 *(int *) p);
		else
		  (*info->fprintf_func) (info->stream, "%f", *(float *) p);
		p += 4;
		break;

	      case 'd':
		if (INVALID_FLOAT (p, 8))
		  (*info->fprintf_func) (info->stream,
					 "<<invalid float 0x%x%08x>>",
					 ((long *) p)[1], ((long *) p)[0]);
		else
		  (*info->fprintf_func) (info->stream, "%f", *(double *) p);
		p += 8;
		break;

	      case 'g':
		(*info->fprintf_func) (info->stream, "g-float");
		p += 8;
		break;

	      case 'h':
		(*info->fprintf_func) (info->stream, "h-float");
		p += 16;
		break;

	      }
	  }
	else
	  (*info->fprintf_func) (info->stream, "(%s)+", REGISTER_NAME (regnum));
	break;

      case 11:			/* Byte displacement deferred */
	(*info->fprintf_func) (info->stream, "@");
      case 10:			/* Byte displacement */
	if (regnum == PC_REGNUM)
	  {
	    info->target = addr + *p + 2;
	    (*info->print_address_func) (info->target, info);
	  }
	else
	  (*info->fprintf_func) (info->stream, "%d(%s)", *p, REGISTER_NAME (regnum));
	p += 1;
	break;

      case 13:			/* Word displacement deferred */
	(*info->fprintf_func) (info->stream, "@");
      case 12:			/* Word displacement */
	if (regnum == PC_REGNUM)
	  {
	    info->target = addr + *(short *) p + 3;
	    (*info->print_address_func) (info->target, info);
	  }
	else
	  (*info->fprintf_func) (info->stream, "%d(%s)",
				 *(short *) p, REGISTER_NAME (regnum));
	p += 2;
	break;

      case 15:			/* Long displacement deferred */
	(*info->fprintf_func) (info->stream, "@");
      case 14:			/* Long displacement */
	if (regnum == PC_REGNUM)
	  {
	    info->target = addr + *(short *) p + 5;
	    (*info->print_address_func) (info->target, info);
	  }
	else
	  (*info->fprintf_func) (info->stream, "%d(%s)",
				 *(long *) p, REGISTER_NAME (regnum));
	p += 4;
      }

  return (unsigned char *) p;
}

/* 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);

  /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
     ready to unwind the PC first (see frame.c:get_prev_frame()).  */
  set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_default);

  /* Register info */
  set_gdbarch_num_regs (gdbarch, VAX_NUM_REGS);
  set_gdbarch_sp_regnum (gdbarch, VAX_SP_REGNUM);
  set_gdbarch_fp_regnum (gdbarch, VAX_FP_REGNUM);
  set_gdbarch_pc_regnum (gdbarch, VAX_PC_REGNUM);
  set_gdbarch_ps_regnum (gdbarch, VAX_PS_REGNUM);

  set_gdbarch_register_name (gdbarch, vax_register_name);
  set_gdbarch_register_size (gdbarch, VAX_REGISTER_SIZE);
  set_gdbarch_register_bytes (gdbarch, VAX_REGISTER_BYTES);
  set_gdbarch_register_byte (gdbarch, vax_register_byte);
  set_gdbarch_register_raw_size (gdbarch, vax_register_raw_size);
  set_gdbarch_deprecated_max_register_raw_size (gdbarch, VAX_MAX_REGISTER_RAW_SIZE);
  set_gdbarch_register_virtual_size (gdbarch, vax_register_virtual_size);
  set_gdbarch_deprecated_max_register_virtual_size (gdbarch,
                                         VAX_MAX_REGISTER_VIRTUAL_SIZE);
  set_gdbarch_register_virtual_type (gdbarch, vax_register_virtual_type);

  /* Frame and stack info */
  set_gdbarch_skip_prologue (gdbarch, vax_skip_prologue);
  set_gdbarch_deprecated_saved_pc_after_call (gdbarch, vax_saved_pc_after_call);

  set_gdbarch_frame_num_args (gdbarch, vax_frame_num_args);
  set_gdbarch_frameless_function_invocation (gdbarch,
				   generic_frameless_function_invocation_not);

  set_gdbarch_deprecated_frame_chain (gdbarch, vax_frame_chain);
  set_gdbarch_deprecated_frame_saved_pc (gdbarch, vax_frame_saved_pc);

  set_gdbarch_frame_args_address (gdbarch, vax_frame_args_address);
  set_gdbarch_frame_locals_address (gdbarch, vax_frame_locals_address);

  set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, vax_frame_init_saved_regs);

  set_gdbarch_frame_args_skip (gdbarch, 4);

  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);

  /* Return value info */
  set_gdbarch_deprecated_store_struct_return (gdbarch, vax_store_struct_return);
  set_gdbarch_deprecated_extract_return_value (gdbarch, vax_extract_return_value);
  set_gdbarch_deprecated_store_return_value (gdbarch, vax_store_return_value);
  set_gdbarch_deprecated_extract_struct_value_address (gdbarch, vax_extract_struct_value_address);

  /* Call dummy info */
  set_gdbarch_deprecated_push_dummy_frame (gdbarch, vax_push_dummy_frame);
  set_gdbarch_deprecated_pop_frame (gdbarch, vax_pop_frame);
  set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
  set_gdbarch_call_dummy_words (gdbarch, vax_call_dummy_words);
  set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof_vax_call_dummy_words);
  set_gdbarch_fix_call_dummy (gdbarch, vax_fix_call_dummy);
  set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 7);
  set_gdbarch_deprecated_use_generic_dummy_frames (gdbarch, 0);
  set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_on_stack);

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

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

  /* Should be using push_dummy_call.  */
  set_gdbarch_deprecated_dummy_write_sp (gdbarch, generic_target_write_sp);

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

  return (gdbarch);
}

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

  tm_print_insn = vax_print_insn;
}
