OSDN Git Service

Update copyright year in most headers.
[pf3gnuchains/pf3gnuchains3x.git] / gdb / mep-tdep.c
index 0f1ec47..bd200c1 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for the Toshiba MeP for GDB, the GNU debugger.
 
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    Contributed by Red Hat, Inc.
@@ -9,7 +9,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -18,9 +18,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "frame.h"
@@ -48,7 +46,7 @@
 #include "elf-bfd.h"
 #include "elf/mep.h"
 #include "prologue-value.h"
-#include "opcode/cgen-bitset.h"
+#include "cgen/bitset.h"
 #include "infcall.h"
 
 #include "gdb_assert.h"
@@ -266,7 +264,7 @@ me_module_register_set (CONFIG_ATTR me_module,
        mask contains any of the me_module's coprocessor ISAs,
        specifically excluding the generic coprocessor register sets.  */
 
-  CGEN_CPU_DESC desc = gdbarch_tdep (current_gdbarch)->cpu_desc;
+  CGEN_CPU_DESC desc = gdbarch_tdep (target_gdbarch)->cpu_desc;
   const CGEN_HW_ENTRY *hw;
 
   if (me_module == CONFIG_NONE)
@@ -787,7 +785,7 @@ mep_init_pseudoregister_maps (void)
 
 
 static int
-mep_debug_reg_to_regnum (int debug_reg)
+mep_debug_reg_to_regnum (struct gdbarch *gdbarch, int debug_reg)
 {
   /* The debug info uses the raw register numbers.  */
   return mep_raw_to_pseudo[debug_reg];
@@ -852,12 +850,12 @@ current_me_module ()
   if (target_has_registers)
     {
       ULONGEST regval;
-      regcache_cooked_read_unsigned (current_regcache,
+      regcache_cooked_read_unsigned (get_current_regcache (),
                                     MEP_MODULE_REGNUM, &regval);
       return regval;
     }
   else
-    return gdbarch_tdep (current_gdbarch)->me_module;
+    return gdbarch_tdep (target_gdbarch)->me_module;
 }
 
 
@@ -875,7 +873,7 @@ current_options ()
   if (target_has_registers)
     {
       ULONGEST regval;
-      regcache_cooked_read_unsigned (current_regcache,
+      regcache_cooked_read_unsigned (get_current_regcache (),
                                     MEP_OPT_REGNUM, &regval);
       return regval;
     }
@@ -930,9 +928,9 @@ current_ccr_names ()
 
 
 static const char *
-mep_register_name (int regnr)
+mep_register_name (struct gdbarch *gdbarch, int regnr)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);  
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);  
 
   /* General-purpose registers.  */
   static const char *gpr_names[] = {
@@ -1033,7 +1031,7 @@ mep_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 {
   /* Filter reserved or unused register numbers.  */
   {
-    const char *name = mep_register_name (regnum);
+    const char *name = mep_register_name (gdbarch, regnum);
 
     if (! name || name[0] == '\0')
       return 0;
@@ -1086,7 +1084,7 @@ mep_register_type (struct gdbarch *gdbarch, int reg_nr)
      keep the 'g' packet format fixed), and the pseudoregisters vary
      in length.  */
   if (IS_RAW_CR_REGNUM (reg_nr))
-    return builtin_type_uint64;
+    return builtin_type (gdbarch)->builtin_uint64;
 
   /* Since GDB doesn't allow registers to change type, we have two
      banks of pseudoregisters for the coprocessor general-purpose
@@ -1099,16 +1097,16 @@ mep_register_type (struct gdbarch *gdbarch, int reg_nr)
       if (size == 32)
         {
           if (mep_pseudo_cr_is_float (reg_nr))
-            return builtin_type_float;
+            return builtin_type (gdbarch)->builtin_float;
           else
-            return builtin_type_uint32;
+            return builtin_type (gdbarch)->builtin_uint32;
         }
       else if (size == 64)
         {
           if (mep_pseudo_cr_is_float (reg_nr))
-            return builtin_type_double;
+            return builtin_type (gdbarch)->builtin_double;
           else
-            return builtin_type_uint64;
+            return builtin_type (gdbarch)->builtin_uint64;
         }
       else
         gdb_assert (0);
@@ -1116,36 +1114,22 @@ mep_register_type (struct gdbarch *gdbarch, int reg_nr)
 
   /* All other registers are 32 bits long.  */
   else
-    return builtin_type_uint32;
+    return builtin_type (gdbarch)->builtin_uint32;
 }
 
 
 static CORE_ADDR
-mep_read_pc (ptid_t ptid)
+mep_read_pc (struct regcache *regcache)
 {
-  ptid_t saved_ptid;
-  CORE_ADDR pc;
-
-  saved_ptid = inferior_ptid;
-  inferior_ptid = ptid;
-
-  pc = read_register (MEP_PC_REGNUM);
-
-  inferior_ptid = saved_ptid;
+  ULONGEST pc;
+  regcache_cooked_read_unsigned (regcache, MEP_PC_REGNUM, &pc);
   return pc;
 }
 
 static void
-mep_write_pc (CORE_ADDR pc, ptid_t ptid)
+mep_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
-  ptid_t saved_ptid;
-
-  saved_ptid = inferior_ptid;
-  inferior_ptid = ptid;
-
-  write_register (MEP_PC_REGNUM, pc);
-
-  inferior_ptid = saved_ptid;
+  regcache_cooked_write_unsigned (regcache, MEP_PC_REGNUM, pc);
 }
 
 
@@ -1155,6 +1139,7 @@ mep_pseudo_cr32_read (struct gdbarch *gdbarch,
                       int cookednum,
                       void *buf)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   /* Read the raw register into a 64-bit buffer, and then return the
      appropriate end of that buffer.  */
   int rawnum = mep_pseudo_to_raw[cookednum];
@@ -1164,7 +1149,8 @@ mep_pseudo_cr32_read (struct gdbarch *gdbarch,
   gdb_assert (TYPE_LENGTH (register_type (gdbarch, cookednum)) == 4);
   regcache_raw_read (regcache, rawnum, buf64);
   /* Slow, but legible.  */
-  store_unsigned_integer (buf, 4, extract_unsigned_integer (buf64, 8));
+  store_unsigned_integer (buf, 4, byte_order,
+                         extract_unsigned_integer (buf64, 8, byte_order));
 }
 
 
@@ -1204,6 +1190,7 @@ mep_pseudo_csr_write (struct gdbarch *gdbarch,
                       int cookednum,
                       const void *buf)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, cookednum);
   struct mep_csr_register *r
     = &mep_csr_registers[cookednum - MEP_FIRST_CSR_REGNUM];
