run copyright.sh for 2011.
[deliverable/binutils-gdb.git] / gdb / sh-tdep.c
index 1db65c66c5df602c27d2e50bf4290a3485d9239d..2964d526e245e983bbc292371cf483924616efa2 100644 (file)
@@ -1,12 +1,14 @@
 /* Target-dependent code for Renesas Super-H, for GDB.
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+
+   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+   2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    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
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -15,9 +17,7 @@
    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.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /*
    Contributed by Steve Chamberlain
@@ -30,7 +30,6 @@
 #include "frame-unwind.h"
 #include "dwarf2-frame.h"
 #include "symtab.h"
-#include "symfile.h"
 #include "gdbtypes.h"
 #include "gdbcmd.h"
 #include "gdbcore.h"
@@ -44,6 +43,8 @@
 #include "regcache.h"
 #include "doublest.h"
 #include "osabi.h"
+#include "reggroups.h"
+#include "regset.h"
 
 #include "sh-tdep.h"
 
 
 /* sh flags */
 #include "elf/sh.h"
+#include "dwarf2.h"
 /* registers numbers shared with the simulator */
 #include "gdb/sim-sh.h"
 
-static void (*sh_show_regs) (void);
+/* List of "set sh ..." and "show sh ..." commands.  */
+static struct cmd_list_element *setshcmdlist = NULL;
+static struct cmd_list_element *showshcmdlist = NULL;
+
+static const char sh_cc_gcc[] = "gcc";
+static const char sh_cc_renesas[] = "renesas";
+static const char *sh_cc_enum[] = {
+  sh_cc_gcc,
+  sh_cc_renesas, 
+  NULL
+};
+
+static const char *sh_active_calling_convention = sh_cc_gcc;
 
-#define SH_NUM_REGS 59
+static void (*sh_show_regs) (struct frame_info *);
+
+#define SH_NUM_REGS 67
 
 struct sh_frame_cache
 {
@@ -74,19 +90,28 @@ struct sh_frame_cache
   CORE_ADDR saved_sp;
 };
 
+static int
+sh_is_renesas_calling_convention (struct type *func_type)
+{
+  return ((func_type
+          && TYPE_CALLING_CONVENTION (func_type) == DW_CC_GNU_renesas_sh)
+         || sh_active_calling_convention == sh_cc_renesas);
+}
+
 static const char *
-sh_generic_register_name (int reg_nr)
+sh_sh_register_name (struct gdbarch *gdbarch, int reg_nr)
 {
   static char *register_names[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
-    "fpul", "fpscr",
-    "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
-    "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
-    "ssr", "spc",
-    "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
-    "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1",
+    "", "",
+    "", "", "", "", "", "", "", "",
+    "", "", "", "", "", "", "", "",
+    "", "",
+    "", "", "", "", "", "", "", "",
+    "", "", "", "", "", "", "", "",
+    "", "", "", "", "", "", "", "",
   };
   if (reg_nr < 0)
     return NULL;
@@ -96,7 +121,7 @@ sh_generic_register_name (int reg_nr)
 }
 
 static const char *
-sh_sh_register_name (int reg_nr)
+sh_sh3_register_name (struct gdbarch *gdbarch, int reg_nr)
 {
   static char *register_names[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -105,8 +130,9 @@ sh_sh_register_name (int reg_nr)
     "", "",
     "", "", "", "", "", "", "", "",
     "", "", "", "", "", "", "", "",
-    "", "",
-    "", "", "", "", "", "", "", "",
+    "ssr", "spc",
+    "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
+    "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1"
     "", "", "", "", "", "", "", "",
   };
   if (reg_nr < 0)
@@ -117,18 +143,19 @@ sh_sh_register_name (int reg_nr)
 }
 
 static const char *
-sh_sh3_register_name (int reg_nr)
+sh_sh3e_register_name (struct gdbarch *gdbarch, int reg_nr)
 {
   static char *register_names[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
-    "", "",
-    "", "", "", "", "", "", "", "",
-    "", "", "", "", "", "", "", "",
+    "fpul", "fpscr",
+    "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
+    "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
     "ssr", "spc",
     "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
-    "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1"
+    "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1",
+    "", "", "", "", "", "", "", "",
   };
   if (reg_nr < 0)
     return NULL;
@@ -138,7 +165,7 @@ sh_sh3_register_name (int reg_nr)
 }
 
 static const char *
-sh_sh3e_register_name (int reg_nr)
+sh_sh2e_register_name (struct gdbarch *gdbarch, int reg_nr)
 {
   static char *register_names[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -147,9 +174,10 @@ sh_sh3e_register_name (int reg_nr)
     "fpul", "fpscr",
     "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
     "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
-    "ssr", "spc",
-    "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
-    "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1",
+    "", "",
+    "", "", "", "", "", "", "", "",
+    "", "", "", "", "", "", "", "",
+    "", "", "", "", "", "", "", "",
   };
   if (reg_nr < 0)
     return NULL;
@@ -159,17 +187,76 @@ sh_sh3e_register_name (int reg_nr)
 }
 
 static const char *
-sh_sh2e_register_name (int reg_nr)
+sh_sh2a_register_name (struct gdbarch *gdbarch, int reg_nr)
 {
   static char *register_names[] = {
+    /* general registers 0-15 */
     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+    /* 16 - 22 */
     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
+    /* 23, 24 */
     "fpul", "fpscr",
+    /* floating point registers 25 - 40 */
     "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
     "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
+    /* 41, 42 */
     "", "",
+    /* 43 - 62.  Banked registers.  The bank number used is determined by
+       the bank register (63). */
+    "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b",
+    "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b",
+    "machb", "ivnb", "prb", "gbrb", "maclb",
+    /* 63: register bank number, not a real register but used to
+       communicate the register bank currently get/set.  This register
+       is hidden to the user, who manipulates it using the pseudo
+       register called "bank" (67).  See below.  */
+    "",
+    /* 64 - 66 */
+    "ibcr", "ibnr", "tbr",
+    /* 67: register bank number, the user visible pseudo register.  */
+    "bank",
+    /* double precision (pseudo) 68 - 75 */
+    "dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14",
+  };
+  if (reg_nr < 0)
+    return NULL;
+  if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
+    return NULL;
+  return register_names[reg_nr];
+}
+
+static const char *
+sh_sh2a_nofpu_register_name (struct gdbarch *gdbarch, int reg_nr)
+{
+  static char *register_names[] = {
+    /* general registers 0-15 */
+    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+    /* 16 - 22 */
+    "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
+    /* 23, 24 */
+    "", "",
+    /* floating point registers 25 - 40 */
+    "", "", "", "", "", "", "", "",
     "", "", "", "", "", "", "", "",
+    /* 41, 42 */
+    "", "",
+    /* 43 - 62.  Banked registers.  The bank number used is determined by
+       the bank register (63). */
+    "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b",
+    "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b",
+    "machb", "ivnb", "prb", "gbrb", "maclb",
+    /* 63: register bank number, not a real register but used to
+       communicate the register bank currently get/set.  This register
+       is hidden to the user, who manipulates it using the pseudo
+       register called "bank" (67).  See below.  */
+    "",
+    /* 64 - 66 */
+    "ibcr", "ibnr", "tbr",
+    /* 67: register bank number, the user visible pseudo register.  */
+    "bank",
+    /* double precision (pseudo) 68 - 75 */
     "", "", "", "", "", "", "", "",
   };
   if (reg_nr < 0)
@@ -180,7 +267,7 @@ sh_sh2e_register_name (int reg_nr)
 }
 
 static const char *
-sh_sh_dsp_register_name (int reg_nr)
+sh_sh_dsp_register_name (struct gdbarch *gdbarch, int reg_nr)
 {
   static char *register_names[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -192,6 +279,7 @@ sh_sh_dsp_register_name (int reg_nr)
     "", "",
     "rs", "re", "", "", "", "", "", "",
     "", "", "", "", "", "", "", "",
+    "", "", "", "", "", "", "", "",
   };
   if (reg_nr < 0)
     return NULL;
@@ -201,7 +289,7 @@ sh_sh_dsp_register_name (int reg_nr)
 }
 
 static const char *
-sh_sh3_dsp_register_name (int reg_nr)
+sh_sh3_dsp_register_name (struct gdbarch *gdbarch, int reg_nr)
 {
   static char *register_names[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -214,6 +302,7 @@ sh_sh3_dsp_register_name (int reg_nr)
     "rs", "re", "", "", "", "", "", "",
     "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b",
     "", "", "", "", "", "", "", "",
+    "", "", "", "", "", "", "", "",
   };
   if (reg_nr < 0)
     return NULL;
@@ -223,7 +312,7 @@ sh_sh3_dsp_register_name (int reg_nr)
 }
 
 static const char *
