/* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger.
   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
   Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "defs.h"
#include "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 "doublest.h"
#include "arch-utils.h"
#include "osabi.h"
#include "block.h"

#include "elf-bfd.h"

#include "alpha-tdep.h"

static gdbarch_init_ftype alpha_gdbarch_init;

static gdbarch_register_name_ftype alpha_register_name;
static gdbarch_register_raw_size_ftype alpha_register_raw_size;
static gdbarch_register_virtual_size_ftype alpha_register_virtual_size;
static gdbarch_register_virtual_type_ftype alpha_register_virtual_type;
static gdbarch_register_byte_ftype alpha_register_byte;
static gdbarch_cannot_fetch_register_ftype alpha_cannot_fetch_register;
static gdbarch_cannot_store_register_ftype alpha_cannot_store_register;
static gdbarch_register_convertible_ftype alpha_register_convertible;
static gdbarch_register_convert_to_virtual_ftype
    alpha_register_convert_to_virtual;
static gdbarch_register_convert_to_raw_ftype alpha_register_convert_to_raw;
static gdbarch_deprecated_extract_return_value_ftype alpha_extract_return_value;
static gdbarch_deprecated_extract_struct_value_address_ftype
    alpha_extract_struct_value_address;
static gdbarch_use_struct_convention_ftype alpha_use_struct_convention;

static gdbarch_breakpoint_from_pc_ftype alpha_breakpoint_from_pc;

static gdbarch_frame_args_address_ftype alpha_frame_args_address;
static gdbarch_frame_locals_address_ftype alpha_frame_locals_address;

static gdbarch_skip_prologue_ftype alpha_skip_prologue;

static gdbarch_fix_call_dummy_ftype alpha_fix_call_dummy;

static gdbarch_get_longjmp_target_ftype alpha_get_longjmp_target;

struct frame_extra_info
  {
    alpha_extra_func_info_t proc_desc;
    int localoff;
    int pc_reg;
  };

/* FIXME: Some of this code should perhaps be merged with mips-tdep.c.  */

/* Prototypes for local functions. */

static void alpha_find_saved_regs (struct frame_info *);

static alpha_extra_func_info_t push_sigtramp_desc (CORE_ADDR low_addr);

static CORE_ADDR read_next_frame_reg (struct frame_info *, int);

static CORE_ADDR heuristic_proc_start (CORE_ADDR);

static alpha_extra_func_info_t heuristic_proc_desc (CORE_ADDR,
						    CORE_ADDR,
						    struct frame_info *);

static alpha_extra_func_info_t find_proc_desc (CORE_ADDR,
					       struct frame_info *);

#if 0
static int alpha_in_lenient_prologue (CORE_ADDR, CORE_ADDR);
#endif

static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);

static CORE_ADDR after_prologue (CORE_ADDR pc,
				 alpha_extra_func_info_t proc_desc);

static int alpha_in_prologue (CORE_ADDR pc,
			      alpha_extra_func_info_t proc_desc);

static int alpha_about_to_return (CORE_ADDR pc);

void _initialize_alpha_tdep (void);

/* 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;
/* *INDENT-OFF* */
/* Layout of a stack frame on the alpha:

                |				|
 pdr members:	|  7th ... nth arg,		|
                |  `pushed' by caller.		|
                |				|
----------------|-------------------------------|<--  old_sp == vfp
   ^  ^  ^  ^	|				|
   |  |  |  |	|				|
   |  |localoff	|  Copies of 1st .. 6th		|
   |  |  |  |	|  argument if necessary.	|
   |  |  |  v	|				|
   |  |  |  ---	|-------------------------------|<-- FRAME_LOCALS_ADDRESS
   |  |  |      |				|
   |  |  |      |  Locals and temporaries.	|
   |  |  |      |				|
   |  |  |      |-------------------------------|
   |  |  |      |				|
   |-fregoffset	|  Saved float registers.	|
   |  |  |      |  F9				|
   |  |  |      |   .				|
   |  |  |      |   .				|
   |  |  |      |  F2				|
   |  |  v      |				|
   |  |  -------|-------------------------------|
   |  |         |				|
   |  |         |  Saved registers.		|
   |  |         |  S6				|
   |-regoffset	|   .				|
   |  |         |   .				|
   |  |         |  S0				|
   |  |         |  pdr.pcreg			|
   |  v         |				|
   |  ----------|-------------------------------|
   |            |				|
 frameoffset    |  Argument build area, gets	|
   |            |  7th ... nth arg for any	|
   |            |  called procedure.		|
   v            |  				|
   -------------|-------------------------------|<-- sp
                |				|
*/
/* *INDENT-ON* */

#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr)	/* least address */
/* These next two fields are kind of being hijacked.  I wonder if
   iline is too small for the values it needs to hold, if GDB is
   running on a 32-bit host.  */
#define PROC_HIGH_ADDR(proc) ((proc)->pdr.iline)	/* upper address bound */
#define PROC_DUMMY_FRAME(proc) ((proc)->pdr.cbLineOffset)	/*CALL_DUMMY frame */
#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset)
#define PROC_FRAME_REG(proc) ((proc)->pdr.framereg)
#define PROC_REG_MASK(proc) ((proc)->pdr.regmask)
#define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask)
#define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset)
#define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset)
#define PROC_PC_REG(proc) ((proc)->pdr.pcreg)
#define PROC_LOCALOFF(proc) ((proc)->pdr.localoff)
#define PROC_SYMBOL(proc) (*(struct symbol**)&(proc)->pdr.isym)
#define _PROC_MAGIC_ 0x0F0F0F0F
#define PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym == _PROC_MAGIC_)
#define SET_PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym = _PROC_MAGIC_)

struct linked_proc_info
  {
    struct alpha_extra_func_info info;
    struct linked_proc_info *next;
  }
 *linked_proc_desc_table = NULL;

static CORE_ADDR
alpha_frame_past_sigtramp_frame (struct frame_info *frame, CORE_ADDR pc)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);

  if (tdep->skip_sigtramp_frame != NULL)
    return (tdep->skip_sigtramp_frame (frame, pc));

  return (0);
}

static LONGEST
alpha_dynamic_sigtramp_offset (CORE_ADDR pc)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);

  /* Must be provided by OS/ABI variant code if supported. */
  if (tdep->dynamic_sigtramp_offset != NULL)
    return (tdep->dynamic_sigtramp_offset (pc));

  return (-1);
}

#define ALPHA_PROC_SIGTRAMP_MAGIC 0x0e0f0f0f

/* Return TRUE if the procedure descriptor PROC is a procedure
   descriptor that refers to a dynamically generated signal
   trampoline routine.  */
static int
alpha_proc_desc_is_dyn_sigtramp (struct alpha_extra_func_info *proc)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);

  if (tdep->dynamic_sigtramp_offset != NULL)
    return (proc->pdr.isym == ALPHA_PROC_SIGTRAMP_MAGIC);

  return (0);
}

