2003-04-28 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / d10v-tdep.c
index 8001d46b184a11d3b7c72c26c6210eb790e2c014..93236a350fecd66bfb3f6c21d8cb618ce74e9c7c 100644 (file)
@@ -25,6 +25,7 @@
 #include "defs.h"
 #include "frame.h"
 #include "frame-unwind.h"
+#include "frame-base.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "gdbcmd.h"
@@ -70,7 +71,7 @@ enum
     R3_REGNUM = 3,
     D10V_FP_REGNUM = 11,
     LR_REGNUM = 13,
-    _SP_REGNUM = 15,
+    D10V_SP_REGNUM = 15,
     PSW_REGNUM = 16,
     _PC_REGNUM = 18,
     NR_IMAP_REGS = 2,
@@ -83,8 +84,17 @@ enum
     RET1_REGNUM = R0_REGNUM,
   };
 
-#define NR_DMAP_REGS (gdbarch_tdep (current_gdbarch)->nr_dmap_regs)
-#define A0_REGNUM (gdbarch_tdep (current_gdbarch)->a0_regnum)
+int
+nr_dmap_regs (struct gdbarch *gdbarch)
+{
+  return gdbarch_tdep (gdbarch)->nr_dmap_regs;
+}
+
+int
+a0_regnum (struct gdbarch *gdbarch)
+{
+  return gdbarch_tdep (gdbarch)->a0_regnum;
+}
 
 /* Local functions */
 
@@ -92,8 +102,6 @@ extern void _initialize_d10v_tdep (void);
 
 static CORE_ADDR d10v_read_sp (void);
 
-static CORE_ADDR d10v_read_fp (void);
-
 static void d10v_eva_prepare_to_trace (void);
 
 static void d10v_eva_get_trace_data (void);
@@ -306,37 +314,6 @@ d10v_ts3_register_sim_regno (int nr)
   return nr;
 }
 
-/* Index within `registers' of the first byte of the space for
-   register REG_NR.  */
-
-static int
-d10v_register_byte (int reg_nr)
-{
-  if (reg_nr < A0_REGNUM)
-    return (reg_nr * 2);
-  else if (reg_nr < (A0_REGNUM + NR_A_REGS))
-    return (A0_REGNUM * 2
-           + (reg_nr - A0_REGNUM) * 8);
-  else
-    return (A0_REGNUM * 2
-           + NR_A_REGS * 8
-           + (reg_nr - A0_REGNUM - NR_A_REGS) * 2);
-}
-
-/* Number of bytes of storage in the actual machine representation for
-   register REG_NR.  */
-
-static int
-d10v_register_raw_size (int reg_nr)
-{
-  if (reg_nr < A0_REGNUM)
-    return 2;
-  else if (reg_nr < (A0_REGNUM + NR_A_REGS))
-    return 8;
-  else
-    return 2;
-}
-
 /* Return the GDB type object for the "standard" data type
    of data in register N.  */
 
@@ -345,10 +322,10 @@ d10v_register_type (struct gdbarch *gdbarch, int reg_nr)
 {
   if (reg_nr == PC_REGNUM)
     return builtin_type_void_func_ptr;
-  if (reg_nr == _SP_REGNUM || reg_nr == D10V_FP_REGNUM)
+  if (reg_nr == D10V_SP_REGNUM || reg_nr == D10V_FP_REGNUM)
     return builtin_type_void_data_ptr;
-  else if (reg_nr >= A0_REGNUM
-      && reg_nr < (A0_REGNUM + NR_A_REGS))
+  else if (reg_nr >= a0_regnum (gdbarch)
+          && reg_nr < (a0_regnum (gdbarch) + NR_A_REGS))
     return builtin_type_int64;
   else
     return builtin_type_int16;
@@ -414,8 +391,7 @@ d10v_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr)
 static CORE_ADDR
 d10v_pointer_to_address (struct type *type, const void *buf)
 {
-  CORE_ADDR addr = extract_address (buf, TYPE_LENGTH (type));
-
+  CORE_ADDR addr = extract_unsigned_integer (buf, TYPE_LENGTH (type));
   /* Is it a code address?  */
   if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
       || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD
@@ -487,17 +463,6 @@ d10v_extract_struct_value_address (struct regcache *regcache)
   return (addr | DMEM_START);
 }
 
