Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Bhushan Attarde <bhushan.attarde@imgtec.com>
To: <gdb-patches@sourceware.org>
Cc: <Maciej.Rozycki@imgtec.com>, <Matthew.Fortune@imgtec.com>,
	<James.Hogan@imgtec.com>, <Andrew.Bennett@imgtec.com>,
	<Jaydeep.Patil@imgtec.com>,
	Bhushan Attarde <bhushan.attarde@imgtec.com>
Subject: [PATCH 10/24]     MIPS: override fscr/fir types and print control registers specially
Date: Mon, 27 Jun 2016 14:50:00 -0000	[thread overview]
Message-ID: <1467038991-6600-10-git-send-email-bhushan.attarde@imgtec.com> (raw)
In-Reply-To: <1467038991-6600-1-git-send-email-bhushan.attarde@imgtec.com>

    Define types for the MIPS floating point status and control register and
    implementation register, allowing the fields to be decoded.

    gdb/ChangeLog:

        * mips-tdep.c (mips_frm_type, mips_fcflags_type, mips_fcsr_type,
        mips_fir_type): New functions.
        (mips_value_to_register): Return appropriat type for FP control
        and implementation revision register.
        (print_control_register): New function.
        (mips_print_register): Use print_control_register to print
        control registers.
        (print_control_register_row): New function.
        (mips_print_registers_info): Use print_control_register_row to
        print a single complex control register row.
        (mips_gdbarch_init): Initialize fp_rm_type, fp_cflags_type,
        fp_csr_type and fp_ir_type types.
        * mips-tdep.h (gdbarch_tdep): Add fp_rm_type, fp_cflags_type,
        fp_csr_type and fp_ir_type fields.
---
 gdb/mips-tdep.c | 262 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 gdb/mips-tdep.h |   4 +
 2 files changed, 261 insertions(+), 5 deletions(-)

diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 0024edf..2cc49aa 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -1330,6 +1330,179 @@ mips_fp_type (struct gdbarch *gdbarch, int fpnum)
     return mips_fp32_type (gdbarch);
 }
 