-sh_sh4_register_name (int reg_nr)
+sh_sh4_register_name (struct gdbarch *gdbarch, int reg_nr)
 {
   static char *register_names[] = {
     /* general registers 0-15 */
@@ -242,6 +331,9 @@ sh_sh4_register_name (int reg_nr)
     "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
     /* bank 1 51 - 58 */
     "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1",
+    "", "", "", "", "", "", "", "",
+    /* pseudo bank register. */
+    "",
     /* double precision (pseudo) 59 - 66 */
     "dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14",
     /* vectors (pseudo) 67 - 70 */
@@ -257,7 +349,7 @@ sh_sh4_register_name (int reg_nr)
 }
 
 static const char *
-sh_sh4_nofpu_register_name (int reg_nr)
+sh_sh4_nofpu_register_name (struct gdbarch *gdbarch, int reg_nr)
 {
   static char *register_names[] = {
     /* general registers 0-15 */
@@ -276,6 +368,9 @@ sh_sh4_nofpu_register_name (int reg_nr)
     "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
     /* bank 1 51 - 58 */
     "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1",
+    "", "", "", "", "", "", "", "",
+    /* pseudo bank register. */
+    "",
     /* double precision (pseudo) 59 - 66 -- not for nofpu target */
     "", "", "", "", "", "", "", "",
     /* vectors (pseudo) 67 - 70 -- not for nofpu target */
@@ -289,7 +384,7 @@ sh_sh4_nofpu_register_name (int reg_nr)
 }
 
 static const char *
-sh_sh4al_dsp_register_name (int reg_nr)
+sh_sh4al_dsp_register_name (struct gdbarch *gdbarch, int reg_nr)
 {
   static char *register_names[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -302,6 +397,7 @@ sh_sh4al_dsp_register_name (int reg_nr)
     "rs", "re", "", "", "", "", "", "",
     "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b",
     "", "", "", "", "", "", "", "",
+    "", "", "", "", "", "", "", "",
   };
   if (reg_nr < 0)
     return NULL;
@@ -311,11 +407,29 @@ sh_sh4al_dsp_register_name (int reg_nr)
 }
 
 static const unsigned char *
-sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+sh_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
 {
   /* 0xc3c3 is trapa #c3, and it works in big and little endian modes */
   static unsigned char breakpoint[] = { 0xc3, 0xc3 };
 
+  /* For remote stub targets, trapa #20 is used.  */
+  if (strcmp (target_shortname, "remote") == 0)
+    {
+      static unsigned char big_remote_breakpoint[] = { 0xc3, 0x20 };
+      static unsigned char little_remote_breakpoint[] = { 0x20, 0xc3 };
+
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+       {
+         *lenptr = sizeof (big_remote_breakpoint);
+         return big_remote_breakpoint;
+       }
+      else
+       {
+         *lenptr = sizeof (little_remote_breakpoint);
+         return little_remote_breakpoint;
+       }
+    }
+
   *lenptr = sizeof (breakpoint);
   return breakpoint;
 }
@@ -333,10 +447,17 @@ sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
 #define GET_SOURCE_REG(x)      (((x) >> 4) & 0xf)
 #define GET_TARGET_REG(x)      (((x) >> 8) & 0xf)
 
+/* JSR @Rm         0100mmmm00001011 */
+#define IS_JSR(x)              (((x) & 0xf0ff) == 0x400b)
+
 /* STS.L PR,@-r15  0100111100100010
    r15-4-->r15, PR-->(r15) */
 #define IS_STS(x)              ((x) == 0x4f22)
 
+/* STS.L MACL,@-r15  0100111100010010
+   r15-4-->r15, MACL-->(r15) */
+#define IS_MACL_STS(x)         ((x) == 0x4f12)
+
 /* MOV.L Rm,@-r15  00101111mmmm0110
    r15-4-->r15, Rm-->(R15) */
 #define IS_PUSH(x)             (((x) & 0xff0f) == 0x2f06)
@@ -384,6 +505,8 @@ sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
 #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)
+/* MOVI20 #imm20,Rn           0000nnnniiii0000 */
+#define IS_MOVI20(x)           (((x) & 0xf00f) == 0x0000)
 /* SUB Rn,R15                 00111111nnnn1000 */
 #define IS_SUB_REG_FROM_SP(x)  (((x) & 0xff0f) == 0x3f08)
 
@@ -393,22 +516,17 @@ sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
 #define IS_RESTORE_FP(x)       ((x) == 0x6ef6)
 #define IS_RTS(x)              ((x) == 0x000b)
 #define IS_LDS(x)              ((x) == 0x4f26)
+#define IS_MACL_LDS(x)         ((x) == 0x4f16)
 #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
-gdb_print_insn_sh (bfd_vma memaddr, disassemble_info * info)
-{
-  info->endian = TARGET_BYTE_ORDER;
-  return print_insn_sh (memaddr, info);
-}
-
 static CORE_ADDR
-sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
-                    struct sh_frame_cache *cache)
+sh_analyze_prologue (struct gdbarch *gdbarch,
+                    CORE_ADDR pc, CORE_ADDR current_pc,
+                    struct sh_frame_cache *cache, ULONGEST fpscr)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   ULONGEST inst;
   CORE_ADDR opc;
   int offset;
@@ -422,7 +540,7 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
   cache->uses_fp = 0;
   for (opc = pc + (2 * 28); pc < opc; pc += 2)
     {
-      inst = read_memory_unsigned_integer (pc, 2);
+      inst = read_memory_unsigned_integer (pc, 2, byte_order);
       /* See where the registers will be saved to */
       if (IS_PUSH (inst))
        {
@@ -434,6 +552,11 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
          cache->saved_regs[PR_REGNUM] = cache->sp_offset;
          cache->sp_offset += 4;
        }
+      else if (IS_MACL_STS (inst))
+       {
+         cache->saved_regs[MACL_REGNUM] = cache->sp_offset;
+         cache->sp_offset += 4;
+       }
       else if (IS_MOV_R3 (inst))
        {
          r3_val = ((inst & 0xff) ^ 0x80) - 0x80;
@@ -459,9 +582,9 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
              if (reg < 14)
                {
                  sav_reg = reg;
-                 offset = (((inst & 0xff) ^ 0x80) - 0x80) << 1;
+                 offset = (inst & 0xff) << 1;
                  sav_offset =
-                   read_memory_integer (((pc + 4) & ~3) + offset, 2);
+                   read_memory_integer ((pc + 4) + offset, 2, byte_order);
                }
            }
        }
@@ -469,13 +592,34 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
        {
          if (sav_reg < 0)
            {
-             reg = (inst & 0x0f00) >> 8;
+             reg = GET_TARGET_REG (inst);
              if (reg < 14)
                {
                  sav_reg = reg;
-                 offset = (((inst & 0xff) ^ 0x80) - 0x80) << 1;
+                 offset = (inst & 0xff) << 2;
                  sav_offset =
-                   read_memory_integer (((pc + 4) & ~3) + offset, 4);
+                   read_memory_integer (((pc & 0xfffffffc) + 4) + offset,
+                                        4, byte_order);
+               }
+           }
+       }
+      else if (IS_MOVI20 (inst))
+        {
+         if (sav_reg < 0)
+           {
+             reg = GET_TARGET_REG (inst);
+             if (reg < 14)
+               {
+                 sav_reg = reg;
+                 sav_offset = GET_SOURCE_REG (inst) << 16;
+                 /* MOVI20 is a 32 bit instruction! */
+                 pc += 2;
+                 sav_offset
+                   |= read_memory_unsigned_integer (pc, 2, byte_order);
+                 /* Now sav_offset contains an unsigned 20 bit value.
+                    It must still get sign extended.  */
+                 if (sav_offset & 0x00080000)
+                   sav_offset |= 0xfff00000;
                }
            }
        }
@@ -490,7 +634,7 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
        }
       else if (IS_FPUSH (inst))
        {
-         if (read_register (FPSCR_REGNUM) & FPSCR_SZ)
+         if (fpscr & FPSCR_SZ)
            {
              cache->sp_offset += 8;
            }
@@ -501,8 +645,7 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
        }
       else if (IS_MOV_SP_FP (inst))
        {
-         if (!cache->uses_fp)
-           cache->uses_fp = 1;
+         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
@@ -511,7 +654,7 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
          pc += 2;
          for (opc = pc + 12; pc < opc; pc += 2)
            {
-             inst = read_memory_integer (pc, 2);
+             inst = read_memory_integer (pc, 2, byte_order);
              if (IS_MOV_ARG_TO_IND_R14 (inst))
                {
                  reg = GET_SOURCE_REG (inst);
@@ -532,6 +675,20 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
            }
          break;
        }
+      else if (IS_JSR (inst))
+       {
+         /* We have found a jsr that has been scheduled into the prologue.
+            If we continue the scan and return a pc someplace after this,
+            then setting a breakpoint on this function will cause it to
+            appear to be called after the function it is calling via the
+            jsr, which will be very confusing.  Most likely the next
+            instruction is going to be IS_MOV_SP_FP in the delay slot.  If
+            so, note that before returning the current pc. */
+         inst = read_memory_integer (pc + 2, 2, byte_order);
+         if (IS_MOV_SP_FP (inst))
+           cache->uses_fp = 1;
+         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. */
@@ -574,7 +731,7 @@ after_prologue (CORE_ADDR pc)
 }
 
 static CORE_ADDR
-sh_skip_prologue (CORE_ADDR start_pc)
+sh_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
 {
   CORE_ADDR pc;
   struct sh_frame_cache cache;
@@ -590,7 +747,7 @@ sh_skip_prologue (CORE_ADDR start_pc)
     return max (pc, start_pc);
 
   cache.sp_offset = -4;
-  pc = sh_analyze_prologue (start_pc, (CORE_ADDR) -1, &cache);
+  pc = sh_analyze_prologue (gdbarch, start_pc, (CORE_ADDR) -1, &cache, 0);
   if (!cache.uses_fp)
     return start_pc;
 
@@ -647,11 +804,16 @@ sh_skip_prologue (CORE_ADDR start_pc)
 */
 
 static int
-sh_use_struct_convention (int gcc_p, struct type *type)
+sh_use_struct_convention (int renesas_abi, struct type *type)
 {
   int len = TYPE_LENGTH (type);
   int nelem = TYPE_NFIELDS (type);
 
+  /* The Renesas ABI returns aggregate types always on stack.  */
+  if (renesas_abi && (TYPE_CODE (type) == TYPE_CODE_STRUCT
+                     || TYPE_CODE (type) == TYPE_CODE_UNION))
+    return 1;
+
   /* Non-power of 2 length types and types bigger than 8 bytes (which don't
      fit in two registers anyway) use struct convention.  */
   if (len != 1 && len != 2 && len != 4 && len != 8)
@@ -677,16 +839,13 @@ sh_use_struct_convention (int gcc_p, struct type *type)
   return 1;
 }
 
-/* Extract from an array REGBUF containing the (raw) register state
-   the address in which a function should return its structure value,
-   as a CORE_ADDR (or an expression that can be used as one).  */
-static CORE_ADDR
-sh_extract_struct_value_address (struct regcache *regcache)
+static int
+sh_use_struct_convention_nofpu (int renesas_abi, struct type *type)
 {
-  ULONGEST addr;
-
-  regcache_cooked_read_unsigned (regcache, STRUCT_RETURN_REGNUM, &addr);
-  return addr;
+  /* The Renesas ABI returns long longs/doubles etc. always on stack.  */
+  if (renesas_abi && TYPE_NFIELDS (type) == 0 && TYPE_LENGTH (type) >= 8)
+    return 1;
+  return sh_use_struct_convention (renesas_abi, type);
 }
 
 static CORE_ADDR
@@ -749,7 +908,7 @@ sh_frame_align (struct gdbarch *ignore, CORE_ADDR sp)
 
 /* Helper function to justify value in register according to endianess. */
 static char *
-sh_justify_value_in_reg (struct value *val, int len)
+sh_justify_value_in_reg (struct gdbarch *gdbarch, struct value *val, int len)
 {
   static char valbuf[4];
 
@@ -757,13 +916,13 @@ sh_justify_value_in_reg (struct value *val, int len)
   if (len < 4)
     {
       /* value gets right-justified in the register or stack word */
-      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-       memcpy (valbuf + (4 - len), (char *) VALUE_CONTENTS (val), len);
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+       memcpy (valbuf + (4 - len), (char *) value_contents (val), len);
       else
-       memcpy (valbuf, (char *) VALUE_CONTENTS (val), len);
+       memcpy (valbuf, (char *) value_contents (val), len);
       return valbuf;
     }
-  return (char *) VALUE_CONTENTS (val);
+  return (char *) value_contents (val);
 }
 
 /* Helper function to eval number of bytes to allocate on stack. */
@@ -772,7 +931,7 @@ sh_stack_allocsize (int nargs, struct value **args)
 {
   int stack_alloc = 0;
   while (nargs-- > 0)
-    stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[nargs])) + 3) & ~3);
+    stack_alloc += ((TYPE_LENGTH (value_type (args[nargs])) + 3) & ~3);
   return stack_alloc;
 }
 
@@ -800,7 +959,7 @@ sh_init_flt_argreg (void)
    29) the parity of the register number is preserved, which is important
    for the double register passing test (see the "argreg & 1" test below). */
 static int
-sh_next_flt_argreg (int len)
+sh_next_flt_argreg (struct gdbarch *gdbarch, int len, struct type *func_type)
 {
   int argreg;
 
@@ -819,7 +978,10 @@ sh_next_flt_argreg (int len)
       /* Doubles are always starting in a even register number. */
       if (argreg & 1)
        {
-         flt_argreg_array[argreg] = 1;
+         /* In gcc ABI, the skipped register is lost for further argument
+            passing now.  Not so in Renesas ABI.  */
+         if (!sh_is_renesas_calling_convention (func_type))
+           flt_argreg_array[argreg] = 1;
 
          ++argreg;
 
@@ -830,7 +992,8 @@ sh_next_flt_argreg (int len)
       /* Also mark the next register as used. */
       flt_argreg_array[argreg + 1] = 1;
     }
-  else if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
+  else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE
+          && !sh_is_renesas_calling_convention (func_type))
     {
       /* In little endian, gcc passes floats like this: f5, f4, f7, f6, ... */
       if (!flt_argreg_array[argreg + 1])
@@ -891,31 +1054,37 @@ sh_treat_as_flt_p (struct type *type)
 
 static CORE_ADDR
 sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
-                       CORE_ADDR func_addr,
+                       struct value *function,
                        struct regcache *regcache,
                        CORE_ADDR bp_addr, int nargs,
                        struct value **args,
                        CORE_ADDR sp, int struct_return,
                        CORE_ADDR struct_addr)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int stack_offset = 0;
   int argreg = ARG0_REGNUM;
   int flt_argreg = 0;
   int argnum;
+  struct type *func_type = value_type (function);
   struct type *type;
   CORE_ADDR regval;
   char *val;
   int len, reg_size = 0;
   int pass_on_stack = 0;
   int treat_as_flt;
+  int last_reg_arg = INT_MAX;
+
+  /* The Renesas ABI expects all varargs arguments, plus the last
+     non-vararg argument to be on the stack, no matter how many
+     registers have been used so far.  */
+  if (sh_is_renesas_calling_convention (func_type)
+      && TYPE_VARARGS (func_type))
+    last_reg_arg = TYPE_NFIELDS (func_type) - 2;
 
   /* first force sp to a 4-byte alignment */
   sp = sh_frame_align (gdbarch, sp);
 
-  if (struct_return)
-    regcache_cooked_write_unsigned (regcache,
-                                   STRUCT_RETURN_REGNUM, struct_addr);
-
   /* make room on stack for args */
   sp -= sh_stack_allocsize (nargs, args);
 
@@ -927,9 +1096,9 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
      in four registers available.  Loop thru args from first to last.  */
   for (argnum = 0; argnum < nargs; argnum++)
     {
-      type = VALUE_TYPE (args[argnum]);
+      type = value_type (args[argnum]);
       len = TYPE_LENGTH (type);
-      val = sh_justify_value_in_reg (args[argnum], len);
+      val = sh_justify_value_in_reg (gdbarch, args[argnum], len);
 
       /* Some decisions have to be made how various types are handled.
          This also differs in different ABIs. */
@@ -938,7 +1107,14 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
       /* Find out the next register to use for a floating point value. */
       treat_as_flt = sh_treat_as_flt_p (type);
       if (treat_as_flt)
-       flt_argreg = sh_next_flt_argreg (len);
+       flt_argreg = sh_next_flt_argreg (gdbarch, len, func_type);
+      /* In Renesas ABI, long longs and aggregate types are always passed
+        on stack.  */
+      else if (sh_is_renesas_calling_convention (func_type)
+              && ((TYPE_CODE (type) == TYPE_CODE_INT && len == 8)
+                  || TYPE_CODE (type) == TYPE_CODE_STRUCT
+                  || TYPE_CODE (type) == TYPE_CODE_UNION))
+       pass_on_stack = 1;
       /* In contrast to non-FPU CPUs, arguments are never split between
         registers and stack.  If an argument doesn't fit in the remaining
         registers it's always pushed entirely on the stack.  */
@@ -949,7 +1125,8 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
        {
          if ((treat_as_flt && flt_argreg > FLOAT_ARGLAST_REGNUM)
              || (!treat_as_flt && (argreg > ARGLAST_REGNUM
-                                   || pass_on_stack)))
+                                   || pass_on_stack))
+             || argnum > last_reg_arg)
            {
              /* The data goes entirely on the stack, 4-byte aligned. */
              reg_size = (len + 3) & ~3;
@@ -960,7 +1137,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
            {
              /* Argument goes in a float argument register.  */
              reg_size = register_size (gdbarch, flt_argreg);
-             regval = extract_unsigned_integer (val, reg_size);
+             regval = extract_unsigned_integer (val, reg_size, byte_order);
              /* In little endian mode, float types taking two registers
                 (doubles on sh4, long doubles on sh2e, sh3e and sh4) must
                 be stored swapped in the argument registers.  The below
@@ -968,14 +1145,14 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
                 register, increments the val and len values accordingly
                 and then proceeds as normal by writing the second 32 bits
                 into the next register. */
-             if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE
+             if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE
                  && TYPE_LENGTH (type) == 2 * reg_size)
                {
                  regcache_cooked_write_unsigned (regcache, flt_argreg + 1,
                                                  regval);
                  val += reg_size;
                  len -= reg_size;
-                 regval = extract_unsigned_integer (val, reg_size);
+                 regval = extract_unsigned_integer (val, reg_size, byte_order);
                }
              regcache_cooked_write_unsigned (regcache, flt_argreg++, regval);
            }
@@ -983,7 +1160,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
            {
              /* there's room in a register */
              reg_size = register_size (gdbarch, argreg);
-             regval = extract_unsigned_integer (val, reg_size);
+             regval = extract_unsigned_integer (val, reg_size, byte_order);
              regcache_cooked_write_unsigned (regcache, argreg++, regval);
            }
          /* Store the value one register at a time or in one step on stack.  */
@@ -992,39 +1169,60 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
        }
     }
 
+  if (struct_return)
+    {
+      if (sh_is_renesas_calling_convention (func_type))
+       /* If the function uses the Renesas ABI, subtract another 4 bytes from
+          the stack and store the struct return address there.  */
+       write_memory_unsigned_integer (sp -= 4, 4, byte_order, struct_addr);
+      else
+       /* Using the gcc ABI, the "struct return pointer" pseudo-argument has
+          its own dedicated register.  */
+       regcache_cooked_write_unsigned (regcache,
+                                       STRUCT_RETURN_REGNUM, struct_addr);
+    }
+
   /* Store return address. */
   regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr);
 
   /* Update stack pointer.  */
