]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/cris-tdep.c
Turn value_type into method
[thirdparty/binutils-gdb.git] / gdb / cris-tdep.c
index 6b060ea3708b499674667ce473465f504ca0c101..cc8d7634c9d0e8d89073e91a1def8622db331b22 100644 (file)
@@ -1,6 +1,6 @@
 /* Target dependent code for CRIS, for GDB, the GNU debugger.
 
-   Copyright (C) 2001-2016 Free Software Foundation, Inc.
+   Copyright (C) 2001-2023 Free Software Foundation, Inc.
 
    Contributed by Axis Communications AB.
    Written by Hendrik Ruijter, Stefan Andersson, and Orjan Friberg.
@@ -25,7 +25,7 @@
 #include "frame-unwind.h"
 #include "frame-base.h"
 #include "trad-frame.h"
-#include "dwarf2-frame.h"
+#include "dwarf2/frame.h"
 #include "symtab.h"
 #include "inferior.h"
 #include "gdbtypes.h"
@@ -37,6 +37,7 @@
 #include "osabi.h"
 #include "arch-utils.h"
 #include "regcache.h"
+#include "regset.h"
 
 #include "objfiles.h"
 
@@ -148,7 +149,7 @@ extern const struct cris_spec_reg cris_spec_regs[];
 static unsigned int usr_cmd_cris_version;
 
 /* Indicates whether to trust the above variable.  */
-static int usr_cmd_cris_version_valid = 0;
+static bool usr_cmd_cris_version_valid = false;
 
 static const char cris_mode_normal[] = "normal";
 static const char cris_mode_guru[] = "guru";
