/* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger.

   Copyright (C) 1993-2013 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 "doublest.h"
#include "frame.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "dwarf2-frame.h"
#include "inferior.h"
#include "symtab.h"
#include "value.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "dis-asm.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdb_string.h"
#include "linespec.h"
#include "regcache.h"
#include "reggroups.h"
#include "arch-utils.h"
#include "osabi.h"
#include "block.h"
#include "infcall.h"
#include "trad-frame.h"

#include "elf-bfd.h"

#include "alpha-tdep.h"

/* Instruction decoding.  The notations for registers, immediates and
   opcodes are the same as the one used in Compaq's Alpha architecture
   handbook.  */

#define INSN_OPCODE(insn) ((insn & 0xfc000000) >> 26)

/* Memory instruction format */
#define MEM_RA(insn) ((insn & 0x03e00000) >> 21)
#define MEM_RB(insn) ((insn & 0x001f0000) >> 16)
#define MEM_DISP(insn) \
  (((insn & 0x8000) == 0) ? (insn & 0xffff) : -((-insn) & 0xffff))

static const int lda_opcode = 0x08;
static const int stq_opcode = 0x2d;

/* Branch instruction format */
#define BR_RA(insn) MEM_RA(insn)

static const int br_opcode = 0x30;
static const int bne_opcode = 0x3d;

/* Operate instruction format */
#define OPR_FUNCTION(insn) ((insn & 0xfe0) >> 5)
#define OPR_HAS_IMMEDIATE(insn) ((insn & 0x1000) == 0x1000)
#define OPR_RA(insn) MEM_RA(insn)
#define OPR_RC(insn) ((insn & 0x1f))
#define OPR_LIT(insn) ((insn & 0x1fe000) >> 13)

static const int subq_opcode = 0x10;
static const int subq_function = 0x29;


/* Return the name of the REGNO register.

   An empty name corresponds to a register number that used to
   be used for a virtual register.  That virtual register has
   been removed, but the index is still reserved to maintain
   compatibility with existing remote alpha targets.  */

static const char *
alpha_register_name (struct gdbarch *gdbarch, int regno)
{
  static const char * const register_names[] =
  {
    "v0",   "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",
    "t7",   "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "fp",
    "a0",   "a1",   "a2",   "a3",   "a4",   "a5",   "t8",   "t9",
    "t10",  "t11",  "ra",   "t12",  "at",   "gp",   "sp",   "zero",
    "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7",
    "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15",
    "f16",  "f17",  "f18",  "f19",  "f20",  "f21",  "f22",  "f23",
    "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "fpcr",
    "pc",   "",     "unique"
  };

  if (regno < 0)
    return NULL;
  if (regno >= ARRAY_SIZE(register_names))
    return NULL;
  return register_names[regno];
}

static int
alpha_cannot_fetch_register (struct gdbarch *gdbarch, int regno)
{
  return (strlen (alpha_register_name (gdbarch, regno)) == 0);
}

static int
alpha_cannot_store_register (struct gdbarch *gdbarch, int regno)
{
  return (regno == ALPHA_ZERO_REGNUM
          || strlen (alpha_register_name (gdbarch, regno)) == 0);
}

static struct type *
alpha_register_type (struct gdbarch *gdbarch, int regno)
{
  if (regno == ALPHA_SP_REGNUM || regno == ALPHA_GP_REGNUM)
    return builtin_type (gdbarch)->builtin_data_ptr;
  if (regno == ALPHA_PC_REGNUM)
    return builtin_type (gdbarch)->builtin_func_ptr;

  /* Don't need to worry about little vs big endian until 
     some jerk tries to port to alpha-unicosmk.  */
  if (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31)
    return builtin_type (gdbarch)->builtin_double;

  return builtin_type (gdbarch)->builtin_int64;
}

/* Is REGNUM a member of REGGROUP?  */

static int
alpha_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
			   struct reggroup *group)
{
  /* Filter out any registers eliminated, but whose regnum is 
     reserved for backward compatibility, e.g. the vfp.  */
  if (gdbarch_register_name (gdbarch, regnum) == NULL
      || *gdbarch_register_name (gdbarch, regnum) == '\0')
    return 0;

  if (group == all_reggroup)
    return 1;

  /* Zero should not be saved or restored.  Technically it is a general
     register (just as $f31 would be a float if we represented it), but
     there's no point displaying it during "info regs", so leave it out
     of all groups except for "all".  */
  if (regnum == ALPHA_ZERO_REGNUM)
    return 0;

  /* All other registers are saved and restored.  */
  if (group == save_reggroup || group == restore_reggroup)
    return 1;

  /* All other groups are non-overlapping.  */

  /* Since this is really a PALcode memory slot...  */
  if (regnum == ALPHA_UNIQUE_REGNUM)
    return group == system_reggroup;

  /* Force the FPCR to be considered part of the floating point state.  */
  if (regnum == ALPHA_FPCR_REGNUM)
    return group == float_reggroup;

  if (regnum >= ALPHA_FP0_REGNUM && regnum < ALPHA_FP0_REGNUM + 31)
    return group == float_reggroup;
  else
    return group == general_reggroup;
}

/* The following represents exactly the conversion performed by
   the LDS instruction.  This applies to both single-precision
   floating point and 32-bit integers.  */

static void
alpha_lds (struct gdbarch *gdbarch, void *out, const void *in)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  ULONGEST mem     = extract_unsigned_integer (in, 4, byte_order);
  ULONGEST frac    = (mem >>  0) & 0x7fffff;
  ULONGEST sign    = (mem >> 31) & 1;
  ULONGEST exp_msb = (mem >> 30) & 1;
  ULONGEST exp_low = (mem >> 23) & 0x7f;
  ULONGEST exp, reg;

  exp = (exp_msb << 10) | exp_low;
  if (exp_msb)
    {
      if (exp_low == 0x7f)
	exp = 0x7ff;
    }
  else
    {
      if (exp_low != 0x00)
	exp |= 0x380;
    }

  reg = (sign << 63) | (exp << 52) | (frac << 29);
  store_unsigned_integer (out, 8, byte_order, reg);
}

/* Similarly, this represents exactly the conversion performed by
   the STS instruction.  */

static void
alpha_sts (struct gdbarch *gdbarch, void *out, const void *in)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  ULONGEST reg, mem;

  reg = extract_unsigned_integer (in, 8, byte_order);
  mem = ((reg >> 32) & 0xc0000000) | ((reg >> 29) & 0x3fffffff);
  store_unsigned_integer (out, 4, byte_order, mem);
}

/* The alpha needs a conversion between register and memory format if the
   register is a floating point register and memory format is float, as the
   register format must be double or memory format is an integer with 4
   bytes or less, as the representation of integers in floating point
   registers is different.  */

static int
alpha_convert_register_p (struct gdbarch *gdbarch, int regno,
			  struct type *type)
{
  return (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31
	  && TYPE_LENGTH (type) != 8);
}

static int
alpha_register_to_value (struct frame_info *frame, int regnum,
			 struct type *valtype, gdb_byte *out,
			int *optimizedp, int *unavailablep)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  gdb_byte in[MAX_REGISTER_SIZE];

  /* Convert to TYPE.  */
  if (!get_frame_register_bytes (frame, regnum, 0,
				 register_size (gdbarch, regnum),
				 in, optimizedp, unavailablep))
    return 0;

  if (TYPE_LENGTH (valtype) == 4)
    {
      alpha_sts (gdbarch, out, in);
      *optimizedp = *unavailablep = 0;
      return 1;
    }

  error (_("Cannot retrieve value from floating point register"));
}

static void
alpha_value_to_register (struct frame_info *frame, int regnum,
			 struct type *valtype, const gdb_byte *in)
{
  gdb_byte out[MAX_REGISTER_SIZE];