-  regcache_cooked_write_unsigned (regcache, SP_REGNUM, sp);
+  regcache_cooked_write_unsigned (regcache,
+                                 gdbarch_sp_regnum (gdbarch), sp);
 
   return sp;
 }
 
 static CORE_ADDR
 sh_push_dummy_call_nofpu (struct gdbarch *gdbarch,
-                         CORE_ADDR func_addr,
+                         struct value *function,
                          struct regcache *regcache,
                          CORE_ADDR bp_addr,
                          int nargs, struct value **args,
                          CORE_ADDR sp, int struct_return,
                          CORE_ADDR struct_addr)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int stack_offset = 0;
   int argreg = ARG0_REGNUM;
   int argnum;
+  struct type *func_type = value_type (function);
   struct type *type;
   CORE_ADDR regval;
   char *val;
-  int len, reg_size;
+  int len, reg_size = 0;
+  int pass_on_stack = 0;
+  int last_reg_arg = INT_MAX;
+
+  /* The Renesas ABI expects all varargs arguments, plus the last
+     non-vararg argument to be on the stack, no matter how many
+     registers have been used so far.  */
+  if (sh_is_renesas_calling_convention (func_type)
+      && TYPE_VARARGS (func_type))
+    last_reg_arg = TYPE_NFIELDS (func_type) - 2;
 
   /* first force sp to a 4-byte alignment */
   sp = sh_frame_align (gdbarch, sp);
 
-  if (struct_return)
-    regcache_cooked_write_unsigned (regcache,
-                                   STRUCT_RETURN_REGNUM, struct_addr);
-
   /* make room on stack for args */
   sp -= sh_stack_allocsize (nargs, args);
 
@@ -1033,13 +1231,25 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch,
      in four registers available.  Loop thru args from first to last.  */
   for (argnum = 0; argnum < nargs; argnum++)
     {
-      type = VALUE_TYPE (args[argnum]);
+      type = value_type (args[argnum]);
       len = TYPE_LENGTH (type);
-      val = sh_justify_value_in_reg (args[argnum], len);
+      val = sh_justify_value_in_reg (gdbarch, args[argnum], len);
 
+      /* Some decisions have to be made how various types are handled.
+        This also differs in different ABIs. */
+      pass_on_stack = 0;
+      /* Renesas ABI pushes doubles and long longs entirely on stack.
+        Same goes for aggregate types.  */
+      if (sh_is_renesas_calling_convention (func_type)
+         && ((TYPE_CODE (type) == TYPE_CODE_INT && len >= 8)
+             || (TYPE_CODE (type) == TYPE_CODE_FLT && len >= 8)
+             || TYPE_CODE (type) == TYPE_CODE_STRUCT
+             || TYPE_CODE (type) == TYPE_CODE_UNION))
+       pass_on_stack = 1;
       while (len > 0)
        {
-         if (argreg > ARGLAST_REGNUM)
+         if (argreg > ARGLAST_REGNUM || pass_on_stack
+             || argnum > last_reg_arg)
            {
              /* The remainder of the data goes entirely on the stack,
                 4-byte aligned. */
@@ -1051,7 +1261,7 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch,
            {
              /* there's room in a register */
              reg_size = register_size (gdbarch, argreg);
-             regval = extract_unsigned_integer (val, reg_size);
+             regval = extract_unsigned_integer (val, reg_size, byte_order);
              regcache_cooked_write_unsigned (regcache, argreg++, regval);
            }
          /* Store the value reg_size bytes at a time.  This means that things
@@ -1062,11 +1272,25 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch,
        }
     }
 
+  if (struct_return)
+    {
+      if (sh_is_renesas_calling_convention (func_type))
+       /* If the function uses the Renesas ABI, subtract another 4 bytes from
+          the stack and store the struct return address there.  */
+       write_memory_unsigned_integer (sp -= 4, 4, byte_order, struct_addr);
+      else
+       /* Using the gcc ABI, the "struct return pointer" pseudo-argument has
+          its own dedicated register.  */
+       regcache_cooked_write_unsigned (regcache,
+                                       STRUCT_RETURN_REGNUM, struct_addr);
+    }
+
   /* Store return address. */
   regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr);
 
   /* Update stack pointer.  */
-  regcache_cooked_write_unsigned (regcache, SP_REGNUM, sp);
+  regcache_cooked_write_unsigned (regcache,
+                                 gdbarch_sp_regnum (gdbarch), sp);
 
   return sp;
 }
@@ -1076,9 +1300,11 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch,
    containing the (raw) register state a function return value of type
    TYPE, and copy that, in virtual format, into VALBUF.  */
 static void
-sh_default_extract_return_value (struct type *type, struct regcache *regcache,
-                                void *valbuf)
+sh_extract_return_value_nofpu (struct type *type, struct regcache *regcache,
+                              void *valbuf)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int len = TYPE_LENGTH (type);
   int return_register = R0_REGNUM;
   int offset;
@@ -1088,7 +1314,7 @@ sh_default_extract_return_value (struct type *type, struct regcache *regcache,
       ULONGEST c;
 
       regcache_cooked_read_unsigned (regcache, R0_REGNUM, &c);
-      store_unsigned_integer (valbuf, len, c);
+      store_unsigned_integer (valbuf, len, byte_order, c);
     }
   else if (len == 8)
     {
@@ -1097,25 +1323,26 @@ sh_default_extract_return_value (struct type *type, struct regcache *regcache,
        regcache_raw_read (regcache, regnum++, (char *) valbuf + i);
     }
   else
-    error ("bad size for return value");
+    error (_("bad size for return value"));
 }
 
 static void
-sh3e_sh4_extract_return_value (struct type *type, struct regcache *regcache,
-                              void *valbuf)
+sh_extract_return_value_fpu (struct type *type, struct regcache *regcache,
+                            void *valbuf)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   if (sh_treat_as_flt_p (type))
     {
       int len = TYPE_LENGTH (type);
-      int i, regnum = FP0_REGNUM;
+      int i, regnum = gdbarch_fp0_regnum (gdbarch);
       for (i = 0; i < len; i += 4)
-       if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
+       if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
          regcache_raw_read (regcache, regnum++, (char *) valbuf + len - 4 - i);
        else
          regcache_raw_read (regcache, regnum++, (char *) valbuf + i);
     }
   else
-    sh_default_extract_return_value (type, regcache, valbuf);
+    sh_extract_return_value_nofpu (type, regcache, valbuf);
 }
 
 /* Write into appropriate registers a function return value
@@ -1125,15 +1352,17 @@ sh3e_sh4_extract_return_value (struct type *type, struct regcache *regcache,
    depending on the type of the return value. In all the other cases
    the result is stored in r0, left-justified. */
 static void
-sh_default_store_return_value (struct type *type, struct regcache *regcache,
-                              const void *valbuf)
+sh_store_return_value_nofpu (struct type *type, struct regcache *regcache,
+                            const void *valbuf)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   ULONGEST val;
   int len = TYPE_LENGTH (type);
 
   if (len <= 4)
     {
-      val = extract_unsigned_integer (valbuf, len);
+      val = extract_unsigned_integer (valbuf, len, byte_order);
       regcache_cooked_write_unsigned (regcache, R0_REGNUM, val);
     }
   else
@@ -1145,332 +1374,773 @@ sh_default_store_return_value (struct type *type, struct regcache *regcache,
 }
 
 static void
-sh3e_sh4_store_return_value (struct type *type, struct regcache *regcache,
-                            const void *valbuf)
+sh_store_return_value_fpu (struct type *type, struct regcache *regcache,
+                          const void *valbuf)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   if (sh_treat_as_flt_p (type))
     {
       int len = TYPE_LENGTH (type);
-      int i, regnum = FP0_REGNUM;
+      int i, regnum = gdbarch_fp0_regnum (gdbarch);
       for (i = 0; i < len; i += 4)
-       regcache_raw_write (regcache, regnum++, (char *) valbuf + i);
+       if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+         regcache_raw_write (regcache, regnum++,
+                             (char *) valbuf + len - 4 - i);
+       else
+         regcache_raw_write (regcache, regnum++, (char *) valbuf + i);
     }
   else
-    sh_default_store_return_value (type, regcache, valbuf);
+    sh_store_return_value_nofpu (type, regcache, valbuf);
+}
+
+static enum return_value_convention
+sh_return_value_nofpu (struct gdbarch *gdbarch, struct type *func_type,
+                      struct type *type, struct regcache *regcache,
+                      gdb_byte *readbuf, const gdb_byte *writebuf)
+{
+  if (sh_use_struct_convention_nofpu (
+       sh_is_renesas_calling_convention (func_type), type))
+    return RETURN_VALUE_STRUCT_CONVENTION;
+  if (writebuf)
+    sh_store_return_value_nofpu (type, regcache, writebuf);
+  else if (readbuf)
+    sh_extract_return_value_nofpu (type, regcache, readbuf);
+  return RETURN_VALUE_REGISTER_CONVENTION;
+}
+
+static enum return_value_convention
+sh_return_value_fpu (struct gdbarch *gdbarch, struct type *func_type,
+                    struct type *type, struct regcache *regcache,
+                    gdb_byte *readbuf, const gdb_byte *writebuf)
+{
+  if (sh_use_struct_convention (
+       sh_is_renesas_calling_convention (func_type), type))
+    return RETURN_VALUE_STRUCT_CONVENTION;
+  if (writebuf)
+    sh_store_return_value_fpu (type, regcache, writebuf);
+  else if (readbuf)
+    sh_extract_return_value_fpu (type, regcache, readbuf);
+  return RETURN_VALUE_REGISTER_CONVENTION;
 }
 
 /* Print the registers in a form similar to the E7000 */
 
 static void
-sh_generic_show_regs (void)
+sh_generic_show_regs (struct frame_info *frame)
 {
-  printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
-                  paddr (read_register (PC_REGNUM)),
-                  (long) read_register (SR_REGNUM),
-                  (long) read_register (PR_REGNUM),
-                  (long) read_register (MACH_REGNUM),
-                  (long) read_register (MACL_REGNUM));
+  printf_filtered
+    ("      PC %s       SR %08lx       PR %08lx     MACH %08lx\n",
+     phex (get_frame_register_unsigned (frame,
+                                       gdbarch_pc_regnum
+                                          (get_frame_arch (frame))), 4),
+     (long) get_frame_register_unsigned (frame, SR_REGNUM),
+     (long) get_frame_register_unsigned (frame, PR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACH_REGNUM));
 
-  printf_filtered ("GBR=%08lx VBR=%08lx",
-                  (long) read_register (GBR_REGNUM),
-                  (long) read_register (VBR_REGNUM));
+  printf_filtered
+    ("     GBR %08lx      VBR %08lx                       MACL %08lx\n",
+     (long) get_frame_register_unsigned (frame, GBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, VBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACL_REGNUM));
 
   printf_filtered
-    ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-     (long) read_register (0), (long) read_register (1),
-     (long) read_register (2), (long) read_register (3),
-     (long) read_register (4), (long) read_register (5),
-     (long) read_register (6), (long) read_register (7));
-  printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-                  (long) read_register (8), (long) read_register (9),
-                  (long) read_register (10), (long) read_register (11),
-                  (long) read_register (12), (long) read_register (13),
-                  (long) read_register (14), (long) read_register (15));
+    ("R0-R7    %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 0),
+     (long) get_frame_register_unsigned (frame, 1),
+     (long) get_frame_register_unsigned (frame, 2),
+     (long) get_frame_register_unsigned (frame, 3),
+     (long) get_frame_register_unsigned (frame, 4),
+     (long) get_frame_register_unsigned (frame, 5),
+     (long) get_frame_register_unsigned (frame, 6),
+     (long) get_frame_register_unsigned (frame, 7));
+  printf_filtered
+    ("R8-R15   %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 8),
+     (long) get_frame_register_unsigned (frame, 9),
+     (long) get_frame_register_unsigned (frame, 10),
+     (long) get_frame_register_unsigned (frame, 11),
+     (long) get_frame_register_unsigned (frame, 12),
+     (long) get_frame_register_unsigned (frame, 13),
+     (long) get_frame_register_unsigned (frame, 14),
+     (long) get_frame_register_unsigned (frame, 15));
 }
 
 static void
-sh3_show_regs (void)
+sh3_show_regs (struct frame_info *frame)
 {
-  printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
-                  paddr (read_register (PC_REGNUM)),
-                  (long) read_register (SR_REGNUM),
-                  (long) read_register (PR_REGNUM),
-                  (long) read_register (MACH_REGNUM),
-                  (long) read_register (MACL_REGNUM));
+  printf_filtered
+    ("      PC %s       SR %08lx       PR %08lx     MACH %08lx\n",
+     phex (get_frame_register_unsigned (frame,
+                                       gdbarch_pc_regnum
+                                         (get_frame_arch (frame))), 4),
+     (long) get_frame_register_unsigned (frame, SR_REGNUM),
+     (long) get_frame_register_unsigned (frame, PR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACH_REGNUM));
 
-  printf_filtered ("GBR=%08lx VBR=%08lx",
-                  (long) read_register (GBR_REGNUM),
-                  (long) read_register (VBR_REGNUM));
-  printf_filtered (" SSR=%08lx SPC=%08lx",
-                  (long) read_register (SSR_REGNUM),
-                  (long) read_register (SPC_REGNUM));
+  printf_filtered
+    ("     GBR %08lx      VBR %08lx                       MACL %08lx\n",
+     (long) get_frame_register_unsigned (frame, GBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, VBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACL_REGNUM));
+  printf_filtered
+    ("     SSR %08lx      SPC %08lx\n",
+     (long) get_frame_register_unsigned (frame, SSR_REGNUM),
+     (long) get_frame_register_unsigned (frame, SPC_REGNUM));
 
   printf_filtered