@@ -163,7 +164,7 @@ static const char *const cris_modes[] = {
 static const char *usr_cmd_cris_mode = cris_mode_normal;
 
 /* Whether to make use of Dwarf-2 CFI (default on).  */
-static int usr_cmd_cris_dwarf2_cfi = 1;
+static bool usr_cmd_cris_dwarf2_cfi = true;
 
 /* Sigtramp identification code copied from i386-linux-tdep.c.  */
 
@@ -192,12 +193,12 @@ static const unsigned short rt_sigtramp_code[] =
    the routine.  Otherwise, return 0.  */
 
 static CORE_ADDR
-cris_sigtramp_start (struct frame_info *this_frame)
+cris_sigtramp_start (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   gdb_byte buf[SIGTRAMP_LEN];
 
-  if (!safe_frame_unwind_memory (this_frame, pc, buf, SIGTRAMP_LEN))
+  if (!safe_frame_unwind_memory (this_frame, pc, buf))
     return 0;
 
   if (((buf[1] << 8) + buf[0]) != SIGTRAMP_INSN0)
@@ -206,7 +207,7 @@ cris_sigtramp_start (struct frame_info *this_frame)
        return 0;
 
       pc -= SIGTRAMP_OFFSET1;
-      if (!safe_frame_unwind_memory (this_frame, pc, buf, SIGTRAMP_LEN))
+      if (!safe_frame_unwind_memory (this_frame, pc, buf))
        return 0;
     }
 
@@ -220,12 +221,12 @@ cris_sigtramp_start (struct frame_info *this_frame)
    the routine.  Otherwise, return 0.  */
 
 static CORE_ADDR
-cris_rt_sigtramp_start (struct frame_info *this_frame)
+cris_rt_sigtramp_start (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   gdb_byte buf[SIGTRAMP_LEN];
 
-  if (!safe_frame_unwind_memory (this_frame, pc, buf, SIGTRAMP_LEN))
+  if (!safe_frame_unwind_memory (this_frame, pc, buf))
     return 0;
 
   if (((buf[1] << 8) + buf[0]) != SIGTRAMP_INSN0)
@@ -234,7 +235,7 @@ cris_rt_sigtramp_start (struct frame_info *this_frame)
        return 0;
 
       pc -= SIGTRAMP_OFFSET1;
-      if (!safe_frame_unwind_memory (this_frame, pc, buf, SIGTRAMP_LEN))
+      if (!safe_frame_unwind_memory (this_frame, pc, buf))
        return 0;
     }
 
@@ -248,7 +249,7 @@ cris_rt_sigtramp_start (struct frame_info *this_frame)
    return the address of the associated sigcontext structure.  */
 
 static CORE_ADDR
-cris_sigcontext_addr (struct frame_info *this_frame)
+cris_sigcontext_addr (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -304,15 +305,15 @@ struct cris_unwind_cache
   int leaf_function;
 
   /* Table indicating the location of each and every register.  */
-  struct trad_frame_saved_reg *saved_regs;
+  trad_frame_saved_reg *saved_regs;
 };
 
 static struct cris_unwind_cache *
-cris_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
+cris_sigtramp_frame_unwind_cache (frame_info_ptr this_frame,
                                  void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct cris_unwind_cache *info;
   CORE_ADDR addr;
@@ -353,18 +354,18 @@ cris_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
       /* R0 to R13 are stored in reverse order at offset (2 * 4) in 
         struct pt_regs.  */
       for (i = 0; i <= 13; i++)
-       info->saved_regs[i].addr = addr + ((15 - i) * 4);
+       info->saved_regs[i].set_addr (addr + ((15 - i) * 4));
 
-      info->saved_regs[MOF_REGNUM].addr = addr + (16 * 4);
-      info->saved_regs[DCCR_REGNUM].addr = addr + (17 * 4);
-      info->saved_regs[SRP_REGNUM].addr = addr + (18 * 4);
+      info->saved_regs[MOF_REGNUM].set_addr (addr + (16 * 4));
+      info->saved_regs[DCCR_REGNUM].set_addr (addr + (17 * 4));
+      info->saved_regs[SRP_REGNUM].set_addr (addr + (18 * 4));
       /* Note: IRP is off by 2 at this point.  There's no point in correcting
         it though since that will mean that the backtrace will show a PC 
         different from what is shown when stopped.  */
-      info->saved_regs[IRP_REGNUM].addr = addr + (19 * 4);
+      info->saved_regs[IRP_REGNUM].set_addr (addr + (19 * 4));
       info->saved_regs[gdbarch_pc_regnum (gdbarch)]
        = info->saved_regs[IRP_REGNUM];
-      info->saved_regs[gdbarch_sp_regnum (gdbarch)].addr = addr + (24 * 4);
+      info->saved_regs[gdbarch_sp_regnum (gdbarch)].set_addr (addr + (24 * 4));
     }
   else
     {
@@ -372,17 +373,17 @@ cris_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
       /* R0 to R13 are stored in order at offset (1 * 4) in 
         struct pt_regs.  */
       for (i = 0; i <= 13; i++)
-       info->saved_regs[i].addr = addr + ((i + 1) * 4);
-
-      info->saved_regs[ACR_REGNUM].addr = addr + (15 * 4);
-      info->saved_regs[SRS_REGNUM].addr = addr + (16 * 4);
-      info->saved_regs[MOF_REGNUM].addr = addr + (17 * 4);
-      info->saved_regs[SPC_REGNUM].addr = addr + (18 * 4);
-      info->saved_regs[CCS_REGNUM].addr = addr + (19 * 4);
-      info->saved_regs[SRP_REGNUM].addr = addr + (20 * 4);
-      info->saved_regs[ERP_REGNUM].addr = addr + (21 * 4);
-      info->saved_regs[EXS_REGNUM].addr = addr + (22 * 4);
-      info->saved_regs[EDA_REGNUM].addr = addr + (23 * 4);
+       info->saved_regs[i].set_addr (addr + ((i + 1) * 4));
+
+      info->saved_regs[ACR_REGNUM].set_addr (addr + (15 * 4));
+      info->saved_regs[SRS_REGNUM].set_addr (addr + (16 * 4));
+      info->saved_regs[MOF_REGNUM].set_addr (addr + (17 * 4));
+      info->saved_regs[SPC_REGNUM].set_addr (addr + (18 * 4));
+      info->saved_regs[CCS_REGNUM].set_addr (addr + (19 * 4));
+      info->saved_regs[SRP_REGNUM].set_addr (addr + (20 * 4));
+      info->saved_regs[ERP_REGNUM].set_addr (addr + (21 * 4));
+      info->saved_regs[EXS_REGNUM].set_addr (addr + (22 * 4));
+      info->saved_regs[EDA_REGNUM].set_addr (addr + (23 * 4));
 
       /* FIXME: If ERP is in a delay slot at this point then the PC will
         be wrong at this point.  This problem manifests itself in the
@@ -394,16 +395,15 @@ cris_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
       info->saved_regs[gdbarch_pc_regnum (gdbarch)]
        = info->saved_regs[ERP_REGNUM];
 
-      info->saved_regs[gdbarch_sp_regnum (gdbarch)].addr
-       = addr + (25 * 4);
+      info->saved_regs[gdbarch_sp_regnum (gdbarch)].set_addr (addr + (25 * 4));
     }
   
   return info;
 }
 
 static void
-cris_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
-                             struct frame_id *this_id)
+cris_sigtramp_frame_this_id (frame_info_ptr this_frame, void **this_cache,
+                            struct frame_id *this_id)
 {
   struct cris_unwind_cache *cache =
     cris_sigtramp_frame_unwind_cache (this_frame, this_cache);
@@ -412,11 +412,11 @@ cris_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
 
 /* Forward declaration.  */
 
-static struct value *cris_frame_prev_register (struct frame_info *this_frame,
+static struct value *cris_frame_prev_register (frame_info_ptr this_frame,
                                               void **this_cache, int regnum);
 static struct value *
-cris_sigtramp_frame_prev_register (struct frame_info *this_frame,
-                                   void **this_cache, int regnum)
+cris_sigtramp_frame_prev_register (frame_info_ptr this_frame,
+                                  void **this_cache, int regnum)
 {
   /* Make sure we've initialized the cache.  */
   cris_sigtramp_frame_unwind_cache (this_frame, this_cache);
@@ -425,7 +425,7 @@ cris_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 cris_sigtramp_frame_sniffer (const struct frame_unwind *self,
-                            struct frame_info *this_frame,
+                            frame_info_ptr this_frame,
                             void **this_cache)
 {
   if (cris_sigtramp_start (this_frame) 
@@ -437,6 +437,7 @@ cris_sigtramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind cris_sigtramp_frame_unwind =
 {
+  "cris sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   cris_sigtramp_frame_this_id,
@@ -447,9 +448,9 @@ static const struct frame_unwind cris_sigtramp_frame_unwind =
 
 static int
 crisv32_single_step_through_delay (struct gdbarch *gdbarch,
-                                  struct frame_info *this_frame)
+                                  frame_info_ptr this_frame)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch);
   ULONGEST erp;
   int ret = 0;
 
@@ -533,9 +534,9 @@ enum cris_opcode_masks
 /* Functions for opcodes.  The general form of the ETRAX 16-bit instruction:
    Bit 15 - 12   Operand2
        11 - 10   Mode
-        9 -  6   Opcode
-        5 -  4   Size
-        3 -  0   Operand1  */
+       9 -  6   Opcode
+       5 -  4   Size
+       3 -  0   Operand1  */
 
 static int 
 cris_get_operand2 (unsigned short insn)
@@ -630,48 +631,43 @@ static void cris_gdb_func (struct gdbarch *, enum cris_op_type, unsigned short,
                           inst_env_type *);
 
 static struct gdbarch *cris_gdbarch_init (struct gdbarch_info,
-                                          struct gdbarch_list *);
+                                         struct gdbarch_list *);
 
 static void cris_dump_tdep (struct gdbarch *, struct ui_file *);
 
-static void set_cris_version (char *ignore_args, int from_tty, 
+static void set_cris_version (const char *ignore_args, int from_tty, 
                              struct cmd_list_element *c);
 
-static void set_cris_mode (char *ignore_args, int from_tty, 
+static void set_cris_mode (const char *ignore_args, int from_tty, 
                           struct cmd_list_element *c);
 
-static void set_cris_dwarf2_cfi (char *ignore_args, int from_tty, 
+static void set_cris_dwarf2_cfi (const char *ignore_args, int from_tty, 
                                 struct cmd_list_element *c);
 
 static CORE_ADDR cris_scan_prologue (CORE_ADDR pc, 
-                                    struct frame_info *this_frame,
+                                    frame_info_ptr this_frame,
                                     struct cris_unwind_cache *info);
 
 static CORE_ADDR crisv32_scan_prologue (CORE_ADDR pc, 
-                                       struct frame_info *this_frame,
+                                       frame_info_ptr this_frame,
                                        struct cris_unwind_cache *info);
 
-static CORE_ADDR cris_unwind_pc (struct gdbarch *gdbarch, 
-                                struct frame_info *next_frame);
-
-static CORE_ADDR cris_unwind_sp (struct gdbarch *gdbarch, 
-                                struct frame_info *next_frame);
-
 /* When arguments must be pushed onto the stack, they go on in reverse
    order.  The below implements a FILO (stack) to do this.
    Copied from d10v-tdep.c.  */
 
-struct stack_item
+struct cris_stack_item
 {
   int len;
-  struct stack_item *prev;
+  struct cris_stack_item *prev;
   gdb_byte *data;
 };
 
-static struct stack_item *
-push_stack_item (struct stack_item *prev, const gdb_byte *contents, int len)
+static struct cris_stack_item *
+push_stack_item (struct cris_stack_item *prev, const gdb_byte *contents,
+                int len)
 {
-  struct stack_item *si = XNEW (struct stack_item);
+  struct cris_stack_item *si = XNEW (struct cris_stack_item);
   si->data = (gdb_byte *) xmalloc (len);
   si->len = len;
   si->prev = prev;
@@ -679,10 +675,10 @@ push_stack_item (struct stack_item *prev, const gdb_byte *contents, int len)
   return si;
 }
 
-static struct stack_item *
-pop_stack_item (struct stack_item *si)
+static struct cris_stack_item *
+pop_stack_item (struct cris_stack_item *si)
 {
-  struct stack_item *dead = si;
+  struct cris_stack_item *dead = si;
   si = si->prev;
   xfree (dead->data);
   xfree (dead);
@@ -696,11 +692,11 @@ pop_stack_item (struct stack_item *si)
    for it IS the sp for the next frame.  */
 
 static struct cris_unwind_cache *
-cris_frame_unwind_cache (struct frame_info *this_frame,
+cris_frame_unwind_cache (frame_info_ptr this_frame,
                         void **this_prologue_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch);
   struct cris_unwind_cache *info;
 
   if ((*this_prologue_cache))
@@ -733,7 +729,7 @@ cris_frame_unwind_cache (struct frame_info *this_frame,
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-cris_frame_this_id (struct frame_info *this_frame,
+cris_frame_this_id (frame_info_ptr this_frame,
                    void **this_prologue_cache,
                    struct frame_id *this_id)
 {
@@ -759,7 +755,7 @@ cris_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-cris_frame_prev_register (struct frame_info *this_frame,
+cris_frame_prev_register (frame_info_ptr this_frame,
                          void **this_prologue_cache, int regnum)
 {
   struct cris_unwind_cache *info
@@ -767,18 +763,6 @@ cris_frame_prev_register (struct frame_info *this_frame,
   return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
 }
 
-/* Assuming THIS_FRAME is a dummy, return the frame ID of that dummy
-   frame.  The frame ID's base needs to match the TOS value saved by
-   save_dummy_frame_tos(), and the PC match the dummy frame's breakpoint.  */
-
-static struct frame_id
-cris_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  CORE_ADDR sp;
-  sp = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
-  return frame_id_build (sp, get_frame_pc (this_frame));
-}
-
 static CORE_ADDR
 cris_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
 {
@@ -789,10 +773,10 @@ cris_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
 
 static CORE_ADDR
 cris_push_dummy_code (struct gdbarch *gdbarch,
-                      CORE_ADDR sp, CORE_ADDR funaddr,
-                      struct value **args, int nargs,
-                      struct type *value_type,
-                      CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
+                     CORE_ADDR sp, CORE_ADDR funaddr,
+                     struct value **args, int nargs,
+                     struct type *value_type,
+                     CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
                      struct regcache *regcache)
 {
   /* Allocate space sufficient for a breakpoint.  */
@@ -808,13 +792,14 @@ static CORE_ADDR
 cris_push_dummy_call (struct gdbarch *gdbarch, 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)
+                     function_call_return_method return_method,
+                     CORE_ADDR struct_addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int argreg;
   int argnum;
 
-  struct stack_item *si = NULL;
+  struct cris_stack_item *si = NULL;
 
   /* Push the return address.  */
   regcache_cooked_write_unsigned (regcache, SRP_REGNUM, bp_addr);
@@ -822,10 +807,8 @@ cris_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   /* Are we returning a value using a structure return or a normal value
      return?  struct_addr is the address of the reserved space for the return
      structure to be written on the stack.  */
-  if (struct_return)
-    {
-      regcache_cooked_write_unsigned (regcache, STR_REGNUM, struct_addr);
-    }
+  if (return_method == return_method_struct)
+    regcache_cooked_write_unsigned (regcache, STR_REGNUM, struct_addr);
 
   /* Now load as many as possible of the first arguments into registers,
      and push the rest onto the stack.  */
@@ -838,45 +821,45 @@ cris_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       int reg_demand;
       int i;
       
-      len = TYPE_LENGTH (value_type (args[argnum]));
-      val = value_contents (args[argnum]);
+      len = args[argnum]->type ()->length ();
+      val = value_contents (args[argnum]).data ();
       
       /* How may registers worth of storage do we need for this argument?  */
       reg_demand = (len / 4) + (len % 4 != 0 ? 1 : 0);
-        
+       
       if (len <= (2 * 4) && (argreg + reg_demand - 1 <= ARG4_REGNUM))
-        {
-          /* Data passed by value.  Fits in available register(s).  */
-          for (i = 0; i < reg_demand; i++)
-            {
-              regcache_cooked_write (regcache, argreg, val);
-              argreg++;
-              val += 4;
-            }
-        }
+       {
+         /* Data passed by value.  Fits in available register(s).  */
+         for (i = 0; i < reg_demand; i++)
+           {
+             regcache->cooked_write (argreg, val);
+             argreg++;
+             val += 4;
+           }
+       }
       else if (len <= (2 * 4) && argreg <= ARG4_REGNUM)
-        {
-          /* Data passed by value. Does not fit in available register(s).
-             Use the register(s) first, then the stack.  */
-          for (i = 0; i < reg_demand; i++)
-            {
-              if (argreg <= ARG4_REGNUM)
-                {
-                 regcache_cooked_write (regcache, argreg, val);
-                  argreg++;
-                  val += 4;
-                }
-              else
-                {
+       {
+         /* Data passed by value. Does not fit in available register(s).
+            Use the register(s) first, then the stack.  */
+         for (i = 0; i < reg_demand; i++)
+           {
+             if (argreg <= ARG4_REGNUM)
+               {
+                 regcache->cooked_write (argreg, val);
+                 argreg++;
+                 val += 4;
+               }
+             else
+               {
                  /* Push item for later so that pushed arguments
                     come in the right order.  */
                  si = push_stack_item (si, val, 4);
-                  val += 4;
-                }
-            }
-        }
+                 val += 4;
+               }
+           }
+       }
       else if (len > (2 * 4))
-        {
+       {
          /* Data passed by reference.  Push copy of data onto stack
             and pass pointer to this copy as argument.  */
          sp = (sp - len) & ~3;
@@ -893,13 +876,13 @@ cris_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
              store_unsigned_integer (buf, 4, byte_order, sp);
              si = push_stack_item (si, buf, 4);
            }
-        }
+       }
       else
-        {
-          /* Data passed by value.  No available registers.  Put it on
-             the stack.  */
+       {
+         /* Data passed by value.  No available registers.  Put it on
+            the stack.  */
           si = push_stack_item (si, val, len);
-        }
+       }
     }
 
   while (si)
@@ -919,6 +902,7 @@ cris_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
 static const struct frame_unwind cris_frame_unwind = 
 {
+  "cris prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   cris_frame_this_id,
@@ -928,7 +912,7 @@ static const struct frame_unwind cris_frame_unwind =
 };
 
 static CORE_ADDR
-cris_frame_base_address (struct frame_info *this_frame, void **this_cache)
+cris_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct cris_unwind_cache *info
     = cris_frame_unwind_cache (this_frame, this_cache);
@@ -1020,7 +1004,7 @@ static const struct frame_base cris_frame_base =
    determine that it is a prologue (1).  */
 
 static CORE_ADDR 
-cris_scan_prologue (CORE_ADDR pc, struct frame_info *this_frame,
+cris_scan_prologue (CORE_ADDR pc, frame_info_ptr this_frame,
                    struct cris_unwind_cache *info)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -1067,165 +1051,165 @@ cris_scan_prologue (CORE_ADDR pc, struct frame_info *this_frame,
       insn = read_memory_unsigned_integer (pc, 2, byte_order);
       pc += 2;
       if (insn == 0xE1FC)
-        {
-          /* push <reg> 32 bit instruction.  */
-          insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
-          pc += 2;
-          regno = cris_get_operand2 (insn_next);
+       {
+         /* push <reg> 32 bit instruction.  */
+         insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
+         pc += 2;
+         regno = cris_get_operand2 (insn_next);
          if (info)
            {
              info->sp_offset += 4;
            }
-          /* This check, meant to recognize srp, used to be regno == 
-             (SRP_REGNUM - NUM_GENREGS), but that covers r11 also.  */
-          if (insn_next == 0xBE7E)
-            {
+         /* This check, meant to recognize srp, used to be regno == 
+            (SRP_REGNUM - NUM_GENREGS), but that covers r11 also.  */
+         if (insn_next == 0xBE7E)
+           {
              if (info)
                {
                  info->leaf_function = 0;
                }
-            }
+           }
          else if (insn_next == 0x8FEE)
-            {
+           {
              /* push $r8 */
              if (info)
                {
                  info->r8_offset = info->sp_offset;
                }
-            }
-        }
+           }
+       }
       else if (insn == 0x866E)
-        {
-          /* move.d sp,r8 */
+       {
+         /* move.d sp,r8 */
          if (info)
            {
              info->uses_frame = 1;
            }
-          continue;
-        }
+         continue;
+       }
       else if (cris_get_operand2 (insn) == gdbarch_sp_regnum (gdbarch)
-               && cris_get_mode (insn) == 0x0000
-               && cris_get_opcode (insn) == 0x000A)
-        {
-          /* subq <val>,sp */
+              && cris_get_mode (insn) == 0x0000
+              && cris_get_opcode (insn) == 0x000A)
+       {
+         /* subq <val>,sp */
          if (info)
            {
              info->sp_offset += cris_get_quick_value (insn);
            }
-        }
+       }
       else if (cris_get_mode (insn) == 0x0002 
-               && cris_get_opcode (insn) == 0x000F
-               && cris_get_size (insn) == 0x0003
-               && cris_get_operand1 (insn) == gdbarch_sp_regnum (gdbarch))
-        {
-          /* movem r<regsave>,[sp] */
-          regsave = cris_get_operand2 (insn);
-        }
+              && cris_get_opcode (insn) == 0x000F
+              && cris_get_size (insn) == 0x0003
+              && cris_get_operand1 (insn) == gdbarch_sp_regnum (gdbarch))
+       {
+         /* movem r<regsave>,[sp] */
+         regsave = cris_get_operand2 (insn);
+       }
       else if (cris_get_operand2 (insn) == gdbarch_sp_regnum (gdbarch)
-               && ((insn & 0x0F00) >> 8) == 0x0001
-               && (cris_get_signed_offset (insn) < 0))
-        {
-          /* Immediate byte offset addressing prefix word with sp as base 
-             register.  Used for CRIS v8 i.e. ETRAX 100 and newer if <val> 
-             is between 64 and 128. 
-             movem r<regsave>,[sp=sp-<val>] */
+              && ((insn & 0x0F00) >> 8) == 0x0001
+              && (cris_get_signed_offset (insn) < 0))
+       {
+         /* Immediate byte offset addressing prefix word with sp as base 
+            register.  Used for CRIS v8 i.e. ETRAX 100 and newer if <val> 
+            is between 64 and 128. 
+            movem r<regsave>,[sp=sp-<val>] */
          if (info)
            {
              info->sp_offset += -cris_get_signed_offset (insn);
            }
          insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
-          pc += 2;
-          if (cris_get_mode (insn_next) == PREFIX_ASSIGN_MODE
-              && cris_get_opcode (insn_next) == 0x000F
-              && cris_get_size (insn_next) == 0x0003
-              && cris_get_operand1 (insn_next) == gdbarch_sp_regnum
+         pc += 2;
+         if (cris_get_mode (insn_next) == PREFIX_ASSIGN_MODE
+             && cris_get_opcode (insn_next) == 0x000F
+             && cris_get_size (insn_next) == 0x0003
+             && cris_get_operand1 (insn_next) == gdbarch_sp_regnum
                                                  (gdbarch))
-            {
-              regsave = cris_get_operand2 (insn_next);
-            }
-          else
-            {
-              /* The prologue ended before the limit was reached.  */
-              pc -= 4;
-              break;
-            }
-        }
+           {
+             regsave = cris_get_operand2 (insn_next);
+           }
+         else
+           {
+             /* The prologue ended before the limit was reached.  */
+             pc -= 4;
+             break;
+           }
+       }
       else if (cris_get_mode (insn) == 0x0001
-               && cris_get_opcode (insn) == 0x0009
-               && cris_get_size (insn) == 0x0002)
-        {
-          /* move.d r<10..13>,r<0..15> */
-          source_register = cris_get_operand1 (insn);
-
-          /* FIXME?  In the glibc solibs, the prologue might contain something
-             like (this example taken from relocate_doit):
-             move.d $pc,$r0
-             sub.d 0xfffef426,$r0
-             which isn't covered by the source_register check below.  Question
-             is whether to add a check for this combo, or make better use of
-             the limit variable instead.  */
-          if (source_register < ARG1_REGNUM || source_register > ARG4_REGNUM)
-            {
-              /* The prologue ended before the limit was reached.  */
-              pc -= 2;
-              break;
-            }
-        }
+              && cris_get_opcode (insn) == 0x0009
+              && cris_get_size (insn) == 0x0002)
+       {
+         /* move.d r<10..13>,r<0..15> */
+         source_register = cris_get_operand1 (insn);
+
+         /* FIXME?  In the glibc solibs, the prologue might contain something
+            like (this example taken from relocate_doit):
+            move.d $pc,$r0
+            sub.d 0xfffef426,$r0
+            which isn't covered by the source_register check below.  Question
+            is whether to add a check for this combo, or make better use of
+            the limit variable instead.  */
+         if (source_register < ARG1_REGNUM || source_register > ARG4_REGNUM)
+           {
+             /* The prologue ended before the limit was reached.  */
+             pc -= 2;
+             break;
+           }
+       }
       else if (cris_get_operand2 (insn) == CRIS_FP_REGNUM 
-               /* The size is a fixed-size.  */
-               && ((insn & 0x0F00) >> 8) == 0x0001 
-               /* A negative offset.  */
-               && (cris_get_signed_offset (insn) < 0))  
-        {
-          /* move.S rZ,[r8-U] (?) */
-          insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
-          pc += 2;
-          regno = cris_get_operand2 (insn_next);
-          if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch))
-              && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE
-              && cris_get_opcode (insn_next) == 0x000F)
-            {
-              /* move.S rZ,[r8-U] */
-              continue;
-            }
-          else
-            {
-              /* The prologue ended before the limit was reached.  */
-              pc -= 4;
-              break;
-            }
-        }
+              /* The size is a fixed-size.  */
+              && ((insn & 0x0F00) >> 8) == 0x0001 
+              /* A negative offset.  */
+              && (cris_get_signed_offset (insn) < 0))  
+       {
+         /* move.S rZ,[r8-U] (?) */
+         insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
+         pc += 2;
+         regno = cris_get_operand2 (insn_next);
+         if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch))
+             && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE
+             && cris_get_opcode (insn_next) == 0x000F)
+           {
+             /* move.S rZ,[r8-U] */
+             continue;
+           }
+         else
+           {
+             /* The prologue ended before the limit was reached.  */
+             pc -= 4;
+             break;
+           }
+       }
       else if (cris_get_operand2 (insn) == CRIS_FP_REGNUM 
-               /* The size is a fixed-size.  */
-               && ((insn & 0x0F00) >> 8) == 0x0001 
-               /* A positive offset.  */
-               && (cris_get_signed_offset (insn) > 0))  
-        {
-          /* move.S [r8+U],rZ (?) */
+              /* The size is a fixed-size.  */
+              && ((insn & 0x0F00) >> 8) == 0x0001 
+              /* A positive offset.  */
+              && (cris_get_signed_offset (insn) > 0))  
+       {
+         /* move.S [r8+U],rZ (?) */
          insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
-          pc += 2;
-          regno = cris_get_operand2 (insn_next);
-          if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch))
-              && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE
-              && cris_get_opcode (insn_next) == 0x0009
-              && cris_get_operand1 (insn_next) == regno)
-            {
-              /* move.S [r8+U],rZ */
-              continue;
-            }
-          else
-            {
-              /* The prologue ended before the limit was reached.  */
-              pc -= 4;
-              break;
-            }
-        }
+         pc += 2;
+         regno = cris_get_operand2 (insn_next);
+         if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch))
+             && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE
+             && cris_get_opcode (insn_next) == 0x0009
+             && cris_get_operand1 (insn_next) == regno)
+           {
+             /* move.S [r8+U],rZ */
+             continue;
+           }
+         else
+           {
+             /* The prologue ended before the limit was reached.  */
+             pc -= 4;
+             break;
+           }
+       }
       else