static void
alpha_set_proc_desc_is_dyn_sigtramp (struct alpha_extra_func_info *proc)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);

  if (tdep->dynamic_sigtramp_offset != NULL)
    proc->pdr.isym = ALPHA_PROC_SIGTRAMP_MAGIC;
}

/* Dynamically create a signal-handler caller procedure descriptor for
   the signal-handler return code starting at address LOW_ADDR.  The
   descriptor is added to the linked_proc_desc_table.  */

static alpha_extra_func_info_t
push_sigtramp_desc (CORE_ADDR low_addr)
{
  struct linked_proc_info *link;
  alpha_extra_func_info_t proc_desc;

  link = (struct linked_proc_info *)
    xmalloc (sizeof (struct linked_proc_info));
  link->next = linked_proc_desc_table;
  linked_proc_desc_table = link;

  proc_desc = &link->info;

  proc_desc->numargs = 0;
  PROC_LOW_ADDR (proc_desc) = low_addr;
  PROC_HIGH_ADDR (proc_desc) = low_addr + 3 * 4;
  PROC_DUMMY_FRAME (proc_desc) = 0;
  PROC_FRAME_OFFSET (proc_desc) = 0x298;	/* sizeof(struct sigcontext_struct) */
  PROC_FRAME_REG (proc_desc) = SP_REGNUM;
  PROC_REG_MASK (proc_desc) = 0xffff;
  PROC_FREG_MASK (proc_desc) = 0xffff;
  PROC_PC_REG (proc_desc) = 26;
  PROC_LOCALOFF (proc_desc) = 0;
  alpha_set_proc_desc_is_dyn_sigtramp (proc_desc);
  return (proc_desc);
}


static const char *
alpha_register_name (int regno)
{
  static char *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",   "vfp",  "unique",
  };

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

static int
alpha_cannot_fetch_register (int regno)
{
  return (regno == FP_REGNUM || regno == ALPHA_ZERO_REGNUM);
}

static int
alpha_cannot_store_register (int regno)
{
  return (regno == FP_REGNUM || regno == ALPHA_ZERO_REGNUM);
}

static int
alpha_register_convertible (int regno)
{
  return (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31);
}

static struct type *
alpha_register_virtual_type (int regno)
{
  return ((regno >= FP0_REGNUM && regno < (FP0_REGNUM+31))
	  ? builtin_type_double : builtin_type_long);
}

static int
alpha_register_byte (int regno)
{
  return (regno * 8);
}

static int
alpha_register_raw_size (int regno)
{
  return 8;
}

static int
alpha_register_virtual_size (int regno)
{
  return 8;
}


static CORE_ADDR
alpha_sigcontext_addr (struct frame_info *fi)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);

  if (tdep->sigcontext_addr)
    return (tdep->sigcontext_addr (fi));

  return (0);
}

/* Guaranteed to set frame->saved_regs to some values (it never leaves it
   NULL).  */

static void
alpha_find_saved_regs (struct frame_info *frame)
{
  int ireg;
  CORE_ADDR reg_position;
  unsigned long mask;
  alpha_extra_func_info_t proc_desc;
  int returnreg;

  frame_saved_regs_zalloc (frame);

  /* If it is the frame for __sigtramp, the saved registers are located
     in a sigcontext structure somewhere on the stack. __sigtramp
     passes a pointer to the sigcontext structure on the stack.
     If the stack layout for __sigtramp changes, or if sigcontext offsets
     change, we might have to update this code.  */
#ifndef SIGFRAME_PC_OFF
#define SIGFRAME_PC_OFF		(2 * 8)
#define SIGFRAME_REGSAVE_OFF	(4 * 8)
#define SIGFRAME_FPREGSAVE_OFF	(SIGFRAME_REGSAVE_OFF + 32 * 8 + 8)
#endif
  if ((get_frame_type (frame) == SIGTRAMP_FRAME))
    {
      CORE_ADDR sigcontext_addr;

      sigcontext_addr = alpha_sigcontext_addr (frame);
      if (sigcontext_addr == 0)
	{
	  /* Don't know where the sigcontext is; just bail.  */
	  return;
	}
      for (ireg = 0; ireg < 32; ireg++)
	{
	  reg_position = sigcontext_addr + SIGFRAME_REGSAVE_OFF + ireg * 8;
	  get_frame_saved_regs (frame)[ireg] = reg_position;
	}
      for (ireg = 0; ireg < 32; ireg++)
	{
	  reg_position = sigcontext_addr + SIGFRAME_FPREGSAVE_OFF + ireg * 8;
	  get_frame_saved_regs (frame)[FP0_REGNUM + ireg] = reg_position;
	}
      get_frame_saved_regs (frame)[PC_REGNUM] = sigcontext_addr + SIGFRAME_PC_OFF;
      return;
    }

  proc_desc = get_frame_extra_info (frame)->proc_desc;
  if (proc_desc == NULL)
    /* I'm not sure how/whether this can happen.  Normally when we can't
       find a proc_desc, we "synthesize" one using heuristic_proc_desc
       and set the saved_regs right away.  */
    return;

  /* Fill in the offsets for the registers which gen_mask says
     were saved.  */

  reg_position = get_frame_base (frame) + PROC_REG_OFFSET (proc_desc);
  mask = PROC_REG_MASK (proc_desc);

  returnreg = PROC_PC_REG (proc_desc);

  /* Note that RA is always saved first, regardless of its actual
     register number.  */
  if (mask & (1 << returnreg))
    {
      get_frame_saved_regs (frame)[returnreg] = reg_position;
      reg_position += 8;
      mask &= ~(1 << returnreg);	/* Clear bit for RA so we
					   don't save again later. */
    }

  for (ireg = 0; ireg <= 31; ++ireg)
    if (mask & (1 << ireg))
      {
	get_frame_saved_regs (frame)[ireg] = reg_position;
	reg_position += 8;
      }

  /* Fill in the offsets for the registers which float_mask says
     were saved.  */

  reg_position = get_frame_base (frame) + PROC_FREG_OFFSET (proc_desc);
  mask = PROC_FREG_MASK (proc_desc);

  for (ireg = 0; ireg <= 31; ++ireg)
    if (mask & (1 << ireg))
      {
	get_frame_saved_regs (frame)[FP0_REGNUM + ireg] = reg_position;
	reg_position += 8;
      }

  get_frame_saved_regs (frame)[PC_REGNUM] = get_frame_saved_regs (frame)[returnreg];
}

static void
alpha_frame_init_saved_regs (struct frame_info *fi)
{
  if (get_frame_saved_regs (fi) == NULL)
    alpha_find_saved_regs (fi);
  get_frame_saved_regs (fi)[SP_REGNUM] = get_frame_base (fi);
}

static CORE_ADDR
alpha_init_frame_pc_first (int fromleaf, struct frame_info *prev)
{
  return (fromleaf
	  ? DEPRECATED_SAVED_PC_AFTER_CALL (get_next_frame (prev)) 
	  : get_next_frame (prev)
	  ? DEPRECATED_FRAME_SAVED_PC (get_next_frame (prev))
	  : read_pc ());
}

