/* 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_saved_pc_after_call_ftype alpha_saved_pc_after_call;

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 ? 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_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 (!stop_soon_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 = extract_floating (raw_buffer, REGISTER_RAW_SIZE (regnum));
      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 = extract_floating (virtual_buffer, TYPE_LENGTH (valtype));
      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_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_call_dummy_length (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_p (gdbarch, 1);
  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_call_dummy_breakpoint_offset_p (gdbarch, 1);
  set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
  set_gdbarch_call_dummy_start_offset (gdbarch, 0);
  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);
}