-    ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-     (long) read_register (0), (long) read_register (1),
-     (long) read_register (2), (long) read_register (3),
-     (long) read_register (4), (long) read_register (5),
-     (long) read_register (6), (long) read_register (7));
-  printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-                  (long) read_register (8), (long) read_register (9),
-                  (long) read_register (10), (long) read_register (11),
-                  (long) read_register (12), (long) read_register (13),
-                  (long) read_register (14), (long) read_register (15));
+    ("R0-R7    %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 0),
+     (long) get_frame_register_unsigned (frame, 1),
+     (long) get_frame_register_unsigned (frame, 2),
+     (long) get_frame_register_unsigned (frame, 3),
+     (long) get_frame_register_unsigned (frame, 4),
+     (long) get_frame_register_unsigned (frame, 5),
+     (long) get_frame_register_unsigned (frame, 6),
+     (long) get_frame_register_unsigned (frame, 7));
+  printf_filtered
+    ("R8-R15   %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 8),
+     (long) get_frame_register_unsigned (frame, 9),
+     (long) get_frame_register_unsigned (frame, 10),
+     (long) get_frame_register_unsigned (frame, 11),
+     (long) get_frame_register_unsigned (frame, 12),
+     (long) get_frame_register_unsigned (frame, 13),
+     (long) get_frame_register_unsigned (frame, 14),
+     (long) get_frame_register_unsigned (frame, 15));
 }
 
+static void
+sh2e_show_regs (struct frame_info *frame)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  printf_filtered
+    ("      PC %s       SR %08lx       PR %08lx     MACH %08lx\n",
+     phex (get_frame_register_unsigned (frame,
+                                       gdbarch_pc_regnum (gdbarch)), 4),
+     (long) get_frame_register_unsigned (frame, SR_REGNUM),
+     (long) get_frame_register_unsigned (frame, PR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACH_REGNUM));
+
+  printf_filtered
+    ("     GBR %08lx      VBR %08lx                       MACL %08lx\n",
+     (long) get_frame_register_unsigned (frame, GBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, VBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACL_REGNUM));
+  printf_filtered
+    ("     SSR %08lx      SPC %08lx     FPUL %08lx    FPSCR %08lx\n",
+     (long) get_frame_register_unsigned (frame, SSR_REGNUM),
+     (long) get_frame_register_unsigned (frame, SPC_REGNUM),
+     (long) get_frame_register_unsigned (frame, FPUL_REGNUM),
+     (long) get_frame_register_unsigned (frame, FPSCR_REGNUM));
+
+  printf_filtered
+    ("R0-R7    %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 0),
+     (long) get_frame_register_unsigned (frame, 1),
+     (long) get_frame_register_unsigned (frame, 2),
+     (long) get_frame_register_unsigned (frame, 3),
+     (long) get_frame_register_unsigned (frame, 4),
+     (long) get_frame_register_unsigned (frame, 5),
+     (long) get_frame_register_unsigned (frame, 6),
+     (long) get_frame_register_unsigned (frame, 7));
+  printf_filtered
+    ("R8-R15   %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 8),
+     (long) get_frame_register_unsigned (frame, 9),
+     (long) get_frame_register_unsigned (frame, 10),
+     (long) get_frame_register_unsigned (frame, 11),
+     (long) get_frame_register_unsigned (frame, 12),
+     (long) get_frame_register_unsigned (frame, 13),
+     (long) get_frame_register_unsigned (frame, 14),
+     (long) get_frame_register_unsigned (frame, 15));
+
+  printf_filtered
+    ("FP0-FP7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 0),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 1),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 2),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 3),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 4),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 5),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 6),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 7));
+  printf_filtered
+    ("FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 8),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 9),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 10),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 11),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 12),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 13),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 14),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 15));
+}
 
 static void
-sh2e_show_regs (void)
-{
-  printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
-                  paddr (read_register (PC_REGNUM)),
-                  (long) read_register (SR_REGNUM),
-                  (long) read_register (PR_REGNUM),
-                  (long) read_register (MACH_REGNUM),
-                  (long) read_register (MACL_REGNUM));
-
-  printf_filtered ("GBR=%08lx VBR=%08lx",
-                  (long) read_register (GBR_REGNUM),
-                  (long) read_register (VBR_REGNUM));
-  printf_filtered (" FPUL=%08lx FPSCR=%08lx",
-                  (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), (long) read_register (1),
-     (long) read_register (2), (long) read_register (3),
-     (long) read_register (4), (long) read_register (5),
-     (long) read_register (6), (long) read_register (7));
-  printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-                  (long) read_register (8), (long) read_register (9),
-                  (long) read_register (10), (long) read_register (11),
-                  (long) read_register (12), (long) read_register (13),
-                  (long) read_register (14), (long) read_register (15));
-
-  printf_filtered (("FP0-FP7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 0), (long) read_register (FP0_REGNUM + 1), (long) read_register (FP0_REGNUM + 2), (long) read_register (FP0_REGNUM + 3), (long) read_register (FP0_REGNUM + 4), (long) read_register (FP0_REGNUM + 5), (long) read_register (FP0_REGNUM + 6), (long) read_register (FP0_REGNUM + 7));
-  printf_filtered (("FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 8), (long) read_register (FP0_REGNUM + 9), (long) read_register (FP0_REGNUM + 10), (long) read_register (FP0_REGNUM + 11), (long) read_register (FP0_REGNUM + 12), (long) read_register (FP0_REGNUM + 13), (long) read_register (FP0_REGNUM + 14), (long) read_register (FP0_REGNUM + 15));
+sh2a_show_regs (struct frame_info *frame)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  int pr = get_frame_register_unsigned (frame, FPSCR_REGNUM) & 0x80000;
+
+  printf_filtered
+    ("      PC %s       SR %08lx       PR %08lx     MACH %08lx\n",
+     phex (get_frame_register_unsigned (frame,
+                                       gdbarch_pc_regnum (gdbarch)), 4),
+     (long) get_frame_register_unsigned (frame, SR_REGNUM),
+     (long) get_frame_register_unsigned (frame, PR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACH_REGNUM));
+
+  printf_filtered
+    ("     GBR %08lx      VBR %08lx      TBR %08lx     MACL %08lx\n",
+     (long) get_frame_register_unsigned (frame, GBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, VBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, TBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACL_REGNUM));
+  printf_filtered
+    ("     SSR %08lx      SPC %08lx     FPUL %08lx    FPSCR %08lx\n",
+     (long) get_frame_register_unsigned (frame, SSR_REGNUM),
+     (long) get_frame_register_unsigned (frame, SPC_REGNUM),
+     (long) get_frame_register_unsigned (frame, FPUL_REGNUM),
+     (long) get_frame_register_unsigned (frame, FPSCR_REGNUM));
+
+  printf_filtered
+    ("R0-R7    %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 0),
+     (long) get_frame_register_unsigned (frame, 1),
+     (long) get_frame_register_unsigned (frame, 2),
+     (long) get_frame_register_unsigned (frame, 3),
+     (long) get_frame_register_unsigned (frame, 4),
+     (long) get_frame_register_unsigned (frame, 5),
+     (long) get_frame_register_unsigned (frame, 6),
+     (long) get_frame_register_unsigned (frame, 7));
+  printf_filtered
+    ("R8-R15   %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 8),
+     (long) get_frame_register_unsigned (frame, 9),
+     (long) get_frame_register_unsigned (frame, 10),
+     (long) get_frame_register_unsigned (frame, 11),
+     (long) get_frame_register_unsigned (frame, 12),
+     (long) get_frame_register_unsigned (frame, 13),
+     (long) get_frame_register_unsigned (frame, 14),
+     (long) get_frame_register_unsigned (frame, 15));
+
+  printf_filtered
+    (pr ? "DR0-DR6  %08lx%08lx  %08lx%08lx  %08lx%08lx  %08lx%08lx\n"
+       : "FP0-FP7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 0),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 1),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 2),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 3),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 4),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 5),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 6),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 7));
+  printf_filtered
+    (pr ? "DR8-DR14 %08lx%08lx  %08lx%08lx  %08lx%08lx  %08lx%08lx\n"
+       : "FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 8),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 9),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 10),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 11),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 12),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 13),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 14),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 15));
+  printf_filtered
+    ("BANK=%-3d\n", (int) get_frame_register_unsigned (frame, BANK_REGNUM));
+  printf_filtered
+    ("R0b-R7b  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 0),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 1),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 2),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 3),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 4),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 5),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 6),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 7));
+  printf_filtered
+    ("R8b-R14b %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 8),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 9),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 10),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 11),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 12),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 13),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 14));
+  printf_filtered
+    ("MACHb=%08lx IVNb=%08lx PRb=%08lx GBRb=%08lx MACLb=%08lx\n",
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 15),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 16),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 17),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 18),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 19));
 }
 
 static void
-sh3e_show_regs (void)
-{
-  printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
-                  paddr (read_register (PC_REGNUM)),
-                  (long) read_register (SR_REGNUM),
-                  (long) read_register (PR_REGNUM),
-                  (long) read_register (MACH_REGNUM),
-                  (long) read_register (MACL_REGNUM));
-
-  printf_filtered ("GBR=%08lx VBR=%08lx",
-                  (long) read_register (GBR_REGNUM),
-                  (long) read_register (VBR_REGNUM));
-  printf_filtered (" SSR=%08lx SPC=%08lx",
-                  (long) read_register (SSR_REGNUM),
-                  (long) read_register (SPC_REGNUM));
-  printf_filtered (" FPUL=%08lx FPSCR=%08lx",
-                  (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), (long) read_register (1),
-     (long) read_register (2), (long) read_register (3),
-     (long) read_register (4), (long) read_register (5),
-     (long) read_register (6), (long) read_register (7));
-  printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-                  (long) read_register (8), (long) read_register (9),
-                  (long) read_register (10), (long) read_register (11),
-                  (long) read_register (12), (long) read_register (13),
-                  (long) read_register (14), (long) read_register (15));
-
-  printf_filtered (("FP0-FP7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 0), (long) read_register (FP0_REGNUM + 1), (long) read_register (FP0_REGNUM + 2), (long) read_register (FP0_REGNUM + 3), (long) read_register (FP0_REGNUM + 4), (long) read_register (FP0_REGNUM + 5), (long) read_register (FP0_REGNUM + 6), (long) read_register (FP0_REGNUM + 7));
-  printf_filtered (("FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 8), (long) read_register (FP0_REGNUM + 9), (long) read_register (FP0_REGNUM + 10), (long) read_register (FP0_REGNUM + 11), (long) read_register (FP0_REGNUM + 12), (long) read_register (FP0_REGNUM + 13), (long) read_register (FP0_REGNUM + 14), (long) read_register (FP0_REGNUM + 15));
+sh2a_nofpu_show_regs (struct frame_info *frame)
+{
+  int pr = get_frame_register_unsigned (frame, FPSCR_REGNUM) & 0x80000;
+
+  printf_filtered
+    ("      PC %s       SR %08lx       PR %08lx     MACH %08lx\n",
+     phex (get_frame_register_unsigned (frame,
+                                       gdbarch_pc_regnum
+                                         (get_frame_arch (frame))), 4),
+     (long) get_frame_register_unsigned (frame, SR_REGNUM),
+     (long) get_frame_register_unsigned (frame, PR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACH_REGNUM));
+
+  printf_filtered
+    ("     GBR %08lx      VBR %08lx      TBR %08lx     MACL %08lx\n",
+     (long) get_frame_register_unsigned (frame, GBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, VBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, TBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACL_REGNUM));
+  printf_filtered
+    ("     SSR %08lx      SPC %08lx     FPUL %08lx    FPSCR %08lx\n",
+     (long) get_frame_register_unsigned (frame, SSR_REGNUM),
+     (long) get_frame_register_unsigned (frame, SPC_REGNUM),
+     (long) get_frame_register_unsigned (frame, FPUL_REGNUM),
+     (long) get_frame_register_unsigned (frame, FPSCR_REGNUM));
+
+  printf_filtered
+    ("R0-R7    %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 0),
+     (long) get_frame_register_unsigned (frame, 1),
+     (long) get_frame_register_unsigned (frame, 2),
+     (long) get_frame_register_unsigned (frame, 3),
+     (long) get_frame_register_unsigned (frame, 4),
+     (long) get_frame_register_unsigned (frame, 5),
+     (long) get_frame_register_unsigned (frame, 6),
+     (long) get_frame_register_unsigned (frame, 7));
+  printf_filtered
+    ("R8-R15   %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 8),
+     (long) get_frame_register_unsigned (frame, 9),
+     (long) get_frame_register_unsigned (frame, 10),
+     (long) get_frame_register_unsigned (frame, 11),
+     (long) get_frame_register_unsigned (frame, 12),
+     (long) get_frame_register_unsigned (frame, 13),
+     (long) get_frame_register_unsigned (frame, 14),
+     (long) get_frame_register_unsigned (frame, 15));
+
+  printf_filtered
+    ("BANK=%-3d\n", (int) get_frame_register_unsigned (frame, BANK_REGNUM));
+  printf_filtered
+    ("R0b-R7b  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 0),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 1),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 2),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 3),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 4),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 5),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 6),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 7));
+  printf_filtered
+    ("R8b-R14b %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 8),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 9),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 10),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 11),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 12),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 13),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 14));
+  printf_filtered
+    ("MACHb=%08lx IVNb=%08lx PRb=%08lx GBRb=%08lx MACLb=%08lx\n",
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 15),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 16),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 17),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 18),
+     (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 19));
 }
 
 static void
-sh3_dsp_show_regs (void)
+sh3e_show_regs (struct frame_info *frame)
 {
-  printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
-                  paddr (read_register (PC_REGNUM)),
-                  (long) read_register (SR_REGNUM),
-                  (long) read_register (PR_REGNUM),
-                  (long) read_register (MACH_REGNUM),
-                  (long) read_register (MACL_REGNUM));
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  printf_filtered
+    ("      PC %s       SR %08lx       PR %08lx     MACH %08lx\n",
+     phex (get_frame_register_unsigned (frame,
+                                       gdbarch_pc_regnum (gdbarch)), 4),
+     (long) get_frame_register_unsigned (frame, SR_REGNUM),
+     (long) get_frame_register_unsigned (frame, PR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACH_REGNUM));
 
-  printf_filtered ("GBR=%08lx VBR=%08lx",
-                  (long) read_register (GBR_REGNUM),
-                  (long) read_register (VBR_REGNUM));
+  printf_filtered
+    ("     GBR %08lx      VBR %08lx                       MACL %08lx\n",
+     (long) get_frame_register_unsigned (frame, GBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, VBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACL_REGNUM));
+  printf_filtered
+    ("     SSR %08lx      SPC %08lx     FPUL %08lx    FPSCR %08lx\n",
+     (long) get_frame_register_unsigned (frame, SSR_REGNUM),
+     (long) get_frame_register_unsigned (frame, SPC_REGNUM),
+     (long) get_frame_register_unsigned (frame, FPUL_REGNUM),
+     (long) get_frame_register_unsigned (frame, FPSCR_REGNUM));
 
-  printf_filtered (" SSR=%08lx SPC=%08lx",
-                  (long) read_register (SSR_REGNUM),
-                  (long) read_register (SPC_REGNUM));
+  printf_filtered
+    ("R0-R7    %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 0),
+     (long) get_frame_register_unsigned (frame, 1),
+     (long) get_frame_register_unsigned (frame, 2),
+     (long) get_frame_register_unsigned (frame, 3),
+     (long) get_frame_register_unsigned (frame, 4),
+     (long) get_frame_register_unsigned (frame, 5),
+     (long) get_frame_register_unsigned (frame, 6),
+     (long) get_frame_register_unsigned (frame, 7));
+  printf_filtered
+    ("R8-R15   %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 8),
+     (long) get_frame_register_unsigned (frame, 9),
+     (long) get_frame_register_unsigned (frame, 10),
+     (long) get_frame_register_unsigned (frame, 11),
+     (long) get_frame_register_unsigned (frame, 12),
+     (long) get_frame_register_unsigned (frame, 13),
+     (long) get_frame_register_unsigned (frame, 14),
+     (long) get_frame_register_unsigned (frame, 15));
 
-  printf_filtered (" DSR=%08lx", (long) read_register (DSR_REGNUM));
+  printf_filtered
+    ("FP0-FP7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 0),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 1),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 2),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 3),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 4),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 5),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 6),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 7));
+  printf_filtered
+    ("FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 8),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 9),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 10),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 11),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 12),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 13),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 14),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 15));
+}
+
+static void
+sh3_dsp_show_regs (struct frame_info *frame)
+{
+  printf_filtered
+    ("      PC %s       SR %08lx       PR %08lx     MACH %08lx\n",
+     phex (get_frame_register_unsigned (frame,
+                                       gdbarch_pc_regnum
+                                         (get_frame_arch (frame))), 4),
+     (long) get_frame_register_unsigned (frame, SR_REGNUM),
+     (long) get_frame_register_unsigned (frame, PR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACH_REGNUM));
+
+  printf_filtered
+    ("     GBR %08lx      VBR %08lx                       MACL %08lx\n",
+     (long) get_frame_register_unsigned (frame, GBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, VBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACL_REGNUM));
 
   printf_filtered
-    ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-     (long) read_register (0), (long) read_register (1),
-     (long) read_register (2), (long) read_register (3),
-     (long) read_register (4), (long) read_register (5),
-     (long) read_register (6), (long) read_register (7));
-  printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-                  (long) read_register (8), (long) read_register (9),
-                  (long) read_register (10), (long) read_register (11),
-                  (long) read_register (12), (long) read_register (13),
-                  (long) read_register (14), (long) read_register (15));
+    ("     SSR %08lx      SPC %08lx      DSR %08lx\n",
+     (long) get_frame_register_unsigned (frame, SSR_REGNUM),
+     (long) get_frame_register_unsigned (frame, SPC_REGNUM),
+     (long) get_frame_register_unsigned (frame, DSR_REGNUM));
+
+  printf_filtered
+    ("R0-R7    %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 0),
+     (long) get_frame_register_unsigned (frame, 1),
+     (long) get_frame_register_unsigned (frame, 2),
+     (long) get_frame_register_unsigned (frame, 3),
+     (long) get_frame_register_unsigned (frame, 4),
+     (long) get_frame_register_unsigned (frame, 5),
+     (long) get_frame_register_unsigned (frame, 6),
+     (long) get_frame_register_unsigned (frame, 7));
+  printf_filtered
+    ("R8-R15   %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 8),
+     (long) get_frame_register_unsigned (frame, 9),
+     (long) get_frame_register_unsigned (frame, 10),
+     (long) get_frame_register_unsigned (frame, 11),
+     (long) get_frame_register_unsigned (frame, 12),
+     (long) get_frame_register_unsigned (frame, 13),
+     (long) get_frame_register_unsigned (frame, 14),
+     (long) get_frame_register_unsigned (frame, 15));
 
   printf_filtered
     ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n",
-     (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 (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));
+     (long) get_frame_register_unsigned (frame, A0G_REGNUM) & 0xff,
+     (long) get_frame_register_unsigned (frame, A0_REGNUM),
+     (long) get_frame_register_unsigned (frame, M0_REGNUM),
+     (long) get_frame_register_unsigned (frame, X0_REGNUM),
+     (long) get_frame_register_unsigned (frame, Y0_REGNUM),
+     (long) get_frame_register_unsigned (frame, RS_REGNUM),
+     (long) get_frame_register_unsigned (frame, MOD_REGNUM));
+  printf_filtered
+    ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n",
+     (long) get_frame_register_unsigned (frame, A1G_REGNUM) & 0xff,
+     (long) get_frame_register_unsigned (frame, A1_REGNUM),
+     (long) get_frame_register_unsigned (frame, M1_REGNUM),
+     (long) get_frame_register_unsigned (frame, X1_REGNUM),
+     (long) get_frame_register_unsigned (frame, Y1_REGNUM),
+     (long) get_frame_register_unsigned (frame, RE_REGNUM));
 }
 
 static void
