This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] SH: Deprecate deprecated functions, use new frame interface


Corinna Vinschen writes:
 > Hi,
 > 
 > the attached patch switches sh-tdep.c to using all the new frame code
 > stuff.  All deprecated functions are gone.  It implements its own
 > heuristic frame sniffer plus it adds the dwarf2 frame sniffer to the
 > frame unwind sniffer list.  This new code defines all register numbers
 > as enumeration values instead of as part of the tdep structure.  The
 > result is that the tdep structure could be eliminated entirely.  Some
 > defintions in sh-tdep.c have been changed for readability.
 > 

Seems ok, but....could you split the renaming of insn to inst and
removal of tdep into a separate patch, and repost the 2 patches?
I.e. the renaming/tdep and the real cleanups after that. It's not easy
to see what's going on with this diff.

thanks
elena



 > ChangeLog:
 > 
 > 	* sh-tdep.h (struct gdbarch_tdep): Remove.  Change all register
 > 	numbers to enumeration values.
 > 	* sh-tdep.c: Accomodate above change.
 > 	(SH_NUM_REGS): Rename from SH_DEFAULT_NUM_REGS.
 > 	(struct frame_extra_info): Remove.
 > 	(struct sh_frame_cache): New structure.
 > 	(NUM_PSEUDO_REGS_SH_MEDIA): Remove (sh5 only).
 > 	(NUM_PSEUDO_REGS_SH_COMPACT): Remove (sh5 only).
 > 	(GET_SOURCE_REG): New macro extracting source register of an opcode.
 > 	(GET_TARGET_REG): Ditto but target register.
 > 	(GET_PUSHED_REG): Remove.
 > 	(IS_ADD_IMM_SP): Rename from IS_ADD_SP.
 > 	(IS_FPUSH): Rename from IS_FMOV.
 > 	(IS_MOV_ARG_TO_REG): New macro.
 > 	(IS_MOV_ARG_TO_IND_R14): New macro.
 > 	(IS_MOV_ARG_TO_IND_R14_WITH_DISP): New macro.
 > 	(IS_MOVW_PCREL_TO_REG): New macro.
 > 	(IS_MOVL_PCREL_TO_REG): New macro.
 > 	(IS_SUB_REG_FROM_SP): New macro.
 > 	(IS_ARG_MOV): Remove.
 > 	(IS_MOV_TO_R14): Remove.
 > 	(IS_RESTORE_FP): New macro.
 > 	(IS_RTS): New macro.
 > 	(IS_LDS): New macro.
 > 	(IS_MOV_FP_SP): New macro.
 > 	(IS_ADD_REG_TO_FP): New macro.
 > 	(IS_ADD_IMM_FP): New macro.
 > 	(sh_skip_prologue_hard_way): Remove.
 > 	(sh_saved_pc_after_call): Remove.
 > 	(sh_frame_chain): Remove.
 > 	(sh_find_callers_reg): Remove.
 > 	(sh_nofp_frame_init_saved_regs): Remove.
 > 	(sh_fp_frame_init_saved_regs): Remove.
 > 	(sh_init_extra_frame_info): Remove.
 > 	(sh_analyze_prologue): New function.
 > 	(sh_skip_prologue): Remove deprecated code.  Rely on new function
 > 	sh_analyze_prologue when after_prologue fails.
 > 	(sh_extract_struct_value_address): Remove useless comment.
 > 	(sh_frame_saved_pc): Remove.
 > 	(sh_dsp_register_sim_regno): Use register values from sh-tdep.h
 > 	instead of own local values.
 > 	(sh_alloc_frame_cache): New function.
 > 	(sh_frame_cache): Ditto.
 > 	(sh_frame_prev_register): Ditto.
 > 	(sh_frame_this_id): Ditto.
 > 	(sh_frame_unwind): New structure defining the heuristic frame
 > 	sniffer interface.
 > 	(sh_frame_sniffer): New function.
 > 	(sh_unwind_sp): Ditto.
 > 	(sh_unwind_pc): Ditto.
 > 	(sh_unwind_dummy_id): Ditto.
 > 	(sh_frame_base_address): Ditto.
 > 	(sh_frame_base): New structure defining new frame base code.
 > 	(sh_in_function_epilogue_p): New function.
 > 	(sh_gdbarch_init): Restructure and simplify to eliminate deprecated
 > 	code and to call all new code instead.  Initialize dwarf2 and
 > 	heuristic frame sniffer.
 > 	(sh_dump_tdep): Remove.
 > 	(_initialize_sh_tdep): Accomodate removing sh_dump_tdep.
 > 	* sh3-rom.c (sh3_supply_register): Accomodate sh-tdep.h changes.
 > 
 > Index: sh-tdep.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/sh-tdep.c,v
 > retrieving revision 1.137
 > diff -u -p -r1.137 sh-tdep.c
 > --- sh-tdep.c	8 Sep 2003 11:26:20 -0000	1.137
 > +++ sh-tdep.c	8 Sep 2003 16:26:46 -0000
 > @@ -26,6 +26,9 @@
 >  
 >  #include "defs.h"
 >  #include "frame.h"
 > +#include "frame-base.h"
 > +#include "frame-unwind.h"
 > +#include "dwarf2-frame.h"
 >  #include "symtab.h"
 >  #include "symfile.h"
 >  #include "gdbtypes.h"
 > @@ -35,6 +38,7 @@
 >  #include "dis-asm.h"
 >  #include "inferior.h"
 >  #include "gdb_string.h"
 > +#include "gdb_assert.h"
 >  #include "arch-utils.h"
 >  #include "floatformat.h"
 >  #include "regcache.h"
 > @@ -53,17 +57,21 @@
 >  
 >  static void (*sh_show_regs) (void);
 >  
 > -#define SH_DEFAULT_NUM_REGS 59
 > +#define SH_NUM_REGS 59
 >  
 > -/* Define other aspects of the stack frame.
 > -   we keep a copy of the worked out return pc lying around, since it
 > -   is a useful bit of info */
 > -  
 > -struct frame_extra_info
 > +struct sh_frame_cache
 >  {
 > -  CORE_ADDR return_pc;
 > -  int leaf_function;
 > -  int f_offset;
 > +  /* Base address.  */
 > +  CORE_ADDR base;
 > +  LONGEST sp_offset;
 > +  CORE_ADDR pc;
 > +
 > +  /* Flag showing that a frame has been created in the prologue code. */
 > +  int uses_fp;
 > +
 > +  /* Saved registers.  */
 > +  CORE_ADDR saved_regs[SH_NUM_REGS];
 > +  CORE_ADDR saved_sp;
 >  };
 >  
 >  static const char *
 > @@ -256,9 +264,6 @@ sh_sh4_register_name (int reg_nr)
 >    return register_names[reg_nr];
 >  }
 >  
 > -#define NUM_PSEUDO_REGS_SH_MEDIA 80
 > -#define NUM_PSEUDO_REGS_SH_COMPACT 51
 > -
 >  static const unsigned char *
 >  sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
 >  {
 > @@ -286,29 +291,18 @@ sh_push_dummy_code (struct gdbarch *gdba
 >  }
 >  
 >  /* Prologue looks like
 > -   [mov.l       <regs>,@-r15]...
 > -   [sts.l       pr,@-r15]
 > -   [mov.l       r14,@-r15]
 > -   [mov         r15,r14]
 > -
 > -   Actually it can be more complicated than this.  For instance, with
 > -   newer gcc's:
 > -
 > -   mov.l   r14,@-r15
 > -   add     #-12,r15
 > -   mov     r15,r14
 > -   mov     r4,r1
 > -   mov     r5,r2
 > -   mov.l   r6,@(4,r14)
 > -   mov.l   r7,@(8,r14)
 > -   mov.b   r1,@r14
 > -   mov     r14,r1
 > -   mov     r14,r1
 > -   add     #2,r1
 > -   mov.w   r2,@r1
 > +   mov.l	r14,@-r15
 > +   sts.l	pr,@-r15
 > +   mov.l	<regs>,@-r15
 > +   sub		<room_for_loca_vars>,r15
 > +   mov		r15,r14
 >  
 > +   Actually it can be more complicated than this but that's it, basically.
 >   */
 >  
 > +#define GET_SOURCE_REG(x)  	(((x) >> 4) & 0xf)
 > +#define GET_TARGET_REG(x)  	(((x) >> 8) & 0xf)
 > +
 >  /* STS.L PR,@-r15  0100111100100010
 >     r15-4-->r15, PR-->(r15) */
 >  #define IS_STS(x)  		((x) == 0x4f22)
 > @@ -317,15 +311,13 @@ sh_push_dummy_code (struct gdbarch *gdba
 >     r15-4-->r15, Rm-->(R15) */
 >  #define IS_PUSH(x) 		(((x) & 0xff0f) == 0x2f06)
 >  
 > -#define GET_PUSHED_REG(x)  	(((x) >> 4) & 0xf)
 > -
 >  /* MOV r15,r14     0110111011110011
 >     r15-->r14  */
 >  #define IS_MOV_SP_FP(x)  	((x) == 0x6ef3)
 >  
 >  /* ADD #imm,r15    01111111iiiiiiii
 >     r15+imm-->r15 */
 > -#define IS_ADD_SP(x) 		(((x) & 0xff00) == 0x7f00)
 > +#define IS_ADD_IMM_SP(x) 	(((x) & 0xff00) == 0x7f00)
 >  
 >  #define IS_MOV_R3(x) 		(((x) & 0xff00) == 0x1a00)
 >  #define IS_SHLL_R3(x)		((x) == 0x4300)
 > @@ -337,133 +329,43 @@ sh_push_dummy_code (struct gdbarch *gdba
 >  /* FMOV.S FRm,@-Rn  Rn-4-->Rn, FRm-->(Rn)     1111nnnnmmmm1011
 >     FMOV DRm,@-Rn    Rn-8-->Rn, DRm-->(Rn)     1111nnnnmmm01011
 >     FMOV XDm,@-Rn    Rn-8-->Rn, XDm-->(Rn)     1111nnnnmmm11011 */
 > -#define IS_FMOV(x)		(((x) & 0xf00f) == 0xf00b)
 > +/* CV, 2003-08-28: Only suitable with Rn == SP, therefore name changed to
 > +		   make this entirely clear. */
 > +/* #define IS_FMOV(x)		(((x) & 0xf00f) == 0xf00b) */
 > +#define IS_FPUSH(x)		(((x) & 0xff0f) == 0xff0b)
 > +
 > +/* MOV Rm,Rn          Rm-->Rn        0110nnnnmmmm0011  4 <= m <= 7 */
 > +#define IS_MOV_ARG_TO_REG(x) \
 > +	(((x) & 0xf00f) == 0x6003 && \
 > +	 ((x) & 0x00f0) >= 0x0040 && \
 > +	 ((x) & 0x00f0) <= 0x0070)
 > +/* MOV.L Rm,@Rn               0010nnnnmmmm0010  n = 14, 4 <= m <= 7 */
 > +#define IS_MOV_ARG_TO_IND_R14(x) \
 > +	(((x) & 0xff0f) == 0x2e02 && \
 > +	 ((x) & 0x00f0) >= 0x0040 && \
 > +	 ((x) & 0x00f0) <= 0x0070)
 > +/* MOV.L Rm,@(disp*4,Rn)      00011110mmmmdddd  n = 14, 4 <= m <= 7 */
 > +#define IS_MOV_ARG_TO_IND_R14_WITH_DISP(x) \
 > +	(((x) & 0xff00) == 0x1e00 && \
 > +	 ((x) & 0x00f0) >= 0x0040 && \
 > +	 ((x) & 0x00f0) <= 0x0070)
 > +
 > +/* MOV.W @(disp*2,PC),Rn      1001nnnndddddddd */
 > +#define IS_MOVW_PCREL_TO_REG(x)	(((x) & 0xf000) == 0x9000)
 > +/* MOV.L @(disp*4,PC),Rn      1101nnnndddddddd */
 > +#define IS_MOVL_PCREL_TO_REG(x)	(((x) & 0xf000) == 0xd000)
 > +/* SUB Rn,R15                 00111111nnnn1000 */
 > +#define IS_SUB_REG_FROM_SP(x)	(((x) & 0xff0f) == 0x3f08)
 >  
 > -/* MOV Rm,Rn            Rm-->Rn          0110nnnnmmmm0011 
 > -   MOV.L Rm,@(disp,Rn)  Rm-->(dispx4+Rn) 0001nnnnmmmmdddd
 > -   MOV.L Rm,@Rn         Rm-->(Rn)        0010nnnnmmmm0010
 > -   where Rm is one of r4,r5,r6,r7 which are the argument registers. */
 > -#define IS_ARG_MOV(x) \
 > -(((((x) & 0xf00f) == 0x6003) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070)) \
 > - || ((((x) & 0xf000) == 0x1000) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070)) \
 > - || ((((x) & 0xf00f) == 0x2002) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070)))
 > -
 > -/* MOV.L Rm,@(disp,r14)  00011110mmmmdddd
 > -   Rm-->(dispx4+r14) where Rm is one of r4,r5,r6,r7 */
 > -#define IS_MOV_TO_R14(x) \
 > -     ((((x) & 0xff00) == 0x1e) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070))
 > -                        
 >  #define FPSCR_SZ		(1 << 20)
 >  
 > -/* Skip any prologue before the guts of a function */
 > -
 > -/* Skip the prologue using the debug information. If this fails we'll
 > -   fall back on the 'guess' method below. */
 > -static CORE_ADDR
 > -after_prologue (CORE_ADDR pc)
 > -{
 > -  struct symtab_and_line sal;
 > -  CORE_ADDR func_addr, func_end;
 > -
 > -  /* If we can not find the symbol in the partial symbol table, then
 > -     there is no hope we can determine the function's start address
 > -     with this code.  */
 > -  if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
 > -    return 0;
 > -
 > -  /* Get the line associated with FUNC_ADDR.  */
 > -  sal = find_pc_line (func_addr, 0);
 > -
 > -  /* There are only two cases to consider.  First, the end of the source line
 > -     is within the function bounds.  In that case we return the end of the
 > -     source line.  Second is the end of the source line extends beyond the
 > -     bounds of the current function.  We need to use the slow code to
 > -     examine instructions in that case.  */
 > -  if (sal.end < func_end)
 > -    return sal.end;
 > -  else
 > -    return 0;
 > -}
 > -
 > -/* Here we look at each instruction in the function, and try to guess
 > -   where the prologue ends. Unfortunately this is not always 
 > -   accurate. */
 > -static CORE_ADDR
 > -sh_skip_prologue_hard_way (CORE_ADDR start_pc)
 > -{
 > -  CORE_ADDR here, end;
 > -  int updated_fp = 0;
 > -
 > -  if (!start_pc)
 > -    return 0;
 > -
 > -  for (here = start_pc, end = start_pc + (2 * 28); here < end;)
 > -    {
 > -      int w = read_memory_integer (here, 2);
 > -      here += 2;
 > -      if (IS_FMOV (w) || IS_PUSH (w) || IS_STS (w) || IS_MOV_R3 (w)
 > -	  || IS_ADD_R3SP (w) || IS_ADD_SP (w) || IS_SHLL_R3 (w) 
 > -	  || IS_ARG_MOV (w) || IS_MOV_TO_R14 (w))
 > -	{
 > -	  start_pc = here;
 > -	}
 > -      else if (IS_MOV_SP_FP (w))
 > -	{
 > -	  start_pc = here;
 > -	  updated_fp = 1;
 > -	}
 > -      else
 > -	/* Don't bail out yet, if we are before the copy of sp. */
 > -	if (updated_fp)
 > -	  break;
 > -    }
 > -
 > -  return start_pc;
 > -}
 > -
 > -static CORE_ADDR
 > -sh_skip_prologue (CORE_ADDR pc)
 > -{
 > -  CORE_ADDR post_prologue_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);
 > -
 > -  /* If after_prologue returned a useful address, then use it.  Else
 > -     fall back on the instruction skipping code. */
 > -  if (post_prologue_pc != 0)
 > -    return max (pc, post_prologue_pc);
 > -  else
 > -    return sh_skip_prologue_hard_way (pc);
 > -}
 > -
 > -/* Immediately after a function call, return the saved pc.
 > -   Can't always go through the frames for this because on some machines
 > -   the new frame is not set up until the new function executes
 > -   some instructions.
 > -
 > -   The return address is the value saved in the PR register + 4  */
 > -static CORE_ADDR
 > -sh_saved_pc_after_call (struct frame_info *frame)
 > -{
 > -  return (ADDR_BITS_REMOVE (read_register (PR_REGNUM)));
 > -}
 > -
 > -/* Should call_function allocate stack space for a struct return?  */
 > -static int
 > -sh_use_struct_convention (int gcc_p, struct type *type)
 > -{
 > -#if 0
 > -  return (TYPE_LENGTH (type) > 1);
 > -#else
 > -  int len = TYPE_LENGTH (type);
 > -  int nelem = TYPE_NFIELDS (type);
 > -  return ((len != 1 && len != 2 && len != 4 && len != 8) || nelem != 1) &&
 > -	  (len != 8 || TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) != 4);
 > -#endif
 > -}
 > +/* The following instructions are used for epilogue testing. */
 > +#define IS_RESTORE_FP(x)	((x) == 0x6ef6)
 > +#define IS_RTS(x)		((x) == 0x000b)
 > +#define IS_LDS(x)  		((x) == 0x4f26)
 > +#define IS_MOV_FP_SP(x)  	((x) == 0x6fe3)
 > +#define IS_ADD_REG_TO_FP(x)	(((x) & 0xff0f) == 0x3e0c)
 > +#define IS_ADD_IMM_FP(x) 	(((x) & 0xff00) == 0x7e00)
 >  
 >  /* Disassemble an instruction.  */
 >  static int
 > @@ -473,295 +375,133 @@ gdb_print_insn_sh (bfd_vma memaddr, disa
 >    return print_insn_sh (memaddr, info);
 >  }
 >  
 > -/* Given a GDB frame, determine the address of the calling function's
 > -   frame.  This will be used to create a new GDB frame struct, and
 > -   then DEPRECATED_INIT_EXTRA_FRAME_INFO and DEPRECATED_INIT_FRAME_PC
 > -   will be called for the new frame.
 > -
 > -   For us, the frame address is its stack pointer value, so we look up
 > -   the function prologue to determine the caller's sp value, and return it.  */
 >  static CORE_ADDR
 > -sh_frame_chain (struct frame_info *frame)
 > -{
 > -  if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame),
 > -				   get_frame_base (frame),
 > -				   get_frame_base (frame)))
 > -    return get_frame_base (frame);	/* dummy frame same as caller's frame */
 > -  if (get_frame_pc (frame) && !inside_entry_file (get_frame_pc (frame)))
 > -    return read_memory_integer (get_frame_base (frame)
 > -				+ get_frame_extra_info (frame)->f_offset, 4);
 > -  else
 > -    return 0;
 > -}
 > -
 > -/* Find REGNUM on the stack.  Otherwise, it's in an active register.  One thing
 > -   we might want to do here is to check REGNUM against the clobber mask, and
 > -   somehow flag it as invalid if it isn't saved on the stack somewhere.  This
 > -   would provide a graceful failure mode when trying to get the value of
 > -   caller-saves registers for an inner frame.  */
 > -static CORE_ADDR
 > -sh_find_callers_reg (struct frame_info *fi, int regnum)
 > -{
 > -  for (; fi; fi = get_next_frame (fi))
 > -    if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
 > -				     get_frame_base (fi)))
 > -      /* When the caller requests PR from the dummy frame, we return PC because
 > -         that's where the previous routine appears to have done a call from. */
 > -      return deprecated_read_register_dummy (get_frame_pc (fi),
 > -					     get_frame_base (fi), regnum);
 > -    else
 > -      {
 > -	DEPRECATED_FRAME_INIT_SAVED_REGS (fi);
 > -	if (!get_frame_pc (fi))
 > -	  return 0;
 > -	if (get_frame_saved_regs (fi)[regnum] != 0)
 > -	  return read_memory_integer (get_frame_saved_regs (fi)[regnum],
 > -				      register_size (current_gdbarch, regnum));
 > -      }
 > -  return read_register (regnum);
 > -}
 > -
 > -/* Put here the code to store, into a struct frame_saved_regs, the
 > -   addresses of the saved registers of frame described by FRAME_INFO.
 > -   This includes special registers such as pc and fp saved in special
 > -   ways in the stack frame.  sp is even more special: the address we
 > -   return for it IS the sp for the next frame. */
 > -static void
 > -sh_nofp_frame_init_saved_regs (struct frame_info *fi)
 > -{
 > -  int *where = (int *) alloca ((NUM_REGS + NUM_PSEUDO_REGS) * sizeof(int));
 > -  int rn;
 > -  int have_fp = 0;
 > -  int depth;
 > -  int pc;
 > -  int opc;
 > -  int insn;
 > +sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
 > +		     struct sh_frame_cache *cache)
 > +{ 
 > +  ULONGEST inst;
 > +  CORE_ADDR opc;
 > +  int offset;
 > +  int sav_offset = 0;
 >    int r3_val = 0;
 > -  char *dummy_regs = deprecated_generic_find_dummy_frame (get_frame_pc (fi),
 > -							  get_frame_base (fi));
 > -  
 > -  if (get_frame_saved_regs (fi) == NULL)
 > -    frame_saved_regs_zalloc (fi);
 > -  else
 > -    memset (get_frame_saved_regs (fi), 0, SIZEOF_FRAME_SAVED_REGS);
 > -  
 > -  if (dummy_regs)
 > -    {
 > -      /* DANGER!  This is ONLY going to work if the char buffer format of
 > -         the saved registers is byte-for-byte identical to the 
 > -         CORE_ADDR regs[NUM_REGS] format used by struct frame_saved_regs! */
 > -      memcpy (get_frame_saved_regs (fi), dummy_regs, SIZEOF_FRAME_SAVED_REGS);
 > -      return;
 > -    }
 > -
 > -  get_frame_extra_info (fi)->leaf_function = 1;
 > -  get_frame_extra_info (fi)->f_offset = 0;
 > +  int reg, sav_reg = -1;
 >  
 > -  for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
 > -    where[rn] = -1;
 > -
 > -  depth = 0;
 > -
 > -  /* Loop around examining the prologue insns until we find something
 > -     that does not appear to be part of the prologue.  But give up
 > -     after 20 of them, since we're getting silly then. */
 > -
 > -  pc = get_frame_func (fi);
 > -  if (!pc)
 > -    {
 > -      deprecated_update_frame_pc_hack (fi, 0);
 > -      return;
 > -    }
 > +  if (pc >= current_pc)
 > +    return current_pc;
 >  
 > +  cache->uses_fp = 0;
 >    for (opc = pc + (2 * 28); pc < opc; pc += 2)
 >      {
 > -      insn = read_memory_integer (pc, 2);
 > +      inst = read_memory_unsigned_integer (pc, 2);
 >        /* See where the registers will be saved to */
 > -      if (IS_PUSH (insn))
 > +      if (IS_PUSH (inst))
 >  	{
 > -	  rn = GET_PUSHED_REG (insn);
 > -	  where[rn] = depth;
 > -	  depth += 4;
 > +	  cache->saved_regs[GET_SOURCE_REG (inst)] = cache->sp_offset;
 > +	  cache->sp_offset += 4;
 >  	}
 > -      else if (IS_STS (insn))
 > +      else if (IS_STS (inst))
 >  	{
 > -	  where[PR_REGNUM] = depth;
 > -	  /* If we're storing the pr then this isn't a leaf */
 > -	  get_frame_extra_info (fi)->leaf_function = 0;
 > -	  depth += 4;
 > +	  cache->saved_regs[PR_REGNUM] = cache->sp_offset;
 > +	  cache->sp_offset += 4;
 >  	}
 > -      else if (IS_MOV_R3 (insn))
 > +      else if (IS_MOV_R3 (inst))
 >  	{
 > -	  r3_val = ((insn & 0xff) ^ 0x80) - 0x80;
 > +	  r3_val = ((inst & 0xff) ^ 0x80) - 0x80;
 >  	}
 > -      else if (IS_SHLL_R3 (insn))
 > +      else if (IS_SHLL_R3 (inst))
 >  	{
 >  	  r3_val <<= 1;
 >  	}
 > -      else if (IS_ADD_R3SP (insn))
 > +      else if (IS_ADD_R3SP (inst))
 >  	{
 > -	  depth += -r3_val;
 > +	  cache->sp_offset += -r3_val;
 >  	}
 > -      else if (IS_ADD_SP (insn))
 > +      else if (IS_ADD_IMM_SP (inst))
 >  	{
 > -	  depth -= ((insn & 0xff) ^ 0x80) - 0x80;
 > +	  offset = ((inst & 0xff) ^ 0x80) - 0x80;
 > +	  cache->sp_offset -= offset;
 >  	}
 > -      else if (IS_MOV_SP_FP (insn))
 > -	break;
 > -#if 0 /* This used to just stop when it found an instruction that
 > -	 was not considered part of the prologue.  Now, we just
 > -	 keep going looking for likely instructions. */
 > -      else
 > -	break;
 > -#endif
 > -    }
 > -
 > -  /* Now we know how deep things are, we can work out their addresses */
 > -
 > -  for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
 > -    {
 > -      if (where[rn] >= 0)
 > -	{
 > -	  if (rn == DEPRECATED_FP_REGNUM)
 > -	    have_fp = 1;
 > -
 > -	  get_frame_saved_regs (fi)[rn] = get_frame_base (fi) - where[rn] + depth - 4;
 > -	}
 > -      else
 > -	{
 > -	  get_frame_saved_regs (fi)[rn] = 0;
 > -	}
 > -    }
 > -
 > -  if (have_fp)
 > -    {
 > -      get_frame_saved_regs (fi)[SP_REGNUM] = read_memory_integer (get_frame_saved_regs (fi)[DEPRECATED_FP_REGNUM], 4);
 > -    }
 > -  else
 > -    {
 > -      get_frame_saved_regs (fi)[SP_REGNUM] = get_frame_base (fi) - 4;
 > -    }
 > -
 > -  get_frame_extra_info (fi)->f_offset = depth - where[DEPRECATED_FP_REGNUM] - 4;
 > -  /* Work out the return pc - either from the saved pr or the pr
 > -     value */
 > -}
 > -
 > -/* For vectors of 4 floating point registers. */
 > -static int
 > -fv_reg_base_num (int fv_regnum)
 > -{
 > -  int fp_regnum;
 > -
 > -  fp_regnum = FP0_REGNUM + 
 > -    (fv_regnum - gdbarch_tdep (current_gdbarch)->FV0_REGNUM) * 4;
 > -  return fp_regnum;
 > -}
 > -
 > -/* For double precision floating point registers, i.e 2 fp regs.*/
 > -static int
 > -dr_reg_base_num (int dr_regnum)
 > -{
 > -  int fp_regnum;
 > -
 > -  fp_regnum = FP0_REGNUM + 
 > -    (dr_regnum - gdbarch_tdep (current_gdbarch)->DR0_REGNUM) * 2;
 > -  return fp_regnum;
 > -}
 > -
 > -static void
 > -sh_fp_frame_init_saved_regs (struct frame_info *fi)
 > -{
 > -  int *where = (int *) alloca ((NUM_REGS + NUM_PSEUDO_REGS) * sizeof (int));
 > -  int rn;
 > -  int have_fp = 0;
 > -  int depth;
 > -  int pc;
 > -  int opc;
 > -  int insn;
 > -  int r3_val = 0;
 > -  char *dummy_regs = deprecated_generic_find_dummy_frame (get_frame_pc (fi), get_frame_base (fi));
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); 
 > -  
 > -  if (get_frame_saved_regs (fi) == NULL)
 > -    frame_saved_regs_zalloc (fi);
 > -  else
 > -    memset (get_frame_saved_regs (fi), 0, SIZEOF_FRAME_SAVED_REGS);
 > -  
 > -  if (dummy_regs)
 > -    {
 > -      /* DANGER!  This is ONLY going to work if the char buffer format of
 > -         the saved registers is byte-for-byte identical to the 
 > -         CORE_ADDR regs[NUM_REGS] format used by struct frame_saved_regs! */
 > -      memcpy (get_frame_saved_regs (fi), dummy_regs, SIZEOF_FRAME_SAVED_REGS);
 > -      return;
 > -    }
 > -
 > -  get_frame_extra_info (fi)->leaf_function = 1;
 > -  get_frame_extra_info (fi)->f_offset = 0;
 > -
 > -  for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
 > -    where[rn] = -1;
 > -
 > -  depth = 0;
 > -
 > -  /* Loop around examining the prologue insns until we find something
 > -     that does not appear to be part of the prologue.  But give up
 > -     after 20 of them, since we're getting silly then. */
 > -
 > -  pc = get_frame_func (fi);
 > -  if (!pc)
 > -    {
 > -      deprecated_update_frame_pc_hack (fi, 0);
 > -      return;
 > -    }
 > -
 > -  for (opc = pc + (2 * 28); pc < opc; pc += 2)
 > -    {
 > -      insn = read_memory_integer (pc, 2);
 > -      /* See where the registers will be saved to */
 > -      if (IS_PUSH (insn))
 > -	{
 > -	  rn = GET_PUSHED_REG (insn);
 > -	  where[rn] = depth;
 > -	  depth += 4;
 > -	}
 > -      else if (IS_STS (insn))
 > -	{
 > -	  where[PR_REGNUM] = depth;
 > -	  /* If we're storing the pr then this isn't a leaf */
 > -	  get_frame_extra_info (fi)->leaf_function = 0;
 > -	  depth += 4;
 > -	}
 > -      else if (IS_MOV_R3 (insn))
 > -	{
 > -	  r3_val = ((insn & 0xff) ^ 0x80) - 0x80;
 > -	}
 > -      else if (IS_SHLL_R3 (insn))
 > -	{
 > -	  r3_val <<= 1;
 > +      else if (IS_MOVW_PCREL_TO_REG (inst))
 > +        {
 > +	  if (sav_reg < 0)
 > +	    {
 > +	      reg = GET_TARGET_REG (inst);
 > +	      if (reg < 14)
 > +		{
 > +		  sav_reg = reg;
 > +		  offset = (((inst & 0xff) ^ 0x80) - 0x80) << 1;
 > +		  sav_offset =
 > +		  	read_memory_integer (((pc + 4) & ~3) + offset, 2);
 > +		}
 > +	    }
 >  	}
 > -      else if (IS_ADD_R3SP (insn))
 > -	{
 > -	  depth += -r3_val;
 > +      else if (IS_MOVL_PCREL_TO_REG (inst))
 > +        {
 > +	  if (sav_reg < 0)
 > +	    {
 > +	      reg = (inst & 0x0f00) >> 8;
 > +	      if (reg < 14)
 > +		{
 > +		  sav_reg = reg;
 > +		  offset = (((inst & 0xff) ^ 0x80) - 0x80) << 1;
 > +		  sav_offset =
 > +		  	read_memory_integer (((pc + 4) & ~3) + offset, 4);
 > +		}
 > +	    }
 >  	}
 > -      else if (IS_ADD_SP (insn))
 > -	{
 > -	  depth -= ((insn & 0xff) ^ 0x80) - 0x80;
 > +      else if (IS_SUB_REG_FROM_SP (inst))
 > +        {
 > +	  reg = GET_SOURCE_REG (inst);
 > +	  if (sav_reg > 0 && reg == sav_reg)
 > +	    {
 > +	      sav_reg = -1;
 > +	    }
 > +	  cache->sp_offset += sav_offset;
 >  	}
 > -      else if (IS_FMOV (insn))
 > +      else if (IS_FPUSH (inst))
 >  	{
 > -	  if (read_register (tdep->FPSCR_REGNUM) & FPSCR_SZ)
 > +	  if (read_register (FPSCR_REGNUM) & FPSCR_SZ)
 >  	    {
 > -	      depth += 8;
 > +	      cache->sp_offset += 8;
 >  	    }
 >  	  else
 >  	    {
 > -	      depth += 4;
 > +	      cache->sp_offset += 4;
 >  	    }
 >  	}
 > -      else if (IS_MOV_SP_FP (insn))
 > -	break;
 > +      else if (IS_MOV_SP_FP (inst))
 > +        {
 > +	  if (!cache->uses_fp)
 > +	    cache->uses_fp = 1;
 > +	  /* At this point, only allow argument register moves to other
 > +	     registers or argument register moves to @(X,fp) which are
 > +	     moving the register arguments onto the stack area allocated
 > +	     by a former add somenumber to SP call.  Don't allow moving
 > +	     to an fp indirect address above fp + cache->sp_offset. */
 > +	  pc += 2;
 > +	  for (opc = pc + 12; pc < opc; pc += 2)
 > +	    {
 > +	      inst = read_memory_integer (pc, 2);
 > +	      if (IS_MOV_ARG_TO_IND_R14 (inst))
 > +	        {
 > +		  reg = GET_SOURCE_REG (inst);
 > +		  if (cache->sp_offset > 0)
 > +		  cache->saved_regs[reg] = cache->sp_offset;
 > +		}
 > +	      else if (IS_MOV_ARG_TO_IND_R14_WITH_DISP (inst))
 > +	        {
 > +		  reg = GET_SOURCE_REG (inst);
 > +		  offset = (inst & 0xf) * 4;
 > +		  if (cache->sp_offset > offset)
 > +		    cache->saved_regs[reg] = cache->sp_offset - offset;
 > +		}
 > +	      else if (IS_MOV_ARG_TO_REG (inst))
 > +	        continue;
 > +	      else
 > +		break;
 > +	    }
 > +	  break;
 > +	}
 >  #if 0 /* This used to just stop when it found an instruction that
 >  	 was not considered part of the prologue.  Now, we just
 >  	 keep going looking for likely instructions. */
 > @@ -770,68 +510,71 @@ sh_fp_frame_init_saved_regs (struct fram
 >  #endif
 >      }
 >  
 > -  /* Now we know how deep things are, we can work out their addresses */
 > +  return pc;
 > +}
 >  
 > -  for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
 > -    {
 > -      if (where[rn] >= 0)
 > -	{
 > -	  if (rn == DEPRECATED_FP_REGNUM)
 > -	    have_fp = 1;
 > +/* Skip any prologue before the guts of a function */
 >  
 > -	  get_frame_saved_regs (fi)[rn] = get_frame_base (fi) - where[rn] + depth - 4;
 > -	}
 > -      else
 > -	{
 > -	  get_frame_saved_regs (fi)[rn] = 0;
 > -	}
 > -    }
 > +/* Skip the prologue using the debug information. If this fails we'll
 > +   fall back on the 'guess' method below. */
 > +static CORE_ADDR
 > +after_prologue (CORE_ADDR pc)
 > +{
 > +  struct symtab_and_line sal;
 > +  CORE_ADDR func_addr, func_end;
 >  
 > -  if (have_fp)
 > -    {
 > -      get_frame_saved_regs (fi)[SP_REGNUM] =
 > -	read_memory_integer (get_frame_saved_regs (fi)[DEPRECATED_FP_REGNUM], 4);
 > -    }
 > -  else
 > -    {
 > -      get_frame_saved_regs (fi)[SP_REGNUM] = get_frame_base (fi) - 4;
 > -    }
 > +  /* If we can not find the symbol in the partial symbol table, then
 > +     there is no hope we can determine the function's start address
 > +     with this code.  */
 > +  if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
 > +    return 0;
 > +
 > +  /* Get the line associated with FUNC_ADDR.  */
 > +  sal = find_pc_line (func_addr, 0);
 >  
 > -  get_frame_extra_info (fi)->f_offset = depth - where[DEPRECATED_FP_REGNUM] - 4;
 > -  /* Work out the return pc - either from the saved pr or the pr
 > -     value */
 > +  /* There are only two cases to consider.  First, the end of the source line
 > +     is within the function bounds.  In that case we return the end of the
 > +     source line.  Second is the end of the source line extends beyond the
 > +     bounds of the current function.  We need to use the slow code to
 > +     examine instructions in that case.  */
 > +  if (sal.end < func_end)
 > +    return sal.end;
 > +  else
 > +    return 0;
 >  }
 >  
 > -/* Initialize the extra info saved in a FRAME */
 > -static void
 > -sh_init_extra_frame_info (int fromleaf, struct frame_info *fi)
 > +static CORE_ADDR
 > +sh_skip_prologue (CORE_ADDR start_pc)
 >  {
 > +  CORE_ADDR pc;
 > +  struct sh_frame_cache cache;
 >  
 > -  frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
 > +  /* 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.  */
 > +  pc = after_prologue (start_pc);
 >  
 > -  if (get_next_frame (fi))
 > -    deprecated_update_frame_pc_hack (fi, DEPRECATED_FRAME_SAVED_PC (get_next_frame (fi)));
 > +  /* If after_prologue returned a useful address, then use it.  Else
 > +     fall back on the instruction skipping code. */
 > +  if (pc)
 > +    return max (pc, start_pc);
 >  
 > -  if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
 > -				   get_frame_base (fi)))
 > -    {
 > -      /* We need to setup fi->frame here because call_function_by_hand
 > -         gets it wrong by assuming it's always FP.  */
 > -      deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi),
 > -									     SP_REGNUM));
 > -      get_frame_extra_info (fi)->return_pc = deprecated_read_register_dummy (get_frame_pc (fi),
 > -								  get_frame_base (fi),
 > -								  PC_REGNUM);
 > -      get_frame_extra_info (fi)->f_offset = -(DEPRECATED_CALL_DUMMY_LENGTH + 4);
 > -      get_frame_extra_info (fi)->leaf_function = 0;
 > -      return;
 > -    }
 > -  else
 > -    {
 > -      DEPRECATED_FRAME_INIT_SAVED_REGS (fi);
 > -      get_frame_extra_info (fi)->return_pc = 
 > -	sh_find_callers_reg (fi, PR_REGNUM);
 > -    }
 > +  cache.sp_offset = -4;
 > +  pc = sh_analyze_prologue (start_pc, (CORE_ADDR) -1, &cache);
 > +  if (!cache.uses_fp)
 > +    return start_pc;
 > +
 > +  return pc;
 > +}
 > +
 > +/* Should call_function allocate stack space for a struct return?  */
 > +static int
 > +sh_use_struct_convention (int gcc_p, struct type *type)
 > +{
 > +  int len = TYPE_LENGTH (type);
 > +  int nelem = TYPE_NFIELDS (type);
 > +  return ((len != 1 && len != 2 && len != 4 && len != 8) || nelem != 1) &&
 > +	  (len != 8 || TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) != 4);
 >  }
 >  
 >  /* Extract from an array REGBUF containing the (raw) register state
 > @@ -841,48 +584,12 @@ static CORE_ADDR
 >  sh_extract_struct_value_address (struct regcache *regcache)
 >  {
 >    ULONGEST addr;
 > -  /*FIXME: Is R0 really correct here?  Not STRUCT_RETURN_REGNUM? */
 > +
 >    regcache_cooked_read_unsigned (regcache, STRUCT_RETURN_REGNUM, &addr);
 >    return addr;
 >  }
 >  
 >  static CORE_ADDR
 > -sh_frame_saved_pc (struct frame_info *frame)
 > -{
 > -  return (get_frame_extra_info (frame)->return_pc);
 > -}
 > -
 > -/* Discard from the stack the innermost frame,
 > -   restoring all saved registers.  */
 > -static void
 > -sh_pop_frame (void)
 > -{
 > -  register struct frame_info *frame = get_current_frame ();
 > -  register CORE_ADDR fp;
 > -  register int regnum;
 > -
 > -  if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame),
 > -				   get_frame_base (frame),
 > -				   get_frame_base (frame)))
 > -    generic_pop_dummy_frame ();
 > -  else
 > -    {
 > -      fp = get_frame_base (frame);
 > -      DEPRECATED_FRAME_INIT_SAVED_REGS (frame);
 > -
 > -      /* Copy regs from where they were saved in the frame */
 > -      for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
 > -	if (get_frame_saved_regs (frame)[regnum])
 > -	  write_register (regnum,
 > -			  read_memory_integer (get_frame_saved_regs (frame)[regnum], 4));
 > -
 > -      write_register (PC_REGNUM, get_frame_extra_info (frame)->return_pc);
 > -      write_register (SP_REGNUM, fp + 4);
 > -    }
 > -  flush_cached_frames ();
 > -}
 > -
 > -static CORE_ADDR
 >  sh_frame_align (struct gdbarch *ignore, CORE_ADDR sp)
 >  {
 >    return sp & ~3;
 > @@ -958,16 +665,13 @@ sh_push_dummy_call_fpu (struct gdbarch *
 >    char valbuf[4];
 >    int len;
 >    int odd_sized_struct;
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
 >  
 >    /* first force sp to a 4-byte alignment */
 >    sp = sh_frame_align (gdbarch, sp);
 >  
 > -  /* The "struct return pointer" pseudo-argument has its own dedicated 
 > -     register */
 >    if (struct_return)
 > -    regcache_cooked_write_unsigned (regcache, 
 > -				    STRUCT_RETURN_REGNUM, 
 > +    regcache_cooked_write_unsigned (regcache,
 > +				    STRUCT_RETURN_REGNUM,
 >  				    struct_addr);
 >  
 >    /* Now make sure there's space on the stack */
 > @@ -1069,13 +773,10 @@ sh_push_dummy_call_nofpu (struct gdbarch
 >    char valbuf[4];
 >    int len;
 >    int odd_sized_struct;
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
 >  
 >    /* first force sp to a 4-byte alignment */
 >    sp = sh_frame_align (gdbarch, sp);
 >  
 > -  /* The "struct return pointer" pseudo-argument has its own dedicated 
 > -     register */
 >    if (struct_return)
 >      regcache_cooked_write_unsigned (regcache,
 >  				    STRUCT_RETURN_REGNUM,
 > @@ -1239,8 +940,6 @@ sh3e_sh4_store_return_value (struct type
 >  static void
 >  sh_generic_show_regs (void)
 >  {
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); 
 > -
 >    printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
 >  		   paddr (read_register (PC_REGNUM)),
 >  		   (long) read_register (SR_REGNUM),
 > @@ -1275,8 +974,6 @@ sh_generic_show_regs (void)
 >  static void
 >  sh3_show_regs (void)
 >  {
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); 
 > -
 >    printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
 >  		   paddr (read_register (PC_REGNUM)),
 >  		   (long) read_register (SR_REGNUM),
 > @@ -1288,8 +985,8 @@ sh3_show_regs (void)
 >  		   (long) read_register (GBR_REGNUM),
 >  		   (long) read_register (VBR_REGNUM));
 >    printf_filtered (" SSR=%08lx SPC=%08lx",
 > -	           (long) read_register (tdep->SSR_REGNUM),
 > -		   (long) read_register (tdep->SPC_REGNUM));
 > +	           (long) read_register (SSR_REGNUM),
 > +		   (long) read_register (SPC_REGNUM));
 >  
 >    printf_filtered ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
 >  		   (long) read_register (0),
 > @@ -1326,8 +1023,8 @@ sh2e_show_regs (void)
 >  		   (long) read_register (GBR_REGNUM),
 >  		   (long) read_register (VBR_REGNUM));
 >    printf_filtered (" FPUL=%08lx FPSCR=%08lx",
 > -	  	   (long) read_register (gdbarch_tdep (current_gdbarch)->FPUL_REGNUM),
 > -                   (long) read_register (gdbarch_tdep (current_gdbarch)->FPSCR_REGNUM));
 > +	  	   (long) read_register (FPUL_REGNUM),
 > +                   (long) read_register (FPSCR_REGNUM));
 >  
 >    printf_filtered ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
 >  		   (long) read_register (0),
 > @@ -1371,8 +1068,6 @@ sh2e_show_regs (void)
 >  static void
 >  sh3e_show_regs (void)
 >  {
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); 
 > -
 >    printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
 >  		   paddr (read_register (PC_REGNUM)),
 >  		   (long) read_register (SR_REGNUM),
 > @@ -1384,11 +1079,11 @@ sh3e_show_regs (void)
 >  		   (long) read_register (GBR_REGNUM),
 >  		   (long) read_register (VBR_REGNUM));
 >    printf_filtered (" SSR=%08lx SPC=%08lx",
 > -		   (long) read_register (tdep->SSR_REGNUM),
 > -		   (long) read_register (tdep->SPC_REGNUM));
 > +		   (long) read_register (SSR_REGNUM),
 > +		   (long) read_register (SPC_REGNUM));
 >    printf_filtered (" FPUL=%08lx FPSCR=%08lx",
 > -		   (long) read_register (tdep->FPUL_REGNUM),
 > -		   (long) read_register (tdep->FPSCR_REGNUM));
 > +		   (long) read_register (FPUL_REGNUM),
 > +		   (long) read_register (FPSCR_REGNUM));
 >  
 >    printf_filtered ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
 >  		   (long) read_register (0),
 > @@ -1432,8 +1127,6 @@ sh3e_show_regs (void)
 >  static void
 >  sh3_dsp_show_regs (void)
 >  {
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); 
 > -
 >    printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
 >  		   paddr (read_register (PC_REGNUM)),
 >  		   (long) read_register (SR_REGNUM),
 > @@ -1446,11 +1139,11 @@ sh3_dsp_show_regs (void)
 >  		   (long) read_register (VBR_REGNUM));
 >  
 >    printf_filtered (" SSR=%08lx SPC=%08lx",
 > -		   (long) read_register (tdep->SSR_REGNUM),
 > -		   (long) read_register (tdep->SPC_REGNUM));
 > +		   (long) read_register (SSR_REGNUM),
 > +		   (long) read_register (SPC_REGNUM));
 >  
 >    printf_filtered (" DSR=%08lx", 
 > -		   (long) read_register (tdep->DSR_REGNUM));
 > +		   (long) read_register (DSR_REGNUM));
 >  
 >    printf_filtered ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
 >  		   (long) read_register (0),
 > @@ -1472,28 +1165,26 @@ sh3_dsp_show_regs (void)
 >  		   (long) read_register (15));
 >  
 >    printf_filtered ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n",
 > -		   (long) read_register (tdep->A0G_REGNUM) & 0xff,
 > -		   (long) read_register (tdep->A0_REGNUM),
 > -		   (long) read_register (tdep->M0_REGNUM),
 > -		   (long) read_register (tdep->X0_REGNUM),
 > -		   (long) read_register (tdep->Y0_REGNUM),
 > -		   (long) read_register (tdep->RS_REGNUM),
 > -		   (long) read_register (tdep->MOD_REGNUM));
 > +		   (long) read_register (A0G_REGNUM) & 0xff,
 > +		   (long) read_register (A0_REGNUM),
 > +		   (long) read_register (M0_REGNUM),
 > +		   (long) read_register (X0_REGNUM),
 > +		   (long) read_register (Y0_REGNUM),
 > +		   (long) read_register (RS_REGNUM),
 > +		   (long) read_register (MOD_REGNUM));
 >    printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n",
 > -		   (long) read_register (tdep->A1G_REGNUM) & 0xff,
 > -		   (long) read_register (tdep->A1_REGNUM),
 > -		   (long) read_register (tdep->M1_REGNUM),
 > -		   (long) read_register (tdep->X1_REGNUM),
 > -		   (long) read_register (tdep->Y1_REGNUM),
 > -		   (long) read_register (tdep->RE_REGNUM));
 > +		   (long) read_register (A1G_REGNUM) & 0xff,
 > +		   (long) read_register (A1_REGNUM),
 > +		   (long) read_register (M1_REGNUM),
 > +		   (long) read_register (X1_REGNUM),
 > +		   (long) read_register (Y1_REGNUM),
 > +		   (long) read_register (RE_REGNUM));
 >  }
 >  
 >  static void
 >  sh4_show_regs (void)
 >  {
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); 
 > -
 > -  int pr = read_register (tdep->FPSCR_REGNUM) & 0x80000;
 > +  int pr = read_register (FPSCR_REGNUM) & 0x80000;
 >    printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
 >  		   paddr (read_register (PC_REGNUM)),
 >  		   (long) read_register (SR_REGNUM),
 > @@ -1505,11 +1196,11 @@ sh4_show_regs (void)
 >  		   (long) read_register (GBR_REGNUM),
 >  		   (long) read_register (VBR_REGNUM));
 >    printf_filtered (" SSR=%08lx SPC=%08lx",
 > -		   (long) read_register (tdep->SSR_REGNUM),
 > -		   (long) read_register (tdep->SPC_REGNUM));
 > +		   (long) read_register (SSR_REGNUM),
 > +		   (long) read_register (SPC_REGNUM));
 >    printf_filtered (" FPUL=%08lx FPSCR=%08lx",
 > -		   (long) read_register (tdep->FPUL_REGNUM),
 > -		   (long) read_register (tdep->FPSCR_REGNUM));
 > +		   (long) read_register (FPUL_REGNUM),
 > +		   (long) read_register (FPSCR_REGNUM));
 >  
 >    printf_filtered ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
 >  		   (long) read_register (0),
 > @@ -1557,8 +1248,6 @@ sh4_show_regs (void)
 >  static void
 >  sh_dsp_show_regs (void)
 >  {
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); 
 > -
 >    printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
 >  		   paddr (read_register (PC_REGNUM)),
 >  		   (long) read_register (SR_REGNUM),
 > @@ -1571,7 +1260,7 @@ sh_dsp_show_regs (void)
 >  		   (long) read_register (VBR_REGNUM));
 >  
 >    printf_filtered (" DSR=%08lx", 
 > -		   (long) read_register (tdep->DSR_REGNUM));
 > +		   (long) read_register (DSR_REGNUM));
 >  
 >    printf_filtered ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
 >  		   (long) read_register (0),
 > @@ -1593,20 +1282,20 @@ sh_dsp_show_regs (void)
 >  		   (long) read_register (15));
 >  
 >    printf_filtered ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n",
 > -		   (long) read_register (tdep->A0G_REGNUM) & 0xff,
 > -		   (long) read_register (tdep->A0_REGNUM),
 > -		   (long) read_register (tdep->M0_REGNUM),
 > -		   (long) read_register (tdep->X0_REGNUM),
 > -		   (long) read_register (tdep->Y0_REGNUM),
 > -		   (long) read_register (tdep->RS_REGNUM),
 > -		   (long) read_register (tdep->MOD_REGNUM));
 > +		   (long) read_register (A0G_REGNUM) & 0xff,
 > +		   (long) read_register (A0_REGNUM),
 > +		   (long) read_register (M0_REGNUM),
 > +		   (long) read_register (X0_REGNUM),
 > +		   (long) read_register (Y0_REGNUM),
 > +		   (long) read_register (RS_REGNUM),
 > +		   (long) read_register (MOD_REGNUM));
 >    printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n",
 > -		   (long) read_register (tdep->A1G_REGNUM) & 0xff,
 > -		   (long) read_register (tdep->A1_REGNUM),
 > -		   (long) read_register (tdep->M1_REGNUM),
 > -		   (long) read_register (tdep->X1_REGNUM),
 > -		   (long) read_register (tdep->Y1_REGNUM),
 > -		   (long) read_register (tdep->RE_REGNUM));
 > +		   (long) read_register (A1G_REGNUM) & 0xff,
 > +		   (long) read_register (A1_REGNUM),
 > +		   (long) read_register (M1_REGNUM),
 > +		   (long) read_register (X1_REGNUM),
 > +		   (long) read_register (Y1_REGNUM),
 > +		   (long) read_register (RE_REGNUM));
 >  }
 >  
 >  static void
 > @@ -1621,11 +1310,9 @@ sh_show_regs_command (char *args, int fr
 >  static struct type *
 >  sh_sh3e_register_type (struct gdbarch *gdbarch, int reg_nr)
 >  {
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); 
 > -
 >    if ((reg_nr >= FP0_REGNUM
 > -       && (reg_nr <= tdep->FP_LAST_REGNUM)) 
 > -      || (reg_nr == tdep->FPUL_REGNUM))
 > +       && (reg_nr <= FP_LAST_REGNUM)) 
 > +      || (reg_nr == FPUL_REGNUM))
 >      return builtin_type_float;
 >    else
 >      return builtin_type_int;
 > @@ -1643,17 +1330,15 @@ sh_sh4_build_float_register_type (int hi
 >  static struct type *
 >  sh_sh4_register_type (struct gdbarch *gdbarch, int reg_nr)
 >  {
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
 > -
 >    if ((reg_nr >= FP0_REGNUM
 > -       && (reg_nr <= tdep->FP_LAST_REGNUM)) 
 > -      || (reg_nr == tdep->FPUL_REGNUM))
 > +       && (reg_nr <= FP_LAST_REGNUM)) 
 > +      || (reg_nr == FPUL_REGNUM))
 >      return builtin_type_float;
 > -  else if (reg_nr >= tdep->DR0_REGNUM 
 > -	   && reg_nr <= tdep->DR_LAST_REGNUM)
 > +  else if (reg_nr >= DR0_REGNUM 
 > +	   && reg_nr <= DR_LAST_REGNUM)
 >      return builtin_type_double;
 > -  else if  (reg_nr >= tdep->FV0_REGNUM 
 > -	   && reg_nr <= tdep->FV_LAST_REGNUM)
 > +  else if  (reg_nr >= FV0_REGNUM 
 > +	   && reg_nr <= FV_LAST_REGNUM)
 >      return sh_sh4_build_float_register_type (3);
 >    else
 >      return builtin_type_int;
 > @@ -1695,10 +1380,8 @@ static void
 >  sh_sh4_register_convert_to_virtual (int regnum, struct type *type,
 >                                    char *from, char *to)
 >  {
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); 
 > -
 > -  if (regnum >= tdep->DR0_REGNUM 
 > -      && regnum <= tdep->DR_LAST_REGNUM)
 > +  if (regnum >= DR0_REGNUM 
 > +      && regnum <= DR_LAST_REGNUM)
 >      {
 >        DOUBLEST val;
 >        floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword, from, &val);
 > @@ -1712,10 +1395,8 @@ static void
 >  sh_sh4_register_convert_to_raw (struct type *type, int regnum,
 >  				const void *from, void *to)
 >  {
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); 
 > -
 > -  if (regnum >= tdep->DR0_REGNUM 
 > -      && regnum <= tdep->DR_LAST_REGNUM)
 > +  if (regnum >= DR0_REGNUM 
 > +      && regnum <= DR_LAST_REGNUM)
 >      {
 >        DOUBLEST val = extract_typed_floating (from, type);
 >        floatformat_from_doublest (&floatformat_ieee_double_littlebyte_bigword, &val, to);
 > @@ -1724,16 +1405,37 @@ sh_sh4_register_convert_to_raw (struct t
 >      error("sh_register_convert_to_raw called with non DR register number");
 >  }
 >  
 > +/* For vectors of 4 floating point registers. */
 > +static int
 > +fv_reg_base_num (int fv_regnum)
 > +{
 > +  int fp_regnum;
 > +
 > +  fp_regnum = FP0_REGNUM + 
 > +    (fv_regnum - FV0_REGNUM) * 4;
 > +  return fp_regnum;
 > +}
 > +
 > +/* For double precision floating point registers, i.e 2 fp regs.*/
 > +static int
 > +dr_reg_base_num (int dr_regnum)
 > +{
 > +  int fp_regnum;
 > +
 > +  fp_regnum = FP0_REGNUM + 
 > +    (dr_regnum - DR0_REGNUM) * 2;
 > +  return fp_regnum;
 > +}
 > +
 >  static void
 >  sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 >  			 int reg_nr, void *buffer)
 >  {
 >    int base_regnum, portion;
 >    char temp_buffer[MAX_REGISTER_SIZE];
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
 >  
 > -  if (reg_nr >= tdep->DR0_REGNUM 
 > -      && reg_nr <= tdep->DR_LAST_REGNUM)
 > +  if (reg_nr >= DR0_REGNUM 
 > +      && reg_nr <= DR_LAST_REGNUM)
 >      {
 >        base_regnum = dr_reg_base_num (reg_nr);
 >  
 > @@ -1748,8 +1450,8 @@ sh_pseudo_register_read (struct gdbarch 
 >  					  gdbarch_register_type (gdbarch, reg_nr),
 >  					  temp_buffer, buffer);
 >      }
 > -  else if (reg_nr >= tdep->FV0_REGNUM 
 > -	   && reg_nr <= tdep->FV_LAST_REGNUM)
 > +  else if (reg_nr >= FV0_REGNUM 
 > +	   && reg_nr <= FV_LAST_REGNUM)
 >      {
 >        base_regnum = fv_reg_base_num (reg_nr);
 >  
 > @@ -1767,10 +1469,9 @@ sh_pseudo_register_write (struct gdbarch
 >  {
 >    int base_regnum, portion;
 >    char temp_buffer[MAX_REGISTER_SIZE];
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
 >  
 > -  if (reg_nr >= tdep->DR0_REGNUM
 > -      && reg_nr <= tdep->DR_LAST_REGNUM)
 > +  if (reg_nr >= DR0_REGNUM
 > +      && reg_nr <= DR_LAST_REGNUM)
 >      {
 >        base_regnum = dr_reg_base_num (reg_nr);
 >  
 > @@ -1784,8 +1485,8 @@ sh_pseudo_register_write (struct gdbarch
 >  			    (temp_buffer
 >  			     + register_size (gdbarch, base_regnum) * portion));
 >      }
 > -  else if (reg_nr >= tdep->FV0_REGNUM
 > -	   && reg_nr <= tdep->FV_LAST_REGNUM)
 > +  else if (reg_nr >= FV0_REGNUM
 > +	   && reg_nr <= FV_LAST_REGNUM)
 >      {
 >        base_regnum = fv_reg_base_num (reg_nr);
 >  
 > @@ -1804,7 +1505,7 @@ do_fv_register_info (struct gdbarch *gdb
 >  {
 >    int first_fp_reg_num = fv_reg_base_num (fv_regnum);
 >    fprintf_filtered (file, "fv%d\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n", 
 > -		     fv_regnum - gdbarch_tdep (gdbarch)->FV0_REGNUM, 
 > +		     fv_regnum - FV0_REGNUM, 
 >  		     (int) read_register (first_fp_reg_num),
 >  		     (int) read_register (first_fp_reg_num + 1),
 >  		     (int) read_register (first_fp_reg_num + 2),
 > @@ -1819,7 +1520,7 @@ do_dr_register_info (struct gdbarch *gdb
 >    int first_fp_reg_num = dr_reg_base_num (dr_regnum);
 >  
 >    fprintf_filtered (file, "dr%d\t0x%08x%08x\n", 
 > -		    dr_regnum - gdbarch_tdep (gdbarch)->DR0_REGNUM, 
 > +		    dr_regnum - DR0_REGNUM, 
 >  		    (int) read_register (first_fp_reg_num),
 >  		    (int) read_register (first_fp_reg_num + 1));
 >  }
 > @@ -1828,16 +1529,14 @@ static void
 >  sh_print_pseudo_register (struct gdbarch *gdbarch, struct ui_file *file,
 >  			  int regnum)
 >  {
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
 > -
 >    if (regnum < NUM_REGS || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
 >      internal_error (__FILE__, __LINE__,
 >  		    "Invalid pseudo register number %d\n", regnum);
 > -  else if (regnum >= tdep->DR0_REGNUM
 > -	   && regnum <= tdep->DR_LAST_REGNUM)
 > +  else if (regnum >= DR0_REGNUM
 > +	   && regnum <= DR_LAST_REGNUM)
 >      do_dr_register_info (gdbarch, file, regnum);
 > -  else if (regnum >= tdep->FV0_REGNUM
 > -	   && regnum <= tdep->FV_LAST_REGNUM)
 > +  else if (regnum >= FV0_REGNUM
 > +	   && regnum <= FV_LAST_REGNUM)
 >      do_fv_register_info (gdbarch, file, regnum);
 >  }
 >  
 > @@ -1957,7 +1656,7 @@ sh_print_registers_info (struct gdbarch 
 >  		  regnum ++;
 >  		}
 >  	      else
 > -		regnum += (gdbarch_tdep (gdbarch)->FP_LAST_REGNUM - FP0_REGNUM);	/* skip FP regs */
 > +		regnum += (FP_LAST_REGNUM - FP0_REGNUM);	/* skip FP regs */
 >  	    }
 >  	  else
 >  	    {
 > @@ -2019,86 +1718,317 @@ sh_linux_svr4_fetch_link_map_offsets (vo
 >  }
 >  #endif /* SVR4_SHARED_LIBS */
 >  
 > -
 > -enum
 > -{
 > -   DSP_DSR_REGNUM = 24,
 > -   DSP_A0G_REGNUM,
 > -   DSP_A0_REGNUM,
 > -   DSP_A1G_REGNUM,
 > -   DSP_A1_REGNUM,
 > -   DSP_M0_REGNUM,
 > -   DSP_M1_REGNUM,
 > -   DSP_X0_REGNUM,
 > -   DSP_X1_REGNUM,
 > -   DSP_Y0_REGNUM,
 > -   DSP_Y1_REGNUM,
 > - 
 > -   DSP_MOD_REGNUM = 40,
 > - 
 > -   DSP_RS_REGNUM = 43,
 > -   DSP_RE_REGNUM,
 > - 
 > -   DSP_R0_BANK_REGNUM = 51,
 > -   DSP_R7_BANK_REGNUM = DSP_R0_BANK_REGNUM + 7
 > -};
 > -
 >  static int
 >  sh_dsp_register_sim_regno (int nr)
 >  {
 >    if (legacy_register_sim_regno (nr) < 0)
 >      return legacy_register_sim_regno (nr);
 > -  if (nr >= DSP_DSR_REGNUM && nr <= DSP_Y1_REGNUM)
 > -    return nr - DSP_DSR_REGNUM + SIM_SH_DSR_REGNUM;
 > -  if (nr == DSP_MOD_REGNUM)
 > +  if (nr >= DSR_REGNUM && nr <= Y1_REGNUM)
 > +    return nr - DSR_REGNUM + SIM_SH_DSR_REGNUM;
 > +  if (nr == MOD_REGNUM)
 >      return SIM_SH_MOD_REGNUM;
 > -  if (nr == DSP_RS_REGNUM)
 > +  if (nr == RS_REGNUM)
 >      return SIM_SH_RS_REGNUM;
 > -  if (nr == DSP_RE_REGNUM)
 > +  if (nr == RE_REGNUM)
 >      return SIM_SH_RE_REGNUM;
 > -  if (nr >= DSP_R0_BANK_REGNUM && nr <= DSP_R7_BANK_REGNUM)
 > -    return nr - DSP_R0_BANK_REGNUM + SIM_SH_R0_BANK_REGNUM;
 > +  if (nr >= R0_BANK_REGNUM && nr <= R7_BANK_REGNUM)
 > +    return nr - R0_BANK_REGNUM + SIM_SH_R0_BANK_REGNUM;
 >    return nr;
 >  }
 > -
 > +
 > +static struct sh_frame_cache *
 > +sh_alloc_frame_cache (void)
 > +{
 > +  struct sh_frame_cache *cache;
 > +  int i;
 > +
 > +  cache = FRAME_OBSTACK_ZALLOC (struct sh_frame_cache);
 > +
 > +  /* Base address.  */
 > +  cache->base = 0;
 > +  cache->saved_sp = 0;
 > +  cache->sp_offset = 0;
 > +  cache->pc = 0;
 > +
 > +  /* Frameless until proven otherwise.  */
 > +  cache->uses_fp = 0;
 > +    
 > +  /* Saved registers.  We initialize these to -1 since zero is a valid
 > +     offset (that's where fp is supposed to be stored).  */
 > +  for (i = 0; i < SH_NUM_REGS; i++)
 > +    {
 > +      cache->saved_regs[i] = -1;
 > +    }
 > +  
 > +  return cache;
 > +} 
 > +
 > +static struct sh_frame_cache *
 > +sh_frame_cache (struct frame_info *next_frame, void **this_cache)
 > +{
 > +  struct sh_frame_cache *cache;
 > +  CORE_ADDR current_pc;
 > +  int i;
 > +
 > +  if (*this_cache)
 > +    return *this_cache;
 > +
 > +  cache = sh_alloc_frame_cache ();
 > +  *this_cache = cache;
 > +
 > +  /* In principle, for normal frames, fp holds the frame pointer,
 > +     which holds the base address for the current stack frame.
 > +     However, for functions that don't need it, the frame pointer is
 > +     optional.  For these "frameless" functions the frame pointer is
 > +     actually the frame pointer of the calling frame. */
 > +  cache->base = frame_unwind_register_unsigned (next_frame, FP_REGNUM);
 > +  if (cache->base == 0)
 > +    return cache;
 > +
 > +  cache->pc = frame_func_unwind (next_frame);
 > +  current_pc = frame_pc_unwind (next_frame);
 > +  if (cache->pc != 0)
 > +    sh_analyze_prologue (cache->pc, current_pc, cache);
 > +    
 > +  if (!cache->uses_fp)
 > +    {
 > +      /* We didn't find a valid frame, which means that CACHE->base
 > +         currently holds the frame pointer for our calling frame.  If
 > +         we're at the start of a function, or somewhere half-way its
 > +         prologue, the function's frame probably hasn't been fully
 > +         setup yet.  Try to reconstruct the base address for the stack
 > +         frame by looking at the stack pointer.  For truly "frameless"
 > +         functions this might work too.  */
 > +      cache->base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
 > +    }
 > +
 > +  /* Now that we have the base address for the stack frame we can
 > +     calculate the value of sp in the calling frame.  */
 > +  cache->saved_sp = cache->base + cache->sp_offset;
 > +
 > +  /* Adjust all the saved registers such that they contain addresses
 > +     instead of offsets.  */
 > +  for (i = 0; i < SH_NUM_REGS; i++)
 > +    if (cache->saved_regs[i] != -1)
 > +      cache->saved_regs[i] = cache->saved_sp - cache->saved_regs[i] - 4;
 > +
 > +  return cache;
 > +}
 > +
 > +static void
 > +sh_frame_prev_register (struct frame_info *next_frame, void **this_cache,
 > +			int regnum, int *optimizedp,
 > +			enum lval_type *lvalp, CORE_ADDR *addrp,
 > +			int *realnump, void *valuep)
 > +{
 > +  struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache);
 > +
 > +  gdb_assert (regnum >= 0);
 > +
 > +  if (regnum == SP_REGNUM && cache->saved_sp)
 > +    {
 > +      *optimizedp = 0;
 > +      *lvalp = not_lval;
 > +      *addrp = 0;
 > +      *realnump = -1;
 > +      if (valuep)
 > +        {
 > +          /* Store the value.  */
 > +          store_unsigned_integer (valuep, 4, cache->saved_sp);
 > +        }
 > +      return;
 > +    }
 > +
 > +  /* The PC of the previous frame is stored in the PR register of
 > +     the current frame.  Frob regnum so that we pull the value from
 > +     the correct place.  */
 > +  if (regnum == PC_REGNUM)
 > +    regnum = PR_REGNUM;
 > +
 > +  if (regnum < SH_NUM_REGS && cache->saved_regs[regnum] != -1)
 > +    {
 > +      *optimizedp = 0;
 > +      *lvalp = lval_memory;
 > +      *addrp = cache->saved_regs[regnum];
 > +      *realnump = -1;
 > +      if (valuep)
 > +        {
 > +          /* Read the value in from memory.  */
 > +          read_memory (*addrp, valuep,
 > +                       register_size (current_gdbarch, regnum));
 > +        }
 > +      return;
 > +    }
 > +
 > +  frame_register_unwind (next_frame, regnum,
 > +                         optimizedp, lvalp, addrp, realnump, valuep);
 > +}
 > +
 > +static void
 > +sh_frame_this_id (struct frame_info *next_frame, void **this_cache,
 > +                    struct frame_id *this_id)
 > +{ 
 > +  struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache);
 > +
 > +  /* This marks the outermost frame.  */
 > +  if (cache->base == 0)
 > +    return;
 > +
 > +  *this_id = frame_id_build (cache->saved_sp, cache->pc);
 > +} 
 > +
 > +static const struct frame_unwind sh_frame_unwind =
 > +{
 > +  NORMAL_FRAME,
 > +  sh_frame_this_id,
 > +  sh_frame_prev_register
 > +};
 > +
 > +static const struct frame_unwind *
 > +sh_frame_sniffer (struct frame_info *next_frame)
 > +{
 > +  return &sh_frame_unwind;
 > +}
 > +
 > +static CORE_ADDR
 > +sh_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
 > +{
 > +  return frame_unwind_register_unsigned (next_frame, SP_REGNUM);
 > +}
 > +
 > +static CORE_ADDR
 > +sh_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 > +{
 > +  return frame_unwind_register_unsigned (next_frame, PC_REGNUM);
 > +}
 > +
 > +static struct frame_id
 > +sh_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
 > +{
 > +  return frame_id_build (sh_unwind_sp (gdbarch, next_frame),
 > +			 frame_pc_unwind (next_frame));
 > +}
 > +
 > +static CORE_ADDR
 > +sh_frame_base_address (struct frame_info *next_frame, void **this_cache)
 > +{ 
 > +  struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache);
 > +  
 > +  return cache->base;
 > +}
 > +  
 > +static const struct frame_base sh_frame_base =
 > +{
 > +  &sh_frame_unwind,
 > +  sh_frame_base_address,
 > +  sh_frame_base_address,
 > +  sh_frame_base_address
 > +};  
 > +
 > +/* The epilogue is defined here as the area at the end of a function,
 > +   either on the `ret' instruction itself or after an instruction which
 > +   destroys the function's stack frame. */
 > +static int
 > +sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 > +{
 > +  CORE_ADDR func_addr = 0, func_end = 0;
 > +
 > +  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
 > +    {
 > +      ULONGEST inst;
 > +      /* The sh epilogue is max. 14 bytes long.  Give another 14 bytes
 > +         for a nop and some fixed data (e.g. big offsets) which are
 > +	 unfortunately also treated as part of the function (which
 > +	 means, they are below func_end. */
 > +      CORE_ADDR addr = func_end - 28;
 > +      if (addr < func_addr + 4)
 > +        addr = func_addr + 4;
 > +      if (pc < addr)
 > +	return 0;
 > +
 > +      /* First search forward until hitting an rts. */
 > +      while (addr < func_end
 > +             && !IS_RTS (read_memory_unsigned_integer (addr, 2)))
 > +	addr += 2;
 > +      if (addr >= func_end)
 > +        return 0;
 > +
 > +      /* At this point we should find a mov.l @r15+,r14 instruction,
 > +         either before or after the rts.  If not, then the function has
 > +	 probably no "normal" epilogue and we bail out here. */
 > +      inst = read_memory_unsigned_integer (addr - 2, 2);
 > +      if (IS_RESTORE_FP (read_memory_unsigned_integer (addr - 2, 2)))
 > +        addr -= 2;
 > +      else if (!IS_RESTORE_FP (read_memory_unsigned_integer (addr + 2, 2)))
 > +	return 0;
 > +
 > +      /* Step over possible lds.l @r15+,pr. */
 > +      inst = read_memory_unsigned_integer (addr - 2, 2);
 > +      if (IS_LDS (inst))
 > +        {
 > +	  addr -= 2;
 > +	  inst = read_memory_unsigned_integer (addr - 2, 2);
 > +	}
 > +
 > +      /* Step over possible mov r14,r15. */
 > +      if (IS_MOV_FP_SP (inst))
 > +        {
 > +	  addr -= 2;
 > +	  inst = read_memory_unsigned_integer (addr - 2, 2);
 > +	}
 > +
 > +      /* Now check for FP adjustments, using add #imm,r14 or add rX, r14
 > +         instructions. */
 > +      while (addr > func_addr + 4
 > +             && (IS_ADD_REG_TO_FP (inst) || IS_ADD_IMM_FP (inst)))
 > +	{
 > +	  addr -= 2;
 > +	  inst = read_memory_unsigned_integer (addr - 2, 2);
 > +	}
 > +
 > +      if (pc >= addr)
 > +	return 1;
 > +    }
 > +  return 0;
 > +}
 > +
 >  static gdbarch_init_ftype sh_gdbarch_init;
 >  
 >  static struct gdbarch *
 >  sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 >  {
 >    struct gdbarch *gdbarch;
 > -  struct gdbarch_tdep *tdep;
 >  
 >    sh_show_regs = sh_generic_show_regs;
 >    switch (info.bfd_arch_info->mach)
 >      {
 >        case bfd_mach_sh2e:
 > -        sh_show_regs = sh2e_show_regs;
 > -        break;
 > +	sh_show_regs = sh2e_show_regs;
 > +	break;
 >        case bfd_mach_sh_dsp:
 > -        sh_show_regs = sh_dsp_show_regs;
 > -        break;
 > +	sh_show_regs = sh_dsp_show_regs;
 > +	break;
 >  
 >        case bfd_mach_sh3:
 > -        sh_show_regs = sh3_show_regs;
 > -        break;
 > +	sh_show_regs = sh3_show_regs;
 > +	break;
 >  
 >        case bfd_mach_sh3e:
 > -        sh_show_regs = sh3e_show_regs;
 > -        break;
 > +	sh_show_regs = sh3e_show_regs;
 > +	break;
 >  
 >        case bfd_mach_sh3_dsp:
 > -        sh_show_regs = sh3_dsp_show_regs;
 > -        break;
 > +	sh_show_regs = sh3_dsp_show_regs;
 > +	break;
 >  
 >        case bfd_mach_sh4:
 > -        sh_show_regs = sh4_show_regs;
 > -        break;
 > +	sh_show_regs = sh4_show_regs;
 > +	break;
 >  
 >        case bfd_mach_sh5:
 >  	sh_show_regs = sh64_show_regs;
 > -        /* SH5 is handled entirely in sh64-tdep.c */
 > -        return sh64_gdbarch_init (info, arches);
 > +	/* SH5 is handled entirely in sh64-tdep.c */
 > +	return sh64_gdbarch_init (info, arches);
 >      }
 >  
 >    /* If there is already a candidate, use it.  */
 > @@ -2108,39 +2038,7 @@ sh_gdbarch_init (struct gdbarch_info inf
 >  
 >    /* None found, create a new architecture from the information
 >       provided. */
 > -  tdep = XMALLOC (struct gdbarch_tdep);
 > -  gdbarch = gdbarch_alloc (&info, tdep);
 > -
 > -  /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
 > -     ready to unwind the PC first (see frame.c:get_prev_frame()).  */
 > -  set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_default);
 > -
 > -  /* Initialize the register numbers that are not common to all the
 > -     variants to -1, if necessary thse will be overwritten in the case
 > -     statement below. */
 > -  tdep->FPUL_REGNUM = -1;
 > -  tdep->FPSCR_REGNUM = -1;
 > -  tdep->DSR_REGNUM = -1;
 > -  tdep->FP_LAST_REGNUM = -1;
 > -  tdep->A0G_REGNUM = -1;
 > -  tdep->A0_REGNUM = -1;
 > -  tdep->A1G_REGNUM = -1;
 > -  tdep->A1_REGNUM = -1;
 > -  tdep->M0_REGNUM = -1;
 > -  tdep->M1_REGNUM = -1;
 > -  tdep->X0_REGNUM = -1;
 > -  tdep->X1_REGNUM = -1;
 > -  tdep->Y0_REGNUM = -1;
 > -  tdep->Y1_REGNUM = -1;
 > -  tdep->MOD_REGNUM = -1;
 > -  tdep->RS_REGNUM = -1;
 > -  tdep->RE_REGNUM = -1;
 > -  tdep->SSR_REGNUM = -1;
 > -  tdep->SPC_REGNUM = -1;
 > -  tdep->DR0_REGNUM = -1;
 > -  tdep->DR_LAST_REGNUM = -1;
 > -  tdep->FV0_REGNUM = -1;
 > -  tdep->FV_LAST_REGNUM = -1;
 > +  gdbarch = gdbarch_alloc (&info, NULL);
 >  
 >    set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
 >    set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
 > @@ -2151,13 +2049,16 @@ sh_gdbarch_init (struct gdbarch_info inf
 >    set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
 >    set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
 >  
 > -  set_gdbarch_num_regs (gdbarch, SH_DEFAULT_NUM_REGS);
 > +  set_gdbarch_num_regs (gdbarch, SH_NUM_REGS);
 >    set_gdbarch_sp_regnum (gdbarch, 15);
 > -  set_gdbarch_deprecated_fp_regnum (gdbarch, 14);
 >    set_gdbarch_pc_regnum (gdbarch, 16);
 >    set_gdbarch_fp0_regnum (gdbarch, -1);
 >    set_gdbarch_num_pseudo_regs (gdbarch, 0);
 >  
 > +  set_gdbarch_register_type (gdbarch, sh_default_register_type);
 > +
 > +  set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
 > +
 >    set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc);
 >    set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention);
 >  
 > @@ -2166,164 +2067,84 @@ sh_gdbarch_init (struct gdbarch_info inf
 >  
 >    set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
 >  
 > +  set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value);
 > +  set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value);
 > +  set_gdbarch_extract_struct_value_address (gdbarch,
 > +					    sh_extract_struct_value_address);
 > +
 >    set_gdbarch_skip_prologue (gdbarch, sh_skip_prologue);
 >    set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
 >    set_gdbarch_decr_pc_after_break (gdbarch, 0);
 >    set_gdbarch_function_start_offset (gdbarch, 0);
 >  
 > +  set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code);
 > +  set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu);
 > +
 >    set_gdbarch_frame_args_skip (gdbarch, 0);
 > -  set_gdbarch_frameless_function_invocation (gdbarch, frameless_look_for_prologue);
 > +  set_gdbarch_frameless_function_invocation (gdbarch,
 > +					     frameless_look_for_prologue);
 >    set_gdbarch_believe_pcc_promotion (gdbarch, 1);
 >  
 > -  set_gdbarch_deprecated_frame_chain (gdbarch, sh_frame_chain);
 > -  set_gdbarch_deprecated_get_saved_register (gdbarch, deprecated_generic_get_saved_register);
 > -  set_gdbarch_deprecated_init_extra_frame_info (gdbarch, sh_init_extra_frame_info);
 > -  set_gdbarch_deprecated_pop_frame (gdbarch, sh_pop_frame);
 > -  set_gdbarch_deprecated_frame_saved_pc (gdbarch, sh_frame_saved_pc);
 > -  set_gdbarch_deprecated_saved_pc_after_call (gdbarch, sh_saved_pc_after_call);
 >    set_gdbarch_frame_align (gdbarch, sh_frame_align);
 > +  set_gdbarch_unwind_sp (gdbarch, sh_unwind_sp);
 > +  set_gdbarch_unwind_pc (gdbarch, sh_unwind_pc);
 > +  set_gdbarch_unwind_dummy_id (gdbarch, sh_unwind_dummy_id);
 > +  frame_base_set_default (gdbarch, &sh_frame_base);
 > +
 > +  set_gdbarch_in_function_epilogue_p (gdbarch,
 > +				      sh_in_function_epilogue_p);
 >  
 >    switch (info.bfd_arch_info->mach)
 >      {
 >      case bfd_mach_sh:
 >        set_gdbarch_register_name (gdbarch, sh_sh_register_name);
 > -      set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
 > -      set_gdbarch_register_type (gdbarch, sh_default_register_type);
 > -      set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code);
 > -      set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value);
 > -      set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value);
 > -      set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu);
 > -      set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address);
 > -
 > -      set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
 >        break;
 > +
 >      case bfd_mach_sh2:
 >        set_gdbarch_register_name (gdbarch, sh_sh_register_name);
 > -      set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
 > -      set_gdbarch_register_type (gdbarch, sh_default_register_type);
 > -      set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code);
 > -      set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value);
 > -      set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value);
 > -      set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu);
 > -      set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address);
 > -
 > -      set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
 >        break;      
 > +
 >      case bfd_mach_sh2e:
 >        /* doubles on sh2e and sh3e are actually 4 byte. */
 >        set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
 >  
 >        set_gdbarch_register_name (gdbarch, sh_sh2e_register_name);
 > -      set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
 >        set_gdbarch_register_type (gdbarch, sh_sh3e_register_type);
 > -      set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code);
 >        set_gdbarch_fp0_regnum (gdbarch, 25);
 >        set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value);
 >        set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
 >        set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
 > -      set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address);
 > -      tdep->FPUL_REGNUM = 23;
 > -      tdep->FPSCR_REGNUM = 24;
 > -      tdep->FP_LAST_REGNUM = 40;
 > -
 > -      set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
 >        break;
 > +
 >      case bfd_mach_sh_dsp:
 >        set_gdbarch_register_name (gdbarch, sh_sh_dsp_register_name);
 > -      set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
 > -      set_gdbarch_register_type (gdbarch, sh_default_register_type);
 > -      set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code);
 >        set_gdbarch_register_sim_regno (gdbarch, sh_dsp_register_sim_regno);
 > -      set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value);
 > -      set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value);
 > -      set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu);
 > -      set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address);
 > -      tdep->DSR_REGNUM = 24;
 > -      tdep->A0G_REGNUM = 25;
 > -      tdep->A0_REGNUM = 26;
 > -      tdep->A1G_REGNUM = 27;
 > -      tdep->A1_REGNUM = 28;
 > -      tdep->M0_REGNUM = 29;
 > -      tdep->M1_REGNUM = 30;
 > -      tdep->X0_REGNUM = 31;
 > -      tdep->X1_REGNUM = 32;
 > -      tdep->Y0_REGNUM = 33;
 > -      tdep->Y1_REGNUM = 34;
 > -      tdep->MOD_REGNUM = 40;
 > -      tdep->RS_REGNUM = 43;
 > -      tdep->RE_REGNUM = 44;
 > -
 > -      set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
 >        break;
 > +
 >      case bfd_mach_sh3:
 >        set_gdbarch_register_name (gdbarch, sh_sh3_register_name);
 > -      set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
 > -      set_gdbarch_register_type (gdbarch, sh_default_register_type);
 > -      set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code);
 > -      set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value);
 > -      set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value);
 > -      set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu);
 > -      set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address);
 > -      tdep->SSR_REGNUM = 41;
 > -      tdep->SPC_REGNUM = 42;
 > -
 > -      set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
 >        break;
 > +
 >      case bfd_mach_sh3e:
 >        /* doubles on sh2e and sh3e are actually 4 byte. */
 >        set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
 >  
 >        set_gdbarch_register_name (gdbarch, sh_sh3e_register_name);
 > -      set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
 >        set_gdbarch_register_type (gdbarch, sh_sh3e_register_type);
 > -      set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code);
 >        set_gdbarch_fp0_regnum (gdbarch, 25);
 >        set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value);
 >        set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
 >        set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
 > -      set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address);
 > -      tdep->FPUL_REGNUM = 23;
 > -      tdep->FPSCR_REGNUM = 24;
 > -      tdep->FP_LAST_REGNUM = 40;
 > -      tdep->SSR_REGNUM = 41;
 > -      tdep->SPC_REGNUM = 42;
 > -
 > -      set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_fp_frame_init_saved_regs);
 >        break;
 > +
 >      case bfd_mach_sh3_dsp:
 >        set_gdbarch_register_name (gdbarch, sh_sh3_dsp_register_name);
 > -      set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
 > -      set_gdbarch_register_type (gdbarch, sh_default_register_type);
 > -      set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code);
 >        set_gdbarch_register_sim_regno (gdbarch, sh_dsp_register_sim_regno);
 > -      set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value);
 > -      set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value);
 > -      set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu);
 > -      set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address);
 > -      tdep->DSR_REGNUM = 24;
 > -      tdep->A0G_REGNUM = 25;
 > -      tdep->A0_REGNUM = 26;
 > -      tdep->A1G_REGNUM = 27;
 > -      tdep->A1_REGNUM = 28;
 > -      tdep->M0_REGNUM = 29;
 > -      tdep->M1_REGNUM = 30;
 > -      tdep->X0_REGNUM = 31;
 > -      tdep->X1_REGNUM = 32;
 > -      tdep->Y0_REGNUM = 33;
 > -      tdep->Y1_REGNUM = 34;
 > -      tdep->MOD_REGNUM = 40;
 > -      tdep->RS_REGNUM = 43;
 > -      tdep->RE_REGNUM = 44;
 > -      tdep->SSR_REGNUM = 41;
 > -      tdep->SPC_REGNUM = 42;
 > -
 > -      set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
 >        break;
 > +
 >      case bfd_mach_sh4:
 >        set_gdbarch_register_name (gdbarch, sh_sh4_register_name);
 > -      set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
 >        set_gdbarch_register_type (gdbarch, sh_sh4_register_type);
 > -      set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code);
 >        set_gdbarch_fp0_regnum (gdbarch, 25);
 >        set_gdbarch_num_pseudo_regs (gdbarch, 12);
 >        set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read);
 > @@ -2331,46 +2152,20 @@ sh_gdbarch_init (struct gdbarch_info inf
 >        set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value);
 >        set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
 >        set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
 > -      set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address);
 > -      tdep->FPUL_REGNUM = 23;
 > -      tdep->FPSCR_REGNUM = 24;
 > -      tdep->FP_LAST_REGNUM = 40;
 > -      tdep->SSR_REGNUM = 41;
 > -      tdep->SPC_REGNUM = 42;
 > -      tdep->DR0_REGNUM = 59;
 > -      tdep->DR_LAST_REGNUM = 66;
 > -      tdep->FV0_REGNUM = 67;
 > -      tdep->FV_LAST_REGNUM = 70;
 > -
 > -      set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_fp_frame_init_saved_regs);
 >        break;
 > +
 >      default:
 >        set_gdbarch_register_name (gdbarch, sh_generic_register_name);
 > -      set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
 > -      set_gdbarch_register_type (gdbarch, sh_default_register_type);
 > -      set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code);
 > -      set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value);
 > -      set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value);
 > -
 > -      set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
 >        break;
 >      }
 >  
 >    /* Hook in ABI-specific overrides, if they have been registered.  */
 >    gdbarch_init_osabi (info, gdbarch);
 >  
 > -  return gdbarch;
 > -}
 > -
 > -static void
 > -sh_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
 > -{
 > -  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
 > -
 > -  if (tdep == NULL)
 > -    return;
 > +  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
 > +  frame_unwind_append_sniffer (gdbarch, sh_frame_sniffer);
 >  
 > -  /* FIXME: dump the rest of gdbarch_tdep.  */
 > +  return gdbarch;
 >  }
 >  
 >  extern initialize_file_ftype _initialize_sh_tdep; /* -Wmissing-prototypes */
 > @@ -2380,7 +2175,7 @@ _initialize_sh_tdep (void)
 >  {
 >    struct cmd_list_element *c;
 >    
 > -  gdbarch_register (bfd_arch_sh, sh_gdbarch_init, sh_dump_tdep);
 > +  gdbarch_register (bfd_arch_sh, sh_gdbarch_init, NULL);
 >  
 >    add_com ("regs", class_vars, sh_show_regs_command, "Print all registers");
 >  }
 > Index: sh-tdep.h
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/sh-tdep.h,v
 > retrieving revision 1.5
 > diff -u -p -r1.5 sh-tdep.h
 > --- sh-tdep.h	8 Sep 2003 11:26:20 -0000	1.5
 > +++ sh-tdep.h	8 Sep 2003 16:26:46 -0000
 > @@ -24,52 +24,51 @@
 >  
 >  /* Contributed by Steve Chamberlain sac@cygnus.com */
 >  
 > -struct gdbarch_tdep
 > -  {
 > -    int FPUL_REGNUM;  /*                       sh3e, sh4 */
 > -    int FPSCR_REGNUM; /*                       sh3e, sh4 */
 > -    int DSR_REGNUM;   /* sh-dsp,      sh3-dsp            */
 > -    int FP_LAST_REGNUM; /*                     sh3e, sh4 */
 > -    int A0G_REGNUM;   /* sh-dsp,      sh3-dsp            */
 > -    int A0_REGNUM;    /* sh-dsp,      sh3-dsp            */
 > -    int A1G_REGNUM;   /* sh-dsp,      sh3-dsp            */
 > -    int A1_REGNUM;    /* sh-dsp,      sh3-dsp            */
 > -    int M0_REGNUM;    /* sh-dsp,      sh3-dsp            */
 > -    int M1_REGNUM;    /* sh-dsp,      sh3-dsp            */
 > -    int X0_REGNUM;    /* sh-dsp,      sh3-dsp            */
 > -    int X1_REGNUM;    /* sh-dsp,      sh3-dsp            */
 > -    int Y0_REGNUM;    /* sh-dsp,      sh3-dsp            */
 > -    int Y1_REGNUM;    /* sh-dsp,      sh3-dsp            */
 > -    int MOD_REGNUM;   /* sh-dsp,      sh3-dsp            */
 > -    int SSR_REGNUM;   /*         sh3, sh3-dsp, sh3e, sh4 */
 > -    int SPC_REGNUM;   /*         sh3, sh3-dsp, sh3e, sh4 */
 > -    int RS_REGNUM;    /* sh-dsp,      sh3-dsp            */
 > -    int RE_REGNUM;    /* sh-dsp,      sh3-dsp            */
 > -    int DR0_REGNUM;   /*                             sh4 */
 > -    int DR_LAST_REGNUM; /*                           sh4 */
 > -    int FV0_REGNUM;   /*                             sh4 */
 > -    int FV_LAST_REGNUM; /*                           sh4 */
 > -    /* FPP stands for Floating Point Pair, to avoid confusion with
 > -       GDB's FP0_REGNUM, which is the number of the first Floating
 > -       point register. Unfortunately on the sh5, the floating point
 > -       registers are called FR, and the floating point pairs are called FP. */
 > -  };
 > -
 > -/* Registers common to all the SH variants. */
 > +/* Registers for all SH variants.  Used also by sh3-rom.c. */
 >  enum
 >    {
 >      R0_REGNUM = 0,
 >      STRUCT_RETURN_REGNUM = 2,
 >      ARG0_REGNUM = 4,
 >      ARGLAST_REGNUM = 7,
 > +    FP_REGNUM = 14,
 >      PR_REGNUM = 17,
 >      GBR_REGNUM = 18,
 >      VBR_REGNUM = 19,
 >      MACH_REGNUM = 20,
 >      MACL_REGNUM = 21,
 >      SR_REGNUM = 22,
 > +    FPUL_REGNUM = 23,
 > +    /* Floating point registers */
 > +    FPSCR_REGNUM = 24,
 >      FLOAT_ARG0_REGNUM = 29,
 > -    FLOAT_ARGLAST_REGNUM = 36
 > +    FLOAT_ARGLAST_REGNUM = 36,
 > +    FP_LAST_REGNUM = 40,
 > +    /* sh3,sh4 registers */
 > +    SSR_REGNUM = 41,
 > +    SPC_REGNUM = 42,
 > +    /* DSP registers */
 > +    DSR_REGNUM = 24,
 > +    A0G_REGNUM = 25,
 > +    A0_REGNUM = 26,
 > +    A1G_REGNUM = 27,
 > +    A1_REGNUM = 28,
 > +    M0_REGNUM = 29,
 > +    M1_REGNUM = 30,
 > +    X0_REGNUM = 31,
 > +    X1_REGNUM = 32,
 > +    Y0_REGNUM = 33,
 > +    Y1_REGNUM = 34,
 > +    MOD_REGNUM = 40,
 > +    RS_REGNUM = 43,
 > +    RE_REGNUM = 44,
 > +    R0_BANK_REGNUM = 51,
 > +    R7_BANK_REGNUM = 58,
 > +    /* Floating point pseudo registers */
 > +    DR0_REGNUM = 59,
 > +    DR_LAST_REGNUM = 66,
 > +    FV0_REGNUM = 67,
 > +    FV_LAST_REGNUM = 70
 >    };
 >  
 >  extern gdbarch_init_ftype sh64_gdbarch_init;
 > Index: sh3-rom.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/sh3-rom.c,v
 > retrieving revision 1.15
 > diff -u -p -r1.15 sh3-rom.c
 > --- sh3-rom.c	21 Aug 2003 20:43:10 -0000	1.15
 > +++ sh3-rom.c	8 Sep 2003 16:26:46 -0000
 > @@ -77,9 +77,9 @@ sh3_supply_register (char *regname, int 
 >  	  break;
 >  	case 'S':
 >  	  if (regname[1] == 'S' && regname[2] == 'R')
 > -	    regno = gdbarch_tdep (current_gdbarch)->SSR_REGNUM;
 > +	    regno = SSR_REGNUM;
 >  	  else if (regname[1] == 'P' && regname[2] == 'C')
 > -	    regno = gdbarch_tdep (current_gdbarch)->SPC_REGNUM;
 > +	    regno = SPC_REGNUM;
 >  	  break;
 >  	}
 >      }
 > 
 > -- 
 > Corinna Vinschen
 > Cygwin Developer
 > Red Hat, Inc.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]