Use ".word 0x0012 # Entry mask: r1 r2 >" instead of just "Entry mask: < r1 ... >"
[deliverable/binutils-gdb.git] / gdb / h8300-tdep.c
index d15c43582be52898a7c8835bbcd4207ba2e53d10..2a83f03f0727eecd5ed8bce97e0228049a99b84a 100644 (file)
 #include "gdbcmd.h"
 #include "gdb_assert.h"
 #include "dis-asm.h"
+#include "dwarf2-frame.h"
+#include "frame.h"
+#include "frame-base.h"
+#include "frame-unwind.h"
 
 /* Extra info which is saved in each frame_info. */
 struct frame_extra_info
@@ -61,7 +65,7 @@ static int is_h8300_normal_mode (struct gdbarch *gdbarch);
 enum gdb_regnum
 {
   E_R0_REGNUM, E_ER0_REGNUM = E_R0_REGNUM, E_ARG0_REGNUM = E_R0_REGNUM,
-                                          E_RET0_REGNUM = E_R0_REGNUM,
+  E_RET0_REGNUM = E_R0_REGNUM,
   E_R1_REGNUM, E_ER1_REGNUM = E_R1_REGNUM, E_RET1_REGNUM = E_R1_REGNUM,
   E_R2_REGNUM, E_ER2_REGNUM = E_R2_REGNUM, E_ARGLAST_REGNUM = E_R2_REGNUM,
   E_R3_REGNUM, E_ER3_REGNUM = E_R3_REGNUM,
@@ -81,6 +85,8 @@ enum gdb_regnum
   E_VBR_REGNUM
 };
 
+#define H8300_MAX_NUM_REGS 18
+
 #define E_PSEUDO_CCR_REGNUM (NUM_REGS)
 #define E_PSEUDO_EXR_REGNUM (NUM_REGS+1)
 
@@ -112,83 +118,83 @@ h8300_is_argument_spill (CORE_ADDR pc)
 {
   int w = read_memory_unsigned_integer (pc, 2);
 
-  if (((w & 0xff88) == 0x0c88                 /* mov.b Rsl, Rdl */
-       || (w & 0xff88) == 0x0d00              /* mov.w Rs, Rd */
-       || (w & 0xff88) == 0x0f80)             /* mov.l Rs, Rd */
-      && (w & 0x70) <= 0x20                   /* Rs is R0, R1 or R2 */
-      && (w & 0x7) >= 0x3 && (w & 0x7) <= 0x5)/* Rd is R3, R4 or R5 */
+  if (((w & 0xff88) == 0x0c88  /* mov.b Rsl, Rdl */
+       || (w & 0xff88) == 0x0d00       /* mov.w Rs, Rd */
+       || (w & 0xff88) == 0x0f80)      /* mov.l Rs, Rd */
+      && (w & 0x70) <= 0x20    /* Rs is R0, R1 or R2 */
+      && (w & 0x7) >= 0x3 && (w & 0x7) <= 0x5) /* Rd is R3, R4 or R5 */
     return 2;
 
-  if ((w & 0xfff0) == 0x6ee0                  /* mov.b Rs,@(d:16,er6) */
-      && 8 <= (w & 0xf) && (w & 0xf) <= 10)   /* Rs is R0L, R1L, or R2L  */
+  if ((w & 0xfff0) == 0x6ee0   /* mov.b Rs,@(d:16,er6) */
+      && 8 <= (w & 0xf) && (w & 0xf) <= 10)    /* Rs is R0L, R1L, or R2L  */
     {
       int w2 = read_memory_integer (pc + 2, 2);
 
       /* ... and d:16 is negative.  */
       if (w2 < 0)
-        return 4;
+       return 4;
     }
   else if (w == 0x7860)
     {
       int w2 = read_memory_integer (pc + 2, 2);
 
-      if ((w2 & 0xfff0) == 0x6aa0)              /* mov.b Rs, @(d:24,er6) */
-        {
-          LONGEST disp = read_memory_integer (pc + 4, 4);
+      if ((w2 & 0xfff0) == 0x6aa0)     /* mov.b Rs, @(d:24,er6) */
+       {
+         LONGEST disp = read_memory_integer (pc + 4, 4);
 
-          /* ... and d:24 is negative.  */
-          if (disp < 0 && disp > 0xffffff)
-            return 8;
-        }
+         /* ... and d:24 is negative.  */
+         if (disp < 0 && disp > 0xffffff)
+           return 8;
+       }
     }
-  else if ((w & 0xfff0) == 0x6fe0             /* mov.w Rs,@(d:16,er6) */
-           && (w & 0xf) <= 2)                 /* Rs is R0, R1, or R2 */
+  else if ((w & 0xfff0) == 0x6fe0      /* mov.w Rs,@(d:16,er6) */
+          && (w & 0xf) <= 2)   /* Rs is R0, R1, or R2 */
     {
       int w2 = read_memory_integer (pc + 2, 2);
 
       /* ... and d:16 is negative.  */
       if (w2 < 0)
-        return 4;
+       return 4;
     }
   else if (w == 0x78e0)
     {
       int w2 = read_memory_integer (pc + 2, 2);
 
-      if ((w2 & 0xfff0) == 0x6ba0)              /* mov.b Rs, @(d:24,er6) */
-        {
-          LONGEST disp = read_memory_integer (pc + 4, 4);
+      if ((w2 & 0xfff0) == 0x6ba0)     /* mov.b Rs, @(d:24,er6) */
+       {
+         LONGEST disp = read_memory_integer (pc + 4, 4);
 
-          /* ... and d:24 is negative.  */
-          if (disp < 0 && disp > 0xffffff)
-            return 8;
-        }
+         /* ... and d:24 is negative.  */
+         if (disp < 0 && disp > 0xffffff)
+           return 8;
+       }
     }
   else if (w == 0x0100)
     {
       int w2 = read_memory_integer (pc + 2, 2);
 
-      if ((w2 & 0xfff0) == 0x6fe0             /* mov.l Rs,@(d:16,er6) */
-          && (w2 & 0xf) <= 2)                /* Rs is ER0, ER1, or ER2 */
-        {
-          int w3 = read_memory_integer (pc + 4, 2);
+      if ((w2 & 0xfff0) == 0x6fe0      /* mov.l Rs,@(d:16,er6) */
+         && (w2 & 0xf) <= 2)   /* Rs is ER0, ER1, or ER2 */
+       {
+         int w3 = read_memory_integer (pc + 4, 2);
 
-          /* ... and d:16 is negative.  */
-          if (w3 < 0)
-            return 6;
-        }
+         /* ... and d:16 is negative.  */
+         if (w3 < 0)
+           return 6;
+       }
       else if (w2 == 0x78e0)
-        {
-          int w3 = read_memory_integer (pc + 4, 2);
-
-          if ((w3 & 0xfff0) == 0x6ba0)          /* mov.l Rs, @(d:24,er6) */
-            {
-              LONGEST disp = read_memory_integer (pc + 6, 4);
-
-              /* ... and d:24 is negative.  */
-              if (disp < 0 && disp > 0xffffff)
-                return 10;
-            }
-        }
+       {
+         int w3 = read_memory_integer (pc + 4, 2);
+
+         if ((w3 & 0xfff0) == 0x6ba0)  /* mov.l Rs, @(d:24,er6) */
+           {
+             LONGEST disp = read_memory_integer (pc + 6, 4);
+
+             /* ... and d:24 is negative.  */
+             if (disp < 0 && disp > 0xffffff)
+               return 10;
+           }
+       }
     }
 
   return 0;
@@ -279,292 +285,397 @@ h8300_skip_prologue (CORE_ADDR start_pc)
     {
       int spill_size = h8300_is_argument_spill (start_pc);
       if (spill_size == 0)
-        break;
+       break;
       start_pc += spill_size;
     }
 
   return start_pc;
 }
 