-sh4_show_regs (void)
-{
-  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),
-                  (long) read_register (PR_REGNUM),
-                  (long) read_register (MACH_REGNUM),
-                  (long) read_register (MACL_REGNUM));
-
-  printf_filtered ("GBR=%08lx VBR=%08lx",
-                  (long) read_register (GBR_REGNUM),
-                  (long) read_register (VBR_REGNUM));
-  printf_filtered (" SSR=%08lx SPC=%08lx",
-                  (long) read_register (SSR_REGNUM),
-                  (long) read_register (SPC_REGNUM));
-  printf_filtered (" FPUL=%08lx FPSCR=%08lx",
-                  (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), (long) read_register (1),
-     (long) read_register (2), (long) read_register (3),
-     (long) read_register (4), (long) read_register (5),
-     (long) read_register (6), (long) read_register (7));
-  printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-                  (long) read_register (8), (long) read_register (9),
-                  (long) read_register (10), (long) read_register (11),
-                  (long) read_register (12), (long) read_register (13),
-                  (long) read_register (14), (long) read_register (15));
-
-  printf_filtered ((pr
-                   ? "DR0-DR6  %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n"
-                   :
-                   "FP0-FP7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"),
-                  (long) read_register (FP0_REGNUM + 0),
-                  (long) read_register (FP0_REGNUM + 1),
-                  (long) read_register (FP0_REGNUM + 2),
-                  (long) read_register (FP0_REGNUM + 3),
-                  (long) read_register (FP0_REGNUM + 4),
-                  (long) read_register (FP0_REGNUM + 5),
-                  (long) read_register (FP0_REGNUM + 6),
-                  (long) read_register (FP0_REGNUM + 7));
-  printf_filtered ((pr ?
-                   "DR8-DR14 %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n" :
-                   "FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"),
-                  (long) read_register (FP0_REGNUM + 8),
-                  (long) read_register (FP0_REGNUM + 9),
-                  (long) read_register (FP0_REGNUM + 10),
-                  (long) read_register (FP0_REGNUM + 11),
-                  (long) read_register (FP0_REGNUM + 12),
-                  (long) read_register (FP0_REGNUM + 13),
-                  (long) read_register (FP0_REGNUM + 14),
-                  (long) read_register (FP0_REGNUM + 15));
+sh4_show_regs (struct frame_info *frame)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  int pr = get_frame_register_unsigned (frame, FPSCR_REGNUM) & 0x80000;
+
+  printf_filtered
+    ("      PC %s       SR %08lx       PR %08lx     MACH %08lx\n",
+     phex (get_frame_register_unsigned (frame,
+                                       gdbarch_pc_regnum (gdbarch)), 4),
+     (long) get_frame_register_unsigned (frame, SR_REGNUM),
+     (long) get_frame_register_unsigned (frame, PR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACH_REGNUM));
+
+  printf_filtered
+    ("     GBR %08lx      VBR %08lx                       MACL %08lx\n",
+     (long) get_frame_register_unsigned (frame, GBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, VBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACL_REGNUM));
+  printf_filtered
+    ("     SSR %08lx      SPC %08lx     FPUL %08lx    FPSCR %08lx\n",
+     (long) get_frame_register_unsigned (frame, SSR_REGNUM),
+     (long) get_frame_register_unsigned (frame, SPC_REGNUM),
+     (long) get_frame_register_unsigned (frame, FPUL_REGNUM),
+     (long) get_frame_register_unsigned (frame, FPSCR_REGNUM));
+
+  printf_filtered
+    ("R0-R7    %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 0),
+     (long) get_frame_register_unsigned (frame, 1),
+     (long) get_frame_register_unsigned (frame, 2),
+     (long) get_frame_register_unsigned (frame, 3),
+     (long) get_frame_register_unsigned (frame, 4),
+     (long) get_frame_register_unsigned (frame, 5),
+     (long) get_frame_register_unsigned (frame, 6),
+     (long) get_frame_register_unsigned (frame, 7));
+  printf_filtered
+    ("R8-R15   %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 8),
+     (long) get_frame_register_unsigned (frame, 9),
+     (long) get_frame_register_unsigned (frame, 10),
+     (long) get_frame_register_unsigned (frame, 11),
+     (long) get_frame_register_unsigned (frame, 12),
+     (long) get_frame_register_unsigned (frame, 13),
+     (long) get_frame_register_unsigned (frame, 14),
+     (long) get_frame_register_unsigned (frame, 15));
+
+  printf_filtered
+    (pr ? "DR0-DR6  %08lx%08lx  %08lx%08lx  %08lx%08lx  %08lx%08lx\n"
+       : "FP0-FP7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 0),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 1),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 2),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 3),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 4),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 5),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 6),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 7));
+  printf_filtered
+    (pr ? "DR8-DR14 %08lx%08lx  %08lx%08lx  %08lx%08lx  %08lx%08lx\n"
+       : "FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 8),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 9),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 10),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 11),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 12),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 13),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 14),
+     (long) get_frame_register_unsigned
+             (frame, gdbarch_fp0_regnum (gdbarch) + 15));
 }
 
 static void
-sh4_nofpu_show_regs (void)
-{
-  printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
-                  paddr (read_register (PC_REGNUM)),
-                  (long) read_register (SR_REGNUM),
-                  (long) read_register (PR_REGNUM),
-                  (long) read_register (MACH_REGNUM),
-                  (long) read_register (MACL_REGNUM));
-
-  printf_filtered ("GBR=%08lx VBR=%08lx",
-                  (long) read_register (GBR_REGNUM),
-                  (long) read_register (VBR_REGNUM));
-  printf_filtered (" SSR=%08lx SPC=%08lx",
-                  (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), (long) read_register (1),
-     (long) read_register (2), (long) read_register (3),
-     (long) read_register (4), (long) read_register (5),
-     (long) read_register (6), (long) read_register (7));
-  printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-                  (long) read_register (8), (long) read_register (9),
-                  (long) read_register (10), (long) read_register (11),
-                  (long) read_register (12), (long) read_register (13),
-                  (long) read_register (14), (long) read_register (15));
+sh4_nofpu_show_regs (struct frame_info *frame)
+{
+  printf_filtered
+    ("      PC %s       SR %08lx       PR %08lx     MACH %08lx\n",
+     phex (get_frame_register_unsigned (frame,
+                                       gdbarch_pc_regnum
+                                         (get_frame_arch (frame))), 4),
+     (long) get_frame_register_unsigned (frame, SR_REGNUM),
+     (long) get_frame_register_unsigned (frame, PR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACH_REGNUM));
+
+  printf_filtered
+    ("     GBR %08lx      VBR %08lx                       MACL %08lx\n",
+     (long) get_frame_register_unsigned (frame, GBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, VBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACL_REGNUM));
+  printf_filtered
+    ("     SSR %08lx      SPC %08lx     FPUL %08lx    FPSCR %08lx\n",
+     (long) get_frame_register_unsigned (frame, SSR_REGNUM),
+     (long) get_frame_register_unsigned (frame, SPC_REGNUM),
+     (long) get_frame_register_unsigned (frame, FPUL_REGNUM),
+     (long) get_frame_register_unsigned (frame, FPSCR_REGNUM));
+
+  printf_filtered
+    ("R0-R7    %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 0),
+     (long) get_frame_register_unsigned (frame, 1),
+     (long) get_frame_register_unsigned (frame, 2),
+     (long) get_frame_register_unsigned (frame, 3),
+     (long) get_frame_register_unsigned (frame, 4),
+     (long) get_frame_register_unsigned (frame, 5),
+     (long) get_frame_register_unsigned (frame, 6),
+     (long) get_frame_register_unsigned (frame, 7));
+  printf_filtered
+    ("R8-R15   %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 8),
+     (long) get_frame_register_unsigned (frame, 9),
+     (long) get_frame_register_unsigned (frame, 10),
+     (long) get_frame_register_unsigned (frame, 11),
+     (long) get_frame_register_unsigned (frame, 12),
+     (long) get_frame_register_unsigned (frame, 13),
+     (long) get_frame_register_unsigned (frame, 14),
+     (long) get_frame_register_unsigned (frame, 15));
 }
 
 static void
