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

   Copyright (C) 1993-2003, 2005-2012 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_signed (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 unsigned 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 == UINT_MAX
      || 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);
}