  switch (TYPE_LENGTH (valtype))
    {
    case 4:
      alpha_lds (get_frame_arch (frame), out, in);
      break;
    default:
      error (_("Cannot store value in floating point register"));
    }
  put_frame_register (frame, regnum, out);
}


/* The alpha passes the first six arguments in the registers, the rest on
   the stack.  The register arguments are stored in ARG_REG_BUFFER, and
   then moved into the register file; this simplifies the passing of a
   large struct which extends from the registers to the stack, plus avoids
   three ptrace invocations per word.

   We don't bother tracking which register values should go in integer
   regs or fp regs; we load the same values into both.

   If the called function is returning a structure, the address of the
   structure to be returned is passed as a hidden first argument.  */

static CORE_ADDR
alpha_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);
  int i;
  int accumulate_size = struct_return ? 8 : 0;
  struct alpha_arg
    {
      const gdb_byte *contents;
      int len;
      int offset;
    };
  struct alpha_arg *alpha_args
    = (struct alpha_arg *) alloca (nargs * sizeof (struct alpha_arg));
  struct alpha_arg *m_arg;
  gdb_byte arg_reg_buffer[ALPHA_REGISTER_SIZE * ALPHA_NUM_ARG_REGS];
  int required_arg_regs;
  CORE_ADDR func_addr = find_function_addr (function, NULL);

  /* The ABI places the address of the called function in T12.  */
  regcache_cooked_write_signed (regcache, ALPHA_T12_REGNUM, func_addr);

  /* Set the return address register to point to the entry point
     of the program, where a breakpoint lies in wait.  */
  regcache_cooked_write_signed (regcache, ALPHA_RA_REGNUM, bp_addr);

  /* Lay out the arguments in memory.  */
  for (i = 0, m_arg = alpha_args; i < nargs; i++, m_arg++)
    {
      struct value *arg = args[i];
      struct type *arg_type = check_typedef (value_type (arg));

      /* Cast argument to long if necessary as the compiler does it too.  */
      switch (TYPE_CODE (arg_type))
	{
	case TYPE_CODE_INT:
	case TYPE_CODE_BOOL:
	case TYPE_CODE_CHAR:
	case TYPE_CODE_RANGE:
	case TYPE_CODE_ENUM:
	  if (TYPE_LENGTH (arg_type) == 4)
	    {
	      /* 32-bit values must be sign-extended to 64 bits
		 even if the base data type is unsigned.  */
	      arg_type = builtin_type (gdbarch)->builtin_int32;
	      arg = value_cast (arg_type, arg);
	    }
	  if (TYPE_LENGTH (arg_type) < ALPHA_REGISTER_SIZE)
	    {
	      arg_type = builtin_type (gdbarch)->builtin_int64;
	      arg = value_cast (arg_type, arg);
	    }
	  break;

	case TYPE_CODE_FLT:
	  /* "float" arguments loaded in registers must be passed in
	     register format, aka "double".  */
	  if (accumulate_size < sizeof (arg_reg_buffer)
	      && TYPE_LENGTH (arg_type) == 4)
	    {
	      arg_type = builtin_type (gdbarch)->builtin_double;
	      arg = value_cast (arg_type, arg);
	    }
	  /* Tru64 5.1 has a 128-bit long double, and passes this by
	     invisible reference.  No one else uses this data type.  */
	  else if (TYPE_LENGTH (arg_type) == 16)
	    {
	      /* Allocate aligned storage.  */
	      sp = (sp & -16) - 16;

	      /* Write the real data into the stack.  */
	      write_memory (sp, value_contents (arg), 16);

	      /* Construct the indirection.  */
	      arg_type = lookup_pointer_type (arg_type);
	      arg = value_from_pointer (arg_type, sp);
	    }
	  break;

	case TYPE_CODE_COMPLEX:
	  /* ??? The ABI says that complex values are passed as two
	     separate scalar values.  This distinction only matters
	     for complex float.  However, GCC does not implement this.  */

	  /* Tru64 5.1 has a 128-bit long double, and passes this by
	     invisible reference.  */
	  if (TYPE_LENGTH (arg_type) == 32)
	    {
	      /* Allocate aligned storage.  */
	      sp = (sp & -16) - 16;

	      /* Write the real data into the stack.  */
	      write_memory (sp, value_contents (arg), 32);

	      /* Construct the indirection.  */
	      arg_type = lookup_pointer_type (arg_type);
	      arg = value_from_pointer (arg_type, sp);
	    }
	  break;

	default:
	  break;
	}
      m_arg->len = TYPE_LENGTH (arg_type);
      m_arg->offset = accumulate_size;
      accumulate_size = (accumulate_size + m_arg->len + 7) & ~7;
      m_arg->contents = value_contents (arg);
    }

  /* Determine required argument register loads, loading an argument register
     is expensive as it uses three ptrace calls.  */
  required_arg_regs = accumulate_size / 8;
  if (required_arg_regs > ALPHA_NUM_ARG_REGS)
    required_arg_regs = ALPHA_NUM_ARG_REGS;

  /* Make room for the arguments on the stack.  */
  if (accumulate_size < sizeof(arg_reg_buffer))
    accumulate_size = 0;
  else
    accumulate_size -= sizeof(arg_reg_buffer);
  sp -= accumulate_size;

  /* Keep sp aligned to a multiple of 16 as the ABI requires.  */
  sp &= ~15;

  /* `Push' arguments on the stack.  */
  for (i = nargs; m_arg--, --i >= 0;)
    {
      const gdb_byte *contents = m_arg->contents;
      int offset = m_arg->offset;
      int len = m_arg->len;

      /* Copy the bytes destined for registers into arg_reg_buffer.  */
      if (offset < sizeof(arg_reg_buffer))
	{
	  if (offset + len <= sizeof(arg_reg_buffer))
	    {
	      memcpy (arg_reg_buffer + offset, contents, len);
	      continue;
	    }
	  else
	    {
	      int tlen = sizeof(arg_reg_buffer) - offset;
	      memcpy (arg_reg_buffer + offset, contents, tlen);
	      offset += tlen;
	      contents += tlen;
	      len -= tlen;
	    }
	}

      /* Everything else goes to the stack.  */
      write_memory (sp + offset - sizeof(arg_reg_buffer), contents, len);
    }
  if (struct_return)
    store_unsigned_integer (arg_reg_buffer, ALPHA_REGISTER_SIZE,
			    byte_order, struct_addr);

  /* Load the argument registers.  */
  for (i = 0; i < required_arg_regs; i++)
    {
      regcache_cooked_write (regcache, ALPHA_A0_REGNUM + i,
			     arg_reg_buffer + i*ALPHA_REGISTER_SIZE);
      regcache_cooked_write (regcache, ALPHA_FPA0_REGNUM + i,
			     arg_reg_buffer + i*ALPHA_REGISTER_SIZE);
    }

  /* Finally, update the stack pointer.  */
  regcache_cooked_write_signed (regcache, ALPHA_SP_REGNUM, sp);

  return sp;
}

/* Extract from REGCACHE the value about to be returned from a function
   and copy it into VALBUF.  */