+/* Get floating point rounding mode enumeration type */
+
+static struct type *
+mips_frm_type (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->fp_rm_type == NULL)
+    {
+      const struct builtin_type *bt = builtin_type (gdbarch);
+      struct type *t;
+      struct field *f;
+
+      t = arch_type (gdbarch, TYPE_CODE_ENUM, 1, "__gdb_builtin_type_fp_rm");
+      TYPE_UNSIGNED (t) = 1;
+      f = append_composite_type_field_raw (t, "NEAREST", bt->builtin_uint8);
+      SET_FIELD_ENUMVAL (*f, 0);
+      f = append_composite_type_field_raw (t, "ZERO", bt->builtin_uint8);
+      SET_FIELD_ENUMVAL (*f, 1);
+      f = append_composite_type_field_raw (t, "INF", bt->builtin_uint8);
+      SET_FIELD_ENUMVAL (*f, 2);
+      f = append_composite_type_field_raw (t, "NINF", bt->builtin_uint8);
+      SET_FIELD_ENUMVAL (*f, 3);
+
+      tdep->fp_rm_type = t;
+    }
+  return tdep->fp_rm_type;
+}
+
+/* Get floating point condition flags type */
+
+static struct type *
+mips_fcflags_type (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->fp_cflags_type == NULL)
+    {
+      struct type *t;
+
+      /* Flags, Enables, Cause have common set of condition flags */
+      t = arch_flags_type (gdbarch, "__gdb_builtin_type_fp_cflags", 1);
+      append_flags_type_flag (t, 0, "I");
+      append_flags_type_flag (t, 1, "U");
+      append_flags_type_flag (t, 2, "O");
+      append_flags_type_flag (t, 3, "Z");
+      append_flags_type_flag (t, 4, "V");
+      append_flags_type_flag (t, 5, "E"); /* Cause field only */
+
+      tdep->fp_cflags_type = t;
+    }
+  return tdep->fp_cflags_type;
+}
+
+static struct type *
+mips_fcsr_type (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->fp_csr_type == NULL)
+    {
+      const struct builtin_type *bt = builtin_type (gdbarch);
+      struct type *t, *cflags, *flags;
+      struct field *f;
+
+      /* Flags, Enables, Cause have common set of condition flags */
+      cflags = mips_fcflags_type (gdbarch);
+
+      /* Various bits at top end */
+      flags = arch_flags_type (gdbarch, "__gdb_builtin_type_fp_csr_flags", 2);
+      append_flags_type_flag (flags, 0, "NAN2008");
+      append_flags_type_flag (flags, 1, "ABS2008");
+      append_flags_type_flag (flags, 2, "MAC2008");
+      append_flags_type_flag (flags, 3, "IMPL0");
+      append_flags_type_flag (flags, 4, "IMPL1");
+      append_flags_type_flag (flags, 5, "FCC0");
+      append_flags_type_flag (flags, 6, "FS");
+      append_flags_type_flag (flags, 7, "FCC1");
+      append_flags_type_flag (flags, 8, "FCC2");
+      append_flags_type_flag (flags, 9, "FCC3");
+      append_flags_type_flag (flags, 10, "FCC4");
+      append_flags_type_flag (flags, 11, "FCC5");
+      append_flags_type_flag (flags, 12, "FCC6");
+      append_flags_type_flag (flags, 13, "FCC7");
+
+      t = arch_composite_type (gdbarch, "__gdb_builtin_type_fp_csr",
+			       TYPE_CODE_STRUCT);
+
+      /* rounding mode */
+      f = append_composite_type_field_raw (t, "rm", mips_frm_type (gdbarch));
+      SET_FIELD_BITPOS (*f, 0);
+      FIELD_BITSIZE (*f) = 2;
+
+      f = append_composite_type_field_raw (t, "flags", cflags);
+      SET_FIELD_BITPOS (*f, 2);
+      FIELD_BITSIZE (*f) = 5;
+
+      f = append_composite_type_field_raw (t, "enables", cflags);
+      SET_FIELD_BITPOS (*f, 7);
+      FIELD_BITSIZE (*f) = 5;
+
+      f = append_composite_type_field_raw (t, "cause", cflags);
+      SET_FIELD_BITPOS (*f, 12);
+      FIELD_BITSIZE (*f) = 6;
+
+      f = append_composite_type_field_raw (t, "", flags);
+      SET_FIELD_BITPOS (*f, 18);
+      FIELD_BITSIZE (*f) = 14;
+
+      TYPE_LENGTH (t) = 4;
+      TYPE_NAME (t) = "fp_csr";
+      tdep->fp_csr_type = t;
+    }
+
+  return tdep->fp_csr_type;
+}
+
+static struct type *
+mips_fir_type (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->fp_ir_type == NULL)
+    {
+      const struct builtin_type *bt = builtin_type (gdbarch);
+      struct type *t, *flags;
+      /* top half has flags */
+      flags = arch_flags_type (gdbarch, "__gdb_builtin_type_fp_ir_flags", 2);
+      append_flags_type_flag (flags, 0, "S");
+      append_flags_type_flag (flags, 1, "D");
+      append_flags_type_flag (flags, 2, "PS");
+      append_flags_type_flag (flags, 3, "3D");
+      append_flags_type_flag (flags, 4, "W");
+      append_flags_type_flag (flags, 5, "L");
+      append_flags_type_flag (flags, 6, "F64");
+      append_flags_type_flag (flags, 7, "HAS2008");
+      append_flags_type_flag (flags, 8, "IMPL0");
+      append_flags_type_flag (flags, 9, "IMPL1");
+      append_flags_type_flag (flags, 10, "IMPL2");
+      append_flags_type_flag (flags, 11, "IMPL3");
+      append_flags_type_flag (flags, 12, "UFRP");
+      append_flags_type_flag (flags, 13, "FREP");
+
+      t = arch_composite_type (gdbarch, "__gdb_builtin_type_fp_ir",
+			       TYPE_CODE_STRUCT);
+
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+	{
+	  /* bottom half has revision & processor id */
+	  append_composite_type_field (t, "rev", bt->builtin_uint8);
+	  append_composite_type_field (t, "prid", bt->builtin_uint8);
+
+	  /* top half has flags */
+	  append_composite_type_field (t, "", flags);
+	}
+      else
+	{
+	  /* top half has flags */
+	  append_composite_type_field (t, "", flags);
+
+	  /* bottom half has revision & processor id */
+	  append_composite_type_field (t, "prid", bt->builtin_uint8);
+	  append_composite_type_field (t, "rev", bt->builtin_uint8);
+	}
+
+      TYPE_LENGTH (t) = 4;
+      TYPE_NAME (t) = "fp_ir";
+      tdep->fp_ir_type = t;
+    }
+
+  return tdep->fp_ir_type;
+}
+
 static void
 mips_value_to_register (struct frame_info *frame, int regnum,
 			struct type *type, const gdb_byte *from)
@@ -1415,9 +1588,10 @@ mips_register_type (struct gdbarch *gdbarch, int regnum)
          Use the current setting for cooked registers.  */
       if (mips_float_register_p (gdbarch, regnum))
 	return mips_fp_type (gdbarch, rawnum - mips_regnum (gdbarch)->fp0);