static CORE_ADDR
read_next_frame_reg (struct frame_info *fi, int regno)
{
  for (; fi; fi = get_next_frame (fi))
    {
      /* We have to get the saved sp from the sigcontext
         if it is a signal handler frame.  */
      if (regno == SP_REGNUM && !(get_frame_type (fi) == SIGTRAMP_FRAME))
	return get_frame_base (fi);
      else
	{
	  if (get_frame_saved_regs (fi) == NULL)
	    alpha_find_saved_regs (fi);
	  if (get_frame_saved_regs (fi)[regno])
	    return read_memory_integer (get_frame_saved_regs (fi)[regno], 8);
	}
    }
  return read_register (regno);
}

static CORE_ADDR
alpha_frame_saved_pc (struct frame_info *frame)
{
  alpha_extra_func_info_t proc_desc = get_frame_extra_info (frame)->proc_desc;
  /* We have to get the saved pc from the sigcontext
     if it is a signal handler frame.  */
  int pcreg = ((get_frame_type (frame) == SIGTRAMP_FRAME)
	       ? PC_REGNUM
	       : get_frame_extra_info (frame)->pc_reg);

  if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
    return read_memory_integer  (get_frame_base (frame) - 8, 8);

  return read_next_frame_reg (frame, pcreg);
}

static CORE_ADDR
alpha_saved_pc_after_call (struct frame_info *frame)
{
  CORE_ADDR pc = get_frame_pc (frame);
  CORE_ADDR tmp;
  alpha_extra_func_info_t proc_desc;
  int pcreg;

  /* Skip over shared library trampoline if necessary.  */
  tmp = SKIP_TRAMPOLINE_CODE (pc);
  if (tmp != 0)
    pc = tmp;

  proc_desc = find_proc_desc (pc, get_next_frame (frame));
  pcreg = proc_desc ? PROC_PC_REG (proc_desc) : ALPHA_RA_REGNUM;

  if ((get_frame_type (frame) == SIGTRAMP_FRAME))
    return alpha_frame_saved_pc (frame);
  else
    return read_register (pcreg);
}


static struct alpha_extra_func_info temp_proc_desc;
static CORE_ADDR temp_saved_regs[ALPHA_NUM_REGS];

/* Nonzero if instruction at PC is a return instruction.  "ret
   $zero,($ra),1" on alpha. */

static int
alpha_about_to_return (CORE_ADDR pc)
{
  return read_memory_integer (pc, 4) == 0x6bfa8001;
}



/* This fencepost looks highly suspicious to me.  Removing it also
   seems suspicious as it could affect remote debugging across serial
   lines.  */

static CORE_ADDR
heuristic_proc_start (CORE_ADDR pc)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
  CORE_ADDR start_pc = pc;
  CORE_ADDR fence = start_pc - heuristic_fence_post;

  if (start_pc == 0)
    return 0;

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

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

	    if (fence == tdep->vm_min_address)
	      warning ("Hit beginning of text section without finding");
	    else
	      warning ("Hit heuristic-fence-post without finding");

	    warning ("enclosing function for address 0x%s", paddr_nz (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;
      }
    else if (alpha_about_to_return (start_pc))
      break;

  start_pc += 4;		/* skip return */
  return start_pc;
}

static alpha_extra_func_info_t
heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
		     struct frame_info *next_frame)
{
  CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
  CORE_ADDR vfp = sp;
  CORE_ADDR cur_pc;
  int frame_size;
  int has_frame_reg = 0;
  unsigned long reg_mask = 0;
  int pcreg = -1;
  int regno;

  if (start_pc == 0)
    return NULL;
  memset (&temp_proc_desc, '\0', sizeof (temp_proc_desc));
  memset (&temp_saved_regs, '\0', SIZEOF_FRAME_SAVED_REGS);
  PROC_LOW_ADDR (&temp_proc_desc) = start_pc;

  if (start_pc + 200 < limit_pc)
    limit_pc = start_pc + 200;
  frame_size = 0;
  for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4)
    {
      char buf[4];
      unsigned long word;
      int status;

      status = read_memory_nobpt (cur_pc, buf, 4);
      if (status)
	memory_error (status, cur_pc);
      word = extract_unsigned_integer (buf, 4);

      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) */
	       && (word & 0xffff0000) != 0xb7fe0000)	/* reg != $zero */
	{
	  int reg = (word & 0x03e00000) >> 21;
	  reg_mask |= 1 << reg;

          /* 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.
           */
          temp_saved_regs[reg] = (short) word;

	  /* 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
	     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 (pcreg == -1
	      && cur_pc < (start_pc + 80)
	      && (reg == ALPHA_T7_REGNUM || reg == ALPHA_T9_REGNUM
	          || reg == ALPHA_RA_REGNUM))
	    pcreg = reg;
	}
      else if ((word & 0xffe0ffff) == 0x6be08001)	/* ret zero,reg,1 */
	pcreg = (word >> 16) & 0x1f;
      else if (word == 0x47de040f || word == 0x47fe040f) /* bis sp,sp fp */
        {
          /* ??? I am not sure what instruction is 0x47fe040f, and I
             am suspecting that there was a typo and should have been
             0x47fe040f. I'm keeping it in the test above until further
             investigation */
	    has_frame_reg = 1;
          vfp = read_next_frame_reg (next_frame, ALPHA_GCC_FP_REGNUM);
        }
    }
  if (pcreg == -1)
    {
      /* If we haven't found a valid return address register yet,
         keep searching in the procedure prologue.  */
      while (cur_pc < (limit_pc + 80) && cur_pc < (start_pc + 80))
	{
	  char buf[4];
	  unsigned long word;

	  if (read_memory_nobpt (cur_pc, buf, 4))
	    break;
	  cur_pc += 4;
	  word = extract_unsigned_integer (buf, 4);

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

  if (has_frame_reg)
    PROC_FRAME_REG (&temp_proc_desc) = ALPHA_GCC_FP_REGNUM;
  else
    PROC_FRAME_REG (&temp_proc_desc) = SP_REGNUM;

  /* At this point, we know which of the Stack Pointer or the Frame Pointer
     to use as the reference address to compute the saved registers address.
     But in both cases, the processing above has set vfp to this reference
     address, so just need to increment the offset of each saved register
     by this address. */
  for (regno = 0; regno < NUM_REGS; regno++)
    {
      if (reg_mask & 1 << regno)
	temp_saved_regs[regno] += vfp;
    }

  PROC_FRAME_OFFSET (&temp_proc_desc) = frame_size;
  PROC_REG_MASK (&temp_proc_desc) = reg_mask;
  PROC_PC_REG (&temp_proc_desc) = (pcreg == -1) ? ALPHA_RA_REGNUM : pcreg;
  PROC_LOCALOFF (&temp_proc_desc) = 0;	/* XXX - bogus */
  return &temp_proc_desc;
}

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

static CORE_ADDR
after_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc)
{
  struct symtab_and_line sal;
  CORE_ADDR func_addr, func_end;

  if (!proc_desc)
    proc_desc = find_proc_desc (pc, NULL);

  if (proc_desc)
    {
      if (alpha_proc_desc_is_dyn_sigtramp (proc_desc))
	return PROC_LOW_ADDR (proc_desc);	/* "prologue" is in kernel */

      /* If function is frameless, then we need to do it the hard way.  I
         strongly suspect that frameless always means prologueless... */
      if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
	  && PROC_FRAME_OFFSET (proc_desc) == 0)
	return 0;
    }

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

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

