gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / sparc-tdep.c
index ea2435e666f56f89da24dac34fb44d4ad540bc44..9e00a678a19dc29d6b5b814dce0a01bd3fb03890 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for SPARC.
 
-   Copyright (C) 2003-2016 Free Software Foundation, Inc.
+   Copyright (C) 2003-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -20,8 +20,8 @@
 #include "defs.h"
 #include "arch-utils.h"
 #include "dis-asm.h"
-#include "dwarf2-frame.h"
-#include "floatformat.h"
+#include "dwarf2.h"
+#include "dwarf2/frame.h"
 #include "frame.h"
 #include "frame-base.h"
 #include "frame-unwind.h"
@@ -33,6 +33,7 @@
 #include "osabi.h"
 #include "regcache.h"
 #include "target.h"
+#include "target-descriptions.h"
 #include "value.h"
 
 #include "sparc-tdep.h"
@@ -188,7 +189,7 @@ ULONGEST
 sparc_fetch_wcookie (struct gdbarch *gdbarch)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  struct target_ops *ops = &current_target;
+  struct target_ops *ops = current_top_target ();
   gdb_byte buf[8];
   int len;
 
@@ -213,7 +214,7 @@ sparc_integral_or_pointer_p (const struct type *type)
 {
   int len = TYPE_LENGTH (type);
 
-  switch (TYPE_CODE (type))
+  switch (type->code ())
     {
     case TYPE_CODE_INT:
     case TYPE_CODE_BOOL:
@@ -226,6 +227,7 @@ sparc_integral_or_pointer_p (const struct type *type)
       return (len == 1 || len == 2 || len == 4 || len == 8);
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* Allow either 32-bit or 64-bit pointers.  */
       return (len == 4 || len == 8);
     default:
@@ -240,7 +242,7 @@ sparc_integral_or_pointer_p (const struct type *type)
 static int
 sparc_floating_p (const struct type *type)
 {
-  switch (TYPE_CODE (type))
+  switch (type->code ())
     {
     case TYPE_CODE_FLT:
       {
@@ -259,7 +261,7 @@ sparc_floating_p (const struct type *type)
 static int
 sparc_complex_floating_p (const struct type *type)
 {
-  switch (TYPE_CODE (type))
+  switch (type->code ())
     {
     case TYPE_CODE_COMPLEX:
       {
@@ -282,7 +284,7 @@ sparc_complex_floating_p (const struct type *type)
 static int
 sparc_structure_or_union_p (const struct type *type)
 {
-  switch (TYPE_CODE (type))
+  switch (type->code ())
     {
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
@@ -295,21 +297,81 @@ sparc_structure_or_union_p (const struct type *type)
   return 0;
 }
 
-/* Register information.  */
+/* Return true if TYPE is returned by memory, false if returned by
+   register.  */
 
-static const char *sparc32_register_names[] =
+static bool
+sparc_structure_return_p (const struct type *type)
+{
+  if (type->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
+    {
+      /* Float vectors are always returned by memory.  */
+      if (sparc_floating_p (check_typedef (TYPE_TARGET_TYPE (type))))
+       return true;
+      /* Integer vectors are returned by memory if the vector size
+        is greater than 8 bytes long.  */
+      return (TYPE_LENGTH (type) > 8);
+    }
+
+  if (sparc_floating_p (type))
+    {
+      /* Floating point types are passed by register for size 4 and
+        8 bytes, and by memory for size 16 bytes.  */
+      return (TYPE_LENGTH (type) == 16);
+    }
+
+  /* Other than that, only aggregates of all sizes get returned by
+     memory.  */
+  return sparc_structure_or_union_p (type);
+}
+
+/* Return true if arguments of the given TYPE are passed by
+   memory; false if returned by register.  */
+
+static bool
+sparc_arg_by_memory_p (const struct type *type)
 {
-  "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
-  "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
-  "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
-  "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
+  if (type->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
+    {
+      /* Float vectors are always passed by memory.  */
+      if (sparc_floating_p (check_typedef (TYPE_TARGET_TYPE (type))))
+       return true;
+      /* Integer vectors are passed by memory if the vector size
+        is greater than 8 bytes long.  */
+      return (TYPE_LENGTH (type) > 8);
+    }
+
+  /* Floats are passed by register for size 4 and 8 bytes, and by memory
+     for size 16 bytes.  */
+  if (sparc_floating_p (type))
+    return (TYPE_LENGTH (type) == 16);
 
-  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
-  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
-  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
-  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+  /* Complex floats and aggregates of all sizes are passed by memory.  */
+  if (sparc_complex_floating_p (type) || sparc_structure_or_union_p (type))
+    return true;
 
+  /* Everything else gets passed by register.  */
+  return false;
+}
+
+/* Register information.  */
+#define SPARC32_FPU_REGISTERS                             \
+  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",         \
+  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",   \
+  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
+  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
+#define SPARC32_CP0_REGISTERS \
   "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr"
+
+static const char *sparc_core_register_names[] = { SPARC_CORE_REGISTERS };
+static const char *sparc32_fpu_register_names[] = { SPARC32_FPU_REGISTERS };
+static const char *sparc32_cp0_register_names[] = { SPARC32_CP0_REGISTERS };
+
+static const char *sparc32_register_names[] =
+{
+  SPARC_CORE_REGISTERS,
+  SPARC32_FPU_REGISTERS,
+  SPARC32_CP0_REGISTERS
 };
 
 /* Total number of registers.  */
@@ -327,18 +389,33 @@ static const char *sparc32_pseudo_register_names[] =
 /* Total number of pseudo registers.  */
 #define SPARC32_NUM_PSEUDO_REGS ARRAY_SIZE (sparc32_pseudo_register_names)
 
+/* Return the name of pseudo register REGNUM.  */
+
+static const char *
+sparc32_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
+{
+  regnum -= gdbarch_num_regs (gdbarch);
+
+  if (regnum < SPARC32_NUM_PSEUDO_REGS)
+    return sparc32_pseudo_register_names[regnum];
+
+  internal_error (__FILE__, __LINE__,
+                  _("sparc32_pseudo_register_name: bad register number %d"),
+                  regnum);
+}
+
 /* Return the name of register REGNUM.  */
 
 static const char *
 sparc32_register_name (struct gdbarch *gdbarch, int regnum)
 {
-  if (regnum >= 0 && regnum < SPARC32_NUM_REGS)
-    return sparc32_register_names[regnum];
+  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    return tdesc_register_name (gdbarch, regnum);
 
-  if (regnum < SPARC32_NUM_REGS + SPARC32_NUM_PSEUDO_REGS)
-    return sparc32_pseudo_register_names[regnum - SPARC32_NUM_REGS];
+  if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch))
+    return sparc32_register_names[regnum];
 
-  return NULL;
+  return sparc32_pseudo_register_name (gdbarch, regnum);
 }
 \f
 /* Construct types for ISA-specific registers.  */
@@ -352,7 +429,7 @@ sparc_psr_type (struct gdbarch *gdbarch)
     {
       struct type *type;
 
-      type = arch_flags_type (gdbarch, "builtin_type_sparc_psr", 4);
+      type = arch_flags_type (gdbarch, "builtin_type_sparc_psr", 32);
       append_flags_type_flag (type, 5, "ET");
       append_flags_type_flag (type, 6, "PS");
       append_flags_type_flag (type, 7, "S");
@@ -374,7 +451,7 @@ sparc_fsr_type (struct gdbarch *gdbarch)
     {
       struct type *type;
 
-      type = arch_flags_type (gdbarch, "builtin_type_sparc_fsr", 4);
+      type = arch_flags_type (gdbarch, "builtin_type_sparc_fsr", 32);
       append_flags_type_flag (type, 0, "NXA");
       append_flags_type_flag (type, 1, "DZA");
       append_flags_type_flag (type, 2, "UFA");
@@ -398,18 +475,34 @@ sparc_fsr_type (struct gdbarch *gdbarch)
   return tdep->sparc_fsr_type;
 }
 
+/* Return the GDB type object for the "standard" data type of data in
+   pseudo register REGNUM.  */
+
+static struct type *
+sparc32_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
+{
+  regnum -= gdbarch_num_regs (gdbarch);
+
+  if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM)
+    return builtin_type (gdbarch)->builtin_double;
+
+  internal_error (__FILE__, __LINE__,
+                  _("sparc32_pseudo_register_type: bad register number %d"),
+                  regnum);
+}
+
 /* Return the GDB type object for the "standard" data type of data in
    register REGNUM.  */
 
 static struct type *
 sparc32_register_type (struct gdbarch *gdbarch, int regnum)
 {
+  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    return tdesc_register_type (gdbarch, regnum);
+
   if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
     return builtin_type (gdbarch)->builtin_float;
 
-  if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM)
-    return builtin_type (gdbarch)->builtin_double;
-
   if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM)
     return builtin_type (gdbarch)->builtin_data_ptr;
 
@@ -422,22 +515,26 @@ sparc32_register_type (struct gdbarch *gdbarch, int regnum)
   if (regnum == SPARC32_FSR_REGNUM)
     return sparc_fsr_type (gdbarch);
 
+  if (regnum >= gdbarch_num_regs (gdbarch))
+    return sparc32_pseudo_register_type (gdbarch, regnum);
+
   return builtin_type (gdbarch)->builtin_int32;
 }
 
 static enum register_status
 sparc32_pseudo_register_read (struct gdbarch *gdbarch,
-                             struct regcache *regcache,
+                             readable_regcache *regcache,
                              int regnum, gdb_byte *buf)
 {
   enum register_status status;
 
+  regnum -= gdbarch_num_regs (gdbarch);
   gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM);
 
   regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM);
-  status = regcache_raw_read (regcache, regnum, buf);
+  status = regcache->raw_read (regnum, buf);
   if (status == REG_VALID)
-    status = regcache_raw_read (regcache, regnum + 1, buf + 4);
+    status = regcache->raw_read (regnum + 1, buf + 4);
   return status;
 }
 
@@ -446,11 +543,12 @@ sparc32_pseudo_register_write (struct gdbarch *gdbarch,
                               struct regcache *regcache,
                               int regnum, const gdb_byte *buf)
 {
+  regnum -= gdbarch_num_regs (gdbarch);
   gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM);
 
   regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM);
-  regcache_raw_write (regcache, regnum, buf);
-  regcache_raw_write (regcache, regnum + 1, buf + 4);
+  regcache->raw_write (regnum, buf);
+  regcache->raw_write (regnum + 1, buf + 4);
 }
 \f
 /* Implement the stack_frame_destroyed_p gdbarch method.  */
@@ -514,9 +612,10 @@ sparc32_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
 static CORE_ADDR
 sparc32_store_arguments (struct regcache *regcache, int nargs,
                         struct value **args, CORE_ADDR sp,
-                        int struct_return, CORE_ADDR struct_addr)
+                        function_call_return_method return_method,
+                        CORE_ADDR struct_addr)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   /* Number of words in the "parameter array".  */
   int num_elements = 0;
@@ -528,9 +627,7 @@ sparc32_store_arguments (struct regcache *regcache, int nargs,
       struct type *type = value_type (args[i]);
       int len = TYPE_LENGTH (type);
 
-      if (sparc_structure_or_union_p (type)
-         || (sparc_floating_p (type) && len == 16)
-         || sparc_complex_floating_p (type))
+      if (sparc_arg_by_memory_p (type))
        {
          /* Structure, Union and Quad-Precision Arguments.  */
          sp -= len;
@@ -551,12 +648,7 @@ sparc32_store_arguments (struct regcache *regcache, int nargs,
        }
       else
        {
-         /* Integral and pointer arguments.  */
-         gdb_assert (sparc_integral_or_pointer_p (type));
-
-         if (len < 4)
-           args[i] = value_cast (builtin_type (gdbarch)->builtin_int32,
-                                 args[i]);
+         /* Arguments passed via the General Purpose Registers.  */
          num_elements += ((len + 3) / 4);
        }
     }
@@ -578,6 +670,15 @@ sparc32_store_arguments (struct regcache *regcache, int nargs,
       const bfd_byte *valbuf = value_contents (args[i]);
       struct type *type = value_type (args[i]);
       int len = TYPE_LENGTH (type);
+      gdb_byte buf[4];
+
+      if (len < 4)
+        {
+          memset (buf, 0, 4 - len);
+          memcpy (buf + 4 - len, valbuf, len);
+          valbuf = buf;
+          len = 4;
+        }
 
       gdb_assert (len == 4 || len == 8);
 
@@ -585,9 +686,9 @@ sparc32_store_arguments (struct regcache *regcache, int nargs,
        {
          int regnum = SPARC_O0_REGNUM + element;
 
-         regcache_cooked_write (regcache, regnum, valbuf);
+         regcache->cooked_write (regnum, valbuf);
          if (len > 4 && element < 5)
-           regcache_cooked_write (regcache, regnum + 1, valbuf + 4);
+           regcache->cooked_write (regnum + 1, valbuf + 4);
        }
 
       /* Always store the argument in memory.  */
@@ -597,7 +698,7 @@ sparc32_store_arguments (struct regcache *regcache, int nargs,
 
   gdb_assert (element == num_elements);
 
-  if (struct_return)
+  if (return_method == return_method_struct)
     {
       gdb_byte buf[4];
 
@@ -612,16 +713,18 @@ static CORE_ADDR
 sparc32_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)
+                        function_call_return_method return_method,
+                        CORE_ADDR struct_addr)
 {
-  CORE_ADDR call_pc = (struct_return ? (bp_addr - 12) : (bp_addr - 8));
+  CORE_ADDR call_pc = (return_method == return_method_struct
+                      ? (bp_addr - 12) : (bp_addr - 8));
 
   /* Set return address.  */
   regcache_cooked_write_unsigned (regcache, SPARC_O7_REGNUM, call_pc);
 
   /* Set up function arguments.  */
-  sp = sparc32_store_arguments (regcache, nargs, args, sp,
-                               struct_return, struct_addr);
+  sp = sparc32_store_arguments (regcache, nargs, args, sp, return_method,
+                               struct_addr);
 
   /* Allocate the 16-word window save area.  */
   sp -= 16 * 4;
@@ -1011,13 +1114,6 @@ sparc_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
   return pc;
 }
 
-static CORE_ADDR
-sparc_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  return frame_unwind_register_unsigned (this_frame, tdep->pc_regnum);
-}
-
 /* Return PC of first real instruction of the function starting at
    START_PC.  */
 
@@ -1132,7 +1228,7 @@ static int
 sparc32_struct_return_from_sym (struct symbol *sym)
 {
   struct type *type = check_typedef (SYMBOL_TYPE (sym));
-  enum type_code code = TYPE_CODE (type);
+  enum type_code code = type->code ();
 
   if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD)
     {
@@ -1303,26 +1399,26 @@ sparc32_extract_return_value (struct type *type, struct regcache *regcache,
   int len = TYPE_LENGTH (type);
   gdb_byte buf[32];
 
-  gdb_assert (!sparc_structure_or_union_p (type));
-  gdb_assert (!(sparc_floating_p (type) && len == 16));
+  gdb_assert (!sparc_structure_return_p (type));
 
-  if (sparc_floating_p (type) || sparc_complex_floating_p (type))
+  if (sparc_floating_p (type) || sparc_complex_floating_p (type)
+      || type->code () == TYPE_CODE_ARRAY)
     {
       /* Floating return values.  */
-      regcache_cooked_read (regcache, SPARC_F0_REGNUM, buf);
+      regcache->cooked_read (SPARC_F0_REGNUM, buf);
       if (len > 4)
-       regcache_cooked_read (regcache, SPARC_F1_REGNUM, buf + 4);
+       regcache->cooked_read (SPARC_F1_REGNUM, buf + 4);
       if (len > 8)
        {
-         regcache_cooked_read (regcache, SPARC_F2_REGNUM, buf + 8);
-         regcache_cooked_read (regcache, SPARC_F3_REGNUM, buf + 12);
+         regcache->cooked_read (SPARC_F2_REGNUM, buf + 8);
+         regcache->cooked_read (SPARC_F3_REGNUM, buf + 12);
        }
       if (len > 16)
        {
-         regcache_cooked_read (regcache, SPARC_F4_REGNUM, buf + 16);
-         regcache_cooked_read (regcache, SPARC_F5_REGNUM, buf + 20);
-         regcache_cooked_read (regcache, SPARC_F6_REGNUM, buf + 24);
-         regcache_cooked_read (regcache, SPARC_F7_REGNUM, buf + 28);
+         regcache->cooked_read (SPARC_F4_REGNUM, buf + 16);
+         regcache->cooked_read (SPARC_F5_REGNUM, buf + 20);
+         regcache->cooked_read (SPARC_F6_REGNUM, buf + 24);
+         regcache->cooked_read (SPARC_F7_REGNUM, buf + 28);
        }
       memcpy (valbuf, buf, len);
     }
@@ -1331,10 +1427,10 @@ sparc32_extract_return_value (struct type *type, struct regcache *regcache,
       /* Integral and pointer return values.  */
       gdb_assert (sparc_integral_or_pointer_p (type));
 
-      regcache_cooked_read (regcache, SPARC_O0_REGNUM, buf);
+      regcache->cooked_read (SPARC_O0_REGNUM, buf);
       if (len > 4)
        {
-         regcache_cooked_read (regcache, SPARC_O1_REGNUM, buf + 4);
+         regcache->cooked_read (SPARC_O1_REGNUM, buf + 4);
          gdb_assert (len == 8);
          memcpy (valbuf, buf, 8);
        }
@@ -1355,30 +1451,28 @@ sparc32_store_return_value (struct type *type, struct regcache *regcache,
                            const gdb_byte *valbuf)
 {
   int len = TYPE_LENGTH (type);
-  gdb_byte buf[8];
+  gdb_byte buf[32];
 
-  gdb_assert (!sparc_structure_or_union_p (type));
-  gdb_assert (!(sparc_floating_p (type) && len == 16));
-  gdb_assert (len <= 8);
+  gdb_assert (!sparc_structure_return_p (type));
 
   if (sparc_floating_p (type) || sparc_complex_floating_p (type))
     {
       /* Floating return values.  */
       memcpy (buf, valbuf, len);
-      regcache_cooked_write (regcache, SPARC_F0_REGNUM, buf);
+      regcache->cooked_write (SPARC_F0_REGNUM, buf);
       if (len > 4)
-       regcache_cooked_write (regcache, SPARC_F1_REGNUM, buf + 4);
+       regcache->cooked_write (SPARC_F1_REGNUM, buf + 4);
       if (len > 8)
        {
-         regcache_cooked_write (regcache, SPARC_F2_REGNUM, buf + 8);
-         regcache_cooked_write (regcache, SPARC_F3_REGNUM, buf + 12);
+         regcache->cooked_write (SPARC_F2_REGNUM, buf + 8);
+         regcache->cooked_write (SPARC_F3_REGNUM, buf + 12);
        }
       if (len > 16)
        {
-         regcache_cooked_write (regcache, SPARC_F4_REGNUM, buf + 16);
-         regcache_cooked_write (regcache, SPARC_F5_REGNUM, buf + 20);
-         regcache_cooked_write (regcache, SPARC_F6_REGNUM, buf + 24);
-         regcache_cooked_write (regcache, SPARC_F7_REGNUM, buf + 28);
+         regcache->cooked_write (SPARC_F4_REGNUM, buf + 16);
+         regcache->cooked_write (SPARC_F5_REGNUM, buf + 20);
+         regcache->cooked_write (SPARC_F6_REGNUM, buf + 24);
+         regcache->cooked_write (SPARC_F7_REGNUM, buf + 28);
        }
     }
   else
@@ -1390,14 +1484,14 @@ sparc32_store_return_value (struct type *type, struct regcache *regcache,
        {
          gdb_assert (len == 8);
          memcpy (buf, valbuf, 8);
-         regcache_cooked_write (regcache, SPARC_O1_REGNUM, buf + 4);
+         regcache->cooked_write (SPARC_O1_REGNUM, buf + 4);
        }
       else
        {
          /* ??? Do we need to do any sign-extension here?  */
          memcpy (buf + 4 - len, valbuf, len);
        }
-      regcache_cooked_write (regcache, SPARC_O0_REGNUM, buf);
+      regcache->cooked_write (SPARC_O0_REGNUM, buf);
     }
 }
 
@@ -1415,8 +1509,7 @@ sparc32_return_value (struct gdbarch *gdbarch, struct value *function,
      guarantees that we can always find the return value, not just
      before the function returns.  */
 
-  if (sparc_structure_or_union_p (type)
-      || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
+  if (sparc_structure_return_p (type))
     {
       ULONGEST sp;
       CORE_ADDR addr;
@@ -1495,13 +1588,41 @@ sparc32_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
     }
 }
 
+/* Implement the execute_dwarf_cfa_vendor_op method.  */
+
+static bool
+sparc_execute_dwarf_cfa_vendor_op (struct gdbarch *gdbarch, gdb_byte op,
+                                  struct dwarf2_frame_state *fs)
+{
+  /* Only DW_CFA_GNU_window_save is expected on SPARC.  */
+  if (op != DW_CFA_GNU_window_save)
+    return false;
+
+  uint64_t reg;
+  int size = register_size (gdbarch, 0);
+
+  fs->regs.alloc_regs (32);
+  for (reg = 8; reg < 16; reg++)
+    {
+      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_REG;
+      fs->regs.reg[reg].loc.reg = reg + 16;
+    }
+  for (reg = 16; reg < 32; reg++)
+    {
+      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET;
+      fs->regs.reg[reg].loc.offset = (reg - 16) * size;
+    }
+
+  return true;
+}
+
 \f
 /* The SPARC Architecture doesn't have hardware single-step support,
    and most operating systems don't implement it either, so we provide
    software single-step mechanism.  */
 
 static CORE_ADDR
-sparc_analyze_control_transfer (struct frame_info *frame,
+sparc_analyze_control_transfer (struct regcache *regcache,
                                CORE_ADDR pc, CORE_ADDR *npc)
 {
   unsigned long insn = sparc_fetch_instruction (pc);
@@ -1552,8 +1673,11 @@ sparc_analyze_control_transfer (struct frame_info *frame,
     }
   else if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3a)
     {
+      struct frame_info *frame = get_current_frame ();
+
       /* Trap instruction (TRAP).  */
-      return gdbarch_tdep (get_frame_arch (frame))->step_trap (frame, insn);
+      return gdbarch_tdep (regcache->arch ())->step_trap (frame,
+                                                                    insn);
     }
 
   /* FIXME: Handle DONE and RETRY instructions.  */
@@ -1563,7 +1687,7 @@ sparc_analyze_control_transfer (struct frame_info *frame,
       if (fused_p)
        {
          /* Fused compare-and-branch instructions are non-delayed,
-            and do not have an annuling capability.  So we need to
+            and do not have an annulling capability.  So we need to
             always set a breakpoint on both the NPC and the branch
             target address.  */
          gdb_assert (offset != 0);
@@ -1599,27 +1723,26 @@ sparc_step_trap (struct frame_info *frame, unsigned long insn)
   return 0;
 }
 
-static VEC (CORE_ADDR) *
-sparc_software_single_step (struct frame_info *frame)
+static std::vector<CORE_ADDR>
+sparc_software_single_step (struct regcache *regcache)
 {
-  struct gdbarch *arch = get_frame_arch (frame);
+  struct gdbarch *arch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
-  struct address_space *aspace = get_frame_address_space (frame);
   CORE_ADDR npc, nnpc;
 
   CORE_ADDR pc, orig_npc;
-  VEC (CORE_ADDR) *next_pcs = NULL;
+  std::vector<CORE_ADDR> next_pcs;
 
-  pc = get_frame_register_unsigned (frame, tdep->pc_regnum);
-  orig_npc = npc = get_frame_register_unsigned (frame, tdep->npc_regnum);
+  pc = regcache_raw_get_unsigned (regcache, tdep->pc_regnum);
+  orig_npc = npc = regcache_raw_get_unsigned (regcache, tdep->npc_regnum);
 
   /* Analyze the instruction at PC.  */
-  nnpc = sparc_analyze_control_transfer (frame, pc, &npc);
+  nnpc = sparc_analyze_control_transfer (regcache, pc, &npc);
   if (npc != 0)
-    VEC_safe_push (CORE_ADDR, next_pcs, npc);
+    next_pcs.push_back (npc);
 
   if (nnpc != 0)
-    VEC_safe_push (CORE_ADDR, next_pcs, nnpc);
+    next_pcs.push_back (nnpc);
 
   /* Assert that we have set at least one breakpoint, and that
      they're not set at the same spot - unless we're going
@@ -1633,7 +1756,7 @@ sparc_software_single_step (struct frame_info *frame)
 static void
 sparc_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
+  struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
 
   regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc);
   regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4);
@@ -1650,16 +1773,43 @@ sparc_iterate_over_regset_sections (struct gdbarch *gdbarch,
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  cb (".reg", tdep->sizeof_gregset, tdep->gregset, NULL, cb_data);
-  cb (".reg2", tdep->sizeof_fpregset, tdep->fpregset, NULL, cb_data);
+  cb (".reg", tdep->sizeof_gregset, tdep->sizeof_gregset, tdep->gregset, NULL,
+      cb_data);
+  cb (".reg2", tdep->sizeof_fpregset, tdep->sizeof_fpregset, tdep->fpregset,
+      NULL, cb_data);
 }
 \f
 
+static int
+validate_tdesc_registers (const struct target_desc *tdesc,
+                          struct tdesc_arch_data *tdesc_data,
+                          const char *feature_name,
+                          const char *register_names[],
+                          unsigned int registers_num,
+                          unsigned int reg_start)
+{
+  int valid_p = 1;
+  const struct tdesc_feature *feature;
+
+  feature = tdesc_find_feature (tdesc, feature_name);
+  if (feature == NULL)
+    return 0;
+
+  for (unsigned int i = 0; i < registers_num; i++)
+    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                        reg_start + i,
+                                        register_names[i]);
+
+  return valid_p;
+}
+
 static struct gdbarch *
 sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   struct gdbarch_tdep *tdep;
+  const struct target_desc *tdesc = info.target_desc;
   struct gdbarch *gdbarch;
+  int valid_p = 1;
 
   /* If there is already a candidate, use it.  */
   arches = gdbarch_list_lookup_by_info (arches, &info);
@@ -1673,14 +1823,23 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->pc_regnum = SPARC32_PC_REGNUM;
   tdep->npc_regnum = SPARC32_NPC_REGNUM;
   tdep->step_trap = sparc_step_trap;
+  tdep->fpu_register_names = sparc32_fpu_register_names;
+  tdep->fpu_registers_num = ARRAY_SIZE (sparc32_fpu_register_names);
+  tdep->cp0_register_names = sparc32_cp0_register_names;
+  tdep->cp0_registers_num = ARRAY_SIZE (sparc32_cp0_register_names);
 
   set_gdbarch_long_double_bit (gdbarch, 128);
   set_gdbarch_long_double_format (gdbarch, floatformats_sparc_quad);
 
+  set_gdbarch_wchar_bit (gdbarch, 16);
+  set_gdbarch_wchar_signed (gdbarch, 1);
+
   set_gdbarch_num_regs (gdbarch, SPARC32_NUM_REGS);
   set_gdbarch_register_name (gdbarch, sparc32_register_name);
   set_gdbarch_register_type (gdbarch, sparc32_register_type);
   set_gdbarch_num_pseudo_regs (gdbarch, SPARC32_NUM_PSEUDO_REGS);
+  set_tdesc_pseudo_register_name (gdbarch, sparc32_pseudo_register_name);
+  set_tdesc_pseudo_register_type (gdbarch, sparc32_pseudo_register_type);
   set_gdbarch_pseudo_register_read (gdbarch, sparc32_pseudo_register_read);
   set_gdbarch_pseudo_register_write (gdbarch, sparc32_pseudo_register_write);
 
@@ -1711,19 +1870,18 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_frame_args_skip (gdbarch, 8);
 
-  set_gdbarch_print_insn (gdbarch, print_insn_sparc);
-
   set_gdbarch_software_single_step (gdbarch, sparc_software_single_step);
   set_gdbarch_write_pc (gdbarch, sparc_write_pc);
 
   set_gdbarch_dummy_id (gdbarch, sparc_dummy_id);
 
-  set_gdbarch_unwind_pc (gdbarch, sparc_unwind_pc);
-
   frame_base_set_default (gdbarch, &sparc32_frame_base);
 
   /* Hook in the DWARF CFI frame unwinder.  */
   dwarf2_frame_set_init_reg (gdbarch, sparc32_dwarf2_frame_init_reg);
+  /* Register DWARF vendor CFI handler.  */
+  set_gdbarch_execute_dwarf_cfa_vendor_op (gdbarch,
+                                          sparc_execute_dwarf_cfa_vendor_op);
   /* FIXME: kettenis/20050423: Don't enable the unwinder until the
      StackGhost issues have been resolved.  */
 
@@ -1732,6 +1890,39 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   frame_unwind_append_unwinder (gdbarch, &sparc32_frame_unwind);
 
+  if (tdesc_has_registers (tdesc))
+    {
+      struct tdesc_arch_data *tdesc_data = tdesc_data_alloc ();
+
+      /* Validate that the descriptor provides the mandatory registers
+         and allocate their numbers. */
+      valid_p &= validate_tdesc_registers (tdesc, tdesc_data,
+                                           "org.gnu.gdb.sparc.cpu",
+                                           sparc_core_register_names,
+                                           ARRAY_SIZE (sparc_core_register_names),
+                                           SPARC_G0_REGNUM);
+      valid_p &= validate_tdesc_registers (tdesc, tdesc_data,
+                                           "org.gnu.gdb.sparc.fpu",
+                                           tdep->fpu_register_names,
+                                           tdep->fpu_registers_num,
+                                           SPARC_F0_REGNUM);
+      valid_p &= validate_tdesc_registers (tdesc, tdesc_data,
+                                           "org.gnu.gdb.sparc.cp0",
+                                           tdep->cp0_register_names,
+                                           tdep->cp0_registers_num,
+                                           SPARC_F0_REGNUM
+                                           + tdep->fpu_registers_num);
+      if (!valid_p)
+        {
+          tdesc_data_cleanup (tdesc_data);
+          return NULL;
+        }
+
+      /* Target description may have changed. */
+      info.tdesc_data = tdesc_data;
+      tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+    }
+
   /* If we have register sets, enable the generic core file support.  */
   if (tdep->gregset)
     set_gdbarch_iterate_over_regset_sections
@@ -1747,7 +1938,7 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 void
 sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int offset = 0;
   gdb_byte buf[8];
@@ -1775,7 +1966,7 @@ sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum)
                                          i7 ^ wcookie);
                }
 
-             regcache_raw_supply (regcache, i, buf);
+             regcache->raw_supply (i, buf);
            }
        }
     }
@@ -1787,7 +1978,7 @@ sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum)
 
       /* Clear out the top half of the temporary buffer, and put the
         register value in the bottom half if we're in 64-bit mode.  */
-      if (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 64)
+      if (gdbarch_ptr_bit (regcache->arch ()) == 64)
        {
          memset (buf, 0, 4);
          offset = 4;
@@ -1811,7 +2002,7 @@ sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum)
                                          i7 ^ wcookie);
                }
 
-             regcache_raw_supply (regcache, i, buf);
+             regcache->raw_supply (i, buf);
            }
        }
     }