-/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
-   is not the address of a valid instruction, the address of the next
-   instruction beyond ADDR otherwise.  *PWORD1 receives the first word
-   of the instruction. */
-
 static CORE_ADDR
-h8300_next_prologue_insn (CORE_ADDR addr, 
-                         CORE_ADDR lim, 
-                         unsigned short* pword1)
+h8300_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  char buf[2];
-  if (addr < lim + 8)
-    {
-      read_memory (addr, buf, 2);
-      *pword1 = extract_signed_integer (buf, 2);
+  char buf[8];
 
-      return addr + 2;
-    }
-  return 0;
+  frame_unwind_register (next_frame, E_PC_REGNUM, buf);
+  return extract_typed_address (buf, builtin_type_void_func_ptr);
 }
 
-/* Examine the prologue of a function.  `ip' points to the first instruction.
-   `limit' is the limit of the prologue (e.g. the addr of the first
-   linenumber, or perhaps the program counter if we're stepping through).
-   `frame_sp' is the stack pointer value in use in this frame.
-   `fsr' is a pointer to a frame_saved_regs structure into which we put
-   info about the registers saved by this frame.
-   `fi' is a struct frame_info pointer; we fill in various fields in it
-   to reflect the offsets of the arg pointer and the locals pointer.  */
-
-/* Any function with a frame looks like this
-   SECOND ARG
-   FIRST ARG
-   RET PC
-   SAVED R2
-   SAVED R3
-   SAVED FP   <-FP POINTS HERE
-   LOCALS0
-   LOCALS1    <-SP POINTS HERE
- */
+static struct frame_id
+h8300_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+  char buf[4];
+  CORE_ADDR fp;
 
-static CORE_ADDR
-h8300_examine_prologue (CORE_ADDR ip, CORE_ADDR limit,
-                       CORE_ADDR after_prolog_fp, CORE_ADDR *fsr,
-                       struct frame_info *fi)
+  frame_unwind_register (next_frame, E_FP_REGNUM, buf);
+  fp = extract_unsigned_integer (buf, 4);
+
+  return frame_id_build (fp, frame_pc_unwind (next_frame));
+}
+
+struct h8300_frame_cache
 {
-  CORE_ADDR next_ip;
-  int r;
-  int have_fp = 0;
-  unsigned short insn_word;
-  /* Number of things pushed onto stack, starts at 2/4, 'cause the
-     PC is already there */
-  unsigned int reg_save_depth = BINWORD;
+  /* Base address.  */
+  CORE_ADDR base;
+  CORE_ADDR sp_offset;
+  CORE_ADDR pc;
 
-  unsigned int auto_depth = 0; /* Number of bytes of autos */
+  /* Saved registers.  */
+  CORE_ADDR saved_regs[H8300_MAX_NUM_REGS];
+  CORE_ADDR saved_sp;
 
-  char in_frame[11];           /* One for each reg */
+  /* Stack space reserved for local variables.  */
+  long locals;
+};
 
-  int adjust = 0;
+/* Normal frames.  */
 
-  memset (in_frame, 1, 11);
-  for (r = 0; r < 8; r++)
-    {
-      fsr[r] = 0;
-    }
-  if (after_prolog_fp == 0)
-    {
-      after_prolog_fp = read_register (E_SP_REGNUM);
-    }
+/* Allocate and initialize a frame cache.  */
 
-  /* If the PC isn't valid, quit now.  */
-  if (ip == 0 || ip & (is_h8300hmode (current_gdbarch) &&
-                        !is_h8300_normal_mode (current_gdbarch) ? ~0xffffff : ~0xffff))
-    return 0;
+static struct h8300_frame_cache *
+h8300_alloc_frame_cache (void)
+{
+  struct h8300_frame_cache *cache;
+  int i;
 
-  next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
+  cache = FRAME_OBSTACK_ZALLOC (struct h8300_frame_cache);
 
-  if (insn_word == 0x0100)     /* mov.l */
-    {
-      insn_word = read_memory_unsigned_integer (ip + 2, 2);
-      adjust = 2;
-    }
+  /* Base address.  */
+  cache->base = 0;
+  cache->sp_offset = -4;
+  cache->pc = 0;
 
-  /* Skip over any fp push instructions */
-  fsr[E_FP_REGNUM] = after_prolog_fp;
-  while (next_ip && IS_PUSH_FP (insn_word))
-    {
-      ip = next_ip + adjust;
+  /* Saved registers.  We initialize these to -1 since zero is a valid
+     offset (that's where %fp is supposed to be stored).  */
+  for (i = 0; i < NUM_REGS; i++)
+    cache->saved_regs[i] = -1;
 
-      in_frame[insn_word & 0x7] = reg_save_depth;
-      next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
-      reg_save_depth += 2 + adjust;
-    }
+  /* Frameless until proven otherwise.  */
+  cache->locals = -1;
 
-  /* Is this a move into the fp */
-  if (next_ip && IS_MOV_SP_FP (insn_word))
-    {
-      ip = next_ip;
-      next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
-      have_fp = 1;
-    }
+  return cache;
+}
 
-  /* Skip over any stack adjustment, happens either with a number of
-     sub#2,sp or a mov #x,r5 sub r5,sp */
+/* Check whether PC points at a code that sets up a new stack frame.
+   If so, it updates CACHE and returns the address of the first
+   instruction after the sequence that sets removes the "hidden"
+   argument from the stack or CURRENT_PC, whichever is smaller.
+   Otherwise, return PC.  */
 