/* Return non-zero if we *might* be in a function prologue.  Return zero if we
   are definitively *not* in a function prologue.  */

static int
alpha_in_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc)
{
  CORE_ADDR after_prologue_pc;

  after_prologue_pc = after_prologue (pc, proc_desc);

  if (after_prologue_pc == 0
      || pc < after_prologue_pc)
    return 1;
  else
    return 0;
}

static alpha_extra_func_info_t
find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame)
{
  alpha_extra_func_info_t proc_desc;
  struct block *b;
  struct symbol *sym;
  CORE_ADDR startaddr;

  /* Try to get the proc_desc from the linked call dummy proc_descs
     if the pc is in the call dummy.
     This is hairy. In the case of nested dummy calls we have to find the
     right proc_desc, but we might not yet know the frame for the dummy
     as it will be contained in the proc_desc we are searching for.
     So we have to find the proc_desc whose frame is closest to the current
     stack pointer.  */

  if (DEPRECATED_PC_IN_CALL_DUMMY (pc, 0, 0))
    {
      struct linked_proc_info *link;
      CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
      alpha_extra_func_info_t found_proc_desc = NULL;
      long min_distance = LONG_MAX;

      for (link = linked_proc_desc_table; link; link = link->next)
	{
	  long distance = (CORE_ADDR) PROC_DUMMY_FRAME (&link->info) - sp;
	  if (distance > 0 && distance < min_distance)
	    {
	      min_distance = distance;
	      found_proc_desc = &link->info;
	    }
	}
      if (found_proc_desc != NULL)
	return found_proc_desc;
    }

  b = block_for_pc (pc);

  find_pc_partial_function (pc, NULL, &startaddr, NULL);
  if (b == NULL)
    sym = NULL;
  else
    {
      if (startaddr > BLOCK_START (b))
	/* This is the "pathological" case referred to in a comment in
	   print_frame_info.  It might be better to move this check into
	   symbol reading.  */
	sym = NULL;
      else
	sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE,
			     0, NULL);
    }

  /* If we never found a PDR for this function in symbol reading, then
     examine prologues to find the information.  */
  if (sym && ((mips_extra_func_info_t) SYMBOL_VALUE (sym))->pdr.framereg == -1)
    sym = NULL;

  if (sym)
    {
      /* IF this is the topmost frame AND
       * (this proc does not have debugging information OR
       * the PC is in the procedure prologue)
       * THEN create a "heuristic" proc_desc (by analyzing
       * the actual code) to replace the "official" proc_desc.
       */
      proc_desc = (alpha_extra_func_info_t) SYMBOL_VALUE (sym);
      if (next_frame == NULL)
	{
	  if (PROC_DESC_IS_DUMMY (proc_desc) || alpha_in_prologue (pc, proc_desc))
	    {
	      alpha_extra_func_info_t found_heuristic =
	      heuristic_proc_desc (PROC_LOW_ADDR (proc_desc),
				   pc, next_frame);
	      if (found_heuristic)
		{
		  PROC_LOCALOFF (found_heuristic) =
		    PROC_LOCALOFF (proc_desc);
		  PROC_PC_REG (found_heuristic) = PROC_PC_REG (proc_desc);
		  proc_desc = found_heuristic;
		}
	    }
	}
    }
  else
    {
      long offset;

      /* Is linked_proc_desc_table really necessary?  It only seems to be used
         by procedure call dummys.  However, the procedures being called ought
         to have their own proc_descs, and even if they don't,
         heuristic_proc_desc knows how to create them! */

      register struct linked_proc_info *link;
      for (link = linked_proc_desc_table; link; link = link->next)
	if (PROC_LOW_ADDR (&link->info) <= pc
	    && PROC_HIGH_ADDR (&link->info) > pc)
	  return &link->info;

      /* If PC is inside a dynamically generated sigtramp handler,
         create and push a procedure descriptor for that code: */
      offset = alpha_dynamic_sigtramp_offset (pc);
      if (offset >= 0)
	return push_sigtramp_desc (pc - offset);

      /* If heuristic_fence_post is non-zero, determine the procedure
         start address by examining the instructions.
         This allows us to find the start address of static functions which
         have no symbolic information, as startaddr would have been set to
         the preceding global function start address by the
         find_pc_partial_function call above.  */
      if (startaddr == 0 || heuristic_fence_post != 0)
	startaddr = heuristic_proc_start (pc);

      proc_desc =
	heuristic_proc_desc (startaddr, pc, next_frame);
    }
  return proc_desc;
}

alpha_extra_func_info_t cached_proc_desc;

static CORE_ADDR
alpha_frame_chain (struct frame_info *frame)
{
  alpha_extra_func_info_t proc_desc;
  CORE_ADDR saved_pc = DEPRECATED_FRAME_SAVED_PC (frame);

  if (saved_pc == 0 || inside_entry_file (saved_pc))
    return 0;

  proc_desc = find_proc_desc (saved_pc, frame);
  if (!proc_desc)
    return 0;

  cached_proc_desc = proc_desc;

  /* Fetch the frame pointer for a dummy frame from the procedure
     descriptor.  */
  if (PROC_DESC_IS_DUMMY (proc_desc))
    return (CORE_ADDR) PROC_DUMMY_FRAME (proc_desc);

  /* If no frame pointer and frame size is zero, we must be at end
     of stack (or otherwise hosed).  If we don't check frame size,
     we loop forever if we see a zero size frame.  */
  if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
      && PROC_FRAME_OFFSET (proc_desc) == 0
  /* The previous frame from a sigtramp frame might be frameless
     and have frame size zero.  */
      && !(get_frame_type (frame) == SIGTRAMP_FRAME))
    return alpha_frame_past_sigtramp_frame (frame, saved_pc);
  else
    return read_next_frame_reg (frame, PROC_FRAME_REG (proc_desc))
      + PROC_FRAME_OFFSET (proc_desc);
}

void
alpha_print_extra_frame_info (struct frame_info *fi)
{
  if (fi
      && get_frame_extra_info (fi)
      && get_frame_extra_info (fi)->proc_desc
      && get_frame_extra_info (fi)->proc_desc->pdr.framereg < NUM_REGS)
    printf_filtered (" frame pointer is at %s+%s\n",
		     REGISTER_NAME (get_frame_extra_info (fi)->proc_desc->pdr.framereg),
		     paddr_d (get_frame_extra_info (fi)->proc_desc->pdr.frameoffset));
}