-        {
-          /* The prologue ended before the limit was reached.  */
-          pc -= 2;
-          break;
-        }
+       {
+         /* The prologue ended before the limit was reached.  */
+         pc -= 2;
+         break;
+       }
     }
 
   /* We only want to know the end of the prologue when this_frame and info
@@ -1243,21 +1227,21 @@ cris_scan_prologue (CORE_ADDR pc, struct frame_info *this_frame,
     {
       ULONGEST this_base;
       /* The SP was moved to the FP.  This indicates that a new frame
-         was created.  Get THIS frame's FP value by unwinding it from
-         the next frame.  */
+        was created.  Get THIS frame's FP value by unwinding it from
+        the next frame.  */
       this_base = get_frame_register_unsigned (this_frame, CRIS_FP_REGNUM);
       info->base = this_base;
-      info->saved_regs[CRIS_FP_REGNUM].addr = info->base;
+      info->saved_regs[CRIS_FP_REGNUM].set_addr (info->base);
   
       /* The FP points at the last saved register.  Adjust the FP back
-         to before the first saved register giving the SP.  */
+        to before the first saved register giving the SP.  */
       info->prev_sp = info->base + info->r8_offset;
     }
   else
     {
       ULONGEST this_base;      
       /* Assume that the FP is this frame's SP but with that pushed
-         stack space added back.  */
+        stack space added back.  */
       this_base = get_frame_register_unsigned (this_frame,
                                               gdbarch_sp_regnum (gdbarch));
       info->base = this_base;
@@ -1272,14 +1256,13 @@ cris_scan_prologue (CORE_ADDR pc, struct frame_info *this_frame,
 
   for (regno = regsave; regno >= 0; regno--)
     {
-      info->saved_regs[regno].addr = info->base + info->r8_offset - val;
+      info->saved_regs[regno].set_addr (info->base + info->r8_offset - val);
       val -= 4;
     }
 
   /* The previous frame's SP needed to be computed.  Save the computed
      value.  */
-  trad_frame_set_value (info->saved_regs,
-                       gdbarch_sp_regnum (gdbarch), info->prev_sp);
+  info->saved_regs[gdbarch_sp_regnum (gdbarch)].set_value (info->prev_sp);
 
   if (!info->leaf_function)
     {
@@ -1287,12 +1270,12 @@ cris_scan_prologue (CORE_ADDR pc, struct frame_info *this_frame,
       if (info->r8_offset == 0)
        {
          /* R8 not pushed yet.  */
-         info->saved_regs[SRP_REGNUM].addr = info->base;
+         info->saved_regs[SRP_REGNUM].set_addr (info->base);
        }
       else
        {
          /* R8 pushed, but SP may or may not be moved to R8 yet.  */
-         info->saved_regs[SRP_REGNUM].addr = info->base + 4;
+         info->saved_regs[SRP_REGNUM].set_addr (info->base + 4);
        }
     }
 
@@ -1304,7 +1287,7 @@ cris_scan_prologue (CORE_ADDR pc, struct frame_info *this_frame,
 }
 
 static CORE_ADDR 
-crisv32_scan_prologue (CORE_ADDR pc, struct frame_info *this_frame,
+crisv32_scan_prologue (CORE_ADDR pc, frame_info_ptr this_frame,
                    struct cris_unwind_cache *info)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -1351,7 +1334,7 @@ crisv32_scan_prologue (CORE_ADDR pc, struct frame_info *this_frame,
 static CORE_ADDR
 cris_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch);
   CORE_ADDR func_addr, func_end;
   struct symtab_and_line sal;
   CORE_ADDR pc_after_prologue;
@@ -1373,24 +1356,6 @@ cris_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
   return pc_after_prologue;
 }
 
-static CORE_ADDR
-cris_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  ULONGEST pc;
-  pc = frame_unwind_register_unsigned (next_frame,
-                                      gdbarch_pc_regnum (gdbarch));
-  return pc;
-}
-
-static CORE_ADDR
-cris_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  ULONGEST sp;
-  sp = frame_unwind_register_unsigned (next_frame,
-                                      gdbarch_sp_regnum (gdbarch));
-  return sp;
-}
-
 /* Implement the breakpoint_kind_from_pc gdbarch method.  */
 
 static int
@@ -1404,7 +1369,7 @@ cris_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
 static const gdb_byte *
 cris_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch);
   static unsigned char break8_insn[] = {0x38, 0xe9};
   static unsigned char break15_insn[] = {0x3f, 0xe9};
 
@@ -1423,7 +1388,7 @@ static int
 cris_spec_reg_applicable (struct gdbarch *gdbarch,
                          struct cris_spec_reg spec_reg)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch);
   unsigned int version = tdep->cris_version;
   
   switch (spec_reg.applicable_version)