-  if (next_ip && (IS_SUB2_SP (insn_word) || IS_SUB4_SP (insn_word)))
-    {
-      while (next_ip && (IS_SUB2_SP (insn_word) || IS_SUB4_SP (insn_word)))
-       {
-         auto_depth += IS_SUB2_SP (insn_word) ? 2 : 4;
-         ip = next_ip;
-         next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
-       }
-    }
-  else
+static CORE_ADDR
+h8300_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc,
+                          struct h8300_frame_cache *cache)
+{
+  unsigned int op;
+  int subs_count;
+
+  if (pc >= current_pc)
+    return current_pc;
+
+  op = read_memory_unsigned_integer (pc, 4);
+
+  if (op == 0x6df60d76)
     {
-      if (next_ip && IS_MOVK_R5 (insn_word))
+      /* mov.w r6,@-sp; mov.w sp,r6 */
+      cache->saved_regs[E_FP_REGNUM] = 0;
+      cache->sp_offset += 2;
+      op = read_memory_unsigned_integer (pc + 4, 4);
+      if (((op >> 16) & 0xfff0) == 0x7900)
        {
-         ip = next_ip;
-         next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
-         auto_depth += insn_word;
-
-         next_ip = h8300_next_prologue_insn (next_ip, limit, &insn_word);
-         auto_depth += insn_word;
+         /* mov.w #imm,rN */
+         cache->locals = -(short) (op & 0xffff);
+         return pc + 8;
        }
-      if (next_ip && IS_SUBL_SP (insn_word))
+      else if ((op >> 16) == 0x1b87)
        {
-         ip = next_ip;
-         auto_depth += read_memory_unsigned_integer (ip, 4);
-         ip += 4;
-
-         next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
+         /* subs #2,sp */
+         for (cache->locals = 0, pc += 4;
+              read_memory_unsigned_integer (pc, 2) == 0x1b87;
+              pc += 2, cache->locals += 2);
+         return pc;
        }
     }
-
-  /* Now examine the push insns to determine where everything lives
-     on the stack.  */
-  while (1)
+  else if (op == 0x01006df6)
     {
-      adjust = 0;
-      if (!next_ip)
-       break;
-
-      if (insn_word == 0x0100)
+      /* mov.l er6,@-sp */
+      op = read_memory_unsigned_integer (pc + 4, 2);
+      if (op == 0x0ff6)
        {
-         ip = next_ip;
-         next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
-         adjust = 2;
+         /* mov.l sp,er6 */
+         op = read_memory_unsigned_integer (pc + 6, 2);
+         if (op == 0x7a17)
+           {
+             /* add.l #-n,sp */
+             cache->locals = -read_memory_unsigned_integer (pc + 8, 4);
+             return pc + 12;
+           }
+         else if (op == 0x1b97)
+           {
+             /* subs #4,sp */
+             for (cache->locals = 0, pc += 6;
+                  read_memory_unsigned_integer (pc, 2) == 0x1b97;
+                  pc += 2, cache->locals += 2);
+             return pc;
+           }
        }
+    }
 
-      if (IS_PUSH (insn_word))
-       {
-         auto_depth += 2 + adjust;
-         fsr[insn_word & 0x7] = after_prolog_fp - auto_depth;
-         ip = next_ip;
-         next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
-         continue;
-       }
+  return pc;
+}
 
-      /* Now check for push multiple insns.  */
-      if (insn_word == 0x0110 || insn_word == 0x0120 || insn_word == 0x0130)
-       {
-         int count = ((insn_word >> 4) & 0xf) + 1;
-         int start, i;
+/* Check whether PC points at code that saves registers on the stack.
+   If so, it updates CACHE and returns the address of the first
+   instruction after the register saves or CURRENT_PC, whichever is
+   smaller.  Otherwise, return PC.  */
 
-         ip = next_ip;
-         next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
-         start = insn_word & 0x7;
+static CORE_ADDR
+h8300_analyze_register_saves (CORE_ADDR pc, CORE_ADDR current_pc,
+                             struct h8300_frame_cache *cache)
+{
+  if (cache->locals >= 0)
+    {
+      CORE_ADDR offset;
+      int op;
+      int i, regno;
 
-         for (i = start; i < start + count; i++)
+      offset = -cache->locals;
+      while (pc < current_pc)
+       {
+         op = read_memory_unsigned_integer (pc, 2);
+         if ((op & 0xfff0) == 0x6df0)
            {
-             auto_depth += 4;
-             fsr[i] = after_prolog_fp - auto_depth;
+             /* mov.w rN,@-sp */
+             regno = op & 0x000f;
+             cache->saved_regs[regno] = offset;
+             offset -= 2;
+             pc += 2;
            }
+         else if (op == 0x0100)
+           {
+             op = read_memory_unsigned_integer (pc + 2, 2);
+             if ((op & 0xfff0) == 0x6df0)
+               {
+                 /* mov.l erN,@-sp */
+                 regno = op & 0x000f;
+                 cache->saved_regs[regno] = offset;
+                 offset -= 4;
+                 pc += 4;
+               }
+             else
+               break;
+           }
+         else if ((op & 0xffcf) == 0x0100)
+           {
+             int op1;
+             op1 = read_memory_unsigned_integer (pc + 2, 2);
+             if ((op1 & 0xfff0) == 0x6df0)
+               {
+                 /* stm.l reglist,@-sp */
+                 i = ((op & 0x0030) >> 4) + 1;
+                 regno = op1 & 0x000f;
+                 for (; i > 0; regno++, --i)
+                   {
+                     cache->saved_regs[regno] = offset;
+                     offset -= 4;
+                   }
+                 pc += 4;
+               }
+             else
+               break;
+           }
+         else
+           break;
        }
-      break;
     }
+  return pc;
+}
 
-  /* The PC is at a known place */
-  get_frame_extra_info (fi)->from_pc =
-    read_memory_unsigned_integer (after_prolog_fp + BINWORD, BINWORD);
 
-  /* Rememeber any others too */
-  in_frame[E_PC_REGNUM] = 0;
+/* Do a full analysis of the prologue at PC and update CACHE
+   accordingly.  Bail out early if CURRENT_PC is reached.  Return the
+   address where the analysis stopped.
 
-  if (have_fp)
-    /* We keep the old FP in the SP spot */
-    fsr[E_SP_REGNUM] = read_memory_unsigned_integer (fsr[E_FP_REGNUM], 
-                                                    BINWORD);
-  else
-    fsr[E_SP_REGNUM] = after_prolog_fp + auto_depth;
+   We handle all cases that can be generated by gcc.
 
-  return (ip);
-}
+   For allocating a stack frame:
 