static void
alpha_init_extra_frame_info (int fromleaf, struct frame_info *frame)
{
  /* Use proc_desc calculated in frame_chain */
  alpha_extra_func_info_t proc_desc =
    get_next_frame (frame)
    ? cached_proc_desc
    : find_proc_desc (get_frame_pc (frame), get_next_frame (frame));

  frame_extra_info_zalloc (frame, sizeof (struct frame_extra_info));

  /* NOTE: cagney/2003-01-03: No need to set saved_regs to NULL,
     always NULL by default.  */
  /* frame->saved_regs = NULL; */
  get_frame_extra_info (frame)->localoff = 0;
  get_frame_extra_info (frame)->pc_reg = ALPHA_RA_REGNUM;
  get_frame_extra_info (frame)->proc_desc = proc_desc == &temp_proc_desc ? 0 : proc_desc;
  if (proc_desc)
    {
      /* Get the locals offset and the saved pc register from the
         procedure descriptor, they are valid even if we are in the
         middle of the prologue.  */
      get_frame_extra_info (frame)->localoff = PROC_LOCALOFF (proc_desc);
      get_frame_extra_info (frame)->pc_reg = PROC_PC_REG (proc_desc);

      /* Fixup frame-pointer - only needed for top frame */

      /* Fetch the frame pointer for a dummy frame from the procedure
         descriptor.  */
      if (PROC_DESC_IS_DUMMY (proc_desc))
	deprecated_update_frame_base_hack (frame, (CORE_ADDR) PROC_DUMMY_FRAME (proc_desc));

      /* This may not be quite right, if proc has a real frame register.
         Get the value of the frame relative sp, procedure might have been
         interrupted by a signal at it's very start.  */
      else if (get_frame_pc (frame) == PROC_LOW_ADDR (proc_desc)
	       && !alpha_proc_desc_is_dyn_sigtramp (proc_desc))
	deprecated_update_frame_base_hack (frame, read_next_frame_reg (get_next_frame (frame), SP_REGNUM));
      else
	deprecated_update_frame_base_hack (frame, read_next_frame_reg (get_next_frame (frame), PROC_FRAME_REG (proc_desc))
					   + PROC_FRAME_OFFSET (proc_desc));

      if (proc_desc == &temp_proc_desc)
	{
	  char *name;

	  /* Do not set the saved registers for a sigtramp frame,
	     alpha_find_saved_registers will do that for us.  We can't
	     use (get_frame_type (frame) == SIGTRAMP_FRAME), it is not
	     yet set.  */
	  /* FIXME: cagney/2002-11-18: This problem will go away once
             frame.c:get_prev_frame() is modified to set the frame's
             type before calling functions like this.  */
	  find_pc_partial_function (get_frame_pc (frame), &name,
				    (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
	  if (!PC_IN_SIGTRAMP (get_frame_pc (frame), name))
	    {
	      frame_saved_regs_zalloc (frame);
	      memcpy (get_frame_saved_regs (frame), temp_saved_regs,
	              SIZEOF_FRAME_SAVED_REGS);
	      get_frame_saved_regs (frame)[PC_REGNUM]
		= get_frame_saved_regs (frame)[ALPHA_RA_REGNUM];
	    }
	}
    }
}

static CORE_ADDR
alpha_frame_locals_address (struct frame_info *fi)
{
  return (get_frame_base (fi) - get_frame_extra_info (fi)->localoff);
}

static CORE_ADDR
alpha_frame_args_address (struct frame_info *fi)
{
  return (get_frame_base (fi) - (ALPHA_NUM_ARG_REGS * 8));
}

/* ALPHA stack frames are almost impenetrable.  When execution stops,
   we basically have to look at symbol information for the function
   that we stopped in, which tells us *which* register (if any) is
   the base of the frame pointer, and what offset from that register
   the frame itself is at.  

   This presents a problem when trying to examine a stack in memory
   (that isn't executing at the moment), using the "frame" command.  We
   don't have a PC, nor do we have any registers except SP.

   This routine takes two arguments, SP and PC, and tries to make the
   cached frames look as if these two arguments defined a frame on the
   cache.  This allows the rest of info frame to extract the important
   arguments without difficulty.  */

struct frame_info *
alpha_setup_arbitrary_frame (int argc, CORE_ADDR *argv)
{
  if (argc != 2)
    error ("ALPHA frame specifications require two arguments: sp and pc");

  return create_new_frame (argv[0], argv[1]);
}

/* The alpha passes the first six arguments in the registers, the rest on
   the stack. The register arguments are eventually transferred to the
   argument transfer area immediately below the stack by the called function
   anyway. So we `push' at least six arguments on the stack, `reload' the
   argument registers and then adjust the stack pointer to point past the
   sixth argument. This algorithm simplifies the passing of a large struct
   which extends from the registers to the stack.
   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_arguments (int nargs, struct value **args, CORE_ADDR sp,
		      int struct_return, CORE_ADDR struct_addr)
{
  int i;
  int accumulate_size = struct_return ? 8 : 0;
  int arg_regs_size = ALPHA_NUM_ARG_REGS * 8;
  struct alpha_arg
    {
      char *contents;
      int len;
      int offset;
    };
  struct alpha_arg *alpha_args =
  (struct alpha_arg *) alloca (nargs * sizeof (struct alpha_arg));
  register struct alpha_arg *m_arg;
  char raw_buffer[sizeof (CORE_ADDR)];
  int required_arg_regs;

  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) < TYPE_LENGTH (builtin_type_long))
	    {
	      arg_type = builtin_type_long;
	      arg = value_cast (arg_type, arg);
	    }
	  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 < arg_regs_size)
    accumulate_size = arg_regs_size;
  sp -= accumulate_size;

  /* Keep sp aligned to a multiple of 16 as the compiler does it too.  */
  sp &= ~15;

  /* `Push' arguments on the stack.  */
  for (i = nargs; m_arg--, --i >= 0;)
    write_memory (sp + m_arg->offset, m_arg->contents, m_arg->len);
  if (struct_return)
    {
      store_address (raw_buffer, sizeof (CORE_ADDR), struct_addr);
      write_memory (sp, raw_buffer, sizeof (CORE_ADDR));
    }

  /* Load the argument registers.  */
  for (i = 0; i < required_arg_regs; i++)
    {
      LONGEST val;

      val = read_memory_integer (sp + i * 8, 8);
      write_register (ALPHA_A0_REGNUM + i, val);
      write_register (ALPHA_FPA0_REGNUM + i, val);
    }

  return sp + arg_regs_size;
}

static void
alpha_push_dummy_frame (void)
{
  int ireg;
  struct linked_proc_info *link;
  alpha_extra_func_info_t proc_desc;
  CORE_ADDR sp = read_register (SP_REGNUM);
  CORE_ADDR save_address;
  char raw_buffer[ALPHA_MAX_REGISTER_RAW_SIZE];
  unsigned long mask;

  link = (struct linked_proc_info *) xmalloc (sizeof (struct linked_proc_info));
  link->next = linked_proc_desc_table;
  linked_proc_desc_table = link;

  proc_desc = &link->info;

  /*
   * The registers we must save are all those not preserved across
   * procedure calls.
   * In addition, we must save the PC and RA.
   *
   * Dummy frame layout:
   *  (high memory)
   *    Saved PC
   *    Saved F30
   *    ...
   *    Saved F0
   *    Saved R29
   *    ...
   *    Saved R0
   *    Saved R26 (RA)
   *    Parameter build area
   *  (low memory)
   */

/* MASK(i,j) == (1<<i) + (1<<(i+1)) + ... + (1<<j)). Assume i<=j<31. */
#define MASK(i,j) ((((LONGEST)1 << ((j)+1)) - 1) ^ (((LONGEST)1 << (i)) - 1))
#define GEN_REG_SAVE_MASK (MASK(0,8) | MASK(16,29))
#define GEN_REG_SAVE_COUNT 24
#define FLOAT_REG_SAVE_MASK (MASK(0,1) | MASK(10,30))
#define FLOAT_REG_SAVE_COUNT 23
  /* The special register is the PC as we have no bit for it in the save masks.
     alpha_frame_saved_pc knows where the pc is saved in a dummy frame.  */
#define SPECIAL_REG_SAVE_COUNT 1

  PROC_REG_MASK (proc_desc) = GEN_REG_SAVE_MASK;
  PROC_FREG_MASK (proc_desc) = FLOAT_REG_SAVE_MASK;
  /* PROC_REG_OFFSET is the offset from the dummy frame to the saved RA,
     but keep SP aligned to a multiple of 16.  */
  PROC_REG_OFFSET (proc_desc) =
    -((8 * (SPECIAL_REG_SAVE_COUNT
	    + GEN_REG_SAVE_COUNT
	    + FLOAT_REG_SAVE_COUNT)
       + 15) & ~15);
  PROC_FREG_OFFSET (proc_desc) =
    PROC_REG_OFFSET (proc_desc) + 8 * GEN_REG_SAVE_COUNT;

  /* Save general registers.
     The return address register is the first saved register, all other
     registers follow in ascending order.
     The PC is saved immediately below the SP.  */
  save_address = sp + PROC_REG_OFFSET (proc_desc);
  store_address (raw_buffer, 8, read_register (ALPHA_RA_REGNUM));
  write_memory (save_address, raw_buffer, 8);
  save_address += 8;
  mask = PROC_REG_MASK (proc_desc) & 0xffffffffL;
  for (ireg = 0; mask; ireg++, mask >>= 1)
    if (mask & 1)
      {
	if (ireg == ALPHA_RA_REGNUM)
	  continue;
	store_address (raw_buffer, 8, read_register (ireg));
	write_memory (save_address, raw_buffer, 8);
	save_address += 8;
      }

  store_address (raw_buffer, 8, read_register (PC_REGNUM));
  write_memory (sp - 8, raw_buffer, 8);

  /* Save floating point registers.  */
  save_address = sp + PROC_FREG_OFFSET (proc_desc);
  mask = PROC_FREG_MASK (proc_desc) & 0xffffffffL;
  for (ireg = 0; mask; ireg++, mask >>= 1)
    if (mask & 1)
      {
	store_address (raw_buffer, 8, read_register (ireg + FP0_REGNUM));
	write_memory (save_address, raw_buffer, 8);
	save_address += 8;
      }

  /* Set and save the frame address for the dummy.  
     This is tricky. The only registers that are suitable for a frame save
     are those that are preserved across procedure calls (s0-s6). But if
     a read system call is interrupted and then a dummy call is made
     (see testsuite/gdb.t17/interrupt.exp) the dummy call hangs till the read
     is satisfied. Then it returns with the s0-s6 registers set to the values
     on entry to the read system call and our dummy frame pointer would be
     destroyed. So we save the dummy frame in the proc_desc and handle the
     retrieval of the frame pointer of a dummy specifically. The frame register
     is set to the virtual frame (pseudo) register, it's value will always
     be read as zero and will help us to catch any errors in the dummy frame
     retrieval code.  */
  PROC_DUMMY_FRAME (proc_desc) = sp;
  PROC_FRAME_REG (proc_desc) = FP_REGNUM;
  PROC_FRAME_OFFSET (proc_desc) = 0;
  sp += PROC_REG_OFFSET (proc_desc);
  write_register (SP_REGNUM, sp);

  PROC_LOW_ADDR (proc_desc) = CALL_DUMMY_ADDRESS ();
  PROC_HIGH_ADDR (proc_desc) = PROC_LOW_ADDR (proc_desc) + 4;

  SET_PROC_DESC_IS_DUMMY (proc_desc);
  PROC_PC_REG (proc_desc) = ALPHA_RA_REGNUM;
}

static void
alpha_pop_frame (void)
{
  register int regnum;
  struct frame_info *frame = get_current_frame ();
  CORE_ADDR new_sp = get_frame_base (frame);

  alpha_extra_func_info_t proc_desc = get_frame_extra_info (frame)->proc_desc;

  /* we need proc_desc to know how to restore the registers;
     if it is NULL, construct (a temporary) one */
  if (proc_desc == NULL)
    proc_desc = find_proc_desc (get_frame_pc (frame), get_next_frame (frame));

  /* Question: should we copy this proc_desc and save it in
     frame->proc_desc?  If we do, who will free it?
     For now, we don't save a copy... */

  write_register (PC_REGNUM, DEPRECATED_FRAME_SAVED_PC (frame));
  if (get_frame_saved_regs (frame) == NULL)
    alpha_find_saved_regs (frame);
  if (proc_desc)
    {
      for (regnum = 32; --regnum >= 0;)
	if (PROC_REG_MASK (proc_desc) & (1 << regnum))
	  write_register (regnum,
			  read_memory_integer (get_frame_saved_regs (frame)[regnum],
					       8));
      for (regnum = 32; --regnum >= 0;)
	if (PROC_FREG_MASK (proc_desc) & (1 << regnum))
	  write_register (regnum + FP0_REGNUM,
	   read_memory_integer (get_frame_saved_regs (frame)[regnum + FP0_REGNUM], 8));
    }
  write_register (SP_REGNUM, new_sp);
  flush_cached_frames ();

  if (proc_desc && (PROC_DESC_IS_DUMMY (proc_desc)
		    || alpha_proc_desc_is_dyn_sigtramp (proc_desc)))
    {
      struct linked_proc_info *pi_ptr, *prev_ptr;

      for (pi_ptr = linked_proc_desc_table, prev_ptr = NULL;
	   pi_ptr != NULL;
	   prev_ptr = pi_ptr, pi_ptr = pi_ptr->next)
	{
	  if (&pi_ptr->info == proc_desc)
	    break;
	}

      if (pi_ptr == NULL)
	error ("Can't locate dummy extra frame info\n");

      if (prev_ptr != NULL)
	prev_ptr->next = pi_ptr->next;
      else
	linked_proc_desc_table = pi_ptr->next;

      xfree (pi_ptr);
    }
}

/* 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.
   Currently we must not skip more on the alpha, but we might need the
   lenient stuff some day.  */

static CORE_ADDR
alpha_skip_prologue_internal (CORE_ADDR pc, int lenient)
{
  unsigned long inst;
  int offset;
  CORE_ADDR post_prologue_pc;
  char buf[4];

  /* 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, 4))
    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 = after_prologue (pc, NULL);

  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 += 4)
    {
      int status;

      status = read_memory_nobpt (pc + offset, buf, 4);
      if (status)
	memory_error (status, pc + offset);
      inst = extract_unsigned_integer (buf, 4);

      /* The alpha has no delay slots. But let's keep the lenient stuff,
         we might need it for something else in the future.  */
      if (lenient && 0)
	continue;

      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
	  && (inst & 0xffff0000) != 0xb7fe0000)
	continue;		/* stq reg,n($sp) */
      /* reg != $zero */
      if ((inst & 0xfc1f0000) == 0x9c1e0000
	  && (inst & 0xffff0000) != 0x9ffe0000)
	continue;		/* stt reg,n($sp) */
      /* reg != $zero */
      if (inst == 0x47de040f)	/* bis sp,sp,fp */
	continue;

      break;
    }
  return pc + offset;
}