@@ -1434,19 +1399,19 @@ cris_spec_reg_applicable (struct gdbarch *gdbarch,
       /* Indeterminate/obsolete.  */
       return 0;
     case cris_ver_v0_3:
-      return (version >= 0 && version <= 3);
+      return in_inclusive_range (version, 0U, 3U);
     case cris_ver_v3p:
       return (version >= 3);
     case cris_ver_v8:
-      return (version == 8 || version == 9);
+      return in_inclusive_range (version, 8U, 9U);
     case cris_ver_v8p:
       return (version >= 8);
     case cris_ver_v0_10:
-      return (version >= 0 && version <= 10);
+      return in_inclusive_range (version, 0U, 10U);
     case cris_ver_v3_10:
-      return (version >= 3 && version <= 10);
+      return in_inclusive_range (version, 3U, 10U);
     case cris_ver_v8_10:
-      return (version >= 8 && version <= 10);
+      return in_inclusive_range (version, 8U, 10U);
     case cris_ver_v10:
       return (version == 10);
     case cris_ver_v10p:
@@ -1476,16 +1441,16 @@ cris_register_size (struct gdbarch *gdbarch, int regno)
   else if (regno >= NUM_GENREGS && regno < (NUM_GENREGS + NUM_SPECREGS))
     {
       /* Special register (R16 - R31).  cris_spec_regs is zero-based. 
-         Adjust regno accordingly.  */
+        Adjust regno accordingly.  */
       spec_regno = regno - NUM_GENREGS;
       
       for (i = 0; cris_spec_regs[i].name != NULL; i++)
-        {
-          if (cris_spec_regs[i].number == spec_regno 
-              && cris_spec_reg_applicable (gdbarch, cris_spec_regs[i]))
-            /* Go with the first applicable register.  */
-            return cris_spec_regs[i].reg_size;
-        }
+       {
+         if (cris_spec_regs[i].number == spec_regno 
+             && cris_spec_reg_applicable (gdbarch, cris_spec_regs[i]))
+           /* Go with the first applicable register.  */
+           return cris_spec_regs[i].reg_size;
+       }
       /* Special register not applicable to this CRIS version.  */
       return 0;
     }
@@ -1508,7 +1473,7 @@ static int
 cris_cannot_fetch_register (struct gdbarch *gdbarch, int regno)
 {
   return ((regno < 0 || regno >= gdbarch_num_regs (gdbarch))
-          || (cris_register_size (gdbarch, regno) == 0));
+         || (cris_register_size (gdbarch, regno) == 0));
 }
 
 /* Nonzero if regno should not be written to the target, for various 
@@ -1549,7 +1514,7 @@ static int
 crisv32_cannot_fetch_register (struct gdbarch *gdbarch, int regno)
 {
   return ((regno < 0 || regno >= gdbarch_num_regs (gdbarch))
-          || (cris_register_size (gdbarch, regno) == 0));
+         || (cris_register_size (gdbarch, regno) == 0));
 }
 
 /* Nonzero if regno should not be written to the target, for various 
@@ -1643,10 +1608,10 @@ static void
 cris_store_return_value (struct type *type, struct regcache *regcache,
                         const gdb_byte *valbuf)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   ULONGEST val;
-  int len = TYPE_LENGTH (type);
+  int len = type->length ();
   
   if (len <= 4)
     {
@@ -1689,21 +1654,22 @@ cris_special_register_name (struct gdbarch *gdbarch, int regno)
        return cris_spec_regs[i].name;
     }
   /* Special register not applicable to this CRIS version.  */
-  return NULL;
+  return "";
 }
 
 static const char *
 cris_register_name (struct gdbarch *gdbarch, int regno)
 {
-  static char *cris_genreg_names[] =
+  static const char *cris_genreg_names[] =
   { "r0",  "r1",  "r2",  "r3", \
     "r4",  "r5",  "r6",  "r7", \
     "r8",  "r9",  "r10", "r11", \
     "r12", "r13", "sp",  "pc" };
 
-  if (regno >= 0 && regno < NUM_GENREGS)
+  if (regno < NUM_GENREGS)
     {
       /* General register.  */
+      gdb_static_assert (ARRAY_SIZE (cris_genreg_names) == NUM_GENREGS);
       return cris_genreg_names[regno];
     }
   else if (regno >= NUM_GENREGS && regno < gdbarch_num_regs (gdbarch))
@@ -1713,21 +1679,21 @@ cris_register_name (struct gdbarch *gdbarch, int regno)
   else
     {
       /* Invalid register.  */
-      return NULL;
+      return "";
     }
 }
 
 static const char *
 crisv32_register_name (struct gdbarch *gdbarch, int regno)
 {
-  static char *crisv32_genreg_names[] =
+  static const char *crisv32_genreg_names[] =
     { "r0",  "r1",  "r2",  "r3", \
       "r4",  "r5",  "r6",  "r7", \
       "r8",  "r9",  "r10", "r11", \
       "r12", "r13", "sp",  "acr"
     };
 
-  static char *crisv32_sreg_names[] =
+  static const char *crisv32_sreg_names[] =
     { "s0",  "s1",  "s2",  "s3", \
       "s4",  "s5",  "s6",  "s7", \
       "s8",  "s9",  "s10", "s11", \
@@ -1789,8 +1755,8 @@ cris_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 
 static void
 cris_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
-                            struct dwarf2_frame_state_reg *reg,
-                           struct frame_info *this_frame)
+                           struct dwarf2_frame_state_reg *reg,
+                           frame_info_ptr this_frame)
 {
   /* The return address column.  */
   if (regnum == gdbarch_pc_regnum (gdbarch))
@@ -1811,10 +1777,10 @@ static void
 cris_extract_return_value (struct type *type, struct regcache *regcache,
                           gdb_byte *valbuf)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   ULONGEST val;
-  int len = TYPE_LENGTH (type);
+  int len = type->length ();
   
   if (len <= 4)
     {
@@ -1841,9 +1807,9 @@ cris_return_value (struct gdbarch *gdbarch, struct value *function,
                   struct type *type, struct regcache *regcache,
                   gdb_byte *readbuf, const gdb_byte *writebuf)
 {
-  if (TYPE_CODE (type) == TYPE_CODE_STRUCT 
-      || TYPE_CODE (type) == TYPE_CODE_UNION
-      || TYPE_LENGTH (type) > 8)
+  if (type->code () == TYPE_CODE_STRUCT
+      || type->code () == TYPE_CODE_UNION
+      || type->length () > 8)
     /* Structs, unions, and anything larger than 8 bytes (2 registers)
        goes on the stack.  */
     return RETURN_VALUE_STRUCT_CONVENTION;
@@ -1861,7 +1827,7 @@ cris_return_value (struct gdbarch *gdbarch, struct value *function,
 
 static int
 constraint (unsigned int insn, const char *inst_args,
-            inst_env_type *inst_env)
+           inst_env_type *inst_env)
 {
   int retval = 0;
   int tmp, i;
@@ -1872,61 +1838,61 @@ constraint (unsigned int insn, const char *inst_args,
     switch (*s) 
       {
       case 'm':
-        if ((insn & 0x30) == 0x30)
-          return -1;
-        break;
-        
+       if ((insn & 0x30) == 0x30)
+         return -1;
+       break;
+       
       case 'S':
-        /* A prefix operand.  */
-        if (inst_env->prefix_found)
-          break;
-        else
-          return -1;
+       /* A prefix operand.  */
+       if (inst_env->prefix_found)
+         break;
+       else
+         return -1;
 
       case 'B':
-        /* A "push" prefix.  (This check was REMOVED by san 970921.)  Check for
-           valid "push" size.  In case of special register, it may be != 4.  */
-        if (inst_env->prefix_found)
-          break;
-        else
-          return -1;
+       /* A "push" prefix.  (This check was REMOVED by san 970921.)  Check for
+          valid "push" size.  In case of special register, it may be != 4.  */
+       if (inst_env->prefix_found)
+         break;
+       else
+         return -1;
 
       case 'D':
-        retval = (((insn >> 0xC) & 0xF) == (insn & 0xF));
-        if (!retval)
-          return -1;
-        else 
-          retval += 4;
-        break;
+       retval = (((insn >> 0xC) & 0xF) == (insn & 0xF));
+       if (!retval)
+         return -1;
+       else 
+         retval += 4;
+       break;
 
       case 'P':
-        tmp = (insn >> 0xC) & 0xF;
-
-        for (i = 0; cris_spec_regs[i].name != NULL; i++)
-          {
-            /* Since we match four bits, we will give a value of
-               4 - 1 = 3 in a match.  If there is a corresponding
-               exact match of a special register in another pattern, it
-               will get a value of 4, which will be higher.  This should
-               be correct in that an exact pattern would match better that
-               a general pattern.
-               Note that there is a reason for not returning zero; the
-               pattern for "clear" is partly  matched in the bit-pattern
-               (the two lower bits must be zero), while the bit-pattern
-               for a move from a special register is matched in the
-               register constraint.
-               This also means we will will have a race condition if
-               there is a partly match in three bits in the bit pattern.  */
-            if (tmp == cris_spec_regs[i].number)
-              {
-                retval += 3;
-                break;
-              }
-          }
-        
-        if (cris_spec_regs[i].name == NULL)
-          return -1;
-        break;
+       tmp = (insn >> 0xC) & 0xF;
+
+       for (i = 0; cris_spec_regs[i].name != NULL; i++)
+         {
+           /* Since we match four bits, we will give a value of
+              4 - 1 = 3 in a match.  If there is a corresponding
+              exact match of a special register in another pattern, it
+              will get a value of 4, which will be higher.  This should
+              be correct in that an exact pattern would match better that
+              a general pattern.
+              Note that there is a reason for not returning zero; the
+              pattern for "clear" is partly  matched in the bit-pattern
+              (the two lower bits must be zero), while the bit-pattern
+              for a move from a special register is matched in the
+              register constraint.
+              This also means we will will have a race condition if
+              there is a partly match in three bits in the bit pattern.  */
+           if (tmp == cris_spec_regs[i].number)
+             {
+               retval += 3;
+               break;
+             }
+         }
+       
+       if (cris_spec_regs[i].name == NULL)
+         return -1;
+       break;
       }
   return retval;
 }
@@ -1960,27 +1926,27 @@ find_cris_op (unsigned short insn, inst_env_type *inst_env)
   for (i = 0; cris_opcodes[i].name != NULL; i++)
     {
       if (((cris_opcodes[i].match & insn) == cris_opcodes[i].match) 
-          && ((cris_opcodes[i].lose & insn) == 0)
+         && ((cris_opcodes[i].lose & insn) == 0)
          /* Only CRISv10 instructions, please.  */
          && (cris_opcodes[i].applicable_version != cris_ver_v32p))
-        {
-          level_of_match = constraint (insn, cris_opcodes[i].args, inst_env);
-          if (level_of_match >= 0)
-            {
-              level_of_match +=
-                number_of_bits (cris_opcodes[i].match | cris_opcodes[i].lose);
-              if (level_of_match > max_level_of_match)
-                {
-                  max_matched = i;
-                  max_level_of_match = level_of_match;
-                  if (level_of_match == 16)
-                    {
-                      /* All bits matched, cannot find better.  */
-                      break;
-                    }
-                }
-            }
-        }
+       {
+         level_of_match = constraint (insn, cris_opcodes[i].args, inst_env);
+         if (level_of_match >= 0)
+           {
+             level_of_match +=
+               number_of_bits (cris_opcodes[i].match | cris_opcodes[i].lose);
+             if (level_of_match > max_level_of_match)
+               {
+                 max_matched = i;
+                 max_level_of_match = level_of_match;
+                 if (level_of_match == 16)
+                   {
+                     /* All bits matched, cannot find better.  */
+                     break;
+                   }
+               }
+           }
+       }
     }
   return max_matched;
 }
@@ -1994,7 +1960,7 @@ find_step_target (struct regcache *regcache, inst_env_type *inst_env)
   int i;
   int offset;
   unsigned short insn;
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
   /* Create a local register image and set the initial state.  */
@@ -2026,33 +1992,33 @@ find_step_target (struct regcache *regcache, inst_env_type *inst_env)
             (inst_env->reg[gdbarch_pc_regnum (gdbarch)], 2, byte_order);
 
       /* If the instruction is not in a delay slot the new content of the
-         PC is [PC] + 2.  If the instruction is in a delay slot it is not
-         that simple.  Since a instruction in a delay slot cannot change 
-         the content of the PC, it does not matter what value PC will have. 
-         Just make sure it is a valid instruction.  */
+        PC is [PC] + 2.  If the instruction is in a delay slot it is not
+        that simple.  Since a instruction in a delay slot cannot change 
+        the content of the PC, it does not matter what value PC will have. 
+        Just make sure it is a valid instruction.  */
       if (!inst_env->delay_slot_pc_active)
-        {
-          inst_env->reg[gdbarch_pc_regnum (gdbarch)] += 2;
-        }
+       {
+         inst_env->reg[gdbarch_pc_regnum (gdbarch)] += 2;
+       }
       else
-        {
-          inst_env->delay_slot_pc_active = 0;
-          inst_env->reg[gdbarch_pc_regnum (gdbarch)]
+       {
+         inst_env->delay_slot_pc_active = 0;
+         inst_env->reg[gdbarch_pc_regnum (gdbarch)]
            = inst_env->delay_slot_pc;
-        }
+       }
       /* Analyse the present instruction.  */
       i = find_cris_op (insn, inst_env);
       if (i == -1)
-        {
-          inst_env->invalid = 1;
-        }
+       {
+         inst_env->invalid = 1;
+       }
       else
-        {
-          cris_gdb_func (gdbarch, cris_opcodes[i].op, insn, inst_env);
-        }
+       {
+         cris_gdb_func (gdbarch, cris_opcodes[i].op, insn, inst_env);
+       }
     } while (!inst_env->invalid 
-             && (inst_env->prefix_found || inst_env->xflag_found 
-                 || inst_env->slot_needed));
+            && (inst_env->prefix_found || inst_env->xflag_found 
+                || inst_env->slot_needed));
   return i;
 }
 