static void
alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
			    gdb_byte *valbuf)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte raw_buffer[ALPHA_REGISTER_SIZE];
  ULONGEST l;

  switch (TYPE_CODE (valtype))
    {
    case TYPE_CODE_FLT:
      switch (TYPE_LENGTH (valtype))
	{
	case 4:
	  regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, raw_buffer);
	  alpha_sts (gdbarch, valbuf, raw_buffer);
	  break;

	case 8:
	  regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf);
	  break;

	case 16:
	  regcache_cooked_read_unsigned (regcache, ALPHA_V0_REGNUM, &l);
	  read_memory (l, valbuf, 16);
	  break;

	default:
	  internal_error (__FILE__, __LINE__,
			  _("unknown floating point width"));
	}
      break;

    case TYPE_CODE_COMPLEX:
      switch (TYPE_LENGTH (valtype))
	{
	case 8:
	  /* ??? This isn't correct wrt the ABI, but it's what GCC does.  */
	  regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf);
	  break;

	case 16:
	  regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf);
	  regcache_cooked_read (regcache, ALPHA_FP0_REGNUM + 1, valbuf + 8);
	  break;

	case 32:
	  regcache_cooked_read_unsigned (regcache, ALPHA_V0_REGNUM, &l);
	  read_memory (l, valbuf, 32);
	  break;

	default:
	  internal_error (__FILE__, __LINE__,
			  _("unknown floating point width"));
	}
      break;

    default:
      /* Assume everything else degenerates to an integer.  */
      regcache_cooked_read_unsigned (regcache, ALPHA_V0_REGNUM, &l);
      store_unsigned_integer (valbuf, TYPE_LENGTH (valtype), byte_order, l);
      break;
    }
}

/* Insert the given value into REGCACHE as if it was being 
   returned by a function.  */

static void
alpha_store_return_value (struct type *valtype, struct regcache *regcache,
			  const gdb_byte *valbuf)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  gdb_byte raw_buffer[ALPHA_REGISTER_SIZE];
  ULONGEST l;

  switch (TYPE_CODE (valtype))
    {
    case TYPE_CODE_FLT:
      switch (TYPE_LENGTH (valtype))
	{
	case 4:
	  alpha_lds (gdbarch, raw_buffer, valbuf);
	  regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, raw_buffer);
	  break;

	case 8:
	  regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf);
	  break;

	case 16:
	  /* FIXME: 128-bit long doubles are returned like structures:
	     by writing into indirect storage provided by the caller
	     as the first argument.  */
	  error (_("Cannot set a 128-bit long double return value."));

	default:
	  internal_error (__FILE__, __LINE__,
			  _("unknown floating point width"));
	}
      break;

    case TYPE_CODE_COMPLEX:
      switch (TYPE_LENGTH (valtype))
	{
	case 8:
	  /* ??? This isn't correct wrt the ABI, but it's what GCC does.  */
	  regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf);
	  break;

	case 16:
	  regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf);
	  regcache_cooked_write (regcache, ALPHA_FP0_REGNUM + 1, valbuf + 8);
	  break;

	case 32:
	  /* FIXME: 128-bit long doubles are returned like structures:
	     by writing into indirect storage provided by the caller
	     as the first argument.  */
	  error (_("Cannot set a 128-bit long double return value."));

	default:
	  internal_error (__FILE__, __LINE__,
			  _("unknown floating point width"));
	}
      break;

    default:
      /* Assume everything else degenerates to an integer.  */
      /* 32-bit values must be sign-extended to 64 bits
	 even if the base data type is unsigned.  */
      if (TYPE_LENGTH (valtype) == 4)
	valtype = builtin_type (gdbarch)->builtin_int32;
      l = unpack_long (valtype, valbuf);
      regcache_cooked_write_unsigned (regcache, ALPHA_V0_REGNUM, l);
      break;
    }
}

static enum return_value_convention
alpha_return_value (struct gdbarch *gdbarch, struct value *function,
		    struct type *type, struct regcache *regcache,
		    gdb_byte *readbuf, const gdb_byte *writebuf)
{
  enum type_code code = TYPE_CODE (type);

  if ((code == TYPE_CODE_STRUCT
       || code == TYPE_CODE_UNION
       || code == TYPE_CODE_ARRAY)
      && gdbarch_tdep (gdbarch)->return_in_memory (type))
    {
      if (readbuf)
	{
	  ULONGEST addr;
	  regcache_raw_read_unsigned (regcache, ALPHA_V0_REGNUM, &addr);
	  read_memory (addr, readbuf, TYPE_LENGTH (type));
	}

      return RETURN_VALUE_ABI_RETURNS_ADDRESS;
    }

  if (readbuf)
    alpha_extract_return_value (type, regcache, readbuf);
  if (writebuf)
    alpha_store_return_value (type, regcache, writebuf);

  return RETURN_VALUE_REGISTER_CONVENTION;
}

static int
alpha_return_in_memory_always (struct type *type)
{
  return 1;
}

static const gdb_byte *
alpha_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len)
{
  static const gdb_byte break_insn[] = { 0x80, 0, 0, 0 }; /* call_pal bpt */

  *len = sizeof(break_insn);
  return break_insn;
}


/* This returns the PC of the first insn after the prologue.
   If we can't find the prologue, then return 0.  */

CORE_ADDR
alpha_after_prologue (CORE_ADDR pc)
{
  struct symtab_and_line sal;
  CORE_ADDR func_addr, func_end;

  if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
    return 0;

  sal = find_pc_line (func_addr, 0);
  if (sal.end < func_end)
    return sal.end;

  /* The line after the prologue is after the end of the function.  In this
     case, tell the caller to find the prologue the hard way.  */
  return 0;
}

/* Read an instruction from memory at PC, looking through breakpoints.  */

unsigned int
alpha_read_insn (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte buf[ALPHA_INSN_SIZE];
  int status;

  status = target_read_memory (pc, buf, sizeof (buf));
  if (status)
    memory_error (status, pc);
  return extract_unsigned_integer (buf, sizeof (buf), byte_order);
}

/* To skip prologues, I use this predicate.  Returns either PC itself
   if the code at PC does not look like a function prologue; otherwise
   returns an address that (if we're lucky) follows the prologue.  If
   LENIENT, then we must skip everything which is involved in setting
   up the frame (it's OK to skip more, just so long as we don't skip
   anything which might clobber the registers which are being saved.  */

static CORE_ADDR
alpha_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  unsigned long inst;
  int offset;
  CORE_ADDR post_prologue_pc;
  gdb_byte buf[ALPHA_INSN_SIZE];

  /* Silently return the unaltered pc upon memory errors.
     This could happen on OSF/1 if decode_line_1 tries to skip the
     prologue for quickstarted shared library functions when the
     shared library is not yet mapped in.
     Reading target memory is slow over serial lines, so we perform
     this check only if the target has shared libraries (which all
     Alpha targets do).  */
  if (target_read_memory (pc, buf, sizeof (buf)))
    return pc;

  /* See if we can determine the end of the prologue via the symbol table.
     If so, then return either PC, or the PC after the prologue, whichever
     is greater.  */

  post_prologue_pc = alpha_after_prologue (pc);
  if (post_prologue_pc != 0)
    return max (pc, post_prologue_pc);

  /* Can't determine prologue from the symbol table, need to examine
     instructions.  */

  /* Skip the typical prologue instructions.  These are the stack adjustment
     instruction and the instructions that save registers on the stack
     or in the gcc frame.  */
  for (offset = 0; offset < 100; offset += ALPHA_INSN_SIZE)
    {
      inst = alpha_read_insn (gdbarch, pc + offset);

      if ((inst & 0xffff0000) == 0x27bb0000)	/* ldah $gp,n($t12) */
	continue;
      if ((inst & 0xffff0000) == 0x23bd0000)	/* lda $gp,n($gp) */
	continue;
      if ((inst & 0xffff0000) == 0x23de0000)	/* lda $sp,n($sp) */
	continue;
      if ((inst & 0xffe01fff) == 0x43c0153e)	/* subq $sp,n,$sp */
	continue;

      if (((inst & 0xfc1f0000) == 0xb41e0000		/* stq reg,n($sp) */
	   || (inst & 0xfc1f0000) == 0x9c1e0000)	/* stt reg,n($sp) */
	  && (inst & 0x03e00000) != 0x03e00000)		/* reg != $zero */
	continue;

      if (inst == 0x47de040f)			/* bis sp,sp,fp */
	continue;
      if (inst == 0x47fe040f)			/* bis zero,sp,fp */
	continue;

      break;
    }
  return pc + offset;
}


