Target FP printing: Use floatformat_to_string in tdep code
[deliverable/binutils-gdb.git] / gdb / sh64-tdep.c
index cbbefddfe51655beeccb584043b8129e593405cd..ac216232b8fbd28f7cdac46da1bccb527142dae7 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for Renesas Super-H, for GDB.
 
-   Copyright (C) 1993-2016 Free Software Foundation, Inc.
+   Copyright (C) 1993-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -58,8 +58,23 @@ enum sh_abi
 struct gdbarch_tdep
   {
     enum sh_abi sh_abi;
+    /* ISA-specific data types.  */
+    struct type *sh_littlebyte_bigword_type;
   };
 
+struct type *
+sh64_littlebyte_bigword_type (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->sh_littlebyte_bigword_type == NULL)
+    tdep->sh_littlebyte_bigword_type
+      = arch_float_type (gdbarch, -1, "builtin_type_sh_littlebyte_bigword",
+                         floatformats_ieee_double_littlebyte_bigword);
+
+  return tdep->sh_littlebyte_bigword_type;
+}
+
 struct sh64_frame_cache
 {
   /* Base address.  */
@@ -125,7 +140,7 @@ enum
 static const char *
 sh64_register_name (struct gdbarch *gdbarch, int reg_nr)
 {
-  static char *register_names[] =
+  static const char *register_names[] =
   {
     /* SH MEDIA MODE (ISA 32) */
     /* general registers (64-bit) 0-63 */
@@ -1240,18 +1255,11 @@ sh64_extract_return_value (struct type *type, struct regcache *regcache,
       else if (len == 8)
        {
          /* return value stored in DR0_REGNUM.  */
-         DOUBLEST val;
          gdb_byte buf[8];
-
          regcache_cooked_read (regcache, DR0_REGNUM, buf);
          
-         if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
-           floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword,
-                                    buf, &val);
-         else
-           floatformat_to_doublest (&floatformat_ieee_double_big,
-                                    buf, &val);
-         store_typed_floating (valbuf, type, val);
+         convert_typed_floating (buf, sh64_littlebyte_bigword_type (gdbarch),
+                                 valbuf, type);
        }
     }
   else
@@ -1460,12 +1468,8 @@ sh64_register_convert_to_virtual (struct gdbarch *gdbarch, int regnum,
        && regnum <= DR_LAST_REGNUM)
       || (regnum >= DR0_C_REGNUM 
          && regnum <= DR_LAST_C_REGNUM))
-    {
-      DOUBLEST val;
-      floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword, 
-                              from, &val);
-      store_typed_floating (to, type, val);
-    }
+    convert_typed_floating (from, sh64_littlebyte_bigword_type (gdbarch),
+                           to, type);
   else
     error (_("sh64_register_convert_to_virtual "
             "called with non DR register number"));
@@ -1486,11 +1490,8 @@ sh64_register_convert_to_raw (struct gdbarch *gdbarch, struct type *type,
        && regnum <= DR_LAST_REGNUM)
       || (regnum >= DR0_C_REGNUM 
          && regnum <= DR_LAST_C_REGNUM))
-    {
-      DOUBLEST val = extract_typed_floating (from, type);
-      floatformat_from_doublest (&floatformat_ieee_double_littlebyte_bigword, 
-                                &val, to);
-    }
+    convert_typed_floating (from, type,
+                           to, sh64_littlebyte_bigword_type (gdbarch));
   else
     error (_("sh64_register_convert_to_raw called "
             "with non DR register number"));
@@ -1528,12 +1529,12 @@ sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int base_regnum;
   int offset = 0;