-sh_dsp_show_regs (void)
+sh_dsp_show_regs (struct frame_info *frame)
 {
-  printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
-                  paddr (read_register (PC_REGNUM)),
-                  (long) read_register (SR_REGNUM),
-                  (long) read_register (PR_REGNUM),
-                  (long) read_register (MACH_REGNUM),
-                  (long) read_register (MACL_REGNUM));
-
-  printf_filtered ("GBR=%08lx VBR=%08lx",
-                  (long) read_register (GBR_REGNUM),
-                  (long) read_register (VBR_REGNUM));
+  printf_filtered
+    ("      PC %s       SR %08lx       PR %08lx     MACH %08lx\n",
+     phex (get_frame_register_unsigned (frame,
+                                       gdbarch_pc_regnum
+                                         (get_frame_arch (frame))), 4),
+     (long) get_frame_register_unsigned (frame, SR_REGNUM),
+     (long) get_frame_register_unsigned (frame, PR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACH_REGNUM));
 
-  printf_filtered (" DSR=%08lx", (long) read_register (DSR_REGNUM));
+  printf_filtered
+    ("     GBR %08lx      VBR %08lx      DSR %08lx     MACL %08lx\n",
+     (long) get_frame_register_unsigned (frame, GBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, VBR_REGNUM),
+     (long) get_frame_register_unsigned (frame, DSR_REGNUM),
+     (long) get_frame_register_unsigned (frame, MACL_REGNUM));
 
   printf_filtered
-    ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-     (long) read_register (0), (long) read_register (1),
-     (long) read_register (2), (long) read_register (3),
-     (long) read_register (4), (long) read_register (5),
-     (long) read_register (6), (long) read_register (7));
-  printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-                  (long) read_register (8), (long) read_register (9),
-                  (long) read_register (10), (long) read_register (11),
-                  (long) read_register (12), (long) read_register (13),
-                  (long) read_register (14), (long) read_register (15));
+    ("R0-R7    %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 0),
+     (long) get_frame_register_unsigned (frame, 1),
+     (long) get_frame_register_unsigned (frame, 2),
+     (long) get_frame_register_unsigned (frame, 3),
+     (long) get_frame_register_unsigned (frame, 4),
+     (long) get_frame_register_unsigned (frame, 5),
+     (long) get_frame_register_unsigned (frame, 6),
+     (long) get_frame_register_unsigned (frame, 7));
+  printf_filtered
+    ("R8-R15   %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+     (long) get_frame_register_unsigned (frame, 8),
+     (long) get_frame_register_unsigned (frame, 9),
+     (long) get_frame_register_unsigned (frame, 10),
+     (long) get_frame_register_unsigned (frame, 11),
+     (long) get_frame_register_unsigned (frame, 12),
+     (long) get_frame_register_unsigned (frame, 13),
+     (long) get_frame_register_unsigned (frame, 14),
+     (long) get_frame_register_unsigned (frame, 15));
 
   printf_filtered
     ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n",
-     (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));
+     (long) get_frame_register_unsigned (frame, A0G_REGNUM) & 0xff,
+     (long) get_frame_register_unsigned (frame, A0_REGNUM),
+     (long) get_frame_register_unsigned (frame, M0_REGNUM),
+     (long) get_frame_register_unsigned (frame, X0_REGNUM),
+     (long) get_frame_register_unsigned (frame, Y0_REGNUM),
+     (long) get_frame_register_unsigned (frame, RS_REGNUM),
+     (long) get_frame_register_unsigned (frame, MOD_REGNUM));
   printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n",
-                  (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));
+     (long) get_frame_register_unsigned (frame, A1G_REGNUM) & 0xff,
+     (long) get_frame_register_unsigned (frame, A1_REGNUM),
+     (long) get_frame_register_unsigned (frame, M1_REGNUM),
+     (long) get_frame_register_unsigned (frame, X1_REGNUM),
+     (long) get_frame_register_unsigned (frame, Y1_REGNUM),
+     (long) get_frame_register_unsigned (frame, RE_REGNUM));
 }
 
 static void
 sh_show_regs_command (char *args, int from_tty)
 {
   if (sh_show_regs)
-    (*sh_show_regs) ();
+    (*sh_show_regs) (get_current_frame ());
+}
+
+static struct type *
+sh_sh2a_register_type (struct gdbarch *gdbarch, int reg_nr)
+{
+  if ((reg_nr >= gdbarch_fp0_regnum (gdbarch)
+       && (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM))
+    return builtin_type (gdbarch)->builtin_float;
+  else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
+    return builtin_type (gdbarch)->builtin_double;
+  else
+    return builtin_type (gdbarch)->builtin_int;
 }
 
 /* Return the GDB type object for the "standard" data type
@@ -1478,40 +2148,79 @@ sh_show_regs_command (char *args, int from_tty)
 static struct type *
 sh_sh3e_register_type (struct gdbarch *gdbarch, int reg_nr)
 {
-  if ((reg_nr >= FP0_REGNUM
+  if ((reg_nr >= gdbarch_fp0_regnum (gdbarch)
        && (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM))
-    return builtin_type_float;
+    return builtin_type (gdbarch)->builtin_float;
   else
-    return builtin_type_int;
+    return builtin_type (gdbarch)->builtin_int;
 }
 
 static struct type *
-sh_sh4_build_float_register_type (int high)
+sh_sh4_build_float_register_type (struct gdbarch *gdbarch, int high)
 {
-  struct type *temp;
-
-  temp = create_range_type (NULL, builtin_type_int, 0, high);
-  return create_array_type (NULL, builtin_type_float, temp);
+  return lookup_array_range_type (builtin_type (gdbarch)->builtin_float,
+                                 0, high);
 }
 
 static struct type *
 sh_sh4_register_type (struct gdbarch *gdbarch, int reg_nr)
 {
-  if ((reg_nr >= FP0_REGNUM
+  if ((reg_nr >= gdbarch_fp0_regnum (gdbarch)
        && (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM))
-    return builtin_type_float;
+    return builtin_type (gdbarch)->builtin_float;
   else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
-    return builtin_type_double;
+    return builtin_type (gdbarch)->builtin_double;
   else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM)
-    return sh_sh4_build_float_register_type (3);
+    return sh_sh4_build_float_register_type (gdbarch, 3);
   else
-    return builtin_type_int;
+    return builtin_type (gdbarch)->builtin_int;
 }
 
 static struct type *
 sh_default_register_type (struct gdbarch *gdbarch, int reg_nr)
 {
-  return builtin_type_int;
+  return builtin_type (gdbarch)->builtin_int;
+}
+
+/* Is a register in a reggroup?
+   The default code in reggroup.c doesn't identify system registers, some
+   float registers or any of the vector registers.
+   TODO: sh2a and dsp registers.  */
+static int
+sh_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+                       struct reggroup *reggroup)
+{
+  if (gdbarch_register_name (gdbarch, regnum) == NULL
+      || *gdbarch_register_name (gdbarch, regnum) == '\0')
+    return 0;
+
+  if (reggroup == float_reggroup
+      && (regnum == FPUL_REGNUM
+         || regnum == FPSCR_REGNUM))
+    return 1;
+
+  if (regnum >= FV0_REGNUM && regnum <= FV_LAST_REGNUM)
+    {
+      if (reggroup == vector_reggroup || reggroup == float_reggroup)
+       return 1;
+      if (reggroup == general_reggroup)
+       return 0;
+    }
+
+  if (regnum == VBR_REGNUM
+      || regnum == SR_REGNUM
+      || regnum == FPSCR_REGNUM
+      || regnum == SSR_REGNUM
+      || regnum == SPC_REGNUM)
+    {
+      if (reggroup == system_reggroup)
+       return 1;
+      if (reggroup == general_reggroup)
+       return 0;
+    }
+
+  /* The default code can cope with any other registers.  */
+  return default_register_reggroup_p (gdbarch, regnum, reggroup);
 }
 
 /* On the sh4, the DRi pseudo registers are problematic if the target
@@ -1541,8 +2250,8 @@ sh_default_register_type (struct gdbarch *gdbarch, int reg_nr)
    because they are stored as 4 individual FP elements. */
 
 static void
-sh_sh4_register_convert_to_virtual (int regnum, struct type *type,
-                                   char *from, char *to)
+sh_register_convert_to_virtual (int regnum, struct type *type,
+                               char *from, char *to)
 {
   if (regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM)
     {
@@ -1557,8 +2266,8 @@ sh_sh4_register_convert_to_virtual (int regnum, struct type *type,
 }
 
 static void
-sh_sh4_register_convert_to_raw (struct type *type, int regnum,
-                               const void *from, void *to)
+sh_register_convert_to_raw (struct type *type, int regnum,
+                           const void *from, void *to)
 {
   if (regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM)
     {
@@ -1567,39 +2276,44 @@ sh_sh4_register_convert_to_raw (struct type *type, int regnum,
                                 &val, to);
     }
   else
-    error ("sh_register_convert_to_raw called with non DR register number");
+    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)
+fv_reg_base_num (struct gdbarch *gdbarch, int fv_regnum)
 {
   int fp_regnum;
 
-  fp_regnum = FP0_REGNUM + (fv_regnum - FV0_REGNUM) * 4;
+  fp_regnum = gdbarch_fp0_regnum (gdbarch)
+             + (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)
+dr_reg_base_num (struct gdbarch *gdbarch, int dr_regnum)
 {
   int fp_regnum;
 
-  fp_regnum = FP0_REGNUM + (dr_regnum - DR0_REGNUM) * 2;
+  fp_regnum = gdbarch_fp0_regnum (gdbarch)
+             + (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 reg_nr, gdb_byte *buffer)
 {
   int base_regnum, portion;
   char temp_buffer[MAX_REGISTER_SIZE];
 
+  if (reg_nr == PSEUDO_BANK_REGNUM)
+    regcache_raw_read (regcache, BANK_REGNUM, buffer);
+  else
   if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
     {
-      base_regnum = dr_reg_base_num (reg_nr);
+      base_regnum = dr_reg_base_num (gdbarch, reg_nr);
 
       /* Build the value in the provided buffer. */
       /* Read the real regs for which this one is an alias.  */
@@ -1609,14 +2323,13 @@ sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
                            + register_size (gdbarch,
                                             base_regnum) * portion));
       /* We must pay attention to the endiannes. */
-      sh_sh4_register_convert_to_virtual (reg_nr,
-                                         gdbarch_register_type (gdbarch,
-                                                                reg_nr),
-                                         temp_buffer, buffer);
+      sh_register_convert_to_virtual (reg_nr,
+                                     register_type (gdbarch, reg_nr),
+                                     temp_buffer, buffer);
     }
   else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM)
     {
-      base_regnum = fv_reg_base_num (reg_nr);
+      base_regnum = fv_reg_base_num (gdbarch, reg_nr);
 
       /* Read the real regs for which this one is an alias.  */
       for (portion = 0; portion < 4; portion++)
@@ -1629,18 +2342,30 @@ sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 
 static void
 sh_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
-                         int reg_nr, const void *buffer)
+                         int reg_nr, const gdb_byte *buffer)
 {
   int base_regnum, portion;
   char temp_buffer[MAX_REGISTER_SIZE];
 
-  if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
+  if (reg_nr == PSEUDO_BANK_REGNUM)
+    {
+      /* When the bank register is written to, the whole register bank
+         is switched and all values in the bank registers must be read
+        from the target/sim again. We're just invalidating the regcache
+        so that a re-read happens next time it's necessary.  */
+      int bregnum;
+
+      regcache_raw_write (regcache, BANK_REGNUM, buffer);
+      for (bregnum = R0_BANK0_REGNUM; bregnum < MACLB_REGNUM; ++bregnum)
+        regcache_invalidate (regcache, bregnum);
+    }
+  else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
     {
-      base_regnum = dr_reg_base_num (reg_nr);
+      base_regnum = dr_reg_base_num (gdbarch, reg_nr);
 
       /* We must pay attention to the endiannes. */
-      sh_sh4_register_convert_to_raw (gdbarch_register_type (gdbarch, reg_nr),
-                                     reg_nr, buffer, temp_buffer);
+      sh_register_convert_to_raw (register_type (gdbarch, reg_nr),
+                                 reg_nr, buffer, temp_buffer);
 
       /* Write the real regs for which this one is an alias.  */
       for (portion = 0; portion < 2; portion++)
@@ -1651,7 +2376,7 @@ sh_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
     }
   else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM)
     {
-      base_regnum = fv_reg_base_num (reg_nr);
+      base_regnum = fv_reg_base_num (gdbarch, reg_nr);
 
       /* Write the real regs for which this one is an alias.  */
       for (portion = 0; portion < 4; portion++)
@@ -1662,232 +2387,11 @@ sh_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
     }
 }
 
