* frv-tdep.c (frv_register_raw_size, frv_register_virtual_size):
[deliverable/binutils-gdb.git] / gdb / frv-tdep.c
index e7cd69995b217c70b2faed449fc43e8312e25f82..458a4b802f14c621e0b8e6ab5f7d1bf247c38db9 100644 (file)
@@ -37,6 +37,7 @@ static gdbarch_init_ftype frv_gdbarch_init;
 
 static gdbarch_register_name_ftype frv_register_name;
 static gdbarch_breakpoint_from_pc_ftype frv_breakpoint_from_pc;
+static gdbarch_adjust_breakpoint_address_ftype frv_gdbarch_adjust_breakpoint_address;
 static gdbarch_skip_prologue_ftype frv_skip_prologue;
 static gdbarch_deprecated_extract_return_value_ftype frv_extract_return_value;
 static gdbarch_deprecated_extract_struct_value_address_ftype frv_extract_struct_value_address;
@@ -235,21 +236,8 @@ frv_register_name (int reg)
   return CURRENT_VARIANT->register_names[reg];
 }
 
-
-static int
-frv_register_raw_size (int reg)
-{
-  return 4;
-}
-
-static int
-frv_register_virtual_size (int reg)
-{
-  return 4;
-}
-
 static struct type *
-frv_register_virtual_type (int reg)
+frv_register_type (struct gdbarch *gdbarch, int reg)
 {
   if (reg >= 64 && reg <= 127)
     return builtin_type_float;
@@ -271,6 +259,51 @@ frv_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenp)
   return breakpoint;
 }
 
+/* Define the maximum number of instructions which may be packed into a
+   bundle (VLIW instruction).  */
+static const int max_instrs_per_bundle = 8;
+
+/* Define the size (in bytes) of an FR-V instruction.  */
+static const int frv_instr_size = 4;
+
+/* Adjust a breakpoint's address to account for the FR-V architecture's
+   constraint that a break instruction must not appear as any but the
+   first instruction in the bundle.  */
+static CORE_ADDR
+frv_gdbarch_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
+{
+  int count = max_instrs_per_bundle;
+  CORE_ADDR addr = bpaddr - frv_instr_size;
+  CORE_ADDR func_start = get_pc_function_start (bpaddr);
+
+  /* Find the end of the previous packing sequence.  This will be indicated
+     by either attempting to access some inaccessible memory or by finding
+     an instruction word whose packing bit is set to one. */
+  while (count-- > 0 && addr >= func_start)
+    {
+      char instr[frv_instr_size];
+      int status;
+
+      status = read_memory_nobpt (addr, instr, sizeof instr);
+
+      if (status != 0)
+       break;
+
+      /* This is a big endian architecture, so byte zero will have most
+         significant byte.  The most significant bit of this byte is the
+         packing bit.  */
+      if (instr[0] & 0x80)
+       break;
+
+      addr -= frv_instr_size;
+    }
+
+  if (count > 0)
+    bpaddr = addr + frv_instr_size;
+
+  return bpaddr;
+}
+
 
 /* Return true if REG is a caller-saves ("scratch") register,
    false otherwise.  */
@@ -760,14 +793,11 @@ frv_frameless_function_invocation (struct frame_info *frame)
   return frameless_look_for_prologue (frame);
 }
 
-#define ROUND_UP(n,a) (((n)+(a)-1) & ~((a)-1))
-#define ROUND_DOWN(n,a) ((n) & ~((a)-1))
-
 static CORE_ADDR
 frv_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
 {
   /* Require dword alignment.  */
-  return ROUND_DOWN (sp, 8);
+  return align_down (sp, 8);
 }
 
 static CORE_ADDR
@@ -795,14 +825,14 @@ frv_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
 
   stack_space = 0;
   for (argnum = 0; argnum < nargs; ++argnum)
-    stack_space += ROUND_UP (TYPE_LENGTH (VALUE_TYPE (args[argnum])), 4);
+    stack_space += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])), 4);
 
   stack_space -= (6 * 4);
   if (stack_space > 0)
     sp -= stack_space;
 
   /* Make sure stack is dword aligned. */
-  sp = ROUND_DOWN (sp, 8);
+  sp = align_down (sp, 8);
 
   stack_offset = 0;
 
@@ -852,7 +882,7 @@ frv_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                     argnum, *((int *)val), stack_offset, (int) (sp + stack_offset));
 #endif
              write_memory (sp + stack_offset, val, partial_len);
-             stack_offset += ROUND_UP(partial_len, 4);
+             stack_offset += align_up (partial_len, 4);
            }
          len -= partial_len;
          val += partial_len;
@@ -964,10 +994,12 @@ frv_frame_this_id (struct frame_info *next_frame,
   /* The FUNC is easy.  */
   func = frame_func_unwind (next_frame);
 
+#if 0
   /* This is meant to halt the backtrace at "_start".  Make sure we
      don't halt it at a generic dummy frame. */
-  if (inside_entry_file (func))
+  if (inside_entry_func (func))
     return;
+#endif
 
   /* Check if the stack is empty.  */
   msym_stack = lookup_minimal_symbol ("_stack", NULL, NULL);
@@ -1106,17 +1138,12 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_pc_regnum (gdbarch, pc_regnum);
 
   set_gdbarch_register_name (gdbarch, frv_register_name);
-  set_gdbarch_deprecated_register_size (gdbarch, 4);
-  set_gdbarch_deprecated_register_bytes (gdbarch, frv_num_regs * 4);
   set_gdbarch_deprecated_register_byte (gdbarch, frv_register_byte);
-  set_gdbarch_deprecated_register_raw_size (gdbarch, frv_register_raw_size);
-  set_gdbarch_deprecated_max_register_raw_size (gdbarch, 4);
-  set_gdbarch_deprecated_register_virtual_size (gdbarch, frv_register_virtual_size);
-  set_gdbarch_deprecated_max_register_virtual_size (gdbarch, 4);
-  set_gdbarch_deprecated_register_virtual_type (gdbarch, frv_register_virtual_type);
+  set_gdbarch_register_type (gdbarch, frv_register_type);
 
   set_gdbarch_skip_prologue (gdbarch, frv_skip_prologue);
   set_gdbarch_breakpoint_from_pc (gdbarch, frv_breakpoint_from_pc);
+  set_gdbarch_adjust_breakpoint_address (gdbarch, frv_gdbarch_adjust_breakpoint_address);
 
   set_gdbarch_frame_args_skip (gdbarch, 0);
   set_gdbarch_frameless_function_invocation (gdbarch, frv_frameless_function_invocation);
This page took 0.024634 seconds and 4 git commands to generate.