/* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger.
   Copyright 1993, 94, 95, 96, 97, 1998 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"

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

/* Prototypes for local functions. */

static alpha_extra_func_info_t push_sigtramp_desc PARAMS ((CORE_ADDR low_addr));

static CORE_ADDR read_next_frame_reg PARAMS ((struct frame_info *, int));

static CORE_ADDR heuristic_proc_start PARAMS ((CORE_ADDR));

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

static alpha_extra_func_info_t find_proc_desc PARAMS ((CORE_ADDR,
						       struct frame_info *));

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

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

static CORE_ADDR after_prologue PARAMS ((CORE_ADDR pc,
					 alpha_extra_func_info_t proc_desc));

static int alpha_in_prologue PARAMS ((CORE_ADDR pc,
				      alpha_extra_func_info_t proc_desc));

static int alpha_about_to_return PARAMS ((CORE_ADDR pc));

void _initialize_alpha_tdep PARAMS ((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;


/* Under GNU/Linux, signal handler invocations can be identified by the
   designated code sequence that is used to return from a signal
   handler.  In particular, the return address of a signal handler
   points to the following sequence (the first instruction is quadword
   aligned):

   bis $30,$30,$16
   addq $31,0x67,$0
   call_pal callsys

   Each instruction has a unique encoding, so we simply attempt to
   match the instruction the pc is pointing to with any of the above
   instructions.  If there is a hit, we know the offset to the start
   of the designated sequence and can then check whether we really are
   executing in a designated sequence.  If not, -1 is returned,
   otherwise the offset from the start of the desingated sequence is
   returned.

   There is a slight chance of false hits: code could jump into the
   middle of the designated sequence, in which case there is no
   guarantee that we are in the middle of a sigreturn syscall.  Don't
   think this will be a problem in praxis, though.
 */

#ifndef TM_LINUXALPHA_H
/* HACK: Provide a prototype when compiling this file for non
   linuxalpha targets. */
long alpha_linux_sigtramp_offset PARAMS ((CORE_ADDR pc));
#endif
long
alpha_linux_sigtramp_offset (pc)
     CORE_ADDR pc;
{
  unsigned int i[3], w;
  long off;

  if (read_memory_nobpt (pc, (char *) &w, 4) != 0)
    return -1;

  off = -1;
  switch (w)
    {
    case 0x47de0410:
      off = 0;
      break;			/* bis $30,$30,$16 */
    case 0x43ecf400:
      off = 4;
      break;			/* addq $31,0x67,$0 */
    case 0x00000083:
      off = 8;
      break;			/* call_pal callsys */
    default:
      return -1;
    }
  pc -= off;
  if (pc & 0x7)
    {
      /* designated sequence is not quadword aligned */
      return -1;
    }

  if (read_memory_nobpt (pc, (char *) i, sizeof (i)) != 0)
    return -1;

  if (i[0] == 0x47de0410 && i[1] == 0x43ecf400 && i[2] == 0x00000083)
    return off;

  return -1;
}


/* Under OSF/1, the __sigtramp routine is frameless and has a frame
   size of zero, but we are able to backtrace through it.  */
CORE_ADDR
alpha_osf_skip_sigtramp_frame (frame, pc)
     struct frame_info *frame;
     CORE_ADDR pc;
{
  char *name;
  find_pc_partial_function (pc, &name, (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
  if (IN_SIGTRAMP (pc, name))
    return frame->frame;
  else
    return 0;
}


/* 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 (low_addr)
     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;
  SET_PROC_DESC_IS_DYN_SIGTRAMP (proc_desc);
  return (proc_desc);
}


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

void
alpha_find_saved_regs (frame)
     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 (frame->signal_handler_caller)
    {
      CORE_ADDR sigcontext_addr;

      sigcontext_addr = SIGCONTEXT_ADDR (frame);
      for (ireg = 0; ireg < 32; ireg++)
	{
	  reg_position = sigcontext_addr + SIGFRAME_REGSAVE_OFF + ireg * 8;
	  frame->saved_regs[ireg] = reg_position;
	}
      for (ireg = 0; ireg < 32; ireg++)
	{
	  reg_position = sigcontext_addr + SIGFRAME_FPREGSAVE_OFF + ireg * 8;
	  frame->saved_regs[FP0_REGNUM + ireg] = reg_position;
	}
      frame->saved_regs[PC_REGNUM] = sigcontext_addr + SIGFRAME_PC_OFF;
      return;
    }

  proc_desc = 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 = frame->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))
    {
      frame->saved_regs[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))
      {
	frame->saved_regs[ireg] = reg_position;
	reg_position += 8;
      }

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

  reg_position = frame->frame + PROC_FREG_OFFSET (proc_desc);
  mask = PROC_FREG_MASK (proc_desc);

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

  frame->saved_regs[PC_REGNUM] = frame->saved_regs[returnreg];
}

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

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

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

  return read_next_frame_reg (frame, pcreg);
}

CORE_ADDR
alpha_saved_pc_after_call (frame)
     struct frame_info *frame;
{
  CORE_ADDR pc = frame->pc;
  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, frame->next);
  pcreg = proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM;

  if (frame->signal_handler_caller)
    return alpha_frame_saved_pc (frame);
  else
    return read_register (pcreg);
}


static struct alpha_extra_func_info temp_proc_desc;
static struct frame_saved_regs temp_saved_regs;

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

static int
alpha_about_to_return (pc)
     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 (pc)
     CORE_ADDR pc;
{
  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 < VM_MIN_ADDRESS)
    fence = 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 == 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 (start_pc, limit_pc, next_frame)
     CORE_ADDR start_pc, limit_pc;
     struct frame_info *next_frame;
{
  CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
  CORE_ADDR cur_pc;
  int frame_size;
  int has_frame_reg = 0;
  unsigned long reg_mask = 0;
  int pcreg = -1;

  if (start_pc == 0)
    return NULL;
  memset (&temp_proc_desc, '\0', sizeof (temp_proc_desc));
  memset (&temp_saved_regs, '\0', sizeof (struct 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)
	    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;
	  temp_saved_regs.regs[reg] = sp + (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 == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM))
	    pcreg = reg;
	}
      else if ((word & 0xffe0ffff) == 0x6be08001)	/* ret zero,reg,1 */
	pcreg = (word >> 16) & 0x1f;
      else if (word == 0x47de040f)	/* bis sp,sp fp */
	has_frame_reg = 1;
    }
  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 == T7_REGNUM || reg == T9_REGNUM || reg == 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) = GCC_FP_REGNUM;
  else
    PROC_FRAME_REG (&temp_proc_desc) = SP_REGNUM;
  PROC_FRAME_OFFSET (&temp_proc_desc) = frame_size;
  PROC_REG_MASK (&temp_proc_desc) = reg_mask;
  PROC_PC_REG (&temp_proc_desc) = (pcreg == -1) ? 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 (pc, proc_desc)
     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 (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 (pc, proc_desc)
     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 (pc, next_frame)
     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 (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 = 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;

CORE_ADDR
alpha_frame_chain (frame)
     struct frame_info *frame;
{
  alpha_extra_func_info_t proc_desc;
  CORE_ADDR saved_pc = 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.  */
      && !frame->signal_handler_caller)
    return 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
init_extra_frame_info (frame)
     struct frame_info *frame;
{
  /* Use proc_desc calculated in frame_chain */
  alpha_extra_func_info_t proc_desc =
  frame->next ? cached_proc_desc : find_proc_desc (frame->pc, frame->next);

  frame->saved_regs = NULL;
  frame->localoff = 0;
  frame->pc_reg = RA_REGNUM;
  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.  */
      frame->localoff = PROC_LOCALOFF (proc_desc);
      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))
	frame->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 (frame->pc == PROC_LOW_ADDR (proc_desc)
	       && !PROC_DESC_IS_DYN_SIGTRAMP (proc_desc))
	frame->frame = read_next_frame_reg (frame->next, SP_REGNUM);
      else
	frame->frame = read_next_frame_reg (frame->next, 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 frame->signal_handler_caller, it is not yet set.  */
	  find_pc_partial_function (frame->pc, &name,
				    (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
	  if (!IN_SIGTRAMP (frame->pc, name))
	    {
	      frame->saved_regs = (CORE_ADDR *)
		frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS);
	      memcpy (frame->saved_regs, temp_saved_regs.regs, SIZEOF_FRAME_SAVED_REGS);
	      frame->saved_regs[PC_REGNUM]
		= frame->saved_regs[RA_REGNUM];
	    }
	}
    }
}

/* 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 *
setup_arbitrary_frame (argc, argv)
     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.  */

CORE_ADDR
alpha_push_arguments (nargs, args, sp, struct_return, struct_addr)
     int nargs;
     value_ptr *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++)
    {
      value_ptr 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 (A0_REGNUM + i, val);
      write_register (FPA0_REGNUM + i, val);
    }

  return sp + arg_regs_size;
}