-static void
-h8300_frame_init_saved_regs (struct frame_info *fi)
-{
-  CORE_ADDR func_addr, func_end;
+   mov.w r6,@-sp
+   mov.w sp,r6
+   mov.w #-n,rN
+   add.w rN,sp
 
-  if (!deprecated_get_frame_saved_regs (fi))
-    {
-      frame_saved_regs_zalloc (fi);
-
-      /* Find the beginning of this function, so we can analyze its
-        prologue. */
-      if (find_pc_partial_function (get_frame_pc (fi), NULL, 
-                                   &func_addr, &func_end))
-        {
-         struct symtab_and_line sal = find_pc_line (func_addr, 0);
-         CORE_ADDR limit = (sal.end && sal.end < get_frame_pc (fi)) 
-           ? sal.end : get_frame_pc (fi);
-         /* This will fill in fields in fi. */
-         h8300_examine_prologue (func_addr, limit, get_frame_base (fi),
-                                 deprecated_get_frame_saved_regs (fi), fi);
-       }
-      /* Else we're out of luck (can't debug completely stripped code). 
-        FIXME. */
-    }
-}
+   mov.w r6,@-sp
+   mov.w sp,r6
+   subs  #2,sp
+   (repeat)
+
+   mov.l er6,@-sp
+   mov.l sp,er6
+   add.l #-n,sp
+
+   mov.w r6,@-sp
+   mov.w sp,r6
+   subs  #4,sp
+   (repeat)
 
-/* Given a GDB frame, determine the address of the calling function's
-   frame.  This will be used to create a new GDB frame struct, and
-   then DEPRECATED_INIT_EXTRA_FRAME_INFO and DEPRECATED_INIT_FRAME_PC
-   will be called for the new frame.
+   For saving registers:
 
-   For us, the frame address is its stack pointer value, so we look up
-   the function prologue to determine the caller's sp value, and
-   return it.  */
+   mov.w rN,@-sp
+   mov.l erN,@-sp
+   stm.l reglist,@-sp
+
+   For setting up the PIC register:
+
+   Future equivalence...
+
+   */
 
 static CORE_ADDR
-h8300_frame_chain (struct frame_info *thisframe)
+h8300_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
+                       struct h8300_frame_cache *cache)
 {
-  if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (thisframe),
-                                  get_frame_base (thisframe),
-                                  get_frame_base (thisframe)))
-    {                          /* initialize the from_pc now */
-      get_frame_extra_info (thisframe)->from_pc =
-       deprecated_read_register_dummy (get_frame_pc (thisframe),
-                                       get_frame_base (thisframe),
-                                       E_PC_REGNUM);
-      return get_frame_base (thisframe);
-    }
-  return deprecated_get_frame_saved_regs (thisframe)[E_SP_REGNUM];
+  unsigned int op;
+
+  pc = h8300_analyze_frame_setup (pc, current_pc, cache);
+  pc = h8300_analyze_register_saves (pc, current_pc, cache);
+  if (pc >= current_pc)
+    return current_pc;
+
+  /* PIC support */
+
+  return pc;
 }
 
-/* Return the saved PC from this frame.
+static struct h8300_frame_cache *
+h8300_frame_cache (struct frame_info *next_frame, void **this_cache)
+{
+  struct h8300_frame_cache *cache;
+  char buf[4];
+  int i;
+
+  if (*this_cache)
+    return *this_cache;
+
+  cache = h8300_alloc_frame_cache ();
+  *this_cache = cache;
+
+  /* In principle, for normal frames, %fp holds the frame pointer,
+     which holds the base address for the current stack frame.
+     However, for functions that don't need it, the frame pointer is
+     optional.  For these "frameless" functions the frame pointer is
+     actually the frame pointer of the calling frame.  Signal
+     trampolines are just a special case of a "frameless" function.
+     They (usually) share their frame pointer with the frame that was
+     in progress when the signal occurred.  */
+
+  frame_unwind_register (next_frame, E_FP_REGNUM, buf);
+  cache->base = extract_unsigned_integer (buf, 4);
+  if (cache->base == 0)
+    return cache;
+
+  /* For normal frames, %pc is stored at 4(%fp).  */
+  cache->saved_regs[E_PC_REGNUM] = 4;
+
+  cache->pc = frame_func_unwind (next_frame);
+  if (cache->pc != 0)
+    h8300_analyze_prologue (cache->pc, frame_pc_unwind (next_frame), cache);
+
+  if (cache->locals < 0)
+    {
+      /* We didn't find a valid frame, which means that CACHE->base
+         currently holds the frame pointer for our calling frame.  If
+         we're at the start of a function, or somewhere half-way its
+         prologue, the function's frame probably hasn't been fully
+         setup yet.  Try to reconstruct the base address for the stack
+         frame by looking at the stack pointer.  For truly "frameless"
+         functions this might work too.  */
+
+      frame_unwind_register (next_frame, E_SP_REGNUM, buf);
+      cache->base = extract_unsigned_integer (buf, 4) + cache->sp_offset;
+    }
+
+  /* Now that we have the base address for the stack frame we can
+     calculate the value of %sp in the calling frame.  */
+  cache->saved_sp = cache->base;
 
-   If the frame has a memory copy of SRP_REGNUM, use that.  If not,
-   just use the register SRP_REGNUM itself.  */
+  /* Adjust all the saved registers such that they contain addresses
+     instead of offsets.  */
+  for (i = 0; i < NUM_REGS; i++)
+    if (cache->saved_regs[i] != -1)
+      cache->saved_regs[i] += cache->base;
 
-static CORE_ADDR
-h8300_frame_saved_pc (struct frame_info *frame)
+  return cache;
+}
+
+static void
+h8300_frame_this_id (struct frame_info *next_frame, void **this_cache,
+                    struct frame_id *this_id)
 {
-  if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame),
-                                  get_frame_base (frame),
-                                  get_frame_base (frame)))
-    return deprecated_read_register_dummy (get_frame_pc (frame),
-                                          get_frame_base (frame),
-                                          E_PC_REGNUM);
-  else
-    return get_frame_extra_info (frame)->from_pc;
+  struct h8300_frame_cache *cache =
+    h8300_frame_cache (next_frame, this_cache);
+
+  /* This marks the outermost frame.  */
+  if (cache->base == 0)
+    return;
+
+  /* See the end of m68k_push_dummy_call.  */
+  *this_id = frame_id_build (cache->base, cache->pc);
 }
 
 static void