@@ -2060,13 +2026,12 @@ find_step_target (struct regcache *regcache, inst_env_type *inst_env)
    digs through the opcodes in order to find all possible targets.
    Either one ordinary target or two targets for branches may be found.  */
 
-static VEC (CORE_ADDR) *
-cris_software_single_step (struct frame_info *frame)
+static std::vector<CORE_ADDR>
+cris_software_single_step (struct regcache *regcache)
 {
-  struct regcache *regcache = get_current_regcache ();
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   inst_env_type inst_env;
-  VEC (CORE_ADDR) *next_pcs = NULL;
+  std::vector<CORE_ADDR> next_pcs;
 
   /* Analyse the present instruction environment and insert 
      breakpoints.  */
@@ -2080,18 +2045,18 @@ cris_software_single_step (struct frame_info *frame)
   else
     {
       /* Insert at most two breakpoints.  One for the next PC content
-         and possibly another one for a branch, jump, etc.  */
+        and possibly another one for a branch, jump, etc.  */
       CORE_ADDR next_pc
        = (CORE_ADDR) inst_env.reg[gdbarch_pc_regnum (gdbarch)];
 
-      VEC_safe_push (CORE_ADDR, next_pcs, next_pc);
+      next_pcs.push_back (next_pc);
       if (inst_env.branch_found 
          && (CORE_ADDR) inst_env.branch_break_address != next_pc)
        {
          CORE_ADDR branch_target_address
                = (CORE_ADDR) inst_env.branch_break_address;
 
-         VEC_safe_push (CORE_ADDR, next_pcs, branch_target_address);
+         next_pcs.push_back (branch_target_address);
        }
     }
 
@@ -2132,11 +2097,11 @@ process_autoincrement (int size, unsigned short inst, inst_env_type *inst_env)
       inst_env->reg[cris_get_operand1 (inst)] += 1;
 
       /* The PC must be word aligned, so increase the PC with one
-         word even if the size is byte.  */
+        word even if the size is byte.  */
       if (cris_get_operand1 (inst) == REG_PC)
-        {
-          inst_env->reg[REG_PC] += 1;
-        }
+       {
+         inst_env->reg[REG_PC] += 1;
+       }
     }
   else if (size == INST_WORD_SIZE)
     {
@@ -2353,19 +2318,19 @@ abs_op (unsigned short inst, inst_env_type *inst_env)
     
       /* It's invalid to change to the PC if we are in a delay slot.  */
       if (inst_env->slot_needed)
-        {
-          inst_env->invalid = 1;
-          return;
-        }
+       {
+         inst_env->invalid = 1;
+         return;
+       }
 
       value = (long) inst_env->reg[REG_PC];
 
       /* The value of abs (SIGNED_DWORD_MASK) is SIGNED_DWORD_MASK.  */
       if (value != SIGNED_DWORD_MASK)
-        {
-          value = -value;
-          inst_env->reg[REG_PC] = (long) value;
-        }
+       {
+         value = -value;
+         inst_env->reg[REG_PC] = (long) value;
+       }
     }
 
   inst_env->slot_needed = 0;
@@ -2414,10 +2379,10 @@ asr_op (unsigned short inst, inst_env_type *inst_env)
     {
       /* It's invalid to change the PC in a delay slot.  */
       if (inst_env->slot_needed)
-        {
-          inst_env->invalid = 1;
-          return;
-        }
+       {
+         inst_env->invalid = 1;
+         return;
+       }
       /* Get the number of bits to shift.  */
       shift_steps
        = cris_get_asr_shift_steps (inst_env->reg[cris_get_operand1 (inst)]);
@@ -2425,45 +2390,45 @@ asr_op (unsigned short inst, inst_env_type *inst_env)
 
       /* Find out how many bits the operation should apply to.  */
       if (cris_get_size (inst) == INST_BYTE_SIZE)
-        {
-          if (value & SIGNED_BYTE_MASK)
-            {
-              signed_extend_mask = 0xFF;
-              signed_extend_mask = signed_extend_mask >> shift_steps;
-              signed_extend_mask = ~signed_extend_mask;
-            }
-          value = value >> shift_steps;
-          value |= signed_extend_mask;
-          value &= 0xFF;
-          inst_env->reg[REG_PC] &= 0xFFFFFF00;
-          inst_env->reg[REG_PC] |= value;
-        }
+       {
+         if (value & SIGNED_BYTE_MASK)
+           {
+             signed_extend_mask = 0xFF;
+             signed_extend_mask = signed_extend_mask >> shift_steps;
+             signed_extend_mask = ~signed_extend_mask;
+           }
+         value = value >> shift_steps;
+         value |= signed_extend_mask;
+         value &= 0xFF;
+         inst_env->reg[REG_PC] &= 0xFFFFFF00;
+         inst_env->reg[REG_PC] |= value;
+       }
       else if (cris_get_size (inst) == INST_WORD_SIZE)
-        {
-          if (value & SIGNED_WORD_MASK)
-            {
-              signed_extend_mask = 0xFFFF;
-              signed_extend_mask = signed_extend_mask >> shift_steps;
-              signed_extend_mask = ~signed_extend_mask;
-            }
-          value = value >> shift_steps;
-          value |= signed_extend_mask;
-          value &= 0xFFFF;
-          inst_env->reg[REG_PC] &= 0xFFFF0000;
-          inst_env->reg[REG_PC] |= value;
-        }
+       {
+         if (value & SIGNED_WORD_MASK)
+           {
+             signed_extend_mask = 0xFFFF;
+             signed_extend_mask = signed_extend_mask >> shift_steps;
+             signed_extend_mask = ~signed_extend_mask;
+           }
+         value = value >> shift_steps;
+         value |= signed_extend_mask;
+         value &= 0xFFFF;
+         inst_env->reg[REG_PC] &= 0xFFFF0000;
+         inst_env->reg[REG_PC] |= value;
+       }
       else if (cris_get_size (inst) == INST_DWORD_SIZE)
-        {
-          if (value & SIGNED_DWORD_MASK)
-            {
-              signed_extend_mask = 0xFFFFFFFF;
-              signed_extend_mask = signed_extend_mask >> shift_steps;
-              signed_extend_mask = ~signed_extend_mask;
-            }
-          value = value >> shift_steps;
-          value |= signed_extend_mask;
-          inst_env->reg[REG_PC]  = value;
-        }
+       {
+         if (value & SIGNED_DWORD_MASK)
+           {
+             signed_extend_mask = 0xFFFFFFFF;
+             signed_extend_mask = signed_extend_mask >> shift_steps;
+             signed_extend_mask = ~signed_extend_mask;
+           }
+         value = value >> shift_steps;
+         value |= signed_extend_mask;
+         inst_env->reg[REG_PC]  = value;
+       }
     }
   inst_env->slot_needed = 0;
   inst_env->prefix_found = 0;
@@ -2494,20 +2459,20 @@ asrq_op (unsigned short inst, inst_env_type *inst_env)
 
       /* It's invalid to change the PC in a delay slot.  */
       if (inst_env->slot_needed)
-        {
-          inst_env->invalid = 1;
-          return;
-        }
+       {
+         inst_env->invalid = 1;
+         return;
+       }
       /* The shift size is given as a 5 bit quick value, i.e. we don't
-         want the sign bit of the quick value.  */
+        want the sign bit of the quick value.  */
       shift_steps = cris_get_asr_shift_steps (inst);
       value = inst_env->reg[REG_PC];
       if (value & SIGNED_DWORD_MASK)
-        {
-          signed_extend_mask = 0xFFFFFFFF;
-          signed_extend_mask = signed_extend_mask >> shift_steps;
-          signed_extend_mask = ~signed_extend_mask;
-        }
+       {
+         signed_extend_mask = 0xFFFFFFFF;
+         signed_extend_mask = signed_extend_mask >> shift_steps;
+         signed_extend_mask = ~signed_extend_mask;
+       }
       value = value >> shift_steps;
       value |= signed_extend_mask;
       inst_env->reg[REG_PC]  = value;
@@ -2578,10 +2543,10 @@ two_operand_bound_op (unsigned short inst, inst_env_type *inst_env)
     {
       /* It's invalid to change the PC in a delay slot.  */
       if (inst_env->slot_needed)
-        {
-          inst_env->invalid = 1;
-          return;
-        }
+       {
+         inst_env->invalid = 1;
+         return;
+       }
       process_autoincrement (cris_get_size (inst), inst, inst_env);
     }
   inst_env->slot_needed = 0;
@@ -2655,19 +2620,19 @@ reg_mode_clear_op (unsigned short inst, inst_env_type *inst_env)
       /* The instruction will clear the instruction's size bits.  */
       int clear_size = cris_get_clear_size (inst);
       if (clear_size == INST_BYTE_SIZE)
-        {
-          inst_env->delay_slot_pc = inst_env->reg[REG_PC] & 0xFFFFFF00;
-        }
+       {
+         inst_env->delay_slot_pc = inst_env->reg[REG_PC] & 0xFFFFFF00;
+       }
       if (clear_size == INST_WORD_SIZE)
-        {
-          inst_env->delay_slot_pc = inst_env->reg[REG_PC] & 0xFFFF0000;
-        }
+       {
+         inst_env->delay_slot_pc = inst_env->reg[REG_PC] & 0xFFFF0000;
+       }
       if (clear_size == INST_DWORD_SIZE)
-        {
-          inst_env->delay_slot_pc = 0x0;
-        }
+       {
+         inst_env->delay_slot_pc = 0x0;
+       }
       /* The jump will be delayed with one delay slot.  So we need a delay 
-         slot.  */
+        slot.  */
       inst_env->slot_needed = 1;
       inst_env->delay_slot_pc_active = 1;
     }
@@ -2709,7 +2674,7 @@ none_reg_mode_clear_test_op (unsigned short inst, inst_env_type *inst_env)
   if (inst_env->prefix_found)
     {
       /* The only way the PC can change is if this instruction is in
-         assign addressing mode.  */
+        assign addressing mode.  */
       check_assign (inst, inst_env);
     }
   /* Indirect mode can't change the PC so just check if the mode is
@@ -2820,27 +2785,27 @@ none_reg_mode_jump_op (unsigned short inst, inst_env_type *inst_env)
     {
       /* Check if we have a prefix.  */
       if (inst_env->prefix_found)