@@ -1821,7 +2012,7 @@ void
 sparc_collect_rwindow (const struct regcache *regcache,
                       CORE_ADDR sp, int regnum)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int offset = 0;
   gdb_byte buf[8];
@@ -1836,7 +2027,7 @@ sparc_collect_rwindow (const struct regcache *regcache,
        {
          if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i)
            {
-             regcache_raw_collect (regcache, i, buf);
+             regcache->raw_collect (i, buf);
 
              /* Handle StackGhost.  */
              if (i == SPARC_I7_REGNUM)
@@ -1859,14 +2050,14 @@ sparc_collect_rwindow (const struct regcache *regcache,
       sp &= 0xffffffffUL;
 
       /* Only use the bottom half if we're in 64-bit mode.  */
-      if (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 64)
+      if (gdbarch_ptr_bit (regcache->arch ()) == 64)
        offset = 4;
 
       for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
        {
          if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i)
            {
-             regcache_raw_collect (regcache, i, buf);
+             regcache->raw_collect (i, buf);
 
              /* Handle StackGhost.  */
              if (i == SPARC_I7_REGNUM)
@@ -1898,23 +2089,19 @@ sparc32_supply_gregset (const struct sparc_gregmap *gregmap,
   int i;
 
   if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
-    regcache_raw_supply (regcache, SPARC32_PSR_REGNUM,
-                        regs + gregmap->r_psr_offset);
+    regcache->raw_supply (SPARC32_PSR_REGNUM, regs + gregmap->r_psr_offset);
 
   if (regnum == SPARC32_PC_REGNUM || regnum == -1)
-    regcache_raw_supply (regcache, SPARC32_PC_REGNUM,
-                        regs + gregmap->r_pc_offset);
+    regcache->raw_supply (SPARC32_PC_REGNUM, regs + gregmap->r_pc_offset);
 
   if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
-    regcache_raw_supply (regcache, SPARC32_NPC_REGNUM,
-                        regs + gregmap->r_npc_offset);
+    regcache->raw_supply (SPARC32_NPC_REGNUM, regs + gregmap->r_npc_offset);
 
   if (regnum == SPARC32_Y_REGNUM || regnum == -1)
-    regcache_raw_supply (regcache, SPARC32_Y_REGNUM,
-                        regs + gregmap->r_y_offset);
+    regcache->raw_supply (SPARC32_Y_REGNUM, regs + gregmap->r_y_offset);
 
   if (regnum == SPARC_G0_REGNUM || regnum == -1)
-    regcache_raw_supply (regcache, SPARC_G0_REGNUM, &zero);
+    regcache->raw_supply (SPARC_G0_REGNUM, &zero);
 
   if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
     {
@@ -1923,7 +2110,7 @@ sparc32_supply_gregset (const struct sparc_gregmap *gregmap,
       for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
        {
          if (regnum == i || regnum == -1)
-           regcache_raw_supply (regcache, i, regs + offset);
+           regcache->raw_supply (i, regs + offset);
          offset += 4;
        }
     }
@@ -1946,7 +2133,7 @@ sparc32_supply_gregset (const struct sparc_gregmap *gregmap,
          for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
            {
              if (regnum == i || regnum == -1)
-               regcache_raw_supply (regcache, i, regs + offset);
+               regcache->raw_supply (i, regs + offset);
              offset += 4;
            }
        }
@@ -1962,20 +2149,16 @@ sparc32_collect_gregset (const struct sparc_gregmap *gregmap,
   int i;
 
   if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
-    regcache_raw_collect (regcache, SPARC32_PSR_REGNUM,
-                         regs + gregmap->r_psr_offset);
+    regcache->raw_collect (SPARC32_PSR_REGNUM, regs + gregmap->r_psr_offset);
 
   if (regnum == SPARC32_PC_REGNUM || regnum == -1)
-    regcache_raw_collect (regcache, SPARC32_PC_REGNUM,
-                         regs + gregmap->r_pc_offset);
+    regcache->raw_collect (SPARC32_PC_REGNUM, regs + gregmap->r_pc_offset);
 
   if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
-    regcache_raw_collect (regcache, SPARC32_NPC_REGNUM,
-                         regs + gregmap->r_npc_offset);
+    regcache->raw_collect (SPARC32_NPC_REGNUM, regs + gregmap->r_npc_offset);
 
   if (regnum == SPARC32_Y_REGNUM || regnum == -1)
-    regcache_raw_collect (regcache, SPARC32_Y_REGNUM,
-                         regs + gregmap->r_y_offset);
+    regcache->raw_collect (SPARC32_Y_REGNUM, regs + gregmap->r_y_offset);
 
   if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
     {
@@ -1985,7 +2168,7 @@ sparc32_collect_gregset (const struct sparc_gregmap *gregmap,
       for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
        {
          if (regnum == i || regnum == -1)
-           regcache_raw_collect (regcache, i, regs + offset);
+           regcache->raw_collect (i, regs + offset);
          offset += 4;
        }
     }
@@ -2001,7 +2184,7 @@ sparc32_collect_gregset (const struct sparc_gregmap *gregmap,
          for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
            {
              if (regnum == i || regnum == -1)
-               regcache_raw_collect (regcache, i, regs + offset);
+               regcache->raw_collect (i, regs + offset);
              offset += 4;
            }
        }
@@ -2019,13 +2202,12 @@ sparc32_supply_fpregset (const struct sparc_fpregmap *fpregmap,
   for (i = 0; i < 32; i++)
     {
       if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1)
-       regcache_raw_supply (regcache, SPARC_F0_REGNUM + i,
-                            regs + fpregmap->r_f0_offset + (i * 4));
+       regcache->raw_supply (SPARC_F0_REGNUM + i,
+                             regs + fpregmap->r_f0_offset + (i * 4));
     }
 
   if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
-    regcache_raw_supply (regcache, SPARC32_FSR_REGNUM,
-                        regs + fpregmap->r_fsr_offset);
+    regcache->raw_supply (SPARC32_FSR_REGNUM, regs + fpregmap->r_fsr_offset);
 }
 
 void
@@ -2039,13 +2221,13 @@ sparc32_collect_fpregset (const struct sparc_fpregmap *fpregmap,
   for (i = 0; i < 32; i++)
     {
       if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1)
-       regcache_raw_collect (regcache, SPARC_F0_REGNUM + i,
-                             regs + fpregmap->r_f0_offset + (i * 4));
+       regcache->raw_collect (SPARC_F0_REGNUM + i,
+                              regs + fpregmap->r_f0_offset + (i * 4));
     }
 
   if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
-    regcache_raw_collect (regcache, SPARC32_FSR_REGNUM,
-                         regs + fpregmap->r_fsr_offset);
+    regcache->raw_collect (SPARC32_FSR_REGNUM,
+                          regs + fpregmap->r_fsr_offset);
 }
 \f
 
@@ -2075,13 +2257,10 @@ const struct sparc_fpregmap sparc32_bsd_fpregmap =
   0 * 4,                       /* %f0 */
   32 * 4,                      /* %fsr */
 };
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-void _initialize_sparc_tdep (void);
 
+void _initialize_sparc_tdep ();
 void
-_initialize_sparc_tdep (void)
+_initialize_sparc_tdep ()
 {
   register_gdbarch_init (bfd_arch_sparc, sparc32_gdbarch_init);
 }
This page took 0.037702 seconds and 4 git commands to generate.