-/* Immediately after a function call, return the saved pc.  We can't
-   use frame->return_pc beause that is determined by reading R13 off
-   the stack and that may not be written yet. */
-
-static CORE_ADDR
-d10v_saved_pc_after_call (struct frame_info *frame)
-{
-  return ((read_register (LR_REGNUM) << 2)
-         | IMEM_START);
-}
-
 static int
 check_prologue (unsigned short op)
 {
@@ -598,7 +563,10 @@ d10v_skip_prologue (CORE_ADDR pc)
 struct d10v_unwind_cache
 {
   CORE_ADDR return_pc;
-  /* The frame's base.  Used when constructing a frame ID.  */
+  /* The previous frame's inner most stack address.  Used as this
+     frame ID's stack_addr.  */
+  CORE_ADDR prev_sp;
+  /* The frame's base, optionally used by the high-level debug info.  */
   CORE_ADDR base;
   int size;
   CORE_ADDR *saved_regs;
@@ -709,16 +677,16 @@ d10v_frame_unwind_cache (struct frame_info *next_frame,
 
   info = FRAME_OBSTACK_ZALLOC (struct d10v_unwind_cache);
   (*this_prologue_cache) = info;
-  info->saved_regs = frame_obstack_zalloc (SIZEOF_FRAME_SAVED_REGS);
+  info->saved_regs = FRAME_OBSTACK_CALLOC (NUM_REGS, CORE_ADDR);
 
   info->size = 0;
   info->return_pc = 0;
   info->sp_offset = 0;
 
-  pc = get_pc_function_start (frame_pc_unwind (next_frame));
-
   info->uses_frame = 0;
-  while (1)
+  for (pc = frame_func_unwind (next_frame);
+       pc > 0 && pc < frame_pc_unwind (next_frame);
+       pc += 4)
     {
       op = (unsigned long) read_memory_integer (pc, 4);
       if ((op & 0xC0000000) == 0xC0000000)
@@ -765,7 +733,6 @@ d10v_frame_unwind_cache (struct frame_info *next_frame,
              || !prologue_find_regs (info, op2, pc))
            break;
        }
-      pc += 4;
     }
 
   info->size = -info->sp_offset;
@@ -781,32 +748,32 @@ d10v_frame_unwind_cache (struct frame_info *next_frame,
          to before the first saved register giving the SP.  */
       prev_sp = this_base + info->size;
     }
-  else if (info->saved_regs[SP_REGNUM])
+  else if (info->saved_regs[D10V_SP_REGNUM])
     {
       /* The SP was saved (which is very unusual), the frame base is
         just the PREV's frame's TOP-OF-STACK.  */
-      this_base = read_memory_unsigned_integer (info->saved_regs[SP_REGNUM], 
+      this_base = read_memory_unsigned_integer (info->saved_regs[D10V_SP_REGNUM], 
                                                register_size (current_gdbarch,
-                                                              SP_REGNUM));
+                                                              D10V_SP_REGNUM));
       prev_sp = this_base;
     }
   else
     {
       /* Assume that the FP is this frame's SP but with that pushed
          stack space added back.  */
-      frame_unwind_unsigned_register (next_frame, SP_REGNUM, &this_base);
+      frame_unwind_unsigned_register (next_frame, D10V_SP_REGNUM, &this_base);
       prev_sp = this_base + info->size;
     }
 
   info->base = d10v_make_daddr (this_base);
-  prev_sp = d10v_make_daddr (prev_sp);
+  info->prev_sp = d10v_make_daddr (prev_sp);
 
   /* Adjust all the saved registers so that they contain addresses and
      not offsets.  */
   for (i = 0; i < NUM_REGS - 1; i++)
     if (info->saved_regs[i])
       {
-       info->saved_regs[i] = (prev_sp + info->saved_regs[i]);
+       info->saved_regs[i] = (info->prev_sp + info->saved_regs[i]);
       }
 
   if (info->saved_regs[LR_REGNUM])
@@ -823,9 +790,9 @@ d10v_frame_unwind_cache (struct frame_info *next_frame,
       info->return_pc = d10v_make_iaddr (return_pc);
     }
 
-  /* The SP_REGNUM is special.  Instead of the address of the SP, the
+  /* The D10V_SP_REGNUM is special.  Instead of the address of the SP, the
      previous frame's SP value is saved.  */
-  info->saved_regs[SP_REGNUM] = prev_sp;
+  info->saved_regs[D10V_SP_REGNUM] = info->prev_sp;
 
   return info;
 }
@@ -879,12 +846,12 @@ d10v_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
          fprintf_filtered (file, "    ");
        fprintf_filtered (file, "IMAP%d %04lx", a, d10v_imap_register (a));
       }