-      else if (rawnum == mips_regnum (gdbarch)->fp_control_status
-	  || rawnum == mips_regnum (gdbarch)->fp_implementation_revision)
-	return builtin_type (gdbarch)->builtin_int32;
+      else if (rawnum == mips_regnum (gdbarch)->fp_control_status)
+	return mips_fcsr_type (gdbarch);
+      else if (rawnum == mips_regnum (gdbarch)->fp_implementation_revision)
+	return mips_fir_type (gdbarch);
       else if (rawnum == mips_regnum (gdbarch)->config5)
 	return mips_config5_type (gdbarch);
       else if (gdbarch_osabi (gdbarch) != GDB_OSABI_IRIX
@@ -1492,6 +1666,12 @@ mips_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 	      && rawnum < mips_regnum (gdbarch)->dspacc + 6)))
     return builtin_type (gdbarch)->builtin_int32;
 
+  if (rawnum == mips_regnum (gdbarch)->fp_control_status)
+    return mips_fcsr_type (gdbarch);
+
+  if (rawnum == mips_regnum (gdbarch)->fp_implementation_revision)
+    return mips_fir_type (gdbarch);
+
   if (rawnum == mips_regnum (gdbarch)->config5)
     return mips_config5_type (gdbarch);
 
@@ -6741,9 +6921,52 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame,
     }
 }
 
+/* Print a single complex control register */
+
 static void
-mips_print_register (struct ui_file *file, struct frame_info *frame,
-		     int regnum)
+print_control_register (struct ui_file *file, struct frame_info *frame,
+			int regnum)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  const char *name = gdbarch_register_name (gdbarch, regnum);
+  struct value *val = value_of_register (regnum, frame);
+  struct type *regtype = value_type (val);
+  enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (regtype));
+  struct value_print_options opts;
+  const gdb_byte *valaddr;
+
+  fputs_filtered (name, file);
+  print_spaces_filtered (15 - strlen (name), file);
+
+  if (!value_entirely_available (val))
+    {
+      fprintf_filtered (file, "*value not available*\n");
+      return;
+    }
+  else if (value_optimized_out (val))
+    {
+      val_print_optimized_out (val, file);
+      fprintf_filtered (file, "\n");
+      return;
+    }
+
+  valaddr = value_contents_for_printing (val);
+
+  /* Print raw value */
+  fprintf_filtered (file, "\t");
+  print_hex_chars (file, valaddr, TYPE_LENGTH (regtype), byte_order);
+
+  /* Print it according to its natural format. */
+  get_user_print_options (&opts);
+  opts.deref_ref = 1;
+  fprintf_filtered (file, "\t");
+  val_print (regtype, valaddr,
+	     value_embedded_offset (val), 0,
+	     file, 0, val, &opts, current_language);
+}
+
+static void
+mips_print_register (struct ui_file *file, struct frame_info *frame, int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct value_print_options opts;
@@ -6755,6 +6978,14 @@ mips_print_register (struct ui_file *file, struct frame_info *frame,
       return;
     }
 
+  if (mips_register_reggroup_p (gdbarch, regnum, float_reggroup) ||
+      mips_register_reggroup_p (gdbarch, regnum, vector_reggroup))
+    {
+      /* FP & MSA control registers */
+      print_control_register (file, frame, regnum);
+      return;
+    }
+
   val = get_frame_register_value (frame, regnum);
 
   fputs_filtered (gdbarch_register_name (gdbarch, regnum), file);
@@ -6972,6 +7203,19 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame,
   return regnum;
 }
 
+/* Print a single complex control register row */
+
+static int
+print_control_register_row (struct ui_file *file, struct frame_info *frame,
+			    int regnum)
+{
+  print_control_register (file, frame, regnum);
+
+  fprintf_filtered (file, "\n");
+  ++regnum;
+  return regnum;
+}
+
 /* MIPS_DO_REGISTERS_INFO(): called by "info register" command.  */
 
 static void
@@ -7001,6 +7245,10 @@ mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
 	      else
 		regnum += MIPS_NUMREGS;	/* Skip floating point regs.  */
 	    }
+	  else if (mips_register_reggroup_p (gdbarch, regnum, float_reggroup) ||
+		   mips_register_reggroup_p (gdbarch, regnum, vector_reggroup))
+	    /* FP & MSA control registers */
+	    regnum = print_control_register_row (file, frame, regnum);
 	  else
 	    regnum = print_gp_register_row (file, frame, regnum);
 	}
@@ -9033,6 +9281,10 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->fp_mode = ((struct gdbarch_tdep_info*)(info.tdep_info))->fp_mode;
   tdep->fp_register_mode_fixed_p = 0;
   tdep->config5_type = NULL;
+  tdep->fp_rm_type = NULL;
+  tdep->fp_cflags_type = NULL;
+  tdep->fp_csr_type = NULL;
+  tdep->fp_ir_type = NULL;
   tdep->fp32_type = NULL;
   tdep->fp64_type = NULL;
 