-h8300_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+h8300_frame_prev_register (struct frame_info *next_frame, void **this_cache,
+                          int regnum, int *optimizedp,
+                          enum lval_type *lvalp, CORE_ADDR *addrp,
+                          int *realnump, void *valuep)
 {
-  if (!get_frame_extra_info (fi))
+  struct h8300_frame_cache *cache =
+    h8300_frame_cache (next_frame, this_cache);
+
+  gdb_assert (regnum >= 0);
+
+  if (regnum == E_SP_REGNUM && cache->saved_sp)
     {
-      frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
-      get_frame_extra_info (fi)->from_pc = 0;
-      
-      if (!get_frame_pc (fi))
-        {
-         if (get_next_frame (fi))
-           deprecated_update_frame_pc_hack (fi, h8300_frame_saved_pc (get_next_frame (fi)));
+      *optimizedp = 0;
+      *lvalp = not_lval;
+      *addrp = 0;
+      *realnump = -1;
+      if (valuep)
+       {
+         /* Store the value.  */
+         store_unsigned_integer (valuep, 4, cache->saved_sp);
+       }
+      return;
+    }
+
+  if (regnum < NUM_REGS && cache->saved_regs[regnum] != -1)
+    {
+      *optimizedp = 0;
+      *lvalp = lval_memory;
+      *addrp = cache->saved_regs[regnum];
+      *realnump = -1;
+      if (valuep)
+       {
+         /* Read the value in from memory.  */
+         read_memory (*addrp, valuep,
+                      register_size (current_gdbarch, regnum));
        }
-      h8300_frame_init_saved_regs (fi);
+      return;
     }
+
+  frame_register_unwind (next_frame, regnum,
+                        optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind h8300_frame_unwind = {
+  NORMAL_FRAME,
+  h8300_frame_this_id,
+  h8300_frame_prev_register
+};
+
+static const struct frame_unwind *
+h8300_frame_sniffer (struct frame_info *next_frame)
+{
+  return &h8300_frame_unwind;
 }
 
 /* Function: push_dummy_call
@@ -632,10 +743,10 @@ h8300_init_extra_frame_info (int fromleaf, struct frame_info *fi)
      to begin with.  */
 
 static CORE_ADDR
-h8300_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
-                      struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
-                      struct value **args, CORE_ADDR sp, int struct_return,
-                      CORE_ADDR struct_addr)
+h8300_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)
 {
   int stack_alloc = 0, stack_offset = 0;
   int wordsize = BINWORD;
@@ -648,8 +759,8 @@ h8300_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
   /* Now make sure there's space on the stack for the arguments.  We
      may over-allocate a little here, but that won't hurt anything.  */
   for (argument = 0; argument < nargs; argument++)
-    stack_alloc += align_up (TYPE_LENGTH (VALUE_TYPE (args[argument])),
-                             wordsize);
+    stack_alloc += align_up (TYPE_LENGTH (value_type (args[argument])),
+                            wordsize);
   sp -= stack_alloc;
 
   /* Now load as many arguments as possible into registers, and push
@@ -662,9 +773,9 @@ h8300_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
 
   for (argument = 0; argument < nargs; argument++)
     {
-      struct type *type = VALUE_TYPE (args[argument]);
+      struct type *type = value_type (args[argument]);
       int len = TYPE_LENGTH (type);
-      char *contents = (char *) VALUE_CONTENTS (args[argument]);
+      char *contents = (char *) value_contents (args[argument]);
 
       /* Pad the argument appropriately.  */
       int padded_len = align_up (len, wordsize);
@@ -672,50 +783,50 @@ h8300_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
 
       memset (padded, 0, padded_len);
       memcpy (len < wordsize ? padded + padded_len - len : padded,
-              contents, len);
+             contents, len);
 
       /* Could the argument fit in the remaining registers?  */
       if (padded_len <= (E_ARGLAST_REGNUM - reg + 1) * wordsize)
-        {
-          /* Are we going to pass it on the stack anyway, for no good
-             reason?  */
-          if (len > wordsize && len % wordsize)
-            {
-              /* I feel so unclean.  */
-              write_memory (sp + stack_offset, padded, padded_len);
-              stack_offset += padded_len;
-
-              /* That's right --- even though we passed the argument
-                 on the stack, we consume the registers anyway!  Love
-                 me, love my dog.  */
-              reg += padded_len / wordsize;
-            }
-          else
-            {
-              /* Heavens to Betsy --- it's really going in registers!
-                 It would be nice if we could use write_register_bytes
-                 here, but on the h8/300s, there are gaps between
-                 the registers in the register file.  */
-              int offset;
-
-              for (offset = 0; offset < padded_len; offset += wordsize)
-                {
-                  ULONGEST word = extract_unsigned_integer (padded + offset, 
+       {
+         /* Are we going to pass it on the stack anyway, for no good
+            reason?  */
+         if (len > wordsize && len % wordsize)
+           {
+             /* I feel so unclean.  */
+             write_memory (sp + stack_offset, padded, padded_len);
+             stack_offset += padded_len;
+
+             /* That's right --- even though we passed the argument
+                on the stack, we consume the registers anyway!  Love
+                me, love my dog.  */
+             reg += padded_len / wordsize;
+           }
+         else
+           {
+             /* Heavens to Betsy --- it's really going in registers!
+                It would be nice if we could use write_register_bytes
+                here, but on the h8/300s, there are gaps between
+                the registers in the register file.  */
+             int offset;
+
+             for (offset = 0; offset < padded_len; offset += wordsize)
+               {
+                 ULONGEST word = extract_unsigned_integer (padded + offset,
                                                            wordsize);
                  regcache_cooked_write_unsigned (regcache, reg++, word);
-                }
-            }
-        }
+               }
+           }
+       }
       else
-        {
-          /* It doesn't fit in registers!  Onto the stack it goes.  */
-          write_memory (sp + stack_offset, padded, padded_len);
-          stack_offset += padded_len;
-
-          /* Once one argument has spilled onto the stack, all
-             subsequent arguments go on the stack.  */
-          reg = E_ARGLAST_REGNUM + 1;
-        }
+       {
+         /* It doesn't fit in registers!  Onto the stack it goes.  */
+         write_memory (sp + stack_offset, padded, padded_len);
+         stack_offset += padded_len;
+
+         /* Once one argument has spilled onto the stack, all
+            subsequent arguments go on the stack.  */
+         reg = E_ARGLAST_REGNUM + 1;
+       }
     }
 
   /* Store return address.  */
@@ -728,43 +839,6 @@ h8300_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
   return sp;
 }
 
