+static struct value *
+m32r_frame_prev_register (struct frame_info *this_frame,
+ void **this_prologue_cache, int regnum)
+{
+ struct m32r_unwind_cache *info
+ = m32r_frame_unwind_cache (this_frame, this_prologue_cache);
+ return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
+}
+
+static const struct frame_unwind m32r_frame_unwind = {
+ NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
+ m32r_frame_this_id,
+ m32r_frame_prev_register,
+ NULL,
+ default_frame_sniffer
+};
+
+static CORE_ADDR
+m32r_frame_base_address (struct frame_info *this_frame, void **this_cache)
+{
+ struct m32r_unwind_cache *info
+ = m32r_frame_unwind_cache (this_frame, this_cache);
+ return info->base;
+}
+
+static const struct frame_base m32r_frame_base = {
+ &m32r_frame_unwind,
+ m32r_frame_base_address,
+ m32r_frame_base_address,
+ m32r_frame_base_address
+};
+
+/* 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
+m32r_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+{
+ CORE_ADDR sp = get_frame_register_unsigned (this_frame, M32R_SP_REGNUM);
+ return frame_id_build (sp, get_frame_pc (this_frame));
+}
+
+
+static gdbarch_init_ftype m32r_gdbarch_init;
+
+static struct gdbarch *
+m32r_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep;
+
+ /* If there is already a candidate, use it. */
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return arches->gdbarch;
+
+ /* Allocate space for the new architecture. */
+ tdep = XNEW (struct gdbarch_tdep);
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ set_gdbarch_read_pc (gdbarch, m32r_read_pc);
+ set_gdbarch_unwind_sp (gdbarch, m32r_unwind_sp);
+
+ set_gdbarch_num_regs (gdbarch, M32R_NUM_REGS);
+ set_gdbarch_pc_regnum (gdbarch, M32R_PC_REGNUM);
+ set_gdbarch_sp_regnum (gdbarch, M32R_SP_REGNUM);
+ set_gdbarch_register_name (gdbarch, m32r_register_name);
+ set_gdbarch_register_type (gdbarch, m32r_register_type);
+
+ set_gdbarch_push_dummy_call (gdbarch, m32r_push_dummy_call);
+ set_gdbarch_return_value (gdbarch, m32r_return_value);
+
+ set_gdbarch_skip_prologue (gdbarch, m32r_skip_prologue);
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ set_gdbarch_breakpoint_from_pc (gdbarch, m32r_breakpoint_from_pc);
+ set_gdbarch_memory_insert_breakpoint (gdbarch,
+ m32r_memory_insert_breakpoint);
+ set_gdbarch_memory_remove_breakpoint (gdbarch,
+ m32r_memory_remove_breakpoint);
+
+ set_gdbarch_frame_align (gdbarch, m32r_frame_align);
+
+ frame_base_set_default (gdbarch, &m32r_frame_base);
+
+ /* Methods for saving / extracting a dummy frame's ID. The ID's
+ stack address must match the SP value returned by
+ PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
+ set_gdbarch_dummy_id (gdbarch, m32r_dummy_id);
+
+ /* Return the unwound PC value. */
+ set_gdbarch_unwind_pc (gdbarch, m32r_unwind_pc);
+
+ set_gdbarch_print_insn (gdbarch, print_insn_m32r);
+
+ /* Hook in ABI-specific overrides, if they have been registered. */
+ gdbarch_init_osabi (info, gdbarch);
+
+ /* Hook in the default unwinders. */
+ frame_unwind_append_unwinder (gdbarch, &m32r_frame_unwind);
+
+ /* Support simple overlay manager. */
+ set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
+
+ return gdbarch;