-        {
-          check_assign (inst, inst_env);
-
-          /* Get the new value for the PC.  */
-          newpc = 
-            read_memory_unsigned_integer ((CORE_ADDR) inst_env->prefix_value,
-                                          4, inst_env->byte_order);
-        }
+       {
+         check_assign (inst, inst_env);
+
+         /* Get the new value for the PC.  */
+         newpc = 
+           read_memory_unsigned_integer ((CORE_ADDR) inst_env->prefix_value,
+                                         4, inst_env->byte_order);
+       }
       else
-        {
-          /* Get the new value for the PC.  */
-          address = (CORE_ADDR) inst_env->reg[cris_get_operand1 (inst)];
-          newpc = read_memory_unsigned_integer (address,
+       {
+         /* Get the new value for the PC.  */
+         address = (CORE_ADDR) inst_env->reg[cris_get_operand1 (inst)];
+         newpc = read_memory_unsigned_integer (address,
                                                4, inst_env->byte_order);
 
-          /* Check if we should increment a register.  */
-          if (cris_get_mode (inst) == AUTOINC_MODE)
-            {
-              inst_env->reg[cris_get_operand1 (inst)] += 4;
-            }
-        }
+         /* Check if we should increment a register.  */
+         if (cris_get_mode (inst) == AUTOINC_MODE)
+           {
+             inst_env->reg[cris_get_operand1 (inst)] += 4;
+           }
+       }
       inst_env->reg[REG_PC] = newpc;
     }
   inst_env->slot_needed = 0;
@@ -2858,45 +2823,45 @@ move_to_preg_op (struct gdbarch *gdbarch, unsigned short inst,
   if (inst_env->prefix_found)
     {
       /* The instruction has a prefix that means we are only interested if
-         the instruction is in assign mode.  */
+        the instruction is in assign mode.  */
       if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)
-        {
-          /* The prefix handles the problem if we are in a delay slot.  */
-          if (cris_get_operand1 (inst) == REG_PC)
-            {
-              /* Just take care of the assign.  */
-              check_assign (inst, inst_env);
-            }
-        }
+       {
+         /* The prefix handles the problem if we are in a delay slot.  */
+         if (cris_get_operand1 (inst) == REG_PC)
+           {
+             /* Just take care of the assign.  */
+             check_assign (inst, inst_env);
+           }
+       }
     }
   else if (cris_get_mode (inst) == AUTOINC_MODE)
     {
       /* The instruction doesn't have a prefix, the only case left that we
-         are interested in is the autoincrement mode.  */
+        are interested in is the autoincrement mode.  */
       if (cris_get_operand1 (inst) == REG_PC)
-        {
-          /* If the PC is to be incremented it's invalid to be in a 
-             delay slot.  */
-          if (inst_env->slot_needed)
-            {
-              inst_env->invalid = 1;
-              return;
-            }
-
-          /* The increment depends on the size of the special register.  */
-          if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 1)
-            {
-              process_autoincrement (INST_BYTE_SIZE, inst, inst_env);
-            }
-          else if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 2)
-            {
-              process_autoincrement (INST_WORD_SIZE, inst, inst_env);
-            }
-          else
-            {
-              process_autoincrement (INST_DWORD_SIZE, inst, inst_env);
-            }
-        }
+       {
+         /* If the PC is to be incremented it's invalid to be in a 
+            delay slot.  */
+         if (inst_env->slot_needed)
+           {
+             inst_env->invalid = 1;
+             return;
+           }
+
+         /* The increment depends on the size of the special register.  */
+         if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 1)
+           {
+             process_autoincrement (INST_BYTE_SIZE, inst, inst_env);
+           }
+         else if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 2)
+           {
+             process_autoincrement (INST_WORD_SIZE, inst, inst_env);
+           }
+         else
+           {
+             process_autoincrement (INST_DWORD_SIZE, inst, inst_env);
+           }
+       }
     }
   inst_env->slot_needed = 0;
   inst_env->prefix_found = 0;
@@ -2914,45 +2879,45 @@ none_reg_mode_move_from_preg_op (struct gdbarch *gdbarch, unsigned short inst,
   if (inst_env->prefix_found)
     {
       /* The instruction has a prefix that means we are only interested if
-         the instruction is in assign mode.  */
+        the instruction is in assign mode.  */
       if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)
-        {
-          /* The prefix handles the problem if we are in a delay slot.  */
-          if (cris_get_operand1 (inst) == REG_PC)
-            {
-              /* Just take care of the assign.  */
-              check_assign (inst, inst_env);
-            }
-        }
+       {
+         /* The prefix handles the problem if we are in a delay slot.  */
+         if (cris_get_operand1 (inst) == REG_PC)
+           {
+             /* Just take care of the assign.  */
+             check_assign (inst, inst_env);
+           }
+       }
     }    
   /* The instruction doesn't have a prefix, the only case left that we
      are interested in is the autoincrement mode.  */
   else if (cris_get_mode (inst) == AUTOINC_MODE)
     {
       if (cris_get_operand1 (inst) == REG_PC)
-        {
-          /* If the PC is to be incremented it's invalid to be in a 
-             delay slot.  */
-          if (inst_env->slot_needed)
-            {
-              inst_env->invalid = 1;
-              return;
-            }
-          
-          /* The increment depends on the size of the special register.  */
-          if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 1)
-            {
-              process_autoincrement (INST_BYTE_SIZE, inst, inst_env);
-            }
-          else if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 2)
-            {
-              process_autoincrement (INST_WORD_SIZE, inst, inst_env);
-            }
-          else
-            {
-              process_autoincrement (INST_DWORD_SIZE, inst, inst_env);
-            }
-        }
+       {
+         /* If the PC is to be incremented it's invalid to be in a 
+            delay slot.  */
+         if (inst_env->slot_needed)
+           {
+             inst_env->invalid = 1;
+             return;
+           }
+         
+         /* The increment depends on the size of the special register.  */
+         if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 1)
+           {
+             process_autoincrement (INST_BYTE_SIZE, inst, inst_env);
+           }
+         else if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 2)
+           {
+             process_autoincrement (INST_WORD_SIZE, inst, inst_env);
+           }
+         else
+           {
+             process_autoincrement (INST_DWORD_SIZE, inst, inst_env);
+           }
+       }
     }
   inst_env->slot_needed = 0;
   inst_env->prefix_found = 0;
@@ -2977,10 +2942,10 @@ reg_mode_move_from_preg_op (unsigned short inst, inst_env_type *inst_env)
     {
       /* It's invalid to change the PC in a delay slot.  */
       if (inst_env->slot_needed)
-        {
-          inst_env->invalid = 1;
-          return;
-        }
+       {
+         inst_env->invalid = 1;
+         return;
+       }
       /* The destination is the PC, the jump will have a delay slot.  */
       inst_env->delay_slot_pc = inst_env->preg[cris_get_operand2 (inst)];
       inst_env->slot_needed = 1;
@@ -3004,50 +2969,50 @@ move_mem_to_reg_movem_op (unsigned short inst, inst_env_type *inst_env)
   if (inst_env->prefix_found)
     {
       /* The prefix handles the problem if we are in a delay slot.  Is the
-         MOVEM instruction going to change the PC?  */
+        MOVEM instruction going to change the PC?  */
       if (cris_get_operand2 (inst) >= REG_PC)
-        {
-          inst_env->reg[REG_PC] = 
-            read_memory_unsigned_integer (inst_env->prefix_value,
+       {
+         inst_env->reg[REG_PC] = 
+           read_memory_unsigned_integer (inst_env->prefix_value,
                                          4, inst_env->byte_order);
-        }
+       }
       /* The assign value is the value after the increment.  Normally, the   
-         assign value is the value before the increment.  */
+        assign value is the value before the increment.  */
       if ((cris_get_operand1 (inst) == REG_PC) 
-          && (cris_get_mode (inst) == PREFIX_ASSIGN_MODE))
-        {
-          inst_env->reg[REG_PC] = inst_env->prefix_value;
-          inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
-        }
+         && (cris_get_mode (inst) == PREFIX_ASSIGN_MODE))
+       {
+         inst_env->reg[REG_PC] = inst_env->prefix_value;
+         inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
+       }
     }
   else
     {
       /* Is the MOVEM instruction going to change the PC?  */
       if (cris_get_operand2 (inst) == REG_PC)
-        {
-          /* It's invalid to change the PC in a delay slot.  */
-          if (inst_env->slot_needed)
-            {
-              inst_env->invalid = 1;
-              return;
-            }
-          inst_env->reg[REG_PC] =
-            read_memory_unsigned_integer (inst_env->reg[cris_get_operand1 (inst)], 
-                                          4, inst_env->byte_order);
-        }
+       {
+         /* It's invalid to change the PC in a delay slot.  */
+         if (inst_env->slot_needed)
+           {
+             inst_env->invalid = 1;
+             return;
+           }
+         inst_env->reg[REG_PC] =
+           read_memory_unsigned_integer (inst_env->reg[cris_get_operand1 (inst)], 
+                                         4, inst_env->byte_order);
+       }
       /* The increment is not depending on the size, instead it's depending
-         on the number of registers loaded from memory.  */
+        on the number of registers loaded from memory.  */
       if ((cris_get_operand1 (inst) == REG_PC)
          && (cris_get_mode (inst) == AUTOINC_MODE))
-        {
-          /* It's invalid to change the PC in a delay slot.  */
-          if (inst_env->slot_needed)
-            {
-              inst_env->invalid = 1;
-              return;
-            }
-          inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1); 
-        }
+       {
+         /* It's invalid to change the PC in a delay slot.  */
+         if (inst_env->slot_needed)
+           {
+             inst_env->invalid = 1;
+             return;
+           }
+         inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1); 
+       }
     }
   inst_env->slot_needed = 0;
   inst_env->prefix_found = 0;
@@ -3063,30 +3028,30 @@ move_reg_to_mem_movem_op (unsigned short inst, inst_env_type *inst_env)
   if (inst_env->prefix_found)
     {
       /* The assign value is the value after the increment.  Normally, the
-         assign value is the value before the increment.  */
+        assign value is the value before the increment.  */
       if ((cris_get_operand1 (inst) == REG_PC)
-          && (cris_get_mode (inst) == PREFIX_ASSIGN_MODE))
-        {
-          /* The prefix handles the problem if we are in a delay slot.  */
-          inst_env->reg[REG_PC] = inst_env->prefix_value;
-          inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
-        }
+         && (cris_get_mode (inst) == PREFIX_ASSIGN_MODE))
+       {
+         /* The prefix handles the problem if we are in a delay slot.  */
+         inst_env->reg[REG_PC] = inst_env->prefix_value;
+         inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
+       }
     }
   else
     {
       /* The increment is not depending on the size, instead it's depending
-         on the number of registers loaded to memory.  */
+        on the number of registers loaded to memory.  */
       if ((cris_get_operand1 (inst) == REG_PC)
          && (cris_get_mode (inst) == AUTOINC_MODE))
-        {
-          /* It's invalid to change the PC in a delay slot.  */
-          if (inst_env->slot_needed)
-            {
-              inst_env->invalid = 1;
-              return;
-            }
-          inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
-        }
+       {
+         /* It's invalid to change the PC in a delay slot.  */
+         if (inst_env->slot_needed)
+           {
+             inst_env->invalid = 1;
+             return;
+           }
+         inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
+       }
     }
   inst_env->slot_needed = 0;
   inst_env->prefix_found = 0;
@@ -3094,7 +3059,7 @@ move_reg_to_mem_movem_op (unsigned short inst, inst_env_type *inst_env)
   inst_env->disable_interrupt = 0;
 }
 