-/* Function: h8300_pop_frame
-   Restore the machine to the state it had before the current frame 
-   was created.  Usually used either by the "RETURN" command, or by
-   call_function_by_hand after the dummy_frame is finished. */
-
-static void
-h8300_pop_frame (void)
-{
-  unsigned regno;
-  struct frame_info *frame = get_current_frame ();
-
-  if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame),
-                                  get_frame_base (frame),
-                                  get_frame_base (frame)))
-    {
-      generic_pop_dummy_frame ();
-    }
-  else
-    {
-      for (regno = 0; regno < 8; regno++)
-       {
-         /* Don't forget E_SP_REGNUM is a frame_saved_regs struct is the
-            actual value we want, not the address of the value we want.  */
-         if (deprecated_get_frame_saved_regs (frame)[regno] && regno != E_SP_REGNUM)
-           write_register (regno,
-                           read_memory_integer 
-                           (deprecated_get_frame_saved_regs (frame)[regno], BINWORD));
-         else if (deprecated_get_frame_saved_regs (frame)[regno] && regno == E_SP_REGNUM)
-           write_register (regno, get_frame_base (frame) + 2 * BINWORD);
-       }
-
-      /* Don't forget to update the PC too!  */
-      write_register (E_PC_REGNUM, get_frame_extra_info (frame)->from_pc);
-    }
-  flush_cached_frames ();
-}
-
 /* Function: extract_return_value
    Figure out where in REGBUF the called function has left its return value.
    Copy that into VALBUF.  Be sure to account for CPU type.   */
@@ -778,59 +852,59 @@ h8300_extract_return_value (struct type *type, struct regcache *regcache,
 
   switch (len)
     {
-      case 1:
-      case 2:
-       regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
-       store_unsigned_integer (valbuf, len, c);
-       break;
-      case 4:  /* Needs two registers on plain H8/300 */
-       regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
-       store_unsigned_integer (valbuf, 2, c);
-       regcache_cooked_read_unsigned (regcache, E_RET1_REGNUM, &c);
-       store_unsigned_integer ((void*)((char *)valbuf + 2), 2, c);
-       break;
-      case 8:  /* long long is now 8 bytes.  */
-       if (TYPE_CODE (type) == TYPE_CODE_INT)
-         {
-           regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
-           c = read_memory_unsigned_integer ((CORE_ADDR) addr, len);
-           store_unsigned_integer (valbuf, len, c);
-         }
-       else
-         {
-           error ("I don't know how this 8 byte value is returned.");
-         }
-       break;
+    case 1:
+    case 2:
+      regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
+      store_unsigned_integer (valbuf, len, c);
+      break;
+    case 4:                    /* Needs two registers on plain H8/300 */
+      regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
+      store_unsigned_integer (valbuf, 2, c);
+      regcache_cooked_read_unsigned (regcache, E_RET1_REGNUM, &c);
+      store_unsigned_integer ((void *) ((char *) valbuf + 2), 2, c);
+      break;
+    case 8:                    /* long long is now 8 bytes.  */
+      if (TYPE_CODE (type) == TYPE_CODE_INT)
+       {
+         regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
+         c = read_memory_unsigned_integer ((CORE_ADDR) addr, len);
+         store_unsigned_integer (valbuf, len, c);
+       }
+      else
+       {
+         error ("I don't know how this 8 byte value is returned.");
+       }
+      break;
     }
 }
 
 static void
 h8300h_extract_return_value (struct type *type, struct regcache *regcache,
-                           void *valbuf)
+                            void *valbuf)
 {
   int len = TYPE_LENGTH (type);
   ULONGEST c, addr;
 
   switch (len)
     {
-      case 1:
-      case 2:
-      case 4:
-       regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
-       store_unsigned_integer (valbuf, len, c);
-       break;
-      case 8:  /* long long is now 8 bytes.  */
-       if (TYPE_CODE (type) == TYPE_CODE_INT)
-         {
-           regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
-           c = read_memory_unsigned_integer ((CORE_ADDR) addr, len);
-           store_unsigned_integer (valbuf, len, c);
-         }
-       else
-         {
-           error ("I don't know how this 8 byte value is returned.");
-         }
-       break;
+    case 1:
+    case 2:
+    case 4:
+      regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
+      store_unsigned_integer (valbuf, len, c);
+      break;
+    case 8:                    /* long long is now 8 bytes.  */
+      if (TYPE_CODE (type) == TYPE_CODE_INT)
+       {
+         regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
+         c = read_memory_unsigned_integer ((CORE_ADDR) addr, len);
+         store_unsigned_integer (valbuf, len, c);
+       }
+      else
+       {
+         error ("I don't know how this 8 byte value is returned.");
+       }
+      break;
     }
 }
 
@@ -848,21 +922,21 @@ h8300_store_return_value (struct type *type, struct regcache *regcache,
 
   switch (len)
     {
-      case 1:
-    case 2:    /* short... */
-       val = extract_unsigned_integer (valbuf, len);
-       regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val);
-       break;
-      case 4:  /* long, float */
-       val = extract_unsigned_integer (valbuf, len);
-       regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM,
-                                       (val >> 16) &0xffff);
-       regcache_cooked_write_unsigned (regcache, E_RET1_REGNUM, val & 0xffff);
-       break;
-      case 8:  /* long long, double and long double are all defined
-                  as 4 byte types so far so this shouldn't happen.  */
-       error ("I don't know how to return an 8 byte value.");
-       break;
+    case 1:
+    case 2:                    /* short... */
+      val = extract_unsigned_integer (valbuf, len);
+      regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val);
+      break;
+    case 4:                    /* long, float */
+      val = extract_unsigned_integer (valbuf, len);
+      regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM,
+                                     (val >> 16) & 0xffff);
+      regcache_cooked_write_unsigned (regcache, E_RET1_REGNUM, val & 0xffff);
+      break;
+    case 8:                    /* long long, double and long double are all defined
+                                  as 4 byte types so far so this shouldn't happen.  */
+      error ("I don't know how to return an 8 byte value.");
+      break;
     }
 }
 
@@ -875,16 +949,16 @@ h8300h_store_return_value (struct type *type, struct regcache *regcache,
 
   switch (len)
     {
-      case 1:
-      case 2:
-      case 4:  /* long, float */
-       val = extract_unsigned_integer (valbuf, len);
-       regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val);
-       break;
-      case 8:  /* long long, double and long double are all defined
-                  as 4 byte types so far so this shouldn't happen.  */
-       error ("I don't know how to return an 8 byte value.");
-       break;
+    case 1:
+    case 2:
+    case 4:                    /* long, float */
+      val = extract_unsigned_integer (valbuf, len);
+      regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val);
+      break;
+    case 8:                    /* long long, double and long double are all defined
+                                  as 4 byte types so far so this shouldn't happen.  */
+      error ("I don't know how to return an 8 byte value.");
+      break;
     }
 }
 