static CORE_ADDR
alpha_skip_prologue (CORE_ADDR addr)
{
  return (alpha_skip_prologue_internal (addr, 0));
}

#if 0
/* Is address PC in the prologue (loosely defined) for function at
   STARTADDR?  */

static int
alpha_in_lenient_prologue (CORE_ADDR startaddr, CORE_ADDR pc)
{
  CORE_ADDR end_prologue = alpha_skip_prologue_internal (startaddr, 1);
  return pc >= startaddr && pc < end_prologue;
}
#endif

/* 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 void
alpha_register_convert_to_virtual (int regnum, struct type *valtype,
				   char *raw_buffer, char *virtual_buffer)
{
  if (TYPE_LENGTH (valtype) >= REGISTER_RAW_SIZE (regnum))
    {
      memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
      return;
    }

  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
    {
      double d = deprecated_extract_floating (raw_buffer, REGISTER_RAW_SIZE (regnum));
      deprecated_store_floating (virtual_buffer, TYPE_LENGTH (valtype), d);
    }
  else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4)
    {
      ULONGEST l;
      l = extract_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum));
      l = ((l >> 32) & 0xc0000000) | ((l >> 29) & 0x3fffffff);
      store_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype), l);
    }
  else
    error ("Cannot retrieve value from floating point register");
}

static void
alpha_register_convert_to_raw (struct type *valtype, int regnum,
			       char *virtual_buffer, char *raw_buffer)
{
  if (TYPE_LENGTH (valtype) >= REGISTER_RAW_SIZE (regnum))
    {
      memcpy (raw_buffer, virtual_buffer, REGISTER_RAW_SIZE (regnum));
      return;
    }

  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
    {
      double d = deprecated_extract_floating (virtual_buffer, TYPE_LENGTH (valtype));
      deprecated_store_floating (raw_buffer, REGISTER_RAW_SIZE (regnum), d);
    }
  else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4)
    {
      ULONGEST l;
      if (TYPE_UNSIGNED (valtype))
	l = extract_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype));
      else
	l = extract_signed_integer (virtual_buffer, TYPE_LENGTH (valtype));
      l = ((l & 0xc0000000) << 32) | ((l & 0x3fffffff) << 29);
      store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), l);
    }
  else
    error ("Cannot store value in floating point register");
}

static const unsigned char *
alpha_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
{
  static const unsigned char alpha_breakpoint[] =
    { 0x80, 0, 0, 0 };	/* call_pal bpt */

  *lenptr = sizeof(alpha_breakpoint);
  return (alpha_breakpoint);
}