static const int ldl_l_opcode = 0x2a;
static const int ldq_l_opcode = 0x2b;
static const int stl_c_opcode = 0x2e;
static const int stq_c_opcode = 0x2f;

/* Checks for an atomic sequence of instructions beginning with a LDL_L/LDQ_L
   instruction and ending with a STL_C/STQ_C instruction.  If such a sequence
   is found, attempt to step through it.  A breakpoint is placed at the end of 
   the sequence.  */

static int 
alpha_deal_with_atomic_sequence (struct frame_info *frame)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct address_space *aspace = get_frame_address_space (frame);
  CORE_ADDR pc = get_frame_pc (frame);
  CORE_ADDR breaks[2] = {-1, -1};
  CORE_ADDR loc = pc;
  CORE_ADDR closing_insn; /* Instruction that closes the atomic sequence.  */
  unsigned int insn = alpha_read_insn (gdbarch, loc);
  int insn_count;
  int index;
  int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */  
  const int atomic_sequence_length = 16; /* Instruction sequence length.  */
  int bc_insn_count = 0; /* Conditional branch instruction count.  */

  /* Assume all atomic sequences start with a LDL_L/LDQ_L instruction.  */
  if (INSN_OPCODE (insn) != ldl_l_opcode
      && INSN_OPCODE (insn) != ldq_l_opcode)
    return 0;

  /* Assume that no atomic sequence is longer than "atomic_sequence_length" 
     instructions.  */
  for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
    {
      loc += ALPHA_INSN_SIZE;
      insn = alpha_read_insn (gdbarch, loc);

      /* Assume that there is at most one branch in the atomic
	 sequence.  If a branch is found, put a breakpoint in 
	 its destination address.  */
      if (INSN_OPCODE (insn) >= br_opcode)
	{
	  int immediate = (insn & 0x001fffff) << 2;

	  immediate = (immediate ^ 0x400000) - 0x400000;

	  if (bc_insn_count >= 1)
	    return 0; /* More than one branch found, fallback 
			 to the standard single-step code.  */

	  breaks[1] = loc + ALPHA_INSN_SIZE + immediate;

	  bc_insn_count++;
	  last_breakpoint++;
	}

      if (INSN_OPCODE (insn) == stl_c_opcode
	  || INSN_OPCODE (insn) == stq_c_opcode)
	break;
    }

  /* Assume that the atomic sequence ends with a STL_C/STQ_C instruction.  */
  if (INSN_OPCODE (insn) != stl_c_opcode
      && INSN_OPCODE (insn) != stq_c_opcode)
    return 0;

  closing_insn = loc;
  loc += ALPHA_INSN_SIZE;

  /* Insert a breakpoint right after the end of the atomic sequence.  */
  breaks[0] = loc;

  /* Check for duplicated breakpoints.  Check also for a breakpoint
     placed (branch instruction's destination) anywhere in sequence.  */ 
  if (last_breakpoint
      && (breaks[1] == breaks[0]
	  || (breaks[1] >= pc && breaks[1] <= closing_insn)))
    last_breakpoint = 0;

  /* Effectively inserts the breakpoints.  */
  for (index = 0; index <= last_breakpoint; index++)
    insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);

  return 1;
}


/* Figure out where the longjmp will land.
   We expect the first arg to be a pointer to the jmp_buf structure from
   which we extract the PC (JB_PC) that we will land at.  The PC is copied
   into the "pc".  This routine returns true on success.  */

static int
alpha_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR jb_addr;
  gdb_byte raw_buffer[ALPHA_REGISTER_SIZE];

  jb_addr = get_frame_register_unsigned (frame, ALPHA_A0_REGNUM);

  if (target_read_memory (jb_addr + (tdep->jb_pc * tdep->jb_elt_size),
			  raw_buffer, tdep->jb_elt_size))
    return 0;

  *pc = extract_unsigned_integer (raw_buffer, tdep->jb_elt_size, byte_order);
  return 1;
}


/* Frame unwinder for signal trampolines.  We use alpha tdep bits that
   describe the location and shape of the sigcontext structure.  After
   that, all registers are in memory, so it's easy.  */
/* ??? Shouldn't we be able to do this generically, rather than with
   OSABI data specific to Alpha?  */

struct alpha_sigtramp_unwind_cache
{
  CORE_ADDR sigcontext_addr;
};

static struct alpha_sigtramp_unwind_cache *
alpha_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
				   void **this_prologue_cache)
{
  struct alpha_sigtramp_unwind_cache *info;
  struct gdbarch_tdep *tdep;

  if (*this_prologue_cache)
    return *this_prologue_cache;

  info = FRAME_OBSTACK_ZALLOC (struct alpha_sigtramp_unwind_cache);
  *this_prologue_cache = info;

  tdep = gdbarch_tdep (get_frame_arch (this_frame));
  info->sigcontext_addr = tdep->sigcontext_addr (this_frame);

  return info;
}

/* Return the address of REGNUM in a sigtramp frame.  Since this is
   all arithmetic, it doesn't seem worthwhile to cache it.  */

static CORE_ADDR
alpha_sigtramp_register_address (struct gdbarch *gdbarch,
				 CORE_ADDR sigcontext_addr, int regnum)
{ 
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  if (regnum >= 0 && regnum < 32)
    return sigcontext_addr + tdep->sc_regs_offset + regnum * 8;
  else if (regnum >= ALPHA_FP0_REGNUM && regnum < ALPHA_FP0_REGNUM + 32)
    return sigcontext_addr + tdep->sc_fpregs_offset + regnum * 8;
  else if (regnum == ALPHA_PC_REGNUM)
    return sigcontext_addr + tdep->sc_pc_offset; 

  return 0;
}

/* Given a GDB frame, determine the address of the calling function's
   frame.  This will be used to create a new GDB frame struct.  */

static void
alpha_sigtramp_frame_this_id (struct frame_info *this_frame,
			      void **this_prologue_cache,
			      struct frame_id *this_id)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  struct alpha_sigtramp_unwind_cache *info
    = alpha_sigtramp_frame_unwind_cache (this_frame, this_prologue_cache);
  CORE_ADDR stack_addr, code_addr;

  /* If the OSABI couldn't locate the sigcontext, give up.  */
  if (info->sigcontext_addr == 0)
    return;

  /* If we have dynamic signal trampolines, find their start.
     If we do not, then we must assume there is a symbol record
     that can provide the start address.  */
  if (tdep->dynamic_sigtramp_offset)
    {
      int offset;
      code_addr = get_frame_pc (this_frame);
      offset = tdep->dynamic_sigtramp_offset (gdbarch, code_addr);
      if (offset >= 0)
	code_addr -= offset;
      else
	code_addr = 0;
    }
  else
    code_addr = get_frame_func (this_frame);

  /* The stack address is trivially read from the sigcontext.  */
  stack_addr = alpha_sigtramp_register_address (gdbarch, info->sigcontext_addr,
						ALPHA_SP_REGNUM);
  stack_addr = get_frame_memory_unsigned (this_frame, stack_addr,
					  ALPHA_REGISTER_SIZE);

  *this_id = frame_id_build (stack_addr, code_addr);
}

/* Retrieve the value of REGNUM in FRAME.  Don't give up!  */

static struct value *
alpha_sigtramp_frame_prev_register (struct frame_info *this_frame,
				    void **this_prologue_cache, int regnum)
{
  struct alpha_sigtramp_unwind_cache *info
    = alpha_sigtramp_frame_unwind_cache (this_frame, this_prologue_cache);
  CORE_ADDR addr;

  if (info->sigcontext_addr != 0)
    {
      /* All integer and fp registers are stored in memory.  */
      addr = alpha_sigtramp_register_address (get_frame_arch (this_frame),
					      info->sigcontext_addr, regnum);
      if (addr != 0)
        return frame_unwind_got_memory (this_frame, regnum, addr);
    }

  /* This extra register may actually be in the sigcontext, but our
     current description of it in alpha_sigtramp_frame_unwind_cache
     doesn't include it.  Too bad.  Fall back on whatever's in the
     outer frame.  */
  return frame_unwind_got_register (this_frame, regnum, regnum);
}