@@ -1220,7 +1207,7 @@ mep_pseudo_csr_write (struct gdbarch *gdbarch,
       ULONGEST mixed_bits;
           
       regcache_raw_read_unsigned (regcache, r->raw, &old_bits);
-      new_bits = extract_unsigned_integer (buf, size);
+      new_bits = extract_unsigned_integer (buf, size, byte_order);
       mixed_bits = ((r->writeable_bits & new_bits)
                     | (~r->writeable_bits & old_bits));
       regcache_raw_write_unsigned (regcache, r->raw, mixed_bits);
@@ -1234,6 +1221,7 @@ mep_pseudo_cr32_write (struct gdbarch *gdbarch,
                        int cookednum,
                        const void *buf)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   /* Expand the 32-bit value into a 64-bit value, and write that to
      the pseudoregister.  */
   int rawnum = mep_pseudo_to_raw[cookednum];
@@ -1242,7 +1230,8 @@ mep_pseudo_cr32_write (struct gdbarch *gdbarch,
   gdb_assert (TYPE_LENGTH (register_type (gdbarch, rawnum)) == sizeof (buf64));
   gdb_assert (TYPE_LENGTH (register_type (gdbarch, cookednum)) == 4);
   /* Slow, but legible.  */
-  store_unsigned_integer (buf64, 8, extract_unsigned_integer (buf, 4));
+  store_unsigned_integer (buf64, 8, byte_order,
+                         extract_unsigned_integer (buf, 4, byte_order));
   regcache_raw_write (regcache, rawnum, buf64);
 }
 
@@ -1283,7 +1272,7 @@ mep_pseudo_register_write (struct gdbarch *gdbarch,
 
 /* The mep disassembler needs to know about the section in order to
    work correctly. */
-int 
+static int
 mep_gdb_print_insn (bfd_vma pc, disassemble_info * info)
 {
   struct obj_section * s = find_pc_section (pc);
@@ -1431,8 +1420,9 @@ mep_pc_in_vliw_section (CORE_ADDR pc)
    anyway.  */
 
 static CORE_ADDR 
-mep_get_insn (CORE_ADDR pc, long *insn)
+mep_get_insn (struct gdbarch *gdbarch, CORE_ADDR pc, long *insn)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int pc_in_vliw_section;
   int vliw_mode;
   int insn_len;
@@ -1469,7 +1459,7 @@ mep_get_insn (CORE_ADDR pc, long *insn)
     vliw_mode = 0;
 
   read_memory (pc, buf, sizeof (buf));
-  *insn = extract_unsigned_integer (buf, 2) << 16;
+  *insn = extract_unsigned_integer (buf, 2, byte_order) << 16;
 
   /* The major opcode --- the top four bits of the first 16-bit
      part --- indicates whether this instruction is 16 or 32 bits
@@ -1479,7 +1469,7 @@ mep_get_insn (CORE_ADDR pc, long *insn)
     {
       /* Fetch the second 16-bit part of the instruction.  */
       read_memory (pc + 2, buf, sizeof (buf));
-      *insn = *insn | extract_unsigned_integer (buf, 2);
+      *insn = *insn | extract_unsigned_integer (buf, 2, byte_order);
     }
 
   /* If we're in VLIW code, then the VLIW width determines the address
@@ -1592,10 +1582,17 @@ mep_get_insn (CORE_ADDR pc, long *insn)
 #define MOV_TARGET(i)        (FIELD (i, 24, 4))
 #define MOV_SOURCE(i)        (FIELD (i, 20, 4))
 
+/* BRA disp12.align2         1011_dddd_dddd_ddd0 xxxx_xxxx_xxxx_xxxx */
+#define IS_BRA(i)            (((i) & 0xf0010000) == 0xb0000000)
+#define BRA_DISP(i)           (SFIELD (i, 17, 11) << 1)
+
 
 /* This structure holds the results of a prologue analysis.  */
 struct mep_prologue
 {
+  /* The architecture for which we generated this prologue info.  */
+  struct gdbarch *gdbarch;
+
   /* The offset from the frame base to the stack pointer --- always
      zero or negative.
 
@@ -1647,11 +1644,12 @@ is_arg_reg (pv_t value)
    - ADDR is a stack slot's address (e.g., relative to the original
      value of the SP).  */
 static int
-is_arg_spill (pv_t value, pv_t addr, struct pv_area *stack)
+is_arg_spill (struct gdbarch *gdbarch, pv_t value, pv_t addr,
+             struct pv_area *stack)
 {
   return (is_arg_reg (value)
           && pv_is_register (addr, MEP_SP_REGNUM)
-          && ! pv_area_find_reg (stack, current_gdbarch, value.reg, 0));
+          && ! pv_area_find_reg (stack, gdbarch, value.reg, 0));
 }
 
 
@@ -1669,7 +1667,7 @@ check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, pv_t value)
   if (value.kind == pvk_register
       && value.k == 0
       && pv_is_register (addr, MEP_SP_REGNUM)
-      && size == register_size (current_gdbarch, value.reg))
+      && size == register_size (result->gdbarch, value.reg))
     result->reg_offset[value.reg] = addr.k;
 }
 