-  gdb_byte temp_buffer[MAX_REGISTER_SIZE];
   enum register_status status;
 
   if (reg_nr >= DR0_REGNUM 
       && reg_nr <= DR_LAST_REGNUM)
     {
+      gdb_byte temp_buffer[8];
       base_regnum = sh64_dr_reg_base_num (gdbarch, reg_nr);
 
       /* Build the value in the provided buffer.  */ 
@@ -1580,6 +1581,7 @@ sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
   else if (reg_nr >= R0_C_REGNUM 
           && reg_nr <= T_C_REGNUM)
     {
+      gdb_byte temp_buffer[8];
       base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
 
       /* Build the value in the provided buffer.  */ 
@@ -1607,6 +1609,7 @@ sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
   else if (reg_nr >= DR0_C_REGNUM 
           && reg_nr <= DR_LAST_C_REGNUM)
     {
+      gdb_byte temp_buffer[8];
       base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
 
       /* DR_C regs are double precision registers obtained by
@@ -1639,8 +1642,8 @@ sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
     {
       int fpscr_base_regnum;
       int sr_base_regnum;
-      unsigned int fpscr_value;
-      unsigned int sr_value;
+      ULONGEST fpscr_value;
+      ULONGEST sr_value;
       unsigned int fpscr_c_value;
       unsigned int fpscr_c_part1_value;
       unsigned int fpscr_c_part2_value;
@@ -1662,18 +1665,14 @@ sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
             21-31     reserved
        */
       /* *INDENT-ON* */
-      /* Get FPSCR into a local buffer.  */
-      status = regcache_raw_read (regcache, fpscr_base_regnum, temp_buffer);
+      /* Get FPSCR as an int.  */
+      status = regcache->raw_read (fpscr_base_regnum, &fpscr_value);
       if (status != REG_VALID)
        return status;
-      /* Get value as an int.  */
-      fpscr_value = extract_unsigned_integer (temp_buffer, 4, byte_order);
-      /* Get SR into a local buffer */
-      status = regcache_raw_read (regcache, sr_base_regnum, temp_buffer);
+      /* Get SR as an int.  */
+      status = regcache->raw_read (sr_base_regnum, &sr_value);
       if (status != REG_VALID)
        return status;
-      /* Get value as an int.  */
-      sr_value = extract_unsigned_integer (temp_buffer, 4, byte_order);
       /* Build the new value.  */
       fpscr_c_part1_value = fpscr_value & 0x3fffd;
       fpscr_c_part2_value = (sr_value & 0x7000) << 6;
@@ -1704,11 +1703,11 @@ sh64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int base_regnum, portion;
   int offset;
-  gdb_byte temp_buffer[MAX_REGISTER_SIZE];
 
   if (reg_nr >= DR0_REGNUM
       && reg_nr <= DR_LAST_REGNUM)
     {
+      gdb_byte temp_buffer[8];
       base_regnum = sh64_dr_reg_base_num (gdbarch, reg_nr);
       /* We must pay attention to the endianness.  */
       sh64_register_convert_to_raw (gdbarch, register_type (gdbarch, reg_nr),
@@ -1752,6 +1751,7 @@ sh64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
   else if (reg_nr >= R0_C_REGNUM 
           && reg_nr <= T_C_REGNUM)
     {
+      gdb_byte temp_buffer[8];
       base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
       /* reg_nr is 32 bit here, and base_regnum is 64 bits.  */
       if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
@@ -1779,6 +1779,7 @@ sh64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
   else if (reg_nr >= DR0_C_REGNUM 
           && reg_nr <= DR_LAST_C_REGNUM)
     {
+      gdb_byte temp_buffer[8];
       base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
       for (portion = 0; portion < 2; portion++)
        {
@@ -1813,10 +1814,10 @@ sh64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
     {      
       int fpscr_base_regnum;
       int sr_base_regnum;
-      unsigned int fpscr_value;
-      unsigned int sr_value;
-      unsigned int old_fpscr_value;
-      unsigned int old_sr_value;
+      ULONGEST fpscr_value;
+      ULONGEST sr_value;
+      ULONGEST old_fpscr_value;
+      ULONGEST old_sr_value;
       unsigned int fpscr_c_value;
       unsigned int fpscr_mask;
       unsigned int sr_mask;
@@ -1847,19 +1848,15 @@ sh64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
       fpscr_value = fpscr_c_value & fpscr_mask;
       sr_value = (fpscr_value & sr_mask) >> 6;
       
-      regcache_raw_read (regcache, fpscr_base_regnum, temp_buffer);
-      old_fpscr_value = extract_unsigned_integer (temp_buffer, 4, byte_order);
+      regcache->raw_read (fpscr_base_regnum, &old_fpscr_value);
       old_fpscr_value &= 0xfffc0002;
       fpscr_value |= old_fpscr_value;
-      store_unsigned_integer (temp_buffer, 4, byte_order, fpscr_value);
-      regcache_raw_write (regcache, fpscr_base_regnum, temp_buffer);
-      
-      regcache_raw_read (regcache, sr_base_regnum, temp_buffer);
-      old_sr_value = extract_unsigned_integer (temp_buffer, 4, byte_order);
+      regcache->raw_write (fpscr_base_regnum, fpscr_value);
+
+      regcache->raw_read (sr_base_regnum, &old_sr_value);
       old_sr_value &= 0xffff8fff;
       sr_value |= old_sr_value;
-      store_unsigned_integer (temp_buffer, 4, byte_order, sr_value);
-      regcache_raw_write (regcache, sr_base_regnum, temp_buffer);
+      regcache->raw_write (sr_base_regnum, sr_value);
     }
 
   else if (reg_nr == FPUL_C_REGNUM)
@@ -1918,8 +1915,6 @@ sh64_do_fp_register (struct gdbarch *gdbarch, struct ui_file *file,
                     struct frame_info *frame, int regnum)
 {                              /* Do values for FP (float) regs.  */
   unsigned char *raw_buffer;
-  double flt;  /* Double extracted from raw hex data.  */
-  int inv;
 
   /* Allocate space for the float.  */
   raw_buffer = (unsigned char *)
@@ -1930,26 +1925,22 @@ sh64_do_fp_register (struct gdbarch *gdbarch, struct ui_file *file,
     error (_("can't read register %d (%s)"),
           regnum, gdbarch_register_name (gdbarch, regnum));
 
-  /* Get the register as a number.  */ 
-  flt = unpack_double (builtin_type (gdbarch)->builtin_float,
-                      raw_buffer, &inv);
-
   /* Print the name and some spaces.  */
   fputs_filtered (gdbarch_register_name (gdbarch, regnum), file);
   print_spaces_filtered (15 - strlen (gdbarch_register_name
                                        (gdbarch, regnum)), file);
 
   /* Print the value.  */
-  if (inv)
-    fprintf_filtered (file, "<invalid float>");
-  else
-    fprintf_filtered (file, "%-10.9g", flt);
+  const struct floatformat *fmt
+    = floatformat_from_type (builtin_type (gdbarch)->builtin_float);
+  std::string str = floatformat_to_string (fmt, raw_buffer, "%-10.9g");
+  fprintf_filtered (file, "%s", str.c_str ());
 
   /* Print the fp register as hex.  */
   fprintf_filtered (file, "\t(raw ");
   print_hex_chars (file, raw_buffer,
                   register_size (gdbarch, regnum),
-                  gdbarch_byte_order (gdbarch));
+                  gdbarch_byte_order (gdbarch), true);
   fprintf_filtered (file, ")");
   fprintf_filtered (file, "\n");
 }
@@ -2030,15 +2021,16 @@ static void
 sh64_do_register (struct gdbarch *gdbarch, struct ui_file *file,
                  struct frame_info *frame, int regnum)
 {
-  unsigned char raw_buffer[MAX_REGISTER_SIZE];
   struct value_print_options opts;
+  struct value *val;
 
   fputs_filtered (gdbarch_register_name (gdbarch, regnum), file);
   print_spaces_filtered (15 - strlen (gdbarch_register_name
                                      (gdbarch, regnum)), file);
 
   /* Get the data in raw format.  */
-  if (!deprecated_frame_register_read (frame, regnum, raw_buffer))
+  val = get_frame_register_value (frame, regnum);
+  if (value_optimized_out (val) || !value_entirely_available (val))
     {
       fprintf_filtered (file, "*value not available*\n");
       return;
@@ -2046,13 +2038,15 @@ sh64_do_register (struct gdbarch *gdbarch, struct ui_file *file,
 
   get_formatted_print_options (&opts, 'x');
   opts.deref_ref = 1;
-  val_print (register_type (gdbarch, regnum), raw_buffer, 0, 0,
-            file, 0, NULL, &opts, current_language);
+  val_print (register_type (gdbarch, regnum),
+            0, 0,
+            file, 0, val, &opts, current_language);
   fprintf_filtered (file, "\t");
   get_formatted_print_options (&opts, 0);
   opts.deref_ref = 1;
-  val_print (register_type (gdbarch, regnum), raw_buffer, 0, 0,
-            file, 0, NULL, &opts, current_language);
+  val_print (register_type (gdbarch, regnum),
+            0, 0,
+            file, 0, val, &opts, current_language);
   fprintf_filtered (file, "\n");
 }
 
@@ -2368,7 +2362,7 @@ sh64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* None found, create a new architecture from the information
      provided.  */
-  tdep = XNEW (struct gdbarch_tdep);
+  tdep = XCNEW (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
 
   /* Determine the ABI */
@@ -2413,8 +2407,6 @@ sh64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_breakpoint_kind_from_pc (gdbarch, sh64_breakpoint_kind_from_pc);
   set_gdbarch_sw_breakpoint_from_kind (gdbarch, sh64_sw_breakpoint_from_kind);
-
-  set_gdbarch_print_insn (gdbarch, print_insn_sh);
   set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno);
 
   set_gdbarch_return_value (gdbarch, sh64_return_value);
This page took 0.033993 seconds and 4 git commands to generate.