static int
alpha_sigtramp_frame_sniffer (const struct frame_unwind *self,
                              struct frame_info *this_frame,
                              void **this_prologue_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR pc = get_frame_pc (this_frame);
  const char *name;

  /* NOTE: cagney/2004-04-30: Do not copy/clone this code.  Instead
     look at tramp-frame.h and other simplier per-architecture
     sigtramp unwinders.  */

  /* We shouldn't even bother to try if the OSABI didn't register a
     sigcontext_addr handler or pc_in_sigtramp hander.  */
  if (gdbarch_tdep (gdbarch)->sigcontext_addr == NULL)
    return 0;
  if (gdbarch_tdep (gdbarch)->pc_in_sigtramp == NULL)
    return 0;

  /* Otherwise we should be in a signal frame.  */
  find_pc_partial_function (pc, &name, NULL, NULL);
  if (gdbarch_tdep (gdbarch)->pc_in_sigtramp (gdbarch, pc, name))
    return 1;

  return 0;
}

static const struct frame_unwind alpha_sigtramp_frame_unwind = {
  SIGTRAMP_FRAME,
  default_frame_unwind_stop_reason,
  alpha_sigtramp_frame_this_id,
  alpha_sigtramp_frame_prev_register,
  NULL,
  alpha_sigtramp_frame_sniffer
};



/* Heuristic_proc_start may hunt through the text section for a long
   time across a 2400 baud serial line.  Allows the user to limit this
   search.  */
static int heuristic_fence_post = 0;

/* Attempt to locate the start of the function containing PC.  We assume that
   the previous function ends with an about_to_return insn.  Not foolproof by
   any means, since gcc is happy to put the epilogue in the middle of a
   function.  But we're guessing anyway...  */

static CORE_ADDR
alpha_heuristic_proc_start (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  CORE_ADDR last_non_nop = pc;
  CORE_ADDR fence = pc - heuristic_fence_post;
  CORE_ADDR orig_pc = pc;
  CORE_ADDR func;
  struct inferior *inf;

  if (pc == 0)
    return 0;

  /* First see if we can find the start of the function from minimal
     symbol information.  This can succeed with a binary that doesn't
     have debug info, but hasn't been stripped.  */
  func = get_pc_function_start (pc);
  if (func)
    return func;

  if (heuristic_fence_post == -1
      || fence < tdep->vm_min_address)
    fence = tdep->vm_min_address;

  /* Search back for previous return; also stop at a 0, which might be
     seen for instance before the start of a code section.  Don't include
     nops, since this usually indicates padding between functions.  */
  for (pc -= ALPHA_INSN_SIZE; pc >= fence; pc -= ALPHA_INSN_SIZE)
    {
      unsigned int insn = alpha_read_insn (gdbarch, pc);
      switch (insn)
	{
	case 0:			/* invalid insn */
	case 0x6bfa8001:	/* ret $31,($26),1 */
	  return last_non_nop;

	case 0x2ffe0000:	/* unop: ldq_u $31,0($30) */
	case 0x47ff041f:	/* nop: bis $31,$31,$31 */
	  break;

	default:
	  last_non_nop = pc;
	  break;
	}
    }

  inf = current_inferior ();

  /* It's not clear to me why we reach this point when stopping quietly,
     but with this test, at least we don't print out warnings for every
     child forked (eg, on decstation).  22apr93 rich@cygnus.com.  */
  if (inf->control.stop_soon == NO_STOP_QUIETLY)
    {
      static int blurb_printed = 0;

      if (fence == tdep->vm_min_address)
	warning (_("Hit beginning of text section without finding \
enclosing function for address %s"), paddress (gdbarch, orig_pc));
      else
	warning (_("Hit heuristic-fence-post without finding \
enclosing function for address %s"), paddress (gdbarch, orig_pc));

      if (!blurb_printed)
	{
	  printf_filtered (_("\
This warning occurs if you are debugging a function without any symbols\n\
(for example, in a stripped executable).  In that case, you may wish to\n\
increase the size of the search with the `set heuristic-fence-post' command.\n\
\n\
Otherwise, you told GDB there was a function where there isn't one, or\n\
(more likely) you have encountered a bug in GDB.\n"));
	  blurb_printed = 1;
	}
    }

  return 0;
}

/* Fallback alpha frame unwinder.  Uses instruction scanning and knows
   something about the traditional layout of alpha stack frames.  */

struct alpha_heuristic_unwind_cache
{ 
  CORE_ADDR vfp;
  CORE_ADDR start_pc;
  struct trad_frame_saved_reg *saved_regs;
  int return_reg;
};

/* If a probing loop sequence starts at PC, simulate it and compute
   FRAME_SIZE and PC after its execution.  Otherwise, return with PC and
   FRAME_SIZE unchanged.  */

static void
alpha_heuristic_analyze_probing_loop (struct gdbarch *gdbarch, CORE_ADDR *pc,
				      int *frame_size)
{
  CORE_ADDR cur_pc = *pc;
  int cur_frame_size = *frame_size;
  int nb_of_iterations, reg_index, reg_probe;
  unsigned int insn;

  /* The following pattern is recognized as a probing loop:

        lda     REG_INDEX,NB_OF_ITERATIONS
        lda     REG_PROBE,<immediate>(sp)

     LOOP_START:
        stq     zero,<immediate>(REG_PROBE)
        subq    REG_INDEX,0x1,REG_INDEX
        lda     REG_PROBE,<immediate>(REG_PROBE)
        bne     REG_INDEX, LOOP_START
 
        lda     sp,<immediate>(REG_PROBE)

     If anything different is found, the function returns without
     changing PC and FRAME_SIZE.  Otherwise, PC will point immediately
     after this sequence, and FRAME_SIZE will be updated.  */

  /* lda     REG_INDEX,NB_OF_ITERATIONS */

  insn = alpha_read_insn (gdbarch, cur_pc);
  if (INSN_OPCODE (insn) != lda_opcode)
    return;
  reg_index = MEM_RA (insn);
  nb_of_iterations = MEM_DISP (insn);

  /* lda     REG_PROBE,<immediate>(sp) */

  cur_pc += ALPHA_INSN_SIZE;
  insn = alpha_read_insn (gdbarch, cur_pc);
  if (INSN_OPCODE (insn) != lda_opcode
      || MEM_RB (insn) != ALPHA_SP_REGNUM)
    return;
  reg_probe = MEM_RA (insn);
  cur_frame_size -= MEM_DISP (insn);

  /* stq     zero,<immediate>(REG_PROBE) */
  
  cur_pc += ALPHA_INSN_SIZE;
  insn = alpha_read_insn (gdbarch, cur_pc);
  if (INSN_OPCODE (insn) != stq_opcode
      || MEM_RA (insn) != 0x1f
      || MEM_RB (insn) != reg_probe)
    return;
  
  /* subq    REG_INDEX,0x1,REG_INDEX */

  cur_pc += ALPHA_INSN_SIZE;
  insn = alpha_read_insn (gdbarch, cur_pc);
  if (INSN_OPCODE (insn) != subq_opcode
      || !OPR_HAS_IMMEDIATE (insn)
      || OPR_FUNCTION (insn) != subq_function
      || OPR_LIT(insn) != 1
      || OPR_RA (insn) != reg_index
      || OPR_RC (insn) != reg_index)
    return;
  
  /* lda     REG_PROBE,<immediate>(REG_PROBE) */
  
  cur_pc += ALPHA_INSN_SIZE;
  insn = alpha_read_insn (gdbarch, cur_pc);
  if (INSN_OPCODE (insn) != lda_opcode
      || MEM_RA (insn) != reg_probe
      || MEM_RB (insn) != reg_probe)
    return;
  cur_frame_size -= MEM_DISP (insn) * nb_of_iterations;

  /* bne     REG_INDEX, LOOP_START */

  cur_pc += ALPHA_INSN_SIZE;
  insn = alpha_read_insn (gdbarch, cur_pc);
  if (INSN_OPCODE (insn) != bne_opcode
      || MEM_RA (insn) != reg_index)
    return;

  /* lda     sp,<immediate>(REG_PROBE) */

  cur_pc += ALPHA_INSN_SIZE;
  insn = alpha_read_insn (gdbarch, cur_pc);
  if (INSN_OPCODE (insn) != lda_opcode
      || MEM_RA (insn) != ALPHA_SP_REGNUM
      || MEM_RB (insn) != reg_probe)
    return;
  cur_frame_size -= MEM_DISP (insn);

  *pc = cur_pc;
  *frame_size = cur_frame_size;
}