-/* Handles the intructions that's not yet implemented, by setting 
+/* Handles the instructions that's not yet implemented, by setting
    inst_env->invalid to true.  */
 
 static void 
@@ -3120,10 +3085,10 @@ xor_op (unsigned short inst, inst_env_type *inst_env)
     {
       /* It's invalid to change the PC in a delay slot.  */
       if (inst_env->slot_needed)
-        {
-          inst_env->invalid = 1;
-          return;
-        }
+       {
+         inst_env->invalid = 1;
+         return;
+       }
       inst_env->reg[REG_PC] ^= inst_env->reg[cris_get_operand1 (inst)];
     }
   inst_env->slot_needed = 0;
@@ -3185,7 +3150,7 @@ mulu_op (unsigned short inst, inst_env_type *inst_env)
 
 static void 
 add_sub_cmp_and_or_move_action (unsigned short inst, inst_env_type *inst_env, 
-                                unsigned long source1, unsigned long source2)
+                               unsigned long source1, unsigned long source2)
 {
   unsigned long pc_mask;
   unsigned long operation_mask;
@@ -3277,11 +3242,11 @@ do_sign_or_zero_extend (unsigned long value, unsigned short *inst)
       value &= 0xFFFF;
 
       /* Check if the instruction is signed extend.  If so, check if value has
-         the sign bit on.  */
+        the sign bit on.  */
       if (cris_is_signed_extend_bit_on (*inst) && (value & SIGNED_WORD_MASK))
-        {
-          value |= SIGNED_WORD_EXTEND_MASK;
-        
+       {
+         value |= SIGNED_WORD_EXTEND_MASK;
+       } 
     }
   else
     {
@@ -3289,11 +3254,11 @@ do_sign_or_zero_extend (unsigned long value, unsigned short *inst)
       value &= 0xFF;
 
       /* Check if the instruction is signed extend.  If so, check if value has
-         the sign bit on.  */
+        the sign bit on.  */
       if (cris_is_signed_extend_bit_on (*inst) && (value & SIGNED_BYTE_MASK))
-        {
-          value |= SIGNED_BYTE_EXTEND_MASK;
-        }
+       {
+         value |= SIGNED_BYTE_EXTEND_MASK;
+       }
     }
   /* The size should now be dword.  */
   cris_set_size_to_dword (inst);
@@ -3305,7 +3270,7 @@ do_sign_or_zero_extend (unsigned long value, unsigned short *inst)
 
 static void 
 reg_mode_add_sub_cmp_and_or_move_op (unsigned short inst,
-                                     inst_env_type *inst_env)
+                                    inst_env_type *inst_env)
 {
   unsigned long operand1;
   unsigned long operand2;
@@ -3321,21 +3286,21 @@ reg_mode_add_sub_cmp_and_or_move_op (unsigned short inst,
   if (cris_get_operand2 (inst) == REG_PC)
     {
       if (inst_env->slot_needed)
-        {
-          inst_env->invalid = 1;
-          return;
-        }
+       {
+         inst_env->invalid = 1;
+         return;
+       }
       /* The instruction has the PC as its target register.  */
       operand1 = inst_env->reg[cris_get_operand1 (inst)]; 
       operand2 = inst_env->reg[REG_PC];
 
       /* Check if it's a extend, signed or zero instruction.  */
       if (cris_get_opcode (inst) < 4)
-        {
-          operand1 = do_sign_or_zero_extend (operand1, &inst);
-        }
+       {
+         operand1 = do_sign_or_zero_extend (operand1, &inst);
+       }
       /* Calculate the PC value after the instruction, i.e. where the
-         breakpoint should be.  The order of the udw_operands is vital.  */
+        breakpoint should be.  The order of the udw_operands is vital.  */
       add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand1); 
     }
   inst_env->slot_needed = 0;
@@ -3379,7 +3344,7 @@ get_data_from_address (unsigned short *inst, CORE_ADDR address,
 
 static void 
 handle_prefix_assign_mode_for_aritm_op (unsigned short inst, 
-                                        inst_env_type *inst_env)
+                                       inst_env_type *inst_env)
 {
   unsigned long operand2;
   unsigned long operand3;
@@ -3394,7 +3359,7 @@ handle_prefix_assign_mode_for_aritm_op (unsigned short inst,
                                        inst_env->byte_order);
 
       /* Calculate the PC value after the instruction, i.e. where the
-         breakpoint should be.  The order of the udw_operands is vital.  */
+        breakpoint should be.  The order of the udw_operands is vital.  */
       add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand3);
     }
   inst_env->slot_needed = 0;
@@ -3409,7 +3374,7 @@ handle_prefix_assign_mode_for_aritm_op (unsigned short inst,
 
 static void 
 three_operand_add_sub_cmp_and_or_op (unsigned short inst, 
-                                     inst_env_type *inst_env)
+                                    inst_env_type *inst_env)
 {
   unsigned long operand2;
   unsigned long operand3;
@@ -3424,7 +3389,7 @@ three_operand_add_sub_cmp_and_or_op (unsigned short inst,
                                        inst_env->byte_order);
 
       /* Calculate the PC value after the instruction, i.e. where the
-         breakpoint should be.  */
+        breakpoint should be.  */
       add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand3);
     }
   inst_env->slot_needed = 0;
@@ -3438,20 +3403,20 @@ three_operand_add_sub_cmp_and_or_op (unsigned short inst,
 
 static void 
 handle_prefix_index_mode_for_aritm_op (unsigned short inst, 
-                                       inst_env_type *inst_env)
+                                      inst_env_type *inst_env)
 {
   if (cris_get_operand1 (inst) != cris_get_operand2 (inst))
     {
       /* If the instruction is MOVE it's invalid.  If the instruction is ADD,
-         SUB, AND or OR something weird is going on (if everything works these
-         instructions should end up in the three operand version).  */
+        SUB, AND or OR something weird is going on (if everything works these
+        instructions should end up in the three operand version).  */
       inst_env->invalid = 1;
       return;
     }
   else
     {
       /* three_operand_add_sub_cmp_and_or does the same as we should do here
-         so use it.  */
+        so use it.  */
       three_operand_add_sub_cmp_and_or_op (inst, inst_env);
     }
   inst_env->slot_needed = 0;
@@ -3466,7 +3431,7 @@ handle_prefix_index_mode_for_aritm_op (unsigned short inst,
 
 static void 
 handle_inc_and_index_mode_for_aritm_op (unsigned short inst, 
-                                        inst_env_type *inst_env)
+                                       inst_env_type *inst_env)
 {
   unsigned long operand1;
   unsigned long operand2;
@@ -3478,7 +3443,7 @@ handle_inc_and_index_mode_for_aritm_op (unsigned short inst,
   if (cris_get_operand2 (inst) == REG_PC)
     {
       /* Must be done here, get_data_from_address may change the size 
-         field.  */
+        field.  */
       size = cris_get_size (inst);
       operand2 = inst_env->reg[REG_PC];
 
@@ -3487,7 +3452,7 @@ handle_inc_and_index_mode_for_aritm_op (unsigned short inst,
       operand3 = get_data_from_address (&inst, operand1, inst_env->byte_order);
 
       /* Calculate the PC value after the instruction, i.e. where the
-         breakpoint should be.  The order of the udw_operands is vital.  */
+        breakpoint should be.  The order of the udw_operands is vital.  */
       add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand3); 
     }
   /* If this is an autoincrement addressing mode, check if the increment
@@ -3499,11 +3464,11 @@ handle_inc_and_index_mode_for_aritm_op (unsigned short inst,
       size = cris_get_size (inst);
 
       /* If it's an extend instruction we don't want the signed extend bit,
-         because it influences the size.  */
+        because it influences the size.  */
       if (cris_get_opcode (inst) < 4)
-        {
-          size &= ~SIGNED_EXTEND_BIT_MASK;
-        }
+       {
+         size &= ~SIGNED_EXTEND_BIT_MASK;
+       }
       process_autoincrement (size, inst, inst_env);
     } 
   inst_env->slot_needed = 0;
@@ -3517,24 +3482,24 @@ handle_inc_and_index_mode_for_aritm_op (unsigned short inst,
 
 static void 
 none_reg_mode_add_sub_cmp_and_or_move_op (unsigned short inst, 
-                                          inst_env_type *inst_env)
+                                         inst_env_type *inst_env)
 {
   if (inst_env->prefix_found)
     {
       if (cris_get_mode (inst) == PREFIX_INDEX_MODE)
-        {
-          handle_prefix_index_mode_for_aritm_op (inst, inst_env);
-        }
+       {
+         handle_prefix_index_mode_for_aritm_op (inst, inst_env);
+       }
       else if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)
-        {
-          handle_prefix_assign_mode_for_aritm_op (inst, inst_env);
-        }
+       {
+         handle_prefix_assign_mode_for_aritm_op (inst, inst_env);
+       }
       else
-        {
-          /* The mode is invalid for a prefixed base instruction.  */
-          inst_env->invalid = 1;
-          return;
-        }
+       {
+         /* The mode is invalid for a prefixed base instruction.  */
+         inst_env->invalid = 1;
+         return;
+       }
     }
   else
     {
@@ -3562,10 +3527,10 @@ quick_mode_add_sub_op (unsigned short inst, inst_env_type *inst_env)
   if (cris_get_operand2 (inst) == REG_PC)
     {
       if (inst_env->slot_needed)
-        {
-          inst_env->invalid = 1;
-          return;
-        }
+       {
+         inst_env->invalid = 1;
+         return;
+       }
       operand1 = cris_get_quick_value (inst);
       operand2 = inst_env->reg[REG_PC];
 
@@ -3573,7 +3538,7 @@ quick_mode_add_sub_op (unsigned short inst, inst_env_type *inst_env)
       cris_set_size_to_dword (&inst);
 
       /* Calculate the PC value after the instruction, i.e. where the
-         breakpoint should be.  */
+        breakpoint should be.  */
       add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand1);
     }
   inst_env->slot_needed = 0;
@@ -3601,25 +3566,25 @@ quick_mode_and_cmp_move_or_op (unsigned short inst, inst_env_type *inst_env)
   if (cris_get_operand2 (inst) == REG_PC)
     {
       if (inst_env->slot_needed)
-        {
-          inst_env->invalid = 1;
-          return;
-        }
+       {
+         inst_env->invalid = 1;
+         return;
+       }
       /* The instruction has the PC as its target register.  */
       operand1 = cris_get_quick_value (inst);
       operand2 = inst_env->reg[REG_PC];
 
       /* The quick value is signed, so check if we must do a signed extend.  */
       if (operand1 & SIGNED_QUICK_VALUE_MASK)
-        {
-          /* sign extend  */
-          operand1 |= SIGNED_QUICK_VALUE_EXTEND_MASK;
-        }
+       {
+         /* sign extend  */
+         operand1 |= SIGNED_QUICK_VALUE_EXTEND_MASK;
+       }
       /* The size should now be dword.  */
       cris_set_size_to_dword (&inst);
 
       /* Calculate the PC value after the instruction, i.e. where the
-         breakpoint should be.  */
+        breakpoint should be.  */
       add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand1);
     }
   inst_env->slot_needed = 0;
@@ -3786,22 +3751,6 @@ cris_gdb_func (struct gdbarch *gdbarch, enum cris_op_type op_type,
     }
 }
 
-/* This wrapper is to avoid cris_get_assembler being called before 
-   exec_bfd has been set.  */
-
-static int
-cris_delayed_get_disassembler (bfd_vma addr, struct disassemble_info *info)
-{
-  int (*print_insn) (bfd_vma addr, struct disassemble_info *info);
-  /* FIXME: cagney/2003-08-27: It should be possible to select a CRIS
-     disassembler, even when there is no BFD.  Does something like
-     "gdb; target remote; disassmeble *0x123" work?  */
-  gdb_assert (exec_bfd != NULL);
-  print_insn = cris_get_disassembler (exec_bfd);
-  gdb_assert (print_insn != NULL);
-  return print_insn (addr, info);
-}
-
 /* Originally from <asm/elf.h>.  */
 typedef unsigned char cris_elf_greg_t[4];
 