@@ -1677,7 +1675,8 @@ check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, pv_t value)
 /* Analyze a prologue starting at START_PC, going no further than
    LIMIT_PC.  Fill in RESULT as appropriate.  */
 static void
-mep_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
+mep_analyze_prologue (struct gdbarch *gdbarch,
+                     CORE_ADDR start_pc, CORE_ADDR limit_pc,
                       struct mep_prologue *result)
 {
   CORE_ADDR pc;
@@ -1690,6 +1689,7 @@ mep_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
   CORE_ADDR after_last_frame_setup_insn = start_pc;
 
   memset (result, 0, sizeof (*result));
+  result->gdbarch = gdbarch;
 
   for (rn = 0; rn < MEP_NUM_REGS; rn++)
     {
@@ -1697,7 +1697,7 @@ mep_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
       result->reg_offset[rn] = 1;
     }
 
-  stack = make_pv_area (MEP_SP_REGNUM);
+  stack = make_pv_area (MEP_SP_REGNUM, gdbarch_addr_bit (gdbarch));
   back_to = make_cleanup_free_pv_area (stack);
 
   pc = start_pc;
@@ -1706,7 +1706,7 @@ mep_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
       CORE_ADDR next_pc;
       pv_t pre_insn_fp, pre_insn_sp;
 
-      next_pc = mep_get_insn (pc, &insn);
+      next_pc = mep_get_insn (gdbarch, pc, &insn);
 
       /* A zero return from mep_get_insn means that either we weren't
          able to read the instruction from memory, or that we don't
@@ -1753,7 +1753,7 @@ mep_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
           if (pv_area_store_would_trash (stack, reg[rm]))
             break;
           
-          if (is_arg_spill (reg[rn], reg[rm], stack))
+          if (is_arg_spill (gdbarch, reg[rn], reg[rm], stack))
             after_last_frame_setup_insn = next_pc;
 
           pv_area_store (stack, reg[rm], 4, reg[rn]);
@@ -1770,7 +1770,7 @@ mep_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
           if (pv_area_store_would_trash (stack, addr))
             break;
 
-          if (is_arg_spill (reg[rn], addr, stack))
+          if (is_arg_spill (gdbarch, reg[rn], addr, stack))
             after_last_frame_setup_insn = next_pc;
 
           pv_area_store (stack, addr, 4, reg[rn]);
@@ -1799,7 +1799,7 @@ mep_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
           if (pv_area_store_would_trash (stack, addr))
             break;
 
-          if (is_arg_spill (reg[rn], addr, stack))
+          if (is_arg_spill (gdbarch, reg[rn], addr, stack))
             after_last_frame_setup_insn = next_pc;
 
           pv_area_store (stack, addr, size, reg[rn]);
@@ -1820,6 +1820,30 @@ mep_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
 
           reg[rn] = pv_area_fetch (stack, addr, 4);
         }
+      else if (IS_BRA (insn) && BRA_DISP (insn) > 0)
+       {
+         /* When a loop appears as the first statement of a function
+            body, gcc 4.x will use a BRA instruction to branch to the
+            loop condition checking code.  This BRA instruction is
+            marked as part of the prologue.  We therefore set next_pc
+            to this branch target and also stop the prologue scan. 
+            The instructions at and beyond the branch target should
+            no longer be associated with the prologue.
+            
+            Note that we only consider forward branches here.  We
+            presume that a forward branch is being used to skip over
+            a loop body.
+            
+            A backwards branch is covered by the default case below.
+            If we were to encounter a backwards branch, that would
+            most likely mean that we've scanned through a loop body.
+            We definitely want to stop the prologue scan when this
+            happens and that is precisely what is done by the default
+            case below.  */
+         next_pc = pc + BRA_DISP (insn);
+         after_last_frame_setup_insn = next_pc;
+         break;
+       }
       else
         /* We've hit some instruction we don't know how to simulate.
            Strictly speaking, we should set every value we're
@@ -1882,7 +1906,7 @@ mep_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
 
 
 static CORE_ADDR
-mep_skip_prologue (CORE_ADDR pc)
+mep_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   char *name;
   CORE_ADDR func_addr, func_end;
@@ -1892,7 +1916,7 @@ mep_skip_prologue (CORE_ADDR pc)
   if (! find_pc_partial_function (pc, &name, &func_addr, &func_end))
     return pc;
 
-  mep_analyze_prologue (pc, func_end, &p);
+  mep_analyze_prologue (gdbarch, pc, func_end, &p);
   return p.prologue_end;
 }
 
@@ -1901,7 +1925,7 @@ mep_skip_prologue (CORE_ADDR pc)
 /* Breakpoints.  */
 
 static const unsigned char *