-/* Floating point vector of 4 float registers. */
-static void
-do_fv_register_info (struct gdbarch *gdbarch, struct ui_file *file,
-                    int fv_regnum)
-{
-  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 - 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),
-                   (int) read_register (first_fp_reg_num + 3));
-}
-
-/* Double precision registers. */
-static void
-do_dr_register_info (struct gdbarch *gdbarch, struct ui_file *file,
-                    int dr_regnum)
-{
-  int first_fp_reg_num = dr_reg_base_num (dr_regnum);
-
-  fprintf_filtered (file, "dr%d\t0x%08x%08x\n",
-                   dr_regnum - DR0_REGNUM,
-                   (int) read_register (first_fp_reg_num),
-                   (int) read_register (first_fp_reg_num + 1));
-}
-
-static void
-sh_print_pseudo_register (struct gdbarch *gdbarch, struct ui_file *file,
-                         int regnum)
-{
-  if (regnum < NUM_REGS || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
-    internal_error (__FILE__, __LINE__,
-                   "Invalid pseudo register number %d\n", regnum);
-  else if (regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM)
-    do_dr_register_info (gdbarch, file, regnum);
-  else if (regnum >= FV0_REGNUM && regnum <= FV_LAST_REGNUM)
-    do_fv_register_info (gdbarch, file, regnum);
-}
-
-static void
-sh_do_fp_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum)
-{                              /* do values for FP (float) regs */
-  char *raw_buffer;
-  double flt;                  /* double extracted from raw hex data */
-  int inv;
-  int j;
-
-  /* Allocate space for the float. */
-  raw_buffer = (char *) alloca (register_size (gdbarch, FP0_REGNUM));
-
-  /* Get the data in raw format.  */
-  if (!frame_register_read (get_selected_frame (), regnum, raw_buffer))
-    error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
-
-  /* Get the register as a number */
-  flt = unpack_double (builtin_type_float, raw_buffer, &inv);
-
-  /* Print the name and some spaces. */
-  fputs_filtered (REGISTER_NAME (regnum), file);
-  print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
-
-  /* Print the value. */
-  if (inv)
-    fprintf_filtered (file, "<invalid float>");
-  else
-    fprintf_filtered (file, "%-10.9g", flt);
-
-  /* Print the fp register as hex. */
-  fprintf_filtered (file, "\t(raw 0x");
-  for (j = 0; j < register_size (gdbarch, regnum); j++)
-    {
-      int idx = (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
-                ? j
-                : register_size (gdbarch, regnum) - 1 - j);
-      fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[idx]);
-    }
-  fprintf_filtered (file, ")");
-  fprintf_filtered (file, "\n");
-}
-
-static void
-sh_do_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum)
-{
-  char raw_buffer[MAX_REGISTER_SIZE];
-
-  fputs_filtered (REGISTER_NAME (regnum), file);
-  print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
-
-  /* Get the data in raw format.  */
-  if (!frame_register_read (get_selected_frame (), regnum, raw_buffer))
-    fprintf_filtered (file, "*value not available*\n");
-
-  val_print (gdbarch_register_type (gdbarch, regnum), raw_buffer, 0, 0,
-            file, 'x', 1, 0, Val_pretty_default);
-  fprintf_filtered (file, "\t");
-  val_print (gdbarch_register_type (gdbarch, regnum), raw_buffer, 0, 0,
-            file, 0, 1, 0, Val_pretty_default);
-  fprintf_filtered (file, "\n");
-}
-
-static void
-sh_print_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum)
-{
-  if (regnum < 0 || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
-    internal_error (__FILE__, __LINE__,
-                   "Invalid register number %d\n", regnum);
-
-  else if (regnum >= 0 && regnum < NUM_REGS)
-    {
-      if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) ==
-         TYPE_CODE_FLT)
-       sh_do_fp_register (gdbarch, file, regnum);      /* FP regs */
-      else
-       sh_do_register (gdbarch, file, regnum); /* All other regs */
-    }
-
-  else if (regnum < NUM_REGS + NUM_PSEUDO_REGS)
-    {
-      sh_print_pseudo_register (gdbarch, file, regnum);
-    }
-}
-
-static void
-sh_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
-                        struct frame_info *frame, int regnum, int fpregs)
-{
-  if (regnum != -1)            /* do one specified register */
-    {
-      if (*(REGISTER_NAME (regnum)) == '\0')
-       error ("Not a valid register for the current processor type");
-
-      sh_print_register (gdbarch, file, regnum);
-    }
-  else
-    /* do all (or most) registers */
-    {
-      regnum = 0;
-      while (regnum < NUM_REGS)
-       {
-         /* If the register name is empty, it is undefined for this
-            processor, so don't display anything.  */
-         if (REGISTER_NAME (regnum) == NULL
-             || *(REGISTER_NAME (regnum)) == '\0')
-           {
-             regnum++;
-             continue;
-           }
-
-         if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) ==
-             TYPE_CODE_FLT)
-           {
-             if (fpregs)
-               {
-                 /* true for "INFO ALL-REGISTERS" command */
-                 sh_do_fp_register (gdbarch, file, regnum);    /* FP regs */
-                 regnum++;
-               }
-             else
-               regnum += (FP_LAST_REGNUM - FP0_REGNUM);        /* skip FP regs */
-           }
-         else
-           {
-             sh_do_register (gdbarch, file, regnum);   /* All other regs */
-             regnum++;
-           }
-       }
-
-      if (fpregs)
-       while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
-         {
-           sh_print_pseudo_register (gdbarch, file, regnum);
-           regnum++;
-         }
-    }
-}
-
-#ifdef SVR4_SHARED_LIBS
-
-/* Fetch (and possibly build) an appropriate link_map_offsets structure
-   for native i386 linux targets using the struct offsets defined in
-   link.h (but without actual reference to that file).
-
-   This makes it possible to access i386-linux shared libraries from
-   a gdb that was not built on an i386-linux host (for cross debugging).
-   */
-
-struct link_map_offsets *
-sh_linux_svr4_fetch_link_map_offsets (void)
-{
-  static struct link_map_offsets lmo;
-  static struct link_map_offsets *lmp = 0;
-
-  if (lmp == 0)
-    {
-      lmp = &lmo;
-
-      lmo.r_debug_size = 8;    /* 20 not actual size but all we need */
-
-      lmo.r_map_offset = 4;
-      lmo.r_map_size = 4;
-
-      lmo.link_map_size = 20;  /* 552 not actual size but all we need */
-
-      lmo.l_addr_offset = 0;
-      lmo.l_addr_size = 4;
-
-      lmo.l_name_offset = 4;
-      lmo.l_name_size = 4;
-
-      lmo.l_next_offset = 12;
-      lmo.l_next_size = 4;
-
-      lmo.l_prev_offset = 16;
-      lmo.l_prev_size = 4;
-    }
-
-  return lmp;
-}
-#endif /* SVR4_SHARED_LIBS */
-
 static int
-sh_dsp_register_sim_regno (int nr)
+sh_dsp_register_sim_regno (struct gdbarch *gdbarch, int nr)
 {
-  if (legacy_register_sim_regno (nr) < 0)
-    return legacy_register_sim_regno (nr);
+  if (legacy_register_sim_regno (gdbarch, nr) < 0)
+    return legacy_register_sim_regno (gdbarch, nr);
   if (nr >= DSR_REGNUM && nr <= Y1_REGNUM)
     return nr - DSR_REGNUM + SIM_SH_DSR_REGNUM;
   if (nr == MOD_REGNUM)
@@ -1896,11 +2400,92 @@ sh_dsp_register_sim_regno (int nr)
     return SIM_SH_RS_REGNUM;
   if (nr == RE_REGNUM)
     return SIM_SH_RE_REGNUM;
-  if (nr >= R0_BANK_REGNUM && nr <= R7_BANK_REGNUM)
-    return nr - R0_BANK_REGNUM + SIM_SH_R0_BANK_REGNUM;
+  if (nr >= DSP_R0_BANK_REGNUM && nr <= DSP_R7_BANK_REGNUM)
+    return nr - DSP_R0_BANK_REGNUM + SIM_SH_R0_BANK_REGNUM;
   return nr;
 }
 
+static int
+sh_sh2a_register_sim_regno (struct gdbarch *gdbarch, int nr)
+{
+  switch (nr)
+    {
+      case TBR_REGNUM:
+        return SIM_SH_TBR_REGNUM;
+      case IBNR_REGNUM:
+        return SIM_SH_IBNR_REGNUM;
+      case IBCR_REGNUM:
+        return SIM_SH_IBCR_REGNUM;
+      case BANK_REGNUM:
+        return SIM_SH_BANK_REGNUM;
+      case MACLB_REGNUM:
+        return SIM_SH_BANK_MACL_REGNUM;
+      case GBRB_REGNUM:
+        return SIM_SH_BANK_GBR_REGNUM;
+      case PRB_REGNUM:
+        return SIM_SH_BANK_PR_REGNUM;
+      case IVNB_REGNUM:
+        return SIM_SH_BANK_IVN_REGNUM;
+      case MACHB_REGNUM:
+        return SIM_SH_BANK_MACH_REGNUM;
+      default:
+        break;
+    }
+  return legacy_register_sim_regno (gdbarch, nr);
+}
+
+/* Set up the register unwinding such that call-clobbered registers are
+   not displayed in frames >0 because the true value is not certain.
+   The 'undefined' registers will show up as 'not available' unless the
+   CFI says otherwise.
+
+   This function is currently set up for SH4 and compatible only.  */
+
+static void
+sh_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
+                          struct dwarf2_frame_state_reg *reg,
+                         struct frame_info *this_frame)
+{
+  /* Mark the PC as the destination for the return address.  */
+  if (regnum == gdbarch_pc_regnum (gdbarch))
+    reg->how = DWARF2_FRAME_REG_RA;
+
+  /* Mark the stack pointer as the call frame address.  */
+  else if (regnum == gdbarch_sp_regnum (gdbarch))
+    reg->how = DWARF2_FRAME_REG_CFA;
+
+  /* The above was taken from the default init_reg in dwarf2-frame.c
+     while the below is SH specific.  */
+
+  /* Caller save registers.  */
+  else if ((regnum >= R0_REGNUM && regnum <= R0_REGNUM+7)
+          || (regnum >= FR0_REGNUM && regnum <= FR0_REGNUM+11)
+          || (regnum >= DR0_REGNUM && regnum <= DR0_REGNUM+5)
+          || (regnum >= FV0_REGNUM && regnum <= FV0_REGNUM+2)
+          || (regnum == MACH_REGNUM)
+          || (regnum == MACL_REGNUM)
+          || (regnum == FPUL_REGNUM)
+          || (regnum == SR_REGNUM))
+    reg->how = DWARF2_FRAME_REG_UNDEFINED;
+
+  /* Callee save registers.  */
+  else if ((regnum >= R0_REGNUM+8 && regnum <= R0_REGNUM+15)
+          || (regnum >= FR0_REGNUM+12 && regnum <= FR0_REGNUM+15)
+          || (regnum >= DR0_REGNUM+6 && regnum <= DR0_REGNUM+8)
+          || (regnum == FV0_REGNUM+3))
+    reg->how = DWARF2_FRAME_REG_SAME_VALUE;
+
+  /* Other registers.  These are not in the ABI and may or may not
+     mean anything in frames >0 so don't show them.  */
+  else if ((regnum >= R0_BANK0_REGNUM && regnum <= R0_BANK0_REGNUM+15)
+          || (regnum == GBR_REGNUM)
+          || (regnum == VBR_REGNUM)
+          || (regnum == FPSCR_REGNUM)
+          || (regnum == SSR_REGNUM)
+          || (regnum == SPC_REGNUM))
+    reg->how = DWARF2_FRAME_REG_UNDEFINED;
+}
+
 static struct sh_frame_cache *
 sh_alloc_frame_cache (void)
 {
@@ -1929,8 +2514,9 @@ sh_alloc_frame_cache (void)
 }
 
 static struct sh_frame_cache *
-sh_frame_cache (struct frame_info *next_frame, void **this_cache)
+sh_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct sh_frame_cache *cache;
   CORE_ADDR current_pc;
   int i;
@@ -1946,14 +2532,18 @@ sh_frame_cache (struct frame_info *next_frame, void **this_cache)
      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);
+  cache->base = get_frame_register_unsigned (this_frame, FP_REGNUM);
   if (cache->base == 0)
     return cache;
 
-  cache->pc = frame_func_unwind (next_frame);
-  current_pc = frame_pc_unwind (next_frame);
+  cache->pc = get_frame_func (this_frame);
+  current_pc = get_frame_pc (this_frame);
   if (cache->pc != 0)
-    sh_analyze_prologue (cache->pc, current_pc, cache);
+    {
+      ULONGEST fpscr;
+      fpscr = get_frame_register_unsigned (this_frame, FPSCR_REGNUM);
+      sh_analyze_prologue (gdbarch, cache->pc, current_pc, cache, fpscr);
+    }
 
   if (!cache->uses_fp)
     {
@@ -1964,7 +2554,8 @@ sh_frame_cache (struct frame_info *next_frame, void **this_cache)
          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);
+      cache->base = get_frame_register_unsigned
+                    (this_frame, gdbarch_sp_regnum (gdbarch));
     }
 
   /* Now that we have the base address for the stack frame we can
@@ -1980,60 +2571,36 @@ sh_frame_cache (struct frame_info *next_frame, void **this_cache)
   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)
+static struct value *
+sh_frame_prev_register (struct frame_info *this_frame,
+                       void **this_cache, int regnum)
 {
-  struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache);
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  struct sh_frame_cache *cache = sh_frame_cache (this_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;
-    }
+  if (regnum == gdbarch_sp_regnum (gdbarch) && cache->saved_sp)
+    return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
 
   /* 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)
+  if (regnum == gdbarch_pc_regnum (gdbarch))
     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;
-    }
+    return frame_unwind_got_memory (this_frame, regnum,
+                                    cache->saved_regs[regnum]);
 
-  frame_register_unwind (next_frame, regnum,
-                        optimizedp, lvalp, addrp, realnump, valuep);
+  return frame_unwind_got_register (this_frame, regnum, regnum);
 }
 
 static void
-sh_frame_this_id (struct frame_info *next_frame, void **this_cache,
+sh_frame_this_id (struct frame_info *this_frame, void **this_cache,
                  struct frame_id *this_id)
 {
-  struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache);
+  struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache);
 
   /* This marks the outermost frame.  */
   if (cache->base == 0)
@@ -2045,38 +2612,37 @@ sh_frame_this_id (struct frame_info *next_frame, void **this_cache,
 static const struct frame_unwind sh_frame_unwind = {
   NORMAL_FRAME,
   sh_frame_this_id,
-  sh_frame_prev_register
+  sh_frame_prev_register,
+  NULL,
+  default_frame_sniffer
 };
 
-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);
+  return frame_unwind_register_unsigned (next_frame,
+                                        gdbarch_sp_regnum (gdbarch));
 }
 
 static CORE_ADDR
 sh_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  return frame_unwind_register_unsigned (next_frame, PC_REGNUM);
+  return frame_unwind_register_unsigned (next_frame,
+                                        gdbarch_pc_regnum (gdbarch));
 }
 
 static struct frame_id
-sh_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+sh_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
-  return frame_id_build (sh_unwind_sp (gdbarch, next_frame),
-                        frame_pc_unwind (next_frame));
+  CORE_ADDR sp = get_frame_register_unsigned (this_frame,
+                                             gdbarch_sp_regnum (gdbarch));
+  return frame_id_build (sp, get_frame_pc (this_frame));
 }
 
 static CORE_ADDR
-sh_frame_base_address (struct frame_info *next_frame, void **this_cache)
+sh_frame_base_address (struct frame_info *this_frame, void **this_cache)
 {
-  struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache);
+  struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache);
 
   return cache->base;
 }
@@ -2094,6 +2660,7 @@ static const struct frame_base sh_frame_base = {
 static int
 sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR func_addr = 0, func_end = 0;
 
   if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
@@ -2111,7 +2678,7 @@ sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 
       /* First search forward until hitting an rts. */
       while (addr < func_end
-            && !IS_RTS (read_memory_unsigned_integer (addr, 2)))
+            && !IS_RTS (read_memory_unsigned_integer (addr, 2, byte_order)))
        addr += 2;
       if (addr >= func_end)
        return 0;
@@ -2119,25 +2686,35 @@ sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
       /* 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)))
+      inst = read_memory_unsigned_integer (addr - 2, 2, byte_order);
+      if (IS_RESTORE_FP (read_memory_unsigned_integer (addr - 2, 2,
+                                                      byte_order)))
        addr -= 2;
-      else if (!IS_RESTORE_FP (read_memory_unsigned_integer (addr + 2, 2)))
+      else if (!IS_RESTORE_FP (read_memory_unsigned_integer (addr + 2, 2,
+                                                            byte_order)))
        return 0;
 
+      inst = read_memory_unsigned_integer (addr - 2, 2, byte_order);
+
+      /* Step over possible lds.l @r15+,macl. */
+      if (IS_MACL_LDS (inst))
+       {
+         addr -= 2;
+         inst = read_memory_unsigned_integer (addr - 2, 2, byte_order);
+       }
+
       /* 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);
+         inst = read_memory_unsigned_integer (addr - 2, 2, byte_order);
        }
 
       /* Step over possible mov r14,r15. */
       if (IS_MOV_FP_SP (inst))
        {
          addr -= 2;
-         inst = read_memory_unsigned_integer (addr - 2, 2);
+         inst = read_memory_unsigned_integer (addr - 2, 2, byte_order);
        }
 
       /* Now check for FP adjustments, using add #imm,r14 or add rX, r14
@@ -2146,21 +2723,115 @@ sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
             && (IS_ADD_REG_TO_FP (inst) || IS_ADD_IMM_FP (inst)))
        {
          addr -= 2;
-         inst = read_memory_unsigned_integer (addr - 2, 2);
+         inst = read_memory_unsigned_integer (addr - 2, 2, byte_order);
        }
 
+      /* On SH2a check if the previous instruction was perhaps a MOVI20.
+         That's allowed for the epilogue.  */
+      if ((gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_sh2a
+           || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_sh2a_nofpu)
+          && addr > func_addr + 6
+         && IS_MOVI20 (read_memory_unsigned_integer (addr - 4, 2,
+                                                     byte_order)))
+       addr -= 4;
+
       if (pc >= addr)
        return 1;
     }
   return 0;
 }
 
-static gdbarch_init_ftype sh_gdbarch_init;
+
+/* Supply register REGNUM from the buffer specified by REGS and LEN
+   in the register set REGSET to register cache REGCACHE.
+   REGTABLE specifies where each register can be found in REGS.
+   If REGNUM is -1, do this for all registers in REGSET.  */
+
+void
+sh_corefile_supply_regset (const struct regset *regset,
+                          struct regcache *regcache,
+                          int regnum, const void *regs, size_t len)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  const struct sh_corefile_regmap *regmap = (regset == &sh_corefile_gregset
+                                            ? tdep->core_gregmap
+                                            : tdep->core_fpregmap);
+  int i;
+
+  for (i = 0; regmap[i].regnum != -1; i++)
+    {
+      if ((regnum == -1 || regnum == regmap[i].regnum)
+         && regmap[i].offset + 4 <= len)
+       regcache_raw_supply (regcache, regmap[i].regnum,
+                            (char *)regs + regmap[i].offset);
+    }
+}
+
+/* Collect register REGNUM in the register set REGSET from register cache
+   REGCACHE into the buffer specified by REGS and LEN.
+   REGTABLE specifies where each register can be found in REGS.
+   If REGNUM is -1, do this for all registers in REGSET.  */
+
+void
+sh_corefile_collect_regset (const struct regset *regset,
+                           const struct regcache *regcache,
+                           int regnum, void *regs, size_t len)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  const struct sh_corefile_regmap *regmap = (regset == &sh_corefile_gregset
+                                            ? tdep->core_gregmap
+                                            : tdep->core_fpregmap);
+  int i;
+
+  for (i = 0; regmap[i].regnum != -1; i++)
+    {
+      if ((regnum == -1 || regnum == regmap[i].regnum)
+         && regmap[i].offset + 4 <= len)
+       regcache_raw_collect (regcache, regmap[i].regnum,
+                             (char *)regs + regmap[i].offset);
+    }
+}
+
+/* The following two regsets have the same contents, so it is tempting to
+   unify them, but they are distiguished by their address, so don't.  */
+
+struct regset sh_corefile_gregset =
+{
+  NULL,
+  sh_corefile_supply_regset,
+  sh_corefile_collect_regset
+};
+
+static struct regset sh_corefile_fpregset =
+{
+  NULL,
+  sh_corefile_supply_regset,
+  sh_corefile_collect_regset
+};
+
+static const struct regset *
+sh_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name,
+                            size_t sect_size)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->core_gregmap && strcmp (sect_name, ".reg") == 0)
+    return &sh_corefile_gregset;
+
+  if (tdep->core_fpregmap && strcmp (sect_name, ".reg2") == 0)
+    return &sh_corefile_fpregset;
+
+  return NULL;
+}
+\f
 
 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)
@@ -2168,15 +2839,24 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     case bfd_mach_sh2e:
       sh_show_regs = sh2e_show_regs;
       break;
+    case bfd_mach_sh2a:
+      sh_show_regs = sh2a_show_regs;
+      break;
+    case bfd_mach_sh2a_nofpu:
+      sh_show_regs = sh2a_nofpu_show_regs;
+      break;
     case bfd_mach_sh_dsp:
       sh_show_regs = sh_dsp_show_regs;
       break;
 
     case bfd_mach_sh3:
+    case bfd_mach_sh3_nommu:
+    case bfd_mach_sh2a_nofpu_or_sh3_nommu:
       sh_show_regs = sh3_show_regs;
       break;
 
     case bfd_mach_sh3e:
+    case bfd_mach_sh2a_or_sh3e:
       sh_show_regs = sh3e_show_regs;
       break;
 
@@ -2187,11 +2867,14 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
     case bfd_mach_sh4:
     case bfd_mach_sh4a:
+    case bfd_mach_sh2a_or_sh4:
       sh_show_regs = sh4_show_regs;
       break;
 
     case bfd_mach_sh4_nofpu:
+    case bfd_mach_sh4_nommu_nofpu:
     case bfd_mach_sh4a_nofpu:
+    case bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu:
       sh_show_regs = sh4_nofpu_show_regs;
       break;
 
@@ -2208,7 +2891,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* None found, create a new architecture from the information
      provided. */
-  gdbarch = gdbarch_alloc (&info, NULL);
+  tdep = XZALLOC (struct gdbarch_tdep);
+  gdbarch = gdbarch_alloc (&info, tdep);
 
   set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
   set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
@@ -2226,38 +2910,34 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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_register_reggroup_p (gdbarch, sh_register_reggroup_p);
 
   set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc);
-  set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention);
 
-  set_gdbarch_print_insn (gdbarch, gdb_print_insn_sh);
+  set_gdbarch_print_insn (gdbarch, print_insn_sh);
   set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno);
 
-  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_deprecated_extract_struct_value_address (gdbarch, sh_extract_struct_value_address);
+  set_gdbarch_return_value (gdbarch, sh_return_value_nofpu);
 
   set_gdbarch_skip_prologue (gdbarch, sh_skip_prologue);
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
 
   set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu);
 
-  set_gdbarch_frameless_function_invocation (gdbarch,
-                                            frameless_look_for_prologue);
   set_gdbarch_believe_pcc_promotion (gdbarch, 1);
 
   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);
+  set_gdbarch_dummy_id (gdbarch, sh_dummy_id);
   frame_base_set_default (gdbarch, &sh_frame_base);
 
   set_gdbarch_in_function_epilogue_p (gdbarch, sh_in_function_epilogue_p);
 
+  dwarf2_frame_set_init_reg (gdbarch, sh_dwarf2_frame_init_reg);
+
+  set_gdbarch_regset_from_core_section (gdbarch, sh_regset_from_core_section);
+
   switch (info.bfd_arch_info->mach)
     {
     case bfd_mach_sh:
@@ -2275,31 +2955,52 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_register_name (gdbarch, sh_sh2e_register_name);
       set_gdbarch_register_type (gdbarch, sh_sh3e_register_type);
       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_return_value (gdbarch, sh_return_value_fpu);
+      set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
+      break;
+
+    case bfd_mach_sh2a:
+      set_gdbarch_register_name (gdbarch, sh_sh2a_register_name);
+      set_gdbarch_register_type (gdbarch, sh_sh2a_register_type);
+      set_gdbarch_register_sim_regno (gdbarch, sh_sh2a_register_sim_regno);
+
+      set_gdbarch_fp0_regnum (gdbarch, 25);
+      set_gdbarch_num_pseudo_regs (gdbarch, 9);
+      set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read);
+      set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write);
+      set_gdbarch_return_value (gdbarch, sh_return_value_fpu);
       set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
       break;
 
+    case bfd_mach_sh2a_nofpu:
+      set_gdbarch_register_name (gdbarch, sh_sh2a_nofpu_register_name);
+      set_gdbarch_register_sim_regno (gdbarch, sh_sh2a_register_sim_regno);
+
+      set_gdbarch_num_pseudo_regs (gdbarch, 1);
+      set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read);
+      set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write);
+      break;
+
     case bfd_mach_sh_dsp:
       set_gdbarch_register_name (gdbarch, sh_sh_dsp_register_name);
       set_gdbarch_register_sim_regno (gdbarch, sh_dsp_register_sim_regno);
       break;
 
     case bfd_mach_sh3:
+    case bfd_mach_sh3_nommu:
+    case bfd_mach_sh2a_nofpu_or_sh3_nommu:
       set_gdbarch_register_name (gdbarch, sh_sh3_register_name);
       break;
 
     case bfd_mach_sh3e:
+    case bfd_mach_sh2a_or_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_register_type (gdbarch, sh_sh3e_register_type);
       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_return_value (gdbarch, sh_return_value_fpu);
       set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
       break;
 
@@ -2310,20 +3011,21 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
     case bfd_mach_sh4:
     case bfd_mach_sh4a:
+    case bfd_mach_sh2a_or_sh4:
       set_gdbarch_register_name (gdbarch, sh_sh4_register_name);
       set_gdbarch_register_type (gdbarch, sh_sh4_register_type);
       set_gdbarch_fp0_regnum (gdbarch, 25);
-      set_gdbarch_num_pseudo_regs (gdbarch, 12);
+      set_gdbarch_num_pseudo_regs (gdbarch, 13);
       set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read);
       set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write);
-      set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value);
-      set_gdbarch_extract_return_value (gdbarch,
-                                       sh3e_sh4_extract_return_value);
+      set_gdbarch_return_value (gdbarch, sh_return_value_fpu);
       set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
       break;
 
     case bfd_mach_sh4_nofpu:
     case bfd_mach_sh4a_nofpu:
+    case bfd_mach_sh4_nommu_nofpu:
+    case bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu:
       set_gdbarch_register_name (gdbarch, sh_sh4_nofpu_register_name);
       break;
 
@@ -2333,19 +3035,33 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       break;
 
     default:
-      set_gdbarch_register_name (gdbarch, sh_generic_register_name);
+      set_gdbarch_register_name (gdbarch, sh_sh_register_name);
       break;
     }
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
-  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
-  frame_unwind_append_sniffer (gdbarch, sh_frame_sniffer);
+  dwarf2_append_unwinders (gdbarch);
+  frame_unwind_append_unwinder (gdbarch, &sh_frame_unwind);
 
   return gdbarch;
 }
 
+static void
+show_sh_command (char *args, int from_tty)
+{
+  help_list (showshcmdlist, "show sh ", all_commands, gdb_stdout);
+}
+
+static void
+set_sh_command (char *args, int from_tty)
+{
+  printf_unfiltered
+    ("\"set sh\" must be followed by an appropriate subcommand.\n");
+  help_list (setshcmdlist, "set sh ", all_commands, gdb_stdout);
+}
+
 extern initialize_file_ftype _initialize_sh_tdep;      /* -Wmissing-prototypes */
 
 void
@@ -2355,5 +3071,21 @@ _initialize_sh_tdep (void)
 
   gdbarch_register (bfd_arch_sh, sh_gdbarch_init, NULL);
 
-  add_com ("regs", class_vars, sh_show_regs_command, "Print all registers");
+  add_com ("regs", class_vars, sh_show_regs_command, _("Print all registers"));
+  
+  add_prefix_cmd ("sh", no_class, set_sh_command, "SH specific commands.",
+                  &setshcmdlist, "set sh ", 0, &setlist);
+  add_prefix_cmd ("sh", no_class, show_sh_command, "SH specific commands.",
+                  &showshcmdlist, "show sh ", 0, &showlist);
+  
+  add_setshow_enum_cmd ("calling-convention", class_vars, sh_cc_enum,
+                       &sh_active_calling_convention,
+                       _("Set calling convention used when calling target "
+                         "functions from GDB."),
+                       _("Show calling convention used when calling target "
+                         "functions from GDB."),
+                       _("gcc       - Use GCC calling convention (default).\n"
+                         "renesas   - Enforce Renesas calling convention."),
+                       NULL, NULL,
+                       &setshcmdlist, &showshcmdlist);
 }
This page took 0.06115 seconds and 4 git commands to generate.