-    if (NR_DMAP_REGS == 1)
+    if (nr_dmap_regs (gdbarch) == 1)
       /* Registers DMAP0 and DMAP1 are constant.  Just return dmap2.  */
       fprintf_filtered (file, "    DMAP %04lx\n", d10v_dmap_register (2));
     else
       {
-       for (a = 0; a < NR_DMAP_REGS; a++)
+       for (a = 0; a < nr_dmap_regs (gdbarch); a++)
          {
            fprintf_filtered (file, "    DMAP%d %04lx", a, d10v_dmap_register (a));
          }
@@ -896,12 +863,12 @@ d10v_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
     char *num = alloca (max_register_size (gdbarch));
     int a;
     fprintf_filtered (file, "A0-A%d", NR_A_REGS - 1);
-    for (a = A0_REGNUM; a < A0_REGNUM + NR_A_REGS; a++)
+    for (a = a0_regnum (gdbarch); a < a0_regnum (gdbarch) + NR_A_REGS; a++)
       {
        int i;
        fprintf_filtered (file, "  ");
-       frame_register_read (frame, a, num);
-       for (i = 0; i < max_register_size (current_gdbarch); i++)
+       frame_read_register (frame, a, num);
+       for (i = 0; i < register_size (current_gdbarch, a); i++)
          {
            fprintf_filtered (file, "%02x", (num[i] & 0xff));
          }
@@ -946,13 +913,7 @@ d10v_write_pc (CORE_ADDR val, ptid_t ptid)
 static CORE_ADDR
 d10v_read_sp (void)
 {
-  return (d10v_make_daddr (read_register (SP_REGNUM)));
-}
-
-static CORE_ADDR
-d10v_read_fp (void)
-{
-  return (d10v_make_daddr (read_register (D10V_FP_REGNUM)));
+  return (d10v_make_daddr (read_register (D10V_SP_REGNUM)));
 }
 
 /* When arguments must be pushed onto the stack, they go on in reverse
@@ -1064,7 +1025,7 @@ d10v_push_dummy_call (struct gdbarch *gdbarch, struct regcache *regcache,
     }
 
   /* Finally, update the SP register.  */
-  regcache_cooked_write_unsigned (regcache, SP_REGNUM,
+  regcache_cooked_write_unsigned (regcache, D10V_SP_REGNUM,
                                  d10v_convert_daddr_to_raw (sp));
 
   return sp;
@@ -1079,12 +1040,6 @@ d10v_extract_return_value (struct type *type, struct regcache *regcache,
                           void *valbuf)
 {
   int len;
-#if 0
-  printf("RET: TYPE=%d len=%d r%d=0x%x\n", TYPE_CODE (type), 
-        TYPE_LENGTH (type), RET1_REGNUM - R0_REGNUM, 
-        (int) extract_unsigned_integer (regbuf + REGISTER_BYTE(RET1_REGNUM), 
-                                        register_size (current_gdbarch, RET1_REGNUM)));
-#endif
   if (TYPE_LENGTH (type) == 1)
     {
       ULONGEST c;
@@ -1203,9 +1158,9 @@ trace_command (char *args, int from_tty)
   /* Clear the host-side trace buffer, allocating space if needed.  */
   trace_data.size = 0;
   if (trace_data.counts == NULL)
-    trace_data.counts = (short *) xmalloc (65536 * sizeof (short));
+    trace_data.counts = XCALLOC (65536, short);
   if (trace_data.addrs == NULL)
-    trace_data.addrs = (CORE_ADDR *) xmalloc (65536 * sizeof (CORE_ADDR));
+    trace_data.addrs = XCALLOC (65536, CORE_ADDR);
 
   tracing = 1;
 
@@ -1244,24 +1199,6 @@ trace_info (char *args, int from_tty)
   printf_filtered ("Tracing is currently %s.\n", (tracing ? "on" : "off"));
 }
 
-/* Print the instruction at address MEMADDR in debugged memory,
-   on STREAM.  Returns length of the instruction, in bytes.  */
-
-static int
-print_insn (CORE_ADDR memaddr, struct ui_file *stream)
-{
-  /* If there's no disassembler, something is very wrong.  */
-  if (tm_print_insn == NULL)
-    internal_error (__FILE__, __LINE__,
-                   "print_insn: no disassembler");
-
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-    tm_print_insn_info.endian = BFD_ENDIAN_BIG;
-  else
-    tm_print_insn_info.endian = BFD_ENDIAN_LITTLE;
-  return TARGET_PRINT_INSN (memaddr, &tm_print_insn_info);
-}
-
 static void
 d10v_eva_prepare_to_trace (void)
 {
@@ -1422,7 +1359,8 @@ display_trace (int low, int high)
          printf_filtered (":");
          printf_filtered ("\t");
          wrap_here ("    ");
-         next_address = next_address + print_insn (next_address, gdb_stdout);
+         next_address += TARGET_PRINT_INSN (next_address,
+                                            &tm_print_insn_info);
          printf_filtered ("\n");
          gdb_flush (gdb_stdout);
        }
@@ -1448,38 +1386,36 @@ d10v_frame_this_id (struct frame_info *next_frame,
   struct d10v_unwind_cache *info
     = d10v_frame_unwind_cache (next_frame, this_prologue_cache);
   CORE_ADDR base;
-  CORE_ADDR pc;
-
-  /* Start with a NULL frame ID.  */
-  (*this_id) = null_frame_id;
+  CORE_ADDR func;
+  struct frame_id id;
 
-  /* The PC is easy.  */
-  pc = frame_pc_unwind (next_frame);
+  /* The FUNC is easy.  */
+  func = frame_func_unwind (next_frame);
 
   /* This is meant to halt the backtrace at "_start".  Make sure we
      don't halt it at a generic dummy frame. */
-  if (pc == IMEM_START || pc <= IMEM_START || inside_entry_file (pc))
+  if (func <= IMEM_START || inside_entry_file (func))
     return;
 
   /* Hopefully the prologue analysis either correctly determined the
      frame's base (which is the SP from the previous frame), or set
      that base to "NULL".  */
-  base = info->base;
+  base = info->prev_sp;
   if (base == STACK_START || base == 0)
     return;
 
+  id = frame_id_build (base, func);
+
   /* Check that we're not going round in circles with the same frame
      ID (but avoid applying the test to sentinel frames which do go
      round in circles).  Can't use frame_id_eq() as that doesn't yet
      compare the frame's PC value.  */
   if (frame_relative_level (next_frame) >= 0
       && get_frame_type (next_frame) != DUMMY_FRAME
-      && get_frame_id (next_frame).pc == pc
-      && get_frame_id (next_frame).base == base)
+      && frame_id_eq (get_frame_id (next_frame), id))
     return;
 
-  this_id->base = base;
-  this_id->pc = pc;
+  (*this_id) = id;
 }
 
 static void
@@ -1491,7 +1427,7 @@ saved_regs_unwinder (struct frame_info *next_frame,
 {
   if (this_saved_regs[regnum] != 0)
     {
-      if (regnum == SP_REGNUM)
+      if (regnum == D10V_SP_REGNUM)
        {
          /* SP register treated specially.  */
          *optimizedp = 0;
@@ -1499,8 +1435,9 @@ saved_regs_unwinder (struct frame_info *next_frame,
          *addrp = 0;
          *realnump = -1;
          if (bufferp != NULL)
-           store_address (bufferp, register_size (current_gdbarch, regnum),
-                          this_saved_regs[regnum]);
+           store_unsigned_integer (bufferp,
+                                   register_size (current_gdbarch, regnum),
+                                   this_saved_regs[regnum]);
        }
       else
        {
@@ -1553,8 +1490,8 @@ d10v_frame_prev_register (struct frame_info *next_frame,
     }
 }
 
-
-static struct frame_unwind d10v_frame_unwind = {
+static const struct frame_unwind d10v_frame_unwind = {
+  NORMAL_FRAME,
   d10v_frame_this_id,
   d10v_frame_prev_register
 };
@@ -1565,6 +1502,21 @@ d10v_frame_p (CORE_ADDR pc)
   return &d10v_frame_unwind;
 }
 
+static CORE_ADDR
+d10v_frame_base_address (struct frame_info *next_frame, void **this_cache)
+{
+  struct d10v_unwind_cache *info
+    = d10v_frame_unwind_cache (next_frame, this_cache);
+  return info->base;
+}
+
+static const struct frame_base d10v_frame_base = {
+  &d10v_frame_unwind,
+  d10v_frame_base_address,
+  d10v_frame_base_address,
+  d10v_frame_base_address
+};
+
 /* Assuming NEXT_FRAME->prev 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
@@ -1574,11 +1526,8 @@ static struct frame_id
 d10v_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
   ULONGEST base;
-  struct frame_id id;
-  id.pc = frame_pc_unwind (next_frame);
-  frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base);
-  id.base = d10v_make_daddr (base);
-  return id;
+  frame_unwind_unsigned_register (next_frame, D10V_SP_REGNUM, &base);
+  return frame_id_build (d10v_make_daddr (base), frame_pc_unwind (next_frame));
 }
 
 static gdbarch_init_ftype d10v_gdbarch_init;
@@ -1627,17 +1576,14 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_read_pc (gdbarch, d10v_read_pc);
   set_gdbarch_write_pc (gdbarch, d10v_write_pc);
-  set_gdbarch_read_fp (gdbarch, d10v_read_fp);
   set_gdbarch_read_sp (gdbarch, d10v_read_sp);
 
   set_gdbarch_num_regs (gdbarch, d10v_num_regs);
-  set_gdbarch_sp_regnum (gdbarch, 15);
+  set_gdbarch_sp_regnum (gdbarch, D10V_SP_REGNUM);
   set_gdbarch_pc_regnum (gdbarch, 18);
   set_gdbarch_register_name (gdbarch, d10v_register_name);
   set_gdbarch_register_size (gdbarch, 2);
   set_gdbarch_register_bytes (gdbarch, (d10v_num_regs - 2) * 2 + 16);
-  set_gdbarch_register_byte (gdbarch, d10v_register_byte);
-  set_gdbarch_register_raw_size (gdbarch, d10v_register_raw_size);
   set_gdbarch_register_virtual_size (gdbarch, generic_register_size);
   set_gdbarch_register_type (gdbarch, d10v_register_type);
 
@@ -1672,14 +1618,6 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
                      "d10v_gdbarch_init: bad byte order for float format");
     }
 
-  set_gdbarch_call_dummy_length (gdbarch, 0);
-  set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
-  set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
-  set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
-  set_gdbarch_call_dummy_start_offset (gdbarch, 0);
-  set_gdbarch_call_dummy_p (gdbarch, 1);
-  set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
-
   set_gdbarch_extract_return_value (gdbarch, d10v_extract_return_value);
   set_gdbarch_push_dummy_call (gdbarch, d10v_push_dummy_call);
   set_gdbarch_store_return_value (gdbarch, d10v_store_return_value);
@@ -1697,7 +1635,6 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_frame_args_skip (gdbarch, 0);
   set_gdbarch_frameless_function_invocation (gdbarch, frameless_look_for_prologue);
 
-  set_gdbarch_saved_pc_after_call (gdbarch, d10v_saved_pc_after_call);
   set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
   set_gdbarch_stack_align (gdbarch, d10v_stack_align);
 
@@ -1706,6 +1643,7 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_print_registers_info (gdbarch, d10v_print_registers_info);
 
   frame_unwind_append_predicate (gdbarch, d10v_frame_p);
+  frame_base_set_default (gdbarch, &d10v_frame_base);
 
   /* Methods for saving / extracting a dummy frame's ID.  */
   set_gdbarch_unwind_dummy_id (gdbarch, d10v_unwind_dummy_id);
@@ -1714,6 +1652,8 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Return the unwound PC value.  */
   set_gdbarch_unwind_pc (gdbarch, d10v_unwind_pc);
 
+  set_gdbarch_print_insn (gdbarch, print_insn_d10v);
+
   return gdbarch;
 }
 
@@ -1722,8 +1662,6 @@ _initialize_d10v_tdep (void)
 {
   register_gdbarch_init (bfd_arch_d10v, d10v_gdbarch_init);
 
-  tm_print_insn = print_insn_d10v;
-
   target_resume_hook = d10v_eva_prepare_to_trace;
   target_wait_loop_hook = d10v_eva_get_trace_data;
 
@@ -1744,13 +1682,13 @@ as reported by info trace (NOT addresses!).");
   add_info ("itrace", trace_info,
            "Display info about the trace data buffer.");
 
-  add_show_from_set (add_set_cmd ("itracedisplay", no_class,
-                                 var_integer, (char *) &trace_display,
-                            "Set automatic display of trace.\n", &setlist),
-                    &showlist);
-  add_show_from_set (add_set_cmd ("itracesource", no_class,
-                          var_integer, (char *) &default_trace_show_source,
-                     "Set display of source code with trace.\n", &setlist),
-                    &showlist);
-
+  add_setshow_boolean_cmd ("itracedisplay", no_class, &trace_display,
+                          "Set automatic display of trace.\n",
+                          "Show automatic display of trace.\n",
+                          NULL, NULL, &setlist, &showlist);
+  add_setshow_boolean_cmd ("itracesource", no_class,
+                          &default_trace_show_source,
+                          "Set display of source code with trace.\n",
+                          "Show display of source code with trace.\n",
+                          NULL, NULL, &setlist, &showlist);
 }
This page took 0.030897 seconds and 4 git commands to generate.