static struct alpha_heuristic_unwind_cache *
alpha_heuristic_frame_unwind_cache (struct frame_info *this_frame,
				    void **this_prologue_cache,
				    CORE_ADDR start_pc)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct alpha_heuristic_unwind_cache *info;
  ULONGEST val;
  CORE_ADDR limit_pc, cur_pc;
  int frame_reg, frame_size, return_reg, reg;

  if (*this_prologue_cache)
    return *this_prologue_cache;

  info = FRAME_OBSTACK_ZALLOC (struct alpha_heuristic_unwind_cache);
  *this_prologue_cache = info;
  info->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  limit_pc = get_frame_pc (this_frame);
  if (start_pc == 0)
    start_pc = alpha_heuristic_proc_start (gdbarch, limit_pc);
  info->start_pc = start_pc;

  frame_reg = ALPHA_SP_REGNUM;
  frame_size = 0;
  return_reg = -1;

  /* If we've identified a likely place to start, do code scanning.  */
  if (start_pc != 0)
    {
      /* Limit the forward search to 50 instructions.  */
      if (start_pc + 200 < limit_pc)
	limit_pc = start_pc + 200;

      for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += ALPHA_INSN_SIZE)
	{
	  unsigned int word = alpha_read_insn (gdbarch, cur_pc);

	  if ((word & 0xffff0000) == 0x23de0000)	/* lda $sp,n($sp) */
	    {
	      if (word & 0x8000)
		{
		  /* Consider only the first stack allocation instruction
		     to contain the static size of the frame.  */
		  if (frame_size == 0)
		    frame_size = (-word) & 0xffff;
		}
	      else
		{
		  /* Exit loop if a positive stack adjustment is found, which
		     usually means that the stack cleanup code in the function
		     epilogue is reached.  */
		  break;
		}
	    }
	  else if ((word & 0xfc1f0000) == 0xb41e0000)	/* stq reg,n($sp) */
	    {
	      reg = (word & 0x03e00000) >> 21;

              /* Ignore this instruction if we have already encountered
                 an instruction saving the same register earlier in the
                 function code.  The current instruction does not tell
                 us where the original value upon function entry is saved.
                 All it says is that the function we are scanning reused
                 that register for some computation of its own, and is now
                 saving its result.  */
              if (trad_frame_addr_p(info->saved_regs, reg))
                continue;

	      if (reg == 31)
		continue;

	      /* Do not compute the address where the register was saved yet,
		 because we don't know yet if the offset will need to be
		 relative to $sp or $fp (we can not compute the address
		 relative to $sp if $sp is updated during the execution of
		 the current subroutine, for instance when doing some alloca).
		 So just store the offset for the moment, and compute the
		 address later when we know whether this frame has a frame
		 pointer or not.  */
	      /* Hack: temporarily add one, so that the offset is non-zero
		 and we can tell which registers have save offsets below.  */
	      info->saved_regs[reg].addr = (word & 0xffff) + 1;

	      /* Starting with OSF/1-3.2C, the system libraries are shipped
		 without local symbols, but they still contain procedure
		 descriptors without a symbol reference. GDB is currently
		 unable to find these procedure descriptors and uses
		 heuristic_proc_desc instead.
		 As some low level compiler support routines (__div*, __add*)
		 use a non-standard return address register, we have to
		 add some heuristics to determine the return address register,
		 or stepping over these routines will fail.
		 Usually the return address register is the first register
		 saved on the stack, but assembler optimization might
		 rearrange the register saves.
		 So we recognize only a few registers (t7, t9, ra) within
		 the procedure prologue as valid return address registers.
		 If we encounter a return instruction, we extract the
		 return address register from it.

		 FIXME: Rewriting GDB to access the procedure descriptors,
		 e.g. via the minimal symbol table, might obviate this
		 hack.  */
	      if (return_reg == -1
		  && cur_pc < (start_pc + 80)
		  && (reg == ALPHA_T7_REGNUM
		      || reg == ALPHA_T9_REGNUM
		      || reg == ALPHA_RA_REGNUM))
		return_reg = reg;
	    }
	  else if ((word & 0xffe0ffff) == 0x6be08001)	/* ret zero,reg,1 */
	    return_reg = (word >> 16) & 0x1f;
	  else if (word == 0x47de040f)			/* bis sp,sp,fp */
	    frame_reg = ALPHA_GCC_FP_REGNUM;
	  else if (word == 0x47fe040f)			/* bis zero,sp,fp */
	    frame_reg = ALPHA_GCC_FP_REGNUM;

	  alpha_heuristic_analyze_probing_loop (gdbarch, &cur_pc, &frame_size);
	}

      /* If we haven't found a valid return address register yet, keep
	 searching in the procedure prologue.  */
      if (return_reg == -1)
	{
	  while (cur_pc < (limit_pc + 80) && cur_pc < (start_pc + 80))
	    {
	      unsigned int word = alpha_read_insn (gdbarch, cur_pc);

	      if ((word & 0xfc1f0000) == 0xb41e0000)	/* stq reg,n($sp) */
		{
		  reg = (word & 0x03e00000) >> 21;
		  if (reg == ALPHA_T7_REGNUM
		      || reg == ALPHA_T9_REGNUM
		      || reg == ALPHA_RA_REGNUM)
		    {
		      return_reg = reg;
		      break;
		    }
		}
	      else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */
		{
		  return_reg = (word >> 16) & 0x1f;
		  break;
		}

	      cur_pc += ALPHA_INSN_SIZE;
	    }
	}
    }

  /* Failing that, do default to the customary RA.  */
  if (return_reg == -1)
    return_reg = ALPHA_RA_REGNUM;
  info->return_reg = return_reg;

  val = get_frame_register_unsigned (this_frame, frame_reg);
  info->vfp = val + frame_size;

  /* Convert offsets to absolute addresses.  See above about adding
     one to the offsets to make all detected offsets non-zero.  */
  for (reg = 0; reg < ALPHA_NUM_REGS; ++reg)
    if (trad_frame_addr_p(info->saved_regs, reg))
      info->saved_regs[reg].addr += val - 1;

  /* The stack pointer of the previous frame is computed by popping
     the current stack frame.  */
  if (!trad_frame_addr_p (info->saved_regs, ALPHA_SP_REGNUM))
   trad_frame_set_value (info->saved_regs, ALPHA_SP_REGNUM, info->vfp);

  return info;
}

/* Given a GDB frame, determine the address of the calling function's
   frame.  This will be used to create a new GDB frame struct.  */

static void
alpha_heuristic_frame_this_id (struct frame_info *this_frame,
			       void **this_prologue_cache,
			       struct frame_id *this_id)
{
  struct alpha_heuristic_unwind_cache *info
    = alpha_heuristic_frame_unwind_cache (this_frame, this_prologue_cache, 0);

  *this_id = frame_id_build (info->vfp, info->start_pc);
}