diff --git a/gdb/mips-tdep.h b/gdb/mips-tdep.h
index 11353be..ad5cba3 100644
--- a/gdb/mips-tdep.h
+++ b/gdb/mips-tdep.h
@@ -130,6 +130,10 @@ struct gdbarch_tdep
 
   /* ISA-specific data types.  */
   struct type *config5_type;
+  struct type *fp_rm_type;
+  struct type *fp_cflags_type;
+  struct type *fp_csr_type;
+  struct type *fp_ir_type;
   struct type *fp32_type;
   struct type *fp64_type;
 
-- 
1.9-rc2


  parent reply	other threads:[~2016-06-27 14:50 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-27 14:50 [PATCH 01/24] MIPS: Handle run-time reconfigurable FPR size Bhushan Attarde
2016-06-27 14:50 ` [PATCH 08/24] MIPS: Convert FP mode to enum and put fp registers into fp reggroup Bhushan Attarde
2016-06-27 14:50 ` Bhushan Attarde [this message]
2016-06-27 14:50 ` [PATCH 03/24] regcache: handle invalidated regcache Bhushan Attarde
2016-10-21 22:42   ` Maciej W. Rozycki
2016-06-27 14:50 ` [PATCH 06/24] mips-linux-nat: pick fp64 target description when appropriate Bhushan Attarde
2016-06-27 14:50 ` [PATCH 11/24] MIPS: Add support for hybrid fp32/fp64 mode Bhushan Attarde
2016-06-27 14:51 ` [PATCH 23/24] MIPS R6 opcode table shuffle for LDC2/SDC2 Bhushan Attarde
2016-06-27 14:51 ` [PATCH 07/24] MIPS: Make Linux restart register more dynamic Bhushan Attarde
2016-06-27 14:51 ` [PATCH 13/24] Add MIPS MSA GDB target descriptions Bhushan Attarde
2016-06-27 14:51 ` [PATCH 18/24] mips-linux-nat: get msa registers Bhushan Attarde
2016-06-27 14:51 ` [PATCH 02/24] Add MIPS32 FPU64 GDB target descriptions Bhushan Attarde
2016-10-12 12:42   ` Maciej W. Rozycki
2016-10-12 13:58     ` James Hogan
2016-10-12 16:30       ` Maciej W. Rozycki
2016-10-12 18:05         ` James Hogan
2016-10-12 22:04           ` Maciej W. Rozycki
2016-10-13 10:09             ` Matthew Fortune
2016-10-21 19:17               ` Maciej W. Rozycki
2016-10-21 19:24                 ` Maciej W. Rozycki
2016-06-27 14:51 ` [PATCH 04/24] Add MIPS Config5 register related support Bhushan Attarde
2016-06-27 14:51 ` [PATCH 21/24] MIPSR6 support for GDB Bhushan Attarde
2016-07-29 21:10   ` Maciej W. Rozycki
2016-06-27 14:51 ` [PATCH 12/24] o32 sigframe unwinding with FR1 Bhushan Attarde
2016-06-27 14:51 ` [PATCH 05/24] MIPS: Add config5 to MIPS GDB target descriptions Bhushan Attarde
2016-06-27 14:51 ` [PATCH 24/24] MIPS R6 forbidden slot support Bhushan Attarde
2016-06-27 14:51 ` [PATCH 22/24] Support all new ABIs when detecting if an FPU is present Bhushan Attarde
2016-06-27 14:51 ` [PATCH 19/24] Add MIPS MSA vector branch instruction support Bhushan Attarde
2016-06-27 14:51 ` [PATCH 09/24] MIPS: Enhance cooked FP format Bhushan Attarde
2016-06-27 14:51 ` [PATCH 14/24] Implement core MSA stuff Bhushan Attarde
2016-06-27 14:51 ` [PATCH 20/24] Drop FP and MSA control registers from default info registers Bhushan Attarde
2016-07-25 14:03 ` [PATCH 01/24] MIPS: Handle run-time reconfigurable FPR size Maciej W. Rozycki
2016-10-18 17:37   ` Maciej W. Rozycki
2016-11-08 19:46 ` Yao Qi
2016-11-10 12:43   ` Maciej W. Rozycki
2016-11-11 12:29     ` Yao Qi
2016-12-02  2:31       ` Maciej W. Rozycki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1467038991-6600-10-git-send-email-bhushan.attarde@imgtec.com \
    --to=bhushan.attarde@imgtec.com \
    --cc=Andrew.Bennett@imgtec.com \
    --cc=James.Hogan@imgtec.com \
    --cc=Jaydeep.Patil@imgtec.com \
    --cc=Maciej.Rozycki@imgtec.com \
    --cc=Matthew.Fortune@imgtec.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox