gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / riscv-tdep.c
index d585b0be5ab031cf740245528cdf764295dbd1ae..0842dcbcb239abdf82c01c3585c542bdd7d51c18 100644 (file)
@@ -47,7 +47,7 @@
 #include "floatformat.h"
 #include "remote.h"
 #include "target-descriptions.h"
-#include "dwarf2-frame.h"
+#include "dwarf2/frame.h"
 #include "user-regs.h"
 #include "valprint.h"
 #include "gdbsupport/common-defs.h"
@@ -240,7 +240,7 @@ static struct riscv_register_feature riscv_csr_feature =
 {
  "org.gnu.gdb.riscv.csr",
  {
-#define DECLARE_CSR(NAME,VALUE) \
+#define DECLARE_CSR(NAME,VALUE,CLASS,DEFINE_VER,ABORT_VER) \
   { RISCV_ ## VALUE ## _REGNUM, { # NAME }, false },
 #include "opcode/riscv-opc.h"
 #undef DECLARE_CSR
@@ -284,47 +284,11 @@ show_use_compressed_breakpoints (struct ui_file *file, int from_tty,
 static struct cmd_list_element *setriscvcmdlist = NULL;
 static struct cmd_list_element *showriscvcmdlist = NULL;
 
-/* The show callback for the 'show riscv' prefix command.  */
-
-static void
-show_riscv_command (const char *args, int from_tty)
-{
-  help_list (showriscvcmdlist, "show riscv ", all_commands, gdb_stdout);
-}
-
-/* The set callback for the 'set riscv' prefix command.  */
-
-static void
-set_riscv_command (const char *args, int from_tty)
-{
-  printf_unfiltered
-    (_("\"set riscv\" must be followed by an appropriate subcommand.\n"));
-  help_list (setriscvcmdlist, "set riscv ", all_commands, gdb_stdout);
-}
-
 /* The set and show lists for 'set riscv' and 'show riscv' prefixes.  */
 
 static struct cmd_list_element *setdebugriscvcmdlist = NULL;
 static struct cmd_list_element *showdebugriscvcmdlist = NULL;
 
-/* The show callback for the 'show debug riscv' prefix command.  */
-
-static void
-show_debug_riscv_command (const char *args, int from_tty)
-{
-  help_list (showdebugriscvcmdlist, "show debug riscv ", all_commands, gdb_stdout);
-}
-
-/* The set callback for the 'set debug riscv' prefix command.  */
-
-static void
-set_debug_riscv_command (const char *args, int from_tty)
-{
-  printf_unfiltered
-    (_("\"set debug riscv\" must be followed by an appropriate subcommand.\n"));
-  help_list (setdebugriscvcmdlist, "set debug riscv ", all_commands, gdb_stdout);
-}
-
 /* The show callback for all 'show debug riscv VARNAME' variables.  */
 
 static void
@@ -534,7 +498,7 @@ riscv_register_name (struct gdbarch *gdbarch, int regnum)
 
   if (regnum >= RISCV_FIRST_CSR_REGNUM && regnum <= RISCV_LAST_CSR_REGNUM)
     {
-#define DECLARE_CSR(NAME,VALUE) \
+#define DECLARE_CSR(NAME,VALUE,CLASS,DEFINE_VER,ABORT_VER) \
       case RISCV_ ## VALUE ## _REGNUM: return # NAME;
 
       switch (regnum)
@@ -580,7 +544,7 @@ riscv_fpreg_d_type (struct gdbarch *gdbarch)
       append_composite_type_field (t, "float", bt->builtin_float);
       append_composite_type_field (t, "double", bt->builtin_double);
       TYPE_VECTOR (t) = 1;
-      TYPE_NAME (t) = "builtin_type_fpreg_d";
+      t->set_name ("builtin_type_fpreg_d");
       tdep->riscv_fpreg_d_type = t;
     }
 
@@ -610,10 +574,10 @@ riscv_register_type (struct gdbarch *gdbarch, int regnum)
          present the registers using a union type.  */
       int flen = riscv_isa_flen (gdbarch);
       if (flen == 8
-          && TYPE_CODE (type) == TYPE_CODE_FLT
+          && type->code () == TYPE_CODE_FLT
           && TYPE_LENGTH (type) == flen
-          && (strcmp (TYPE_NAME (type), "builtin_type_ieee_double") == 0
-              || strcmp (TYPE_NAME (type), "double") == 0))
+          && (strcmp (type->name (), "builtin_type_ieee_double") == 0
+              || strcmp (type->name (), "double") == 0))
         type = riscv_fpreg_d_type (gdbarch);
     }
 
@@ -623,7 +587,7 @@ riscv_register_type (struct gdbarch *gdbarch, int regnum)
        || regnum == RISCV_SP_REGNUM
        || regnum == RISCV_GP_REGNUM
        || regnum == RISCV_TP_REGNUM)
-      && TYPE_CODE (type) == TYPE_CODE_INT
+      && type->code () == TYPE_CODE_INT
       && TYPE_LENGTH (type) == xlen)
     {
       /* This spots the case where some interesting registers are defined
@@ -676,16 +640,16 @@ riscv_print_one_register_info (struct gdbarch *gdbarch,
   print_raw_format = (value_entirely_available (val)
                      && !value_optimized_out (val));
 
-  if (TYPE_CODE (regtype) == TYPE_CODE_FLT
-      || (TYPE_CODE (regtype) == TYPE_CODE_UNION
-         && TYPE_NFIELDS (regtype) == 2
-         && TYPE_CODE (TYPE_FIELD_TYPE (regtype, 0)) == TYPE_CODE_FLT
-         && TYPE_CODE (TYPE_FIELD_TYPE (regtype, 1)) == TYPE_CODE_FLT)
-      || (TYPE_CODE (regtype) == TYPE_CODE_UNION
-         && TYPE_NFIELDS (regtype) == 3
-         && TYPE_CODE (TYPE_FIELD_TYPE (regtype, 0)) == TYPE_CODE_FLT
-         && TYPE_CODE (TYPE_FIELD_TYPE (regtype, 1)) == TYPE_CODE_FLT
-         && TYPE_CODE (TYPE_FIELD_TYPE (regtype, 2)) == TYPE_CODE_FLT))
+  if (regtype->code () == TYPE_CODE_FLT
+      || (regtype->code () == TYPE_CODE_UNION
+         && regtype->num_fields () == 2
+         && TYPE_FIELD_TYPE (regtype, 0)->code () == TYPE_CODE_FLT
+         && TYPE_FIELD_TYPE (regtype, 1)->code () == TYPE_CODE_FLT)
+      || (regtype->code () == TYPE_CODE_UNION
+         && regtype->num_fields () == 3
+         && TYPE_FIELD_TYPE (regtype, 0)->code () == TYPE_CODE_FLT
+         && TYPE_FIELD_TYPE (regtype, 1)->code () == TYPE_CODE_FLT
+         && TYPE_FIELD_TYPE (regtype, 2)->code () == TYPE_CODE_FLT))
     {
       struct value_print_options opts;
       const gdb_byte *valaddr = value_contents_for_printing (val);
@@ -694,9 +658,7 @@ riscv_print_one_register_info (struct gdbarch *gdbarch,
       get_user_print_options (&opts);
       opts.deref_ref = 1;
 
-      val_print (regtype,
-                value_embedded_offset (val), 0,
-                file, 0, val, &opts, current_language);
+      common_val_print (val, file, 0, &opts, current_language);
 
       if (print_raw_format)
        {
@@ -713,9 +675,7 @@ riscv_print_one_register_info (struct gdbarch *gdbarch,
       /* Print the register in hex.  */
       get_formatted_print_options (&opts, 'x');
       opts.deref_ref = 1;
-      val_print (regtype,
-                value_embedded_offset (val), 0,
-                file, 0, val, &opts, current_language);
+      common_val_print (val, file, 0, &opts, current_language);
 
       if (print_raw_format)
        {
@@ -849,9 +809,7 @@ riscv_print_one_register_info (struct gdbarch *gdbarch,
                  get_user_print_options (&opts);
                  opts.deref_ref = 1;
                  fprintf_filtered (file, "\t");
-                 val_print (regtype,
-                            value_embedded_offset (val), 0,
-                            file, 0, val, &opts, current_language);
+                 common_val_print (val, file, 0, &opts, current_language);
                }
            }
        }
@@ -870,7 +828,7 @@ riscv_is_regnum_a_named_csr (int regnum)
 
   switch (regnum)
     {
-#define DECLARE_CSR(name, num) case RISCV_ ## num ## _REGNUM:
+#define DECLARE_CSR(name, num, class, define_ver, abort_ver) case RISCV_ ## num ## _REGNUM:
 #include "opcode/riscv-opc.h"
 #undef DECLARE_CSR
       return true;
@@ -1670,7 +1628,7 @@ static ULONGEST
 riscv_type_align (gdbarch *gdbarch, type *type)
 {
   type = check_typedef (type);
-  if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
+  if (type->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
     return std::min (TYPE_LENGTH (type), (ULONGEST) BIGGEST_ALIGNMENT);
 
   /* Anything else will be aligned by the generic code.  */
@@ -1733,8 +1691,9 @@ struct riscv_arg_info
        will go.  */
     int c_length;
 
-    /* The offset within CONTENTS for this part of the argument.  Will
-       always be 0 for the first part.  For the second part of the
+    /* The offset within CONTENTS for this part of the argument.  This can
+       be non-zero even for the first part (the first field of a struct can
+       have a non-zero offset due to padding).  For the second part of the
        argument, this might be the C_LENGTH value of the first part,
        however, if we are passing a structure in two registers, and there's
        is padding between the first and second field, then this offset
@@ -2085,7 +2044,7 @@ private:
 void
 riscv_struct_info::analyse_inner (struct type *type, int offset)
 {
-  unsigned int count = TYPE_NFIELDS (type);
+  unsigned int count = type->num_fields ();
   unsigned int i;
 
   for (i = 0; i < count; ++i)
@@ -2098,7 +2057,7 @@ riscv_struct_info::analyse_inner (struct type *type, int offset)
       int field_offset
        = offset + TYPE_FIELD_BITPOS (type, i) / TARGET_CHAR_BIT;
 
-      switch (TYPE_CODE (field_type))
+      switch (field_type->code ())
        {
        case TYPE_CODE_STRUCT:
          analyse_inner (field_type, field_offset);
@@ -2145,7 +2104,7 @@ riscv_call_arg_struct (struct riscv_arg_info *ainfo,
 
       sinfo.analyse (ainfo->type);
       if (sinfo.number_of_fields () == 1
-         && TYPE_CODE (sinfo.field_type (0)) == TYPE_CODE_COMPLEX)
+         && sinfo.field_type(0)->code () == TYPE_CODE_COMPLEX)
        {
          /* The following is similar to RISCV_CALL_ARG_COMPLEX_FLOAT,
             except we use the type of the complex field instead of the
@@ -2175,7 +2134,7 @@ riscv_call_arg_struct (struct riscv_arg_info *ainfo,
        }
 
       if (sinfo.number_of_fields () == 1
-         && TYPE_CODE (sinfo.field_type (0)) == TYPE_CODE_FLT)
+         && sinfo.field_type(0)->code () == TYPE_CODE_FLT)
        {
          /* The following is similar to RISCV_CALL_ARG_SCALAR_FLOAT,
             except we use the type of the first scalar field instead of
@@ -2198,9 +2157,9 @@ riscv_call_arg_struct (struct riscv_arg_info *ainfo,
        }
 
       if (sinfo.number_of_fields () == 2
-         && TYPE_CODE (sinfo.field_type (0)) == TYPE_CODE_FLT
+         && sinfo.field_type(0)->code () == TYPE_CODE_FLT
          && TYPE_LENGTH (sinfo.field_type (0)) <= cinfo->flen
-         && TYPE_CODE (sinfo.field_type (1)) == TYPE_CODE_FLT
+         && sinfo.field_type(1)->code () == TYPE_CODE_FLT
          && TYPE_LENGTH (sinfo.field_type (1)) <= cinfo->flen
          && riscv_arg_regs_available (&cinfo->float_regs) >= 2)
        {
@@ -2224,7 +2183,7 @@ riscv_call_arg_struct (struct riscv_arg_info *ainfo,
 
       if (sinfo.number_of_fields () == 2
          && riscv_arg_regs_available (&cinfo->int_regs) >= 1
-         && (TYPE_CODE (sinfo.field_type (0)) == TYPE_CODE_FLT
+         && (sinfo.field_type(0)->code () == TYPE_CODE_FLT
              && TYPE_LENGTH (sinfo.field_type (0)) <= cinfo->flen
              && is_integral_type (sinfo.field_type (1))
              && TYPE_LENGTH (sinfo.field_type (1)) <= cinfo->xlen))
@@ -2248,7 +2207,7 @@ riscv_call_arg_struct (struct riscv_arg_info *ainfo,
          && riscv_arg_regs_available (&cinfo->int_regs) >= 1
          && (is_integral_type (sinfo.field_type (0))
              && TYPE_LENGTH (sinfo.field_type (0)) <= cinfo->xlen
-             && TYPE_CODE (sinfo.field_type (1)) == TYPE_CODE_FLT
+             && sinfo.field_type(1)->code () == TYPE_CODE_FLT
              && TYPE_LENGTH (sinfo.field_type (1)) <= cinfo->flen))
        {
          int len0 = TYPE_LENGTH (sinfo.field_type (0));
@@ -2301,7 +2260,7 @@ riscv_arg_location (struct gdbarch *gdbarch,
   ainfo->argloc[0].c_length = 0;
   ainfo->argloc[1].c_length = 0;
 
-  switch (TYPE_CODE (ainfo->type))
+  switch (ainfo->type->code ())
     {
     case TYPE_CODE_INT:
     case TYPE_CODE_BOOL:
@@ -2423,6 +2382,26 @@ riscv_print_arg_location (ui_file *stream, struct gdbarch *gdbarch,
     }
 }
 
+/* Wrapper around REGCACHE->cooked_write.  Places the LEN bytes of DATA
+   into a buffer that is at least as big as the register REGNUM, padding
+   out the DATA with either 0x00, or 0xff.  For floating point registers
+   0xff is used, for everyone else 0x00 is used.  */
+
+static void
+riscv_regcache_cooked_write (int regnum, const gdb_byte *data, int len,
+                            struct regcache *regcache, int flen)
+{
+  gdb_byte tmp [sizeof (ULONGEST)];
+
+  /* FP values in FP registers must be NaN-boxed.  */
+  if (riscv_is_fp_regno_p (regnum) && len < flen)
+    memset (tmp, -1, sizeof (tmp));
+  else
+    memset (tmp, 0, sizeof (tmp));
+  memcpy (tmp, data, len);
+  regcache->cooked_write (regnum, tmp);
+}
+
 /* Implement the push dummy call gdbarch callback.  */
 
 static CORE_ADDR
@@ -2449,7 +2428,7 @@ riscv_push_dummy_call (struct gdbarch *gdbarch,
 
   struct type *ftype = check_typedef (value_type (function));
 
-  if (TYPE_CODE (ftype) == TYPE_CODE_PTR)
+  if (ftype->code () == TYPE_CODE_PTR)
     ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
 
   /* We'll use register $a0 if we're returning a struct.  */
@@ -2466,7 +2445,7 @@ riscv_push_dummy_call (struct gdbarch *gdbarch,
       arg_type = check_typedef (value_type (arg_value));
 
       riscv_arg_location (gdbarch, info, &call_info, arg_type,
-                         TYPE_VARARGS (ftype) && i >= TYPE_NFIELDS (ftype));
+                         TYPE_VARARGS (ftype) && i >= ftype->num_fields ());
 
       if (info->type != arg_type)
        arg_value = value_cast (info->type, arg_value);
@@ -2532,18 +2511,13 @@ riscv_push_dummy_call (struct gdbarch *gdbarch,
        {
        case riscv_arg_info::location::in_reg:
          {
-           gdb_byte tmp [sizeof (ULONGEST)];
-
            gdb_assert (info->argloc[0].c_length <= info->length);
-           /* FP values in FP registers must be NaN-boxed.  */
-           if (riscv_is_fp_regno_p (info->argloc[0].loc_data.regno)
-               && info->argloc[0].c_length < call_info.flen)
-             memset (tmp, -1, sizeof (tmp));
-           else
-             memset (tmp, 0, sizeof (tmp));
-           memcpy (tmp, (info->contents + info->argloc[0].c_offset),
-                   info->argloc[0].c_length);
-           regcache->cooked_write (info->argloc[0].loc_data.regno, tmp);
+
+           riscv_regcache_cooked_write (info->argloc[0].loc_data.regno,
+                                        (info->contents
+                                         + info->argloc[0].c_offset),
+                                        info->argloc[0].c_length,
+                                        regcache, call_info.flen);
            second_arg_length =
              (((info->argloc[0].c_length + info->argloc[0].c_offset) < info->length)
               ? info->argloc[1].c_length : 0);
@@ -2575,19 +2549,13 @@ riscv_push_dummy_call (struct gdbarch *gdbarch,
            {
            case riscv_arg_info::location::in_reg:
              {
-               gdb_byte tmp [sizeof (ULONGEST)];
-
                gdb_assert ((riscv_is_fp_regno_p (info->argloc[1].loc_data.regno)
                             && second_arg_length <= call_info.flen)
                            || second_arg_length <= call_info.xlen);
-               /* FP values in FP registers must be NaN-boxed.  */
-               if (riscv_is_fp_regno_p (info->argloc[1].loc_data.regno)
-                   && second_arg_length < call_info.flen)
-                 memset (tmp, -1, sizeof (tmp));
-               else
-                 memset (tmp, 0, sizeof (tmp));
-               memcpy (tmp, second_arg_data, second_arg_length);
-               regcache->cooked_write (info->argloc[1].loc_data.regno, tmp);
+               riscv_regcache_cooked_write (info->argloc[1].loc_data.regno,
+                                            second_arg_data,
+                                            second_arg_length,
+                                            regcache, call_info.flen);
              }
              break;
 
@@ -2707,9 +2675,9 @@ riscv_return_value (struct gdbarch  *gdbarch,
              if (writebuf)
                {
                  const gdb_byte *ptr = writebuf + info.argloc[0].c_offset;
-                 regcache->cooked_write_part (regnum, 0,
+                 riscv_regcache_cooked_write (regnum, ptr,
                                               info.argloc[0].c_length,
-                                              ptr);
+                                              regcache, call_info.flen);
                }
 
              /* A return value in register can have a second part in a
@@ -2736,10 +2704,11 @@ riscv_return_value (struct gdbarch  *gdbarch,
 
                      if (writebuf)
                        {
-                         writebuf += info.argloc[1].c_offset;
-                         regcache->cooked_write_part (regnum, 0,
-                                                      info.argloc[1].c_length,
-                                                      writebuf);
+                         const gdb_byte *ptr
+                           = writebuf + info.argloc[1].c_offset;
+                         riscv_regcache_cooked_write
+                           (regnum, ptr, info.argloc[1].c_length,
+                            regcache, call_info.flen);
                        }
                      break;
 
@@ -2973,7 +2942,7 @@ riscv_find_default_target_description (const struct gdbarch_info info)
     features.xlen = 8;
 
   /* Now build a target description based on the feature set.  */
-  return riscv_create_target_description (features);
+  return riscv_lookup_target_description (features);
 }
 
 /* All of the registers in REG_SET are checked for in FEATURE, TDESC_DATA
@@ -3522,15 +3491,15 @@ _initialize_riscv_tdep ()
 
   /* Add root prefix command for all "set debug riscv" and "show debug
      riscv" commands.  */
-  add_prefix_cmd ("riscv", no_class, set_debug_riscv_command,
-                 _("RISC-V specific debug commands."),
-                 &setdebugriscvcmdlist, "set debug riscv ", 0,
-                 &setdebuglist);
+  add_basic_prefix_cmd ("riscv", no_class,
+                       _("RISC-V specific debug commands."),
+                       &setdebugriscvcmdlist, "set debug riscv ", 0,
+                       &setdebuglist);
 
-  add_prefix_cmd ("riscv", no_class, show_debug_riscv_command,
-                 _("RISC-V specific debug commands."),
-                 &showdebugriscvcmdlist, "show debug riscv ", 0,
-                 &showdebuglist);
+  add_show_prefix_cmd ("riscv", no_class,
+                      _("RISC-V specific debug commands."),
+                      &showdebugriscvcmdlist, "show debug riscv ", 0,
+                      &showdebuglist);
 
   add_setshow_zuinteger_cmd ("breakpoints", class_maintenance,
                             &riscv_debug_breakpoints,  _("\
@@ -3573,13 +3542,13 @@ initialisation process."),
                             &setdebugriscvcmdlist, &showdebugriscvcmdlist);
 
   /* Add root prefix command for all "set riscv" and "show riscv" commands.  */
-  add_prefix_cmd ("riscv", no_class, set_riscv_command,
-                 _("RISC-V specific commands."),
-                 &setriscvcmdlist, "set riscv ", 0, &setlist);
+  add_basic_prefix_cmd ("riscv", no_class,
+                       _("RISC-V specific commands."),
+                       &setriscvcmdlist, "set riscv ", 0, &setlist);
 
-  add_prefix_cmd ("riscv", no_class, show_riscv_command,
-                 _("RISC-V specific commands."),
-                 &showriscvcmdlist, "show riscv ", 0, &showlist);
+  add_show_prefix_cmd ("riscv", no_class,
+                      _("RISC-V specific commands."),
+                      &showriscvcmdlist, "show riscv ", 0, &showlist);
 
 
   use_compressed_breakpoints = AUTO_BOOLEAN_AUTO;
This page took 0.031981 seconds and 4 git commands to generate.