/* Retrieve the value of REGNUM in FRAME.  Don't give up!  */

static struct value *
alpha_heuristic_frame_prev_register (struct frame_info *this_frame,
				     void **this_prologue_cache, int regnum)
{
  struct alpha_heuristic_unwind_cache *info
    = alpha_heuristic_frame_unwind_cache (this_frame, this_prologue_cache, 0);

  /* The PC of the previous frame is stored in the link register of
     the current frame.  Frob regnum so that we pull the value from
     the correct place.  */
  if (regnum == ALPHA_PC_REGNUM)
    regnum = info->return_reg;
  
  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
}

static const struct frame_unwind alpha_heuristic_frame_unwind = {
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  alpha_heuristic_frame_this_id,
  alpha_heuristic_frame_prev_register,
  NULL,
  default_frame_sniffer
};

static CORE_ADDR
alpha_heuristic_frame_base_address (struct frame_info *this_frame,
				    void **this_prologue_cache)
{
  struct alpha_heuristic_unwind_cache *info
    = alpha_heuristic_frame_unwind_cache (this_frame, this_prologue_cache, 0);

  return info->vfp;
}

static const struct frame_base alpha_heuristic_frame_base = {
  &alpha_heuristic_frame_unwind,
  alpha_heuristic_frame_base_address,
  alpha_heuristic_frame_base_address,
  alpha_heuristic_frame_base_address
};

/* Just like reinit_frame_cache, but with the right arguments to be
   callable as an sfunc.  Used by the "set heuristic-fence-post" command.  */

static void
reinit_frame_cache_sfunc (char *args, int from_tty, struct cmd_list_element *c)
{
  reinit_frame_cache ();
}


/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
   dummy frame.  The frame ID's base needs to match the TOS value
   saved by save_dummy_frame_tos(), and the PC match the dummy frame's
   breakpoint.  */

static struct frame_id
alpha_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
  ULONGEST base;
  base = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);
  return frame_id_build (base, get_frame_pc (this_frame));
}

static CORE_ADDR
alpha_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  ULONGEST pc;
  pc = frame_unwind_register_unsigned (next_frame, ALPHA_PC_REGNUM);
  return pc;
}


/* Helper routines for alpha*-nat.c files to move register sets to and
   from core files.  The UNIQUE pointer is allowed to be NULL, as most
   targets don't supply this value in their core files.  */

void
alpha_supply_int_regs (struct regcache *regcache, int regno,
		       const void *r0_r30, const void *pc, const void *unique)
{
  const gdb_byte *regs = r0_r30;
  int i;

  for (i = 0; i < 31; ++i)
    if (regno == i || regno == -1)
      regcache_raw_supply (regcache, i, regs + i * 8);

  if (regno == ALPHA_ZERO_REGNUM || regno == -1)
    {
      const gdb_byte zero[8] = { 0 };

      regcache_raw_supply (regcache, ALPHA_ZERO_REGNUM, zero);
    }

  if (regno == ALPHA_PC_REGNUM || regno == -1)
    regcache_raw_supply (regcache, ALPHA_PC_REGNUM, pc);

  if (regno == ALPHA_UNIQUE_REGNUM || regno == -1)
    regcache_raw_supply (regcache, ALPHA_UNIQUE_REGNUM, unique);
}

void
alpha_fill_int_regs (const struct regcache *regcache,
		     int regno, void *r0_r30, void *pc, void *unique)
{
  gdb_byte *regs = r0_r30;
  int i;

  for (i = 0; i < 31; ++i)
    if (regno == i || regno == -1)
      regcache_raw_collect (regcache, i, regs + i * 8);

  if (regno == ALPHA_PC_REGNUM || regno == -1)
    regcache_raw_collect (regcache, ALPHA_PC_REGNUM, pc);

  if (unique && (regno == ALPHA_UNIQUE_REGNUM || regno == -1))
    regcache_raw_collect (regcache, ALPHA_UNIQUE_REGNUM, unique);
}

void
alpha_supply_fp_regs (struct regcache *regcache, int regno,
		      const void *f0_f30, const void *fpcr)
{
  const gdb_byte *regs = f0_f30;
  int i;

  for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i)
    if (regno == i || regno == -1)
      regcache_raw_supply (regcache, i,
			   regs + (i - ALPHA_FP0_REGNUM) * 8);

  if (regno == ALPHA_FPCR_REGNUM || regno == -1)
    regcache_raw_supply (regcache, ALPHA_FPCR_REGNUM, fpcr);
}

void
alpha_fill_fp_regs (const struct regcache *regcache,
		    int regno, void *f0_f30, void *fpcr)
{
  gdb_byte *regs = f0_f30;
  int i;

  for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i)
    if (regno == i || regno == -1)
      regcache_raw_collect (regcache, i,
			    regs + (i - ALPHA_FP0_REGNUM) * 8);

  if (regno == ALPHA_FPCR_REGNUM || regno == -1)
    regcache_raw_collect (regcache, ALPHA_FPCR_REGNUM, fpcr);
}



/* Return nonzero if the G_floating register value in REG is equal to
   zero for FP control instructions.  */
   
static int
fp_register_zero_p (LONGEST reg)
{
  /* Check that all bits except the sign bit are zero.  */
  const LONGEST zero_mask = ((LONGEST) 1 << 63) ^ -1;

  return ((reg & zero_mask) == 0);
}

/* Return the value of the sign bit for the G_floating register
   value held in REG.  */

static int
fp_register_sign_bit (LONGEST reg)
{
  const LONGEST sign_mask = (LONGEST) 1 << 63;

  return ((reg & sign_mask) != 0);
}

/* alpha_software_single_step() is called just before we want to resume
   the inferior, if we want to single-step it but there is no hardware
   or kernel single-step support (NetBSD on Alpha, for example).  We find
   the target of the coming instruction and breakpoint it.  */

static CORE_ADDR
alpha_next_pc (struct frame_info *frame, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  unsigned int insn;
  unsigned int op;
  int regno;
  int offset;
  LONGEST rav;

  insn = alpha_read_insn (gdbarch, pc);

  /* Opcode is top 6 bits.  */
  op = (insn >> 26) & 0x3f;

  if (op == 0x1a)
    {
      /* Jump format: target PC is:
	 RB & ~3  */
      return (get_frame_register_unsigned (frame, (insn >> 16) & 0x1f) & ~3);
    }

  if ((op & 0x30) == 0x30)
    {
      /* Branch format: target PC is:
	 (new PC) + (4 * sext(displacement))  */
      if (op == 0x30		/* BR */
	  || op == 0x34)	/* BSR */
	{
 branch_taken:
          offset = (insn & 0x001fffff);
	  if (offset & 0x00100000)
	    offset  |= 0xffe00000;
	  offset *= ALPHA_INSN_SIZE;
	  return (pc + ALPHA_INSN_SIZE + offset);
	}

      /* Need to determine if branch is taken; read RA.  */
      regno = (insn >> 21) & 0x1f;
      switch (op)
        {
          case 0x31:              /* FBEQ */
          case 0x36:              /* FBGE */
          case 0x37:              /* FBGT */
          case 0x33:              /* FBLE */
          case 0x32:              /* FBLT */
          case 0x35:              /* FBNE */
            regno += gdbarch_fp0_regnum (gdbarch);
	}
      
      rav = get_frame_register_signed (frame, regno);

      switch (op)
	{
	case 0x38:		/* BLBC */
	  if ((rav & 1) == 0)
	    goto branch_taken;
	  break;
	case 0x3c:		/* BLBS */
	  if (rav & 1)
	    goto branch_taken;
	  break;
	case 0x39:		/* BEQ */
	  if (rav == 0)
	    goto branch_taken;
	  break;
	case 0x3d:		/* BNE */
	  if (rav != 0)
	    goto branch_taken;
	  break;
	case 0x3a:		/* BLT */
	  if (rav < 0)
	    goto branch_taken;
	  break;
	case 0x3b:		/* BLE */
	  if (rav <= 0)
	    goto branch_taken;
	  break;
	case 0x3f:		/* BGT */
	  if (rav > 0)
	    goto branch_taken;
	  break;
	case 0x3e:		/* BGE */
	  if (rav >= 0)
	    goto branch_taken;
	  break;

        /* Floating point branches.  */
        
        case 0x31:              /* FBEQ */
          if (fp_register_zero_p (rav))
            goto branch_taken;
          break;
        case 0x36:              /* FBGE */
          if (fp_register_sign_bit (rav) == 0 || fp_register_zero_p (rav))
            goto branch_taken;
          break;
        case 0x37:              /* FBGT */
          if (fp_register_sign_bit (rav) == 0 && ! fp_register_zero_p (rav))
            goto branch_taken;
          break;
        case 0x33:              /* FBLE */
          if (fp_register_sign_bit (rav) == 1 || fp_register_zero_p (rav))
            goto branch_taken;
          break;
        case 0x32:              /* FBLT */
          if (fp_register_sign_bit (rav) == 1 && ! fp_register_zero_p (rav))
            goto branch_taken;
          break;
        case 0x35:              /* FBNE */
          if (! fp_register_zero_p (rav))
            goto branch_taken;
          break;
	}
    }

  /* Not a branch or branch not taken; target PC is:
     pc + 4  */
  return (pc + ALPHA_INSN_SIZE);
}