/* Given a return value in `regbuf' with a type `valtype', 
   extract and copy its value into `valbuf'.  */

static void
alpha_extract_return_value (struct type *valtype,
			    char regbuf[ALPHA_REGISTER_BYTES], char *valbuf)
{
  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
    alpha_register_convert_to_virtual (FP0_REGNUM, valtype,
				       regbuf + REGISTER_BYTE (FP0_REGNUM),
				       valbuf);
  else
    memcpy (valbuf, regbuf + REGISTER_BYTE (ALPHA_V0_REGNUM),
            TYPE_LENGTH (valtype));
}

/* Given a return value in `regbuf' with a type `valtype', 
   write its value into the appropriate register.  */

static void
alpha_store_return_value (struct type *valtype, char *valbuf)
{
  char raw_buffer[ALPHA_MAX_REGISTER_RAW_SIZE];
  int regnum = ALPHA_V0_REGNUM;
  int length = TYPE_LENGTH (valtype);

  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
    {
      regnum = FP0_REGNUM;
      length = REGISTER_RAW_SIZE (regnum);
      alpha_register_convert_to_raw (valtype, regnum, valbuf, raw_buffer);
    }
  else
    memcpy (raw_buffer, valbuf, length);

  deprecated_write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, length);
}

/* Just like reinit_frame_cache, but with the right arguments to be
   callable as an sfunc.  */

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

/* This is the definition of CALL_DUMMY_ADDRESS.  It's a heuristic that is used
   to find a convenient place in the text segment to stick a breakpoint to
   detect the completion of a target function call (ala call_function_by_hand).
 */

CORE_ADDR
alpha_call_dummy_address (void)
{
  CORE_ADDR entry;
  struct minimal_symbol *sym;

  entry = entry_point_address ();

  if (entry != 0)
    return entry;

  sym = lookup_minimal_symbol ("_Prelude", NULL, symfile_objfile);

  if (!sym || MSYMBOL_TYPE (sym) != mst_text)
    return 0;
  else
    return SYMBOL_VALUE_ADDRESS (sym) + 4;
}

static void
alpha_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
                      struct value **args, struct type *type, int gcc_p)
{
  CORE_ADDR bp_address = CALL_DUMMY_ADDRESS ();

  if (bp_address == 0)
    error ("no place to put call");
  write_register (ALPHA_RA_REGNUM, bp_address);
  write_register (ALPHA_T12_REGNUM, fun);
}

/* On the Alpha, the call dummy code is nevery copied to user space
   (see alpha_fix_call_dummy() above).  The contents of this do not
   matter.  */
LONGEST alpha_call_dummy_words[] = { 0 };

static int
alpha_use_struct_convention (int gcc_p, struct type *type)
{
  /* Structures are returned by ref in extra arg0.  */
  return 1;
}

static void
alpha_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
{
  /* Store the address of the place in which to copy the structure the
     subroutine will return.  Handled by alpha_push_arguments.  */
}

static CORE_ADDR
alpha_extract_struct_value_address (char *regbuf)
{
  return (extract_address (regbuf + REGISTER_BYTE (ALPHA_V0_REGNUM),
			   REGISTER_RAW_SIZE (ALPHA_V0_REGNUM)));
}