@@ -897,13 +971,13 @@ h8300_register_name (int regno)
      type is selected. */
   static char *register_names[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6",
-    "sp", "","pc","cycles", "tick", "inst",
-    "ccr", /* pseudo register */
+    "sp", "", "pc", "cycles", "tick", "inst",
+    "ccr",                     /* pseudo register */
   };
   if (regno < 0
       || regno >= (sizeof (register_names) / sizeof (*register_names)))
     internal_error (__FILE__, __LINE__,
-                    "h8300_register_name: illegal register number %d", regno);
+                   "h8300_register_name: illegal register number %d", regno);
   else
     return register_names[regno];
 }
@@ -915,12 +989,13 @@ h8300s_register_name (int regno)
     "er0", "er1", "er2", "er3", "er4", "er5", "er6",
     "sp", "", "pc", "cycles", "", "tick", "inst",
     "mach", "macl",
-    "ccr", "exr" /* pseudo registers */
+    "ccr", "exr"               /* pseudo registers */
   };
   if (regno < 0
       || regno >= (sizeof (register_names) / sizeof (*register_names)))
     internal_error (__FILE__, __LINE__,
-                    "h8300s_register_name: illegal register number %d", regno);
+                   "h8300s_register_name: illegal register number %d",
+                   regno);
   else
     return register_names[regno];
 }
@@ -932,12 +1007,13 @@ h8300sx_register_name (int regno)
     "er0", "er1", "er2", "er3", "er4", "er5", "er6",
     "sp", "", "pc", "cycles", "", "tick", "inst",
     "mach", "macl", "sbr", "vbr",
-    "ccr", "exr" /* pseudo registers */
+    "ccr", "exr"               /* pseudo registers */
   };
   if (regno < 0
       || regno >= (sizeof (register_names) / sizeof (*register_names)))
     internal_error (__FILE__, __LINE__,
-                   "h8300sx_register_name: illegal register number %d", regno);
+                   "h8300sx_register_name: illegal register number %d",
+                   regno);
   else
     return register_names[regno];
 }
@@ -955,15 +1031,15 @@ h8300_print_register (struct gdbarch *gdbarch, struct ui_file *file,
   rval = get_frame_register_signed (frame, regno);
 
   fprintf_filtered (file, "%-14s ", name);
-  if (regno == E_PSEUDO_CCR_REGNUM ||
-       (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch)))
+  if ((regno == E_PSEUDO_CCR_REGNUM) || \
+      (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch)))
     {
-      fprintf_filtered (file, "0x%02x        ", (unsigned char)rval);
+      fprintf_filtered (file, "0x%02x        ", (unsigned char) rval);
       print_longest (file, 'u', 1, rval);
     }
   else
     {
-      fprintf_filtered (file, "0x%s  ", phex ((ULONGEST)rval, BINWORD));
+      fprintf_filtered (file, "0x%s  ", phex ((ULONGEST) rval, BINWORD));
       print_longest (file, 'd', 1, rval);
     }
   if (regno == E_PSEUDO_CCR_REGNUM)
@@ -1029,7 +1105,7 @@ h8300_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
       h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
       h8300_print_register (gdbarch, file, frame, E_PC_REGNUM);
       if (is_h8300smode (current_gdbarch))
-        {
+       {
          h8300_print_register (gdbarch, file, frame, E_PSEUDO_EXR_REGNUM);
          if (is_h8300sxmode (current_gdbarch))
            {
@@ -1043,7 +1119,7 @@ h8300_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
          h8300_print_register (gdbarch, file, frame, E_INSTS_REGNUM);
        }
       else
-        {
+       {
          h8300_print_register (gdbarch, file, frame, E_CYCLES_REGNUM);
          h8300_print_register (gdbarch, file, frame, E_TICK_REGNUM);
          h8300_print_register (gdbarch, file, frame, E_INST_REGNUM);
@@ -1052,52 +1128,46 @@ h8300_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
   else
     {
       if (regno == E_CCR_REGNUM)
-        h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
-      else if (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch))
+       h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
+      else if (regno == E_PSEUDO_EXR_REGNUM
+              && is_h8300smode (current_gdbarch))
        h8300_print_register (gdbarch, file, frame, E_PSEUDO_EXR_REGNUM);
       else
        h8300_print_register (gdbarch, file, frame, regno);
     }
 }
 
-static CORE_ADDR
-h8300_saved_pc_after_call (struct frame_info *ignore)
-{
-  return read_memory_unsigned_integer (read_register (E_SP_REGNUM), BINWORD);
-}
-
 static struct type *
 h8300_register_type (struct gdbarch *gdbarch, int regno)
 {
   if (regno < 0 || regno >= NUM_REGS + NUM_PSEUDO_REGS)
     internal_error (__FILE__, __LINE__,
-                   "h8300_register_type: illegal register number %d",
-                   regno);
+                   "h8300_register_type: illegal register number %d", regno);
   else
     {
       switch (regno)
-        {
-         case E_PC_REGNUM:
-           return builtin_type_void_func_ptr;
-         case E_SP_REGNUM:
-         case E_FP_REGNUM:
-           return builtin_type_void_data_ptr;
-         default:
-           if (regno == E_PSEUDO_CCR_REGNUM)
-             return builtin_type_uint8;
-           else if (regno == E_PSEUDO_EXR_REGNUM)
-             return builtin_type_uint8;
-           else if (is_h8300hmode (current_gdbarch))
-             return builtin_type_int32;
-           else
-             return builtin_type_int16;
-        }
+       {
+       case E_PC_REGNUM:
+         return builtin_type_void_func_ptr;
+       case E_SP_REGNUM:
+       case E_FP_REGNUM:
+         return builtin_type_void_data_ptr;
+       default:
+         if (regno == E_PSEUDO_CCR_REGNUM)
+           return builtin_type_uint8;
+         else if (regno == E_PSEUDO_EXR_REGNUM)
+           return builtin_type_uint8;
+         else if (is_h8300hmode (current_gdbarch))
+           return builtin_type_int32;
+         else
+           return builtin_type_int16;
+       }
     }
 }
 
 static void
-h8300_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
-                           int regno, void *buf)
+h8300_pseudo_register_read (struct gdbarch *gdbarch,
+                           struct regcache *regcache, int regno, void *buf)
 {
   if (regno == E_PSEUDO_CCR_REGNUM)
     regcache_raw_read (regcache, E_CCR_REGNUM, buf);
@@ -1108,8 +1178,9 @@ h8300_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 }
 
 static void