void
alpha_push_dummy_frame ()
{
  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[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 (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 == 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) = RA_REGNUM;
}

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

  alpha_extra_func_info_t proc_desc = 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 (frame->pc, frame->next);

  /* 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, FRAME_SAVED_PC (frame));
  if (frame->saved_regs == 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 (frame->saved_regs[regnum],
					       8));
      for (regnum = 32; --regnum >= 0;)
	if (PROC_FREG_MASK (proc_desc) & (1 << regnum))
	  write_register (regnum + FP0_REGNUM,
	   read_memory_integer (frame->saved_regs[regnum + FP0_REGNUM], 8));
    }
  write_register (SP_REGNUM, new_sp);
  flush_cached_frames ();

  if (proc_desc && (PROC_DESC_IS_DUMMY (proc_desc)
		    || 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;

      free (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 the lenient
   stuff some day.  */

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

#ifdef GDB_TARGET_HAS_SHARED_LIBS
  /* 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.  */
  if (target_read_memory (pc, buf, 4))
    return pc;
#endif

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

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

static int
alpha_in_lenient_prologue (startaddr, pc)
     CORE_ADDR startaddr;
     CORE_ADDR pc;
{
  CORE_ADDR end_prologue = alpha_skip_prologue (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. */
void
alpha_register_convert_to_virtual (regnum, valtype, raw_buffer, virtual_buffer)
     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");
}

void
alpha_register_convert_to_raw (valtype, regnum, virtual_buffer, raw_buffer)
     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");
}

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

void
alpha_extract_return_value (valtype, regbuf, valbuf)
     struct type *valtype;
     char regbuf[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 (V0_REGNUM), TYPE_LENGTH (valtype));
}

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

void
alpha_store_return_value (valtype, valbuf)
     struct type *valtype;
     char *valbuf;
{
  char raw_buffer[MAX_REGISTER_RAW_SIZE];
  int regnum = 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);

  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 (args, from_tty, c)
     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 ()
{
  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;
}

void
_initialize_alpha_tdep ()
{
  struct cmd_list_element *c;

  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.  */
  c->function.sfunc = reinit_frame_cache_sfunc;
  add_show_from_set (c, &showlist);
}