/* 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 (CORE_ADDR *pc)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
  CORE_ADDR jb_addr;
  char raw_buffer[ALPHA_MAX_REGISTER_RAW_SIZE];

  jb_addr = read_register (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_address (raw_buffer, tdep->jb_elt_size);
  return 1;
}

/* 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.

   single_step is also called just after the inferior stops.  If we had
   set up a simulated single-step, we undo our damage.  */

static CORE_ADDR
alpha_next_pc (CORE_ADDR pc)
{
  unsigned int insn;
  unsigned int op;
  int offset;
  LONGEST rav;

  insn = read_memory_unsigned_integer (pc, sizeof (insn));

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

  if (op == 0x1a)
    {
      /* Jump format: target PC is:
	 RB & ~3  */
      return (read_register ((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 *= 4;
	  return (pc + 4 + offset);
	}

      /* Need to determine if branch is taken; read RA.  */
      rav = (LONGEST) read_register ((insn >> 21) & 0x1f);
      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;
	}
    }

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

void
alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
  static CORE_ADDR next_pc;
  typedef char binsn_quantum[BREAKPOINT_MAX];
  static binsn_quantum break_mem;
  CORE_ADDR pc;

  if (insert_breakpoints_p)
    {
      pc = read_pc ();
      next_pc = alpha_next_pc (pc);

      target_insert_breakpoint (next_pc, break_mem);
    }
  else
    {
      target_remove_breakpoint (next_pc, break_mem);
      write_pc (next_pc);
    }
}



/* 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) 0x120000000;

  tdep->dynamic_sigtramp_offset = NULL;
  tdep->skip_sigtramp_frame = NULL;
  tdep->sigcontext_addr = NULL;

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

  /* 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_fp_regnum (gdbarch, ALPHA_FP_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_size (gdbarch, ALPHA_REGISTER_SIZE);
  set_gdbarch_register_bytes (gdbarch, ALPHA_REGISTER_BYTES);
  set_gdbarch_register_byte (gdbarch, alpha_register_byte);
  set_gdbarch_register_raw_size (gdbarch, alpha_register_raw_size);
  set_gdbarch_deprecated_max_register_raw_size (gdbarch, ALPHA_MAX_REGISTER_RAW_SIZE);
  set_gdbarch_register_virtual_size (gdbarch, alpha_register_virtual_size);
  set_gdbarch_deprecated_max_register_virtual_size (gdbarch,
                                         ALPHA_MAX_REGISTER_VIRTUAL_SIZE);
  set_gdbarch_register_virtual_type (gdbarch, alpha_register_virtual_type);

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

  set_gdbarch_register_convertible (gdbarch, alpha_register_convertible);
  set_gdbarch_register_convert_to_virtual (gdbarch,
                                           alpha_register_convert_to_virtual);
  set_gdbarch_register_convert_to_raw (gdbarch, alpha_register_convert_to_raw);

  set_gdbarch_skip_prologue (gdbarch, alpha_skip_prologue);

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

  set_gdbarch_deprecated_saved_pc_after_call (gdbarch, alpha_saved_pc_after_call);

  set_gdbarch_deprecated_frame_chain (gdbarch, alpha_frame_chain);
  set_gdbarch_deprecated_frame_saved_pc (gdbarch, alpha_frame_saved_pc);

  set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, alpha_frame_init_saved_regs);

  set_gdbarch_use_struct_convention (gdbarch, alpha_use_struct_convention);
  set_gdbarch_deprecated_extract_return_value (gdbarch, alpha_extract_return_value);

  set_gdbarch_deprecated_store_struct_return (gdbarch, alpha_store_struct_return);
  set_gdbarch_deprecated_store_return_value (gdbarch, alpha_store_return_value);
  set_gdbarch_deprecated_extract_struct_value_address (gdbarch,
					    alpha_extract_struct_value_address);

  /* Settings for calling functions in the inferior.  */
  set_gdbarch_deprecated_use_generic_dummy_frames (gdbarch, 0);
  set_gdbarch_deprecated_push_arguments (gdbarch, alpha_push_arguments);
  set_gdbarch_deprecated_pop_frame (gdbarch, alpha_pop_frame);

  /* On the Alpha, the call dummy code is never copied to user space,
     stopping the user call is achieved via a bp_call_dummy breakpoint.
     But we need a fake CALL_DUMMY definition to enable the proper
     call_function_by_hand and to avoid zero length array warnings.  */
  set_gdbarch_call_dummy_words (gdbarch, alpha_call_dummy_words);
  set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
  set_gdbarch_frame_args_address (gdbarch, alpha_frame_args_address);
  set_gdbarch_frame_locals_address (gdbarch, alpha_frame_locals_address);
  set_gdbarch_deprecated_init_extra_frame_info (gdbarch, alpha_init_extra_frame_info);

  /* Alpha OSF/1 inhibits execution of code on the stack.  But there is
     no need for a dummy on the Alpha.  PUSH_ARGUMENTS takes care of all
     argument handling and bp_call_dummy takes care of stopping the dummy.  */
  set_gdbarch_call_dummy_address (gdbarch, alpha_call_dummy_address);
  set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_at_entry_point);
  set_gdbarch_deprecated_push_dummy_frame (gdbarch, alpha_push_dummy_frame);
  /* Should be using push_dummy_call.  */
  set_gdbarch_deprecated_dummy_write_sp (gdbarch, generic_target_write_sp);
  set_gdbarch_fix_call_dummy (gdbarch, alpha_fix_call_dummy);
  set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_noop);
  set_gdbarch_deprecated_init_frame_pc_first (gdbarch, alpha_init_frame_pc_first);

  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, 4);

  set_gdbarch_function_start_offset (gdbarch, 0);
  set_gdbarch_frame_args_skip (gdbarch, 0);

  /* 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);

  return gdbarch;
}

static void
alpha_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);

  if (tdep == NULL)
    return;

  fprintf_unfiltered (file,
                      "alpha_dump_tdep: vm_min_address = 0x%lx\n",
		      (long) tdep->vm_min_address);

  fprintf_unfiltered (file,
		      "alpha_dump_tdep: jb_pc = %d\n",
		      tdep->jb_pc);
  fprintf_unfiltered (file,
		      "alpha_dump_tdep: jb_elt_size = %ld\n",
		      (long) tdep->jb_elt_size);
}

void
_initialize_alpha_tdep (void)
{
  struct cmd_list_element *c;

  gdbarch_register (bfd_arch_alpha, alpha_gdbarch_init, alpha_dump_tdep);

  tm_print_insn = print_insn_alpha;

  /* 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.  */
  c = add_set_cmd ("heuristic-fence-post", class_support, var_zinteger,
		   (char *) &heuristic_fence_post,
		   "\
Set the distance searched for the start of a function.\n\
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.",
		   &setlist);
  /* We need to throw away the frame cache when we set this, since it
     might change our ability to get backtraces.  */
  set_cmd_sfunc (c, reinit_frame_cache_sfunc);
  add_show_from_set (c, &showlist);
}