-mep_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
+mep_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR * pcptr, int *lenptr)
 {
   static unsigned char breakpoint[] = { 0x70, 0x32 };
   *lenptr = sizeof (breakpoint);
@@ -1914,7 +1938,7 @@ mep_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
 
 
 static struct mep_prologue *
-mep_analyze_frame_prologue (struct frame_info *next_frame,
+mep_analyze_frame_prologue (struct frame_info *this_frame,
                             void **this_prologue_cache)
 {
   if (! *this_prologue_cache)
@@ -1924,15 +1948,16 @@ mep_analyze_frame_prologue (struct frame_info *next_frame,
       *this_prologue_cache 
         = FRAME_OBSTACK_ZALLOC (struct mep_prologue);
 
-      func_start = frame_func_unwind (next_frame, NORMAL_FRAME);
-      stop_addr = frame_pc_unwind (next_frame);
+      func_start = get_frame_func (this_frame);
+      stop_addr = get_frame_pc (this_frame);
 
       /* If we couldn't find any function containing the PC, then
          just initialize the prologue cache, but don't do anything.  */
       if (! func_start)
         stop_addr = func_start;
 
-      mep_analyze_prologue (func_start, stop_addr, *this_prologue_cache);
+      mep_analyze_prologue (get_frame_arch (this_frame),
+                           func_start, stop_addr, *this_prologue_cache);
     }
 
   return *this_prologue_cache;
@@ -1942,11 +1967,11 @@ mep_analyze_frame_prologue (struct frame_info *next_frame,
 /* Given the next frame and a prologue cache, return this frame's
    base.  */
 static CORE_ADDR
-mep_frame_base (struct frame_info *next_frame,
+mep_frame_base (struct frame_info *this_frame,
                 void **this_prologue_cache)
 {
   struct mep_prologue *p
-    = mep_analyze_frame_prologue (next_frame, this_prologue_cache);
+    = mep_analyze_frame_prologue (this_frame, this_prologue_cache);
 
   /* In functions that use alloca, the distance between the stack
      pointer and the frame base varies dynamically, so we can't use
@@ -1957,37 +1982,34 @@ mep_frame_base (struct frame_info *next_frame,
   if (p->has_frame_ptr)
     {
       CORE_ADDR fp
-        = frame_unwind_register_unsigned (next_frame, MEP_FP_REGNUM);
+        = get_frame_register_unsigned (this_frame, MEP_FP_REGNUM);
       return fp - p->frame_ptr_offset;
     }
   else
     {
       CORE_ADDR sp
-        = frame_unwind_register_unsigned (next_frame, MEP_SP_REGNUM);
+        = get_frame_register_unsigned (this_frame, MEP_SP_REGNUM);
       return sp - p->frame_size;
     }
 }
 
 
 static void
-mep_frame_this_id (struct frame_info *next_frame,
+mep_frame_this_id (struct frame_info *this_frame,
                    void **this_prologue_cache,
                    struct frame_id *this_id)
 {
-  *this_id = frame_id_build (mep_frame_base (next_frame, this_prologue_cache),
-                             frame_func_unwind (next_frame, NORMAL_FRAME));
+  *this_id = frame_id_build (mep_frame_base (this_frame, this_prologue_cache),
+                             get_frame_func (this_frame));
 }
 
 
-static void
-mep_frame_prev_register (struct frame_info *next_frame,
-                         void **this_prologue_cache,
-                         int regnum, int *optimizedp,
-                         enum lval_type *lvalp, CORE_ADDR *addrp,
-                         int *realnump, gdb_byte *bufferp)
+static struct value *
+mep_frame_prev_register (struct frame_info *this_frame,
+                         void **this_prologue_cache, int regnum)
 {
   struct mep_prologue *p
-    = mep_analyze_frame_prologue (next_frame, this_prologue_cache);
+    = mep_analyze_frame_prologue (this_frame, this_prologue_cache);
 
   /* There are a number of complications in unwinding registers on the
      MeP, having to do with core functions calling VLIW functions and
@@ -2009,68 +2031,59 @@ mep_frame_prev_register (struct frame_info *next_frame,
      do this.  */
   if (regnum == MEP_PC_REGNUM)
     {
-      mep_frame_prev_register (next_frame, this_prologue_cache, MEP_LP_REGNUM,
-                               optimizedp, lvalp, addrp, realnump, bufferp);
-      store_unsigned_integer (bufferp, MEP_LP_SIZE, 
-                              (extract_unsigned_integer (bufferp, MEP_LP_SIZE)
-                               & ~1));
-      *lvalp = not_lval;
+      struct value *value;
+      CORE_ADDR lp;
+      value = mep_frame_prev_register (this_frame, this_prologue_cache,
+                                      MEP_LP_REGNUM);
+      lp = value_as_long (value);
+      release_value (value);
+      value_free (value);
+
+      return frame_unwind_got_constant (this_frame, regnum, lp & ~1);
     }
   else
     {
-      CORE_ADDR frame_base = mep_frame_base (next_frame, this_prologue_cache);
-      int reg_size = register_size (get_frame_arch (next_frame), regnum);
+      CORE_ADDR frame_base = mep_frame_base (this_frame, this_prologue_cache);
+      struct value *value;
 
       /* Our caller's SP is our frame base.  */
       if (regnum == MEP_SP_REGNUM)
-        {
-          *optimizedp = 0;
-          *lvalp = not_lval;
-          *addrp = 0;
-          *realnump = -1;
-          if (bufferp)
-            store_unsigned_integer (bufferp, reg_size, frame_base);
-        }
+       return frame_unwind_got_constant (this_frame, regnum, frame_base);
 
       /* If prologue analysis says we saved this register somewhere,
          return a description of the stack slot holding it.  */
-      else if (p->reg_offset[regnum] != 1)
-        {
-          *optimizedp = 0;
-          *lvalp = lval_memory;
-          *addrp = frame_base + p->reg_offset[regnum];
-          *realnump = -1;
-          if (bufferp)
-            get_frame_memory (next_frame, *addrp, bufferp, reg_size);
-        }
+      if (p->reg_offset[regnum] != 1)
+       value = frame_unwind_got_memory (this_frame, regnum,
+                                        frame_base + p->reg_offset[regnum]);
 
       /* Otherwise, presume we haven't changed the value of this
          register, and get it from the next frame.  */
       else
-        frame_register_unwind (next_frame, regnum,
-                               optimizedp, lvalp, addrp, realnump, bufferp);
+       value = frame_unwind_got_register (this_frame, regnum, regnum);
 
       /* If we need to toggle the operating mode, do so.  */
       if (regnum == MEP_PSW_REGNUM)
         {
-          int lp_optimized;
-          enum lval_type lp_lval;
-          CORE_ADDR lp_addr;
-          int lp_realnum;
-          char lp_buffer[MEP_LP_SIZE];
+         CORE_ADDR psw, lp;
+
+         psw = value_as_long (value);
+         release_value (value);
+         value_free (value);
 
           /* Get the LP's value, too.  */
-          frame_register_unwind (next_frame, MEP_LP_REGNUM,
-                                 &lp_optimized, &lp_lval, &lp_addr,
-                                 &lp_realnum, lp_buffer);
+         value = get_frame_register_value (this_frame, MEP_LP_REGNUM);
+         lp = value_as_long (value);
+         release_value (value);
+         value_free (value);
 
           /* If LP.LTOM is set, then toggle PSW.OM.  */
-          if (extract_unsigned_integer (lp_buffer, MEP_LP_SIZE) & 0x1)
-            store_unsigned_integer
-              (bufferp, MEP_PSW_SIZE,
-               (extract_unsigned_integer (bufferp, MEP_PSW_SIZE) ^ 0x1000));
-          *lvalp = not_lval;
+         if (lp & 0x1)
+           psw ^= 0x1000;
+
+         return frame_unwind_got_constant (this_frame, regnum, psw);
         }
+
+      return value;
     }
 }
 
@@ -2078,17 +2091,12 @@ mep_frame_prev_register (struct frame_info *next_frame,
 static const struct frame_unwind mep_frame_unwind = {
   NORMAL_FRAME,
   mep_frame_this_id,
-  mep_frame_prev_register
+  mep_frame_prev_register,
+  NULL,
+  default_frame_sniffer
 };
 
 
-static const struct frame_unwind *
-mep_frame_sniffer (struct frame_info *next_frame)
-{
-  return &mep_frame_unwind;
-}
-
-
 /* Our general unwinding function can handle unwinding the PC.  */
 static CORE_ADDR
 mep_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
@@ -2182,10 +2190,10 @@ mep_store_return_value (struct gdbarch *arch,
            "Try using the 'return' command with no argument.");
 }
 
-enum return_value_convention
-mep_return_value (struct gdbarch *gdbarch, struct type *type,
-                 struct regcache *regcache, gdb_byte *readbuf,
-                 const gdb_byte *writebuf)
+static enum return_value_convention
+mep_return_value (struct gdbarch *gdbarch, struct type *func_type,
+                 struct type *type, struct regcache *regcache,
+                 gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   if (mep_use_struct_convention (type))
     {
@@ -2292,6 +2300,7 @@ mep_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                      int struct_return,
                      CORE_ADDR struct_addr)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR *copy = (CORE_ADDR *) alloca (argc * sizeof (copy[0]));
   CORE_ADDR func_addr = find_function_addr (function, NULL);
   int i;
@@ -2332,7 +2341,8 @@ mep_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       /* Arguments that fit in a GPR get expanded to fill the GPR.  */
       if (arg_size <= MEP_GPR_SIZE)
         value = extract_unsigned_integer (value_contents (argv[i]),
-                                          TYPE_LENGTH (value_type (argv[i])));
+                                          TYPE_LENGTH (value_type (argv[i])),
+                                         byte_order);
 
       /* Arguments too large to fit in a GPR get copied to the stack,
          and we pass a pointer to the copy.  */
@@ -2348,7 +2358,7 @@ mep_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       else
         {
           char buf[MEP_GPR_SIZE];
-          store_unsigned_integer (buf, MEP_GPR_SIZE, value);
+          store_unsigned_integer (buf, MEP_GPR_SIZE, byte_order, value);
           write_memory (arg_stack, buf, MEP_GPR_SIZE);
           arg_stack += MEP_GPR_SIZE;
         }
@@ -2367,10 +2377,10 @@ mep_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
 
 static struct frame_id
-mep_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+mep_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
-  return frame_id_build (mep_unwind_sp (gdbarch, next_frame),
-                         frame_pc_unwind (next_frame));
+  CORE_ADDR sp = get_frame_register_unsigned (this_frame, MEP_SP_REGNUM);
+  return frame_id_build (sp, get_frame_pc (this_frame));
 }
 
 
@@ -2488,7 +2498,7 @@ mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_skip_prologue (gdbarch, mep_skip_prologue);
 
   /* Frames and frame unwinding.  */
-  frame_unwind_append_sniffer (gdbarch, mep_frame_sniffer);
+  frame_unwind_append_unwinder (gdbarch, &mep_frame_unwind);
   set_gdbarch_unwind_pc (gdbarch, mep_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, mep_unwind_sp);
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
@@ -2500,11 +2510,13 @@ mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Inferior function calls.  */
   set_gdbarch_frame_align (gdbarch, mep_frame_align);
   set_gdbarch_push_dummy_call (gdbarch, mep_push_dummy_call);
-  set_gdbarch_unwind_dummy_id (gdbarch, mep_unwind_dummy_id);
+  set_gdbarch_dummy_id (gdbarch, mep_dummy_id);
 
   return gdbarch;
 }
 
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_mep_tdep;
 
 void
 _initialize_mep_tdep (void)