@@ -3815,78 +3764,61 @@ typedef cris_elf_greg_t crisv32_elf_gregset_t[CRISV32_ELF_NGREG];
 /* Unpack a cris_elf_gregset_t into GDB's register cache.  */
 
 static void 
-cris_supply_gregset (struct regcache *regcache, cris_elf_gregset_t *gregsetp)
+cris_supply_gregset (const struct regset *regset, struct regcache *regcache,
+                    int regnum, const void *gregs, size_t len)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  struct gdbarch *gdbarch = regcache->arch ();
+  cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch);
   int i;
-  cris_elf_greg_t *regp = *gregsetp;
+  const cris_elf_greg_t *regp = static_cast<const cris_elf_greg_t *>(gregs);
+
+  if (len != sizeof (cris_elf_gregset_t)
+      && len != sizeof (crisv32_elf_gregset_t))
+    warning (_("wrong size gregset struct in core file"));
+  gdb_assert (len >= sizeof (crisv32_elf_gregset_t));
 
   /* The kernel dumps all 32 registers as unsigned longs, but supply_register
      knows about the actual size of each register so that's no problem.  */
   for (i = 0; i < NUM_GENREGS + NUM_SPECREGS; i++)
     {
-      regcache_raw_supply (regcache, i, (char *)&regp[i]);
+      if (regnum == -1 || regnum == i)
+       regcache->raw_supply (i, (char *)&regp[i]);
     }
 
-  if (tdep->cris_version == 32)
+  if (tdep->cris_version == 32 && (regnum == -1 || regnum == ERP_REGNUM))
     {
       /* Needed to set pseudo-register PC for CRISv32.  */
       /* FIXME: If ERP is in a delay slot at this point then the PC will
         be wrong.  Issue a warning to alert the user.  */
-      regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch),
-                          (char *)&regp[ERP_REGNUM]);
+      regcache->raw_supply (gdbarch_pc_regnum (gdbarch),
+                           (char *)&regp[ERP_REGNUM]);
 
       if (*(char *)&regp[ERP_REGNUM] & 0x1)
-       fprintf_unfiltered (gdb_stderr, "Warning: PC in delay slot\n");
+       gdb_printf (gdb_stderr, "Warning: PC in delay slot\n");
     }
 }
 
-/*  Use a local version of this function to get the correct types for
-    regsets, until multi-arch core support is ready.  */
+static const struct regset cris_regset = {
+  nullptr,
+  cris_supply_gregset,
+  /* We don't need a collect function because we only use this for core files
+     (via iterate_over_regset_sections).  */
+  nullptr,
+  REGSET_VARIABLE_SIZE
+};
 
-static void
-fetch_core_registers (struct regcache *regcache,
-                     char *core_reg_sect, unsigned core_reg_size,
-                      int which, CORE_ADDR reg_addr)
+static void cris_iterate_over_regset_sections (struct gdbarch *gdbarch,
+                                              iterate_over_regset_sections_cb *cb,
+                                              void *cb_data,
+                                              const struct regcache *regcache)
 {
-  cris_elf_gregset_t gregset;
-
-  switch (which)
-    {
-    case 0:
-      if (core_reg_size != sizeof (cris_elf_gregset_t)
-         && core_reg_size != sizeof (crisv32_elf_gregset_t))
-        {
-          warning (_("wrong size gregset struct in core file"));
-        }
-      else
-        {
-          memcpy (&gregset, core_reg_sect, sizeof (gregset));
-          cris_supply_gregset (regcache, &gregset);
-        }
-
-    default:
-      /* We've covered all the kinds of registers we know about here,
-         so this must be something we wouldn't know what to do with
-         anyway.  Just ignore it.  */
-      break;
-    }
+  cb (".reg", sizeof (crisv32_elf_gregset_t), sizeof (crisv32_elf_gregset_t),
+      &cris_regset, NULL, cb_data);
 }
 
-static struct core_fns cris_elf_core_fns =
-{
-  bfd_target_elf_flavour,               /* core_flavour */
-  default_check_format,                 /* check_format */
-  default_core_sniffer,                 /* core_sniffer */
-  fetch_core_registers,                 /* core_read_registers */
-  NULL                                  /* next */
-};
-
-extern initialize_file_ftype _initialize_cris_tdep; /* -Wmissing-prototypes */
-
+void _initialize_cris_tdep ();
 void
-_initialize_cris_tdep (void)
+_initialize_cris_tdep ()
 {
   gdbarch_register (bfd_arch_cris, cris_gdbarch_init, cris_dump_tdep);
   
@@ -3923,8 +3855,6 @@ Makes GDB use the NRP register instead of the ERP register in certain cases."),
                           NULL, /* FIXME: i18n: Usage of Dwarf-2 CFI
                                    for CRIS is %d.  */
                           &setlist, &showlist);
-
-  deprecated_add_core_fns (&cris_elf_core_fns);
 }
 
 /* Prints out all target specific values.  */
@@ -3932,20 +3862,20 @@ Makes GDB use the NRP register instead of the ERP register in certain cases."),
 static void
 cris_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch);
   if (tdep != NULL)
     {
-      fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_version = %i\n",
-                          tdep->cris_version);
-      fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_mode = %s\n",
-                          tdep->cris_mode);
-      fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_dwarf2_cfi = %i\n",
-                          tdep->cris_dwarf2_cfi);
+      gdb_printf (file, "cris_dump_tdep: tdep->cris_version = %i\n",
+                 tdep->cris_version);
+      gdb_printf (file, "cris_dump_tdep: tdep->cris_mode = %s\n",
+                 tdep->cris_mode);
+      gdb_printf (file, "cris_dump_tdep: tdep->cris_dwarf2_cfi = %i\n",
+                 tdep->cris_dwarf2_cfi);
     }
 }
 
 static void
-set_cris_version (char *ignore_args, int from_tty, 
+set_cris_version (const char *ignore_args, int from_tty, 
                  struct cmd_list_element *c)
 {
   struct gdbarch_info info;
@@ -3953,43 +3883,35 @@ set_cris_version (char *ignore_args, int from_tty,
   usr_cmd_cris_version_valid = 1;
   
   /* Update the current architecture, if needed.  */
-  gdbarch_info_init (&info);
   if (!gdbarch_update_p (info))
-    internal_error (__FILE__, __LINE__, 
-                   _("cris_gdbarch_update: failed to update architecture."));
+    internal_error (_("cris_gdbarch_update: failed to update architecture."));
 }
 
 static void
-set_cris_mode (char *ignore_args, int from_tty, 
+set_cris_mode (const char *ignore_args, int from_tty, 
               struct cmd_list_element *c)
 {
   struct gdbarch_info info;
 
   /* Update the current architecture, if needed.  */
-  gdbarch_info_init (&info);
   if (!gdbarch_update_p (info))
-    internal_error (__FILE__, __LINE__, 
-                   "cris_gdbarch_update: failed to update architecture.");
+    internal_error ("cris_gdbarch_update: failed to update architecture.");
 }
 
 static void
-set_cris_dwarf2_cfi (char *ignore_args, int from_tty, 
+set_cris_dwarf2_cfi (const char *ignore_args, int from_tty, 
                     struct cmd_list_element *c)
 {
   struct gdbarch_info info;
 
   /* Update the current architecture, if needed.  */
-  gdbarch_info_init (&info);
   if (!gdbarch_update_p (info))
-    internal_error (__FILE__, __LINE__, 
-                   _("cris_gdbarch_update: failed to update architecture."));
+    internal_error (_("cris_gdbarch_update: failed to update architecture."));
 }
 
 static struct gdbarch *
 cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
-  struct gdbarch_tdep *tdep;
   unsigned int cris_version;
 
   if (usr_cmd_cris_version_valid)
@@ -4015,42 +3937,26 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        arches != NULL;
        arches = gdbarch_list_lookup_by_info (arches->next, &info))
     {
-      if ((gdbarch_tdep (arches->gdbarch)->cris_version 
-          == usr_cmd_cris_version)
-         && (gdbarch_tdep (arches->gdbarch)->cris_mode 
-          == usr_cmd_cris_mode)
-         && (gdbarch_tdep (arches->gdbarch)->cris_dwarf2_cfi 
-             == usr_cmd_cris_dwarf2_cfi))
-        return arches->gdbarch;
+      cris_gdbarch_tdep *tdep
+       = gdbarch_tdep<cris_gdbarch_tdep> (arches->gdbarch);
+
+      if (tdep->cris_version == usr_cmd_cris_version
+         && tdep->cris_mode == usr_cmd_cris_mode
+         && tdep->cris_dwarf2_cfi == usr_cmd_cris_dwarf2_cfi)
+       return arches->gdbarch;
     }
 
   /* No matching architecture was found.  Create a new one.  */
-  tdep = XNEW (struct gdbarch_tdep);
-  gdbarch = gdbarch_alloc (&info, tdep);
+  info.byte_order = BFD_ENDIAN_LITTLE;
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new cris_gdbarch_tdep));
+  cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch);
 
   tdep->cris_version = usr_cmd_cris_version;
   tdep->cris_mode = usr_cmd_cris_mode;
   tdep->cris_dwarf2_cfi = usr_cmd_cris_dwarf2_cfi;
 
-  /* INIT shall ensure that the INFO.BYTE_ORDER is non-zero.  */
-  switch (info.byte_order)
-    {
-    case BFD_ENDIAN_LITTLE:
-      /* Ok.  */
-      break;
-
-    case BFD_ENDIAN_BIG:
-      /* Cris is always little endian, but the user could have forced
-        big endian with "set endian".  */
-      return 0;
-
-    default:
-      internal_error (__FILE__, __LINE__,
-                     _("cris_gdbarch_init: unknown byte order in info"));
-    }
-
   set_gdbarch_return_value (gdbarch, cris_return_value);
-
   set_gdbarch_sp_regnum (gdbarch, 14);
   
   /* Length of ordinary registers used in push_word and a few other
@@ -4080,7 +3986,7 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     case 10:
     case 11: 
       /* CRIS v10 and v11, a.k.a. ETRAX 100LX.  In addition to ETRAX 100, 
-         P7 (32 bits), and P15 (32 bits) have been implemented.  */
+        P7 (32 bits), and P15 (32 bits) have been implemented.  */
       set_gdbarch_pc_regnum (gdbarch, 15);
       set_gdbarch_register_type (gdbarch, cris_register_type);
       /* There are 32 registers (some of which may not be implemented).  */
@@ -4131,11 +4037,8 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_breakpoint_kind_from_pc (gdbarch, cris_breakpoint_kind_from_pc);
   set_gdbarch_sw_breakpoint_from_kind (gdbarch, cris_sw_breakpoint_from_kind);
+  set_gdbarch_iterate_over_regset_sections (gdbarch, cris_iterate_over_regset_sections);
   
-  set_gdbarch_unwind_pc (gdbarch, cris_unwind_pc);
-  set_gdbarch_unwind_sp (gdbarch, cris_unwind_sp);
-  set_gdbarch_dummy_id (gdbarch, cris_dummy_id);
-
   if (tdep->cris_dwarf2_cfi == 1)
     {
       /* Hook in the Dwarf-2 frame sniffer.  */
@@ -4155,10 +4058,5 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
-  /* FIXME: cagney/2003-08-27: It should be possible to select a CRIS
-     disassembler, even when there is no BFD.  Does something like
-     "gdb; target remote; disassmeble *0x123" work?  */
-  set_gdbarch_print_insn (gdbarch, cris_delayed_get_disassembler);
-
   return gdbarch;
 }