int
alpha_software_single_step (struct frame_info *frame)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct address_space *aspace = get_frame_address_space (frame);
  CORE_ADDR pc, next_pc;

  pc = get_frame_pc (frame);
  next_pc = alpha_next_pc (frame, pc);

  insert_single_step_breakpoint (gdbarch, aspace, next_pc);
  return 1;
}


/* 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 *
alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch_tdep *tdep;
  struct gdbarch *gdbarch;

  /* Try to determine the ABI of the object we are loading.  */
  if (info.abfd != NULL && info.osabi == GDB_OSABI_UNKNOWN)
    {
      /* If it's an ECOFF file, assume it's OSF/1.  */
      if (bfd_get_flavour (info.abfd) == bfd_target_ecoff_flavour)
	info.osabi = GDB_OSABI_OSF1;
    }

  /* Find a candidate among extant architectures.  */
  arches = gdbarch_list_lookup_by_info (arches, &info);
  if (arches != NULL)
    return arches->gdbarch;

  tdep = xmalloc (sizeof (struct gdbarch_tdep));
  gdbarch = gdbarch_alloc (&info, tdep);

  /* Lowest text address.  This is used by heuristic_proc_start()
     to decide when to stop looking.  */
  tdep->vm_min_address = (CORE_ADDR) 0x120000000LL;

  tdep->dynamic_sigtramp_offset = NULL;
  tdep->sigcontext_addr = NULL;
  tdep->sc_pc_offset = 2 * 8;
  tdep->sc_regs_offset = 4 * 8;
  tdep->sc_fpregs_offset = tdep->sc_regs_offset + 32 * 8 + 8;

  tdep->jb_pc = -1;	/* longjmp support not enabled by default.  */

  tdep->return_in_memory = alpha_return_in_memory_always;

  /* Type sizes */
  set_gdbarch_short_bit (gdbarch, 16);
  set_gdbarch_int_bit (gdbarch, 32);
  set_gdbarch_long_bit (gdbarch, 64);
  set_gdbarch_long_long_bit (gdbarch, 64);
  set_gdbarch_float_bit (gdbarch, 32);
  set_gdbarch_double_bit (gdbarch, 64);
  set_gdbarch_long_double_bit (gdbarch, 64);
  set_gdbarch_ptr_bit (gdbarch, 64);

  /* Register info */
  set_gdbarch_num_regs (gdbarch, ALPHA_NUM_REGS);
  set_gdbarch_sp_regnum (gdbarch, ALPHA_SP_REGNUM);
  set_gdbarch_pc_regnum (gdbarch, ALPHA_PC_REGNUM);
  set_gdbarch_fp0_regnum (gdbarch, ALPHA_FP0_REGNUM);

  set_gdbarch_register_name (gdbarch, alpha_register_name);
  set_gdbarch_register_type (gdbarch, alpha_register_type);

  set_gdbarch_cannot_fetch_register (gdbarch, alpha_cannot_fetch_register);
  set_gdbarch_cannot_store_register (gdbarch, alpha_cannot_store_register);

  set_gdbarch_convert_register_p (gdbarch, alpha_convert_register_p);
  set_gdbarch_register_to_value (gdbarch, alpha_register_to_value);
  set_gdbarch_value_to_register (gdbarch, alpha_value_to_register);

  set_gdbarch_register_reggroup_p (gdbarch, alpha_register_reggroup_p);

  /* Prologue heuristics.  */
  set_gdbarch_skip_prologue (gdbarch, alpha_skip_prologue);

  /* Disassembler.  */
  set_gdbarch_print_insn (gdbarch, print_insn_alpha);

  /* Call info.  */

  set_gdbarch_return_value (gdbarch, alpha_return_value);

  /* Settings for calling functions in the inferior.  */
  set_gdbarch_push_dummy_call (gdbarch, alpha_push_dummy_call);

  /* Methods for saving / extracting a dummy frame's ID.  */
  set_gdbarch_dummy_id (gdbarch, alpha_dummy_id);

  /* Return the unwound PC value.  */
  set_gdbarch_unwind_pc (gdbarch, alpha_unwind_pc);

  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);

  set_gdbarch_breakpoint_from_pc (gdbarch, alpha_breakpoint_from_pc);
  set_gdbarch_decr_pc_after_break (gdbarch, ALPHA_INSN_SIZE);
  set_gdbarch_cannot_step_breakpoint (gdbarch, 1);

  /* Handles single stepping of atomic sequences.  */
  set_gdbarch_software_single_step (gdbarch, alpha_deal_with_atomic_sequence);

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

  /* Now that we have tuned the configuration, set a few final things
     based on what the OS ABI has told us.  */

  if (tdep->jb_pc >= 0)
    set_gdbarch_get_longjmp_target (gdbarch, alpha_get_longjmp_target);

  frame_unwind_append_unwinder (gdbarch, &alpha_sigtramp_frame_unwind);
  frame_unwind_append_unwinder (gdbarch, &alpha_heuristic_frame_unwind);

  frame_base_set_default (gdbarch, &alpha_heuristic_frame_base);

  return gdbarch;
}

void
alpha_dwarf2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  dwarf2_append_unwinders (gdbarch);
  frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
}

extern initialize_file_ftype _initialize_alpha_tdep; /* -Wmissing-prototypes */

void
_initialize_alpha_tdep (void)
{
  struct cmd_list_element *c;

  gdbarch_register (bfd_arch_alpha, alpha_gdbarch_init, NULL);

  /* Let the user set the fence post for heuristic_proc_start.  */

  /* We really would like to have both "0" and "unlimited" work, but
     command.c doesn't deal with that.  So make it a var_zinteger
     because the user can always use "999999" or some such for unlimited.  */
  /* We need to throw away the frame cache when we set this, since it
     might change our ability to get backtraces.  */
  add_setshow_zinteger_cmd ("heuristic-fence-post", class_support,
			    &heuristic_fence_post, _("\
Set the distance searched for the start of a function."), _("\
Show the distance searched for the start of a function."), _("\
If you are debugging a stripped executable, GDB needs to search through the\n\
program for the start of a function.  This command sets the distance of the\n\
search.  The only need to set it is when debugging a stripped executable."),
			    reinit_frame_cache_sfunc,
			    NULL, /* FIXME: i18n: The distance searched for
				     the start of a function is \"%d\".  */
			    &setlist, &showlist);
}