-h8300_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
-                            int regno, const void *buf)
+h8300_pseudo_register_write (struct gdbarch *gdbarch,
+                            struct regcache *regcache, int regno,
+                            const void *buf)
 {
   if (regno == E_PSEUDO_CCR_REGNUM)
     regcache_raw_write (regcache, E_CCR_REGNUM, buf);
@@ -1148,8 +1219,8 @@ h8300_extract_struct_value_address (struct regcache *regcache)
 const static unsigned char *
 h8300_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
 {
-  /*static unsigned char breakpoint[] = { 0x7A, 0xFF };*/      /* ??? */
-  static unsigned char breakpoint[] = { 0x01, 0x80 };          /* Sleep */
+  /*static unsigned char breakpoint[] = { 0x7A, 0xFF }; *//* ??? */
+  static unsigned char breakpoint[] = { 0x01, 0x80 };  /* Sleep */
 
   *lenptr = sizeof (breakpoint);
   return breakpoint;
@@ -1223,16 +1294,16 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
       set_gdbarch_stab_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
       set_gdbarch_register_name (gdbarch, h8300_register_name);
-      if(info.bfd_arch_info->mach != bfd_mach_h8300hn)
-        {
-          set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
-          set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
-        }
+      if (info.bfd_arch_info->mach != bfd_mach_h8300hn)
+       {
+         set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+         set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+       }
       else
-        {
-          set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
-          set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
-        }
+       {
+         set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+         set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+       }
       set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
       set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
       set_gdbarch_print_insn (gdbarch, print_insn_h8300h);
@@ -1246,16 +1317,16 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
       set_gdbarch_stab_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
       set_gdbarch_register_name (gdbarch, h8300s_register_name);
-      if(info.bfd_arch_info->mach != bfd_mach_h8300sn)
-        {
-          set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
-          set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
-        }
+      if (info.bfd_arch_info->mach != bfd_mach_h8300sn)
+       {
+         set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+         set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+       }
       else
-        {
-          set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
-          set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
-        }
+       {
+         set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+         set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+       }
       set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
       set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
       set_gdbarch_print_insn (gdbarch, print_insn_h8300s);
@@ -1269,16 +1340,16 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
       set_gdbarch_stab_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
       set_gdbarch_register_name (gdbarch, h8300sx_register_name);
-      if(info.bfd_arch_info->mach != bfd_mach_h8300sxn)
-        {
-          set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
-          set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
-        }
+      if (info.bfd_arch_info->mach != bfd_mach_h8300sxn)
+       {
+         set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+         set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+       }
       else
-        {
-          set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
-          set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
-        }
+       {
+         set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+         set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+       }
       set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
       set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
       set_gdbarch_print_insn (gdbarch, print_insn_h8300s);
@@ -1288,10 +1359,6 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_pseudo_register_read (gdbarch, h8300_pseudo_register_read);
   set_gdbarch_pseudo_register_write (gdbarch, h8300_pseudo_register_write);
 
-  /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
-     ready to unwind the PC first (see frame.c:get_prev_frame()).  */
-  set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
-
   /*
    * Basic register fields and methods.
    */
@@ -1308,25 +1375,23 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
    */
   set_gdbarch_skip_prologue (gdbarch, h8300_skip_prologue);
 
-  set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, 
-                                               h8300_frame_init_saved_regs);
-  set_gdbarch_deprecated_init_extra_frame_info (gdbarch, 
-                                               h8300_init_extra_frame_info);
-  set_gdbarch_deprecated_frame_chain (gdbarch, h8300_frame_chain);
-  set_gdbarch_deprecated_saved_pc_after_call (gdbarch, 
-                                             h8300_saved_pc_after_call);
-  set_gdbarch_deprecated_frame_saved_pc (gdbarch, h8300_frame_saved_pc);
-  set_gdbarch_deprecated_pop_frame (gdbarch, h8300_pop_frame);
+  /* Frame unwinder.  */
+  set_gdbarch_unwind_dummy_id (gdbarch, h8300_unwind_dummy_id);
+  set_gdbarch_unwind_pc (gdbarch, h8300_unwind_pc);
+
+  /* Hook in the DWARF CFI frame unwinder.  */
+  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
 
   /* 
    * Miscelany
    */
   /* Stack grows up. */
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
-  set_gdbarch_deprecated_frameless_function_invocation (gdbarch, legacy_frameless_look_for_prologue);
 
-  set_gdbarch_deprecated_extract_struct_value_address (gdbarch, h8300_extract_struct_value_address);
-  set_gdbarch_use_struct_convention (gdbarch, always_use_struct_convention);
+  set_gdbarch_deprecated_extract_struct_value_address (gdbarch,
+                                                      h8300_extract_struct_value_address);
+  set_gdbarch_deprecated_use_struct_convention (gdbarch,
+                                               always_use_struct_convention);
   set_gdbarch_breakpoint_from_pc (gdbarch, h8300_breakpoint_from_pc);
   set_gdbarch_push_dummy_code (gdbarch, h8300_push_dummy_code);
   set_gdbarch_push_dummy_call (gdbarch, h8300_push_dummy_call);
@@ -1342,10 +1407,13 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Char is unsigned.  */
   set_gdbarch_char_signed (gdbarch, 0);
 
+  frame_unwind_append_sniffer (gdbarch, h8300_frame_sniffer);
+
   return gdbarch;
+
 }
 
-extern initialize_file_ftype _initialize_h8300_tdep; /* -Wmissing-prototypes */
+extern initialize_file_ftype _initialize_h8300_tdep;   /* -Wmissing-prototypes */
 
 void
 _initialize_h8300_tdep (void)
@@ -1357,34 +1425,33 @@ static int
 is_h8300hmode (struct gdbarch *gdbarch)
 {
   return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
-        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
-        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300s
-        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn
-        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300h
-        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300hn;
+    || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
+    || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300s
+    || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn
+    || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300h
+    || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300hn;
 }
 
 static int
 is_h8300smode (struct gdbarch *gdbarch)
 {
   return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
-        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
-        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300s
-        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn;
+    || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
+    || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300s
+    || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn;
 }
 
 static int
 is_h8300sxmode (struct gdbarch *gdbarch)
 {
   return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
-        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn;
+    || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn;
 }
 
 static int
 is_h8300_normal_mode (struct gdbarch *gdbarch)
 {
   return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
-        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn
-        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300hn;
+    || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn
+    || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300hn;
 }
-
This page took 0.046129 seconds and 4 git commands to generate.