diff mbox

[08/24] MIPS: Convert FP mode to enum and put fp registers into fp reggroup

Message ID 1467038991-6600-8-git-send-email-bhushan.attarde@imgtec.com
State New
Headers show

Commit Message

Bhushan Attarde June 27, 2016, 2:49 p.m. UTC
Convert FP mode representation from a register size to an enum, in order
    to allow for more FP modes with the same register size, namely FR=1 &&
    FRE=1, where FP registers are 64-bits, but odd singles reside in the upper
    half of even doubles.

    gdb/ChangeLog:

    	* mips-linux-tdep.c (mips_linux_init_abi): Rename
    	fp_register_size_fixed_p to fp_register_mode_fixed_p.
    	* mips-tdep.c (mips_set_float_regsize, mips_float_regsize,
    	mips_gdbarch_init): Rename fp_register_size_fixed_p to
    	fp_register_mode_fixed_p and convert fp_register_size to fp_mode
    	enum.
        (mips_register_reggroup_p): Put fp registers into fp reggroup.
    	* mips-tdep.h (enum mips_fpu_mode): New definition.
    	(struct gdbarch_tdep): Rename fp_register_size_fixed_p to
    	fp_register_mode_fixed_p and convert fp_register_size to fp_mode
    	enum.
    	(struct gdbarch_tdep_info): Convert fp_register_size to fp_mode
    	enum.
---
 gdb/mips-linux-tdep.c |  2 +-
 gdb/mips-tdep.c       | 50 ++++++++++++++++++++++++++++++++------------------
 gdb/mips-tdep.h       | 21 ++++++++++++++-------
 3 files changed, 47 insertions(+), 26 deletions(-)
diff mbox

Patch

diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
index 82b8127..da5ccc0 100644
--- a/gdb/mips-linux-tdep.c
+++ b/gdb/mips-linux-tdep.c
@@ -1725,7 +1725,7 @@  mips_linux_init_abi (struct gdbarch_info info,
 				    mips_gdb_signal_to_target);
 
   tdep->syscall_next_pc = mips_linux_syscall_next_pc;
-  tdep->fp_register_size_fixed_p = 1;
+  tdep->fp_register_mode_fixed_p = 1;
 
   if (((struct gdbarch_tdep_info*)(info.tdep_info))->tdesc_data)
     {
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 61b560c..47ddef4 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -298,7 +298,7 @@  mips_abi_regsize (struct gdbarch *gdbarch)
    As the CP0 Status register's bit FR cannot be modified on processors
    that do not implement an FPU, backends for operating systems that
    can emulate the FPU in software should set the size according to the
-   ABI in use and then set fp_register_size_fixed_p to 1 to prevent
+   ABI in use and then set fp_register_mode_fixed_p to 1 to prevent
    further updates.  */
 
 static int
@@ -308,11 +308,13 @@  mips_set_float_regsize (struct gdbarch *gdbarch, struct regcache *regcache)
   struct gdbarch_tdep_info tdep_info = { NULL };
   struct gdbarch_info info;
   int fpsize;
+  enum mips_fpu_mode fp_mode;
 
-  if (tdep->fp_register_size_fixed_p)
+  if (tdep->fp_register_mode_fixed_p)
     return 0;
 
   fpsize = mips_isa_regsize (gdbarch);
+  fp_mode = fpsize == 8 ? MIPS_FPU_64 : MIPS_FPU_32;
   if (fpsize == 8)
     {
       enum register_status status;
@@ -320,16 +322,16 @@  mips_set_float_regsize (struct gdbarch *gdbarch, struct regcache *regcache)
 
       status = regcache_raw_read_unsigned (regcache, MIPS_PS_REGNUM, &sr);
       if (status == REG_VALID)
-	fpsize = (sr & ST0_FR) ? 8 : 4;
+	fp_mode = (sr & ST0_FR) ? MIPS_FPU_64 : MIPS_FPU_32;
     }
 
-  if (fpsize == tdep->fp_register_size)
+  if (fp_mode == tdep->fp_mode)
     return 0;
 
   /* Need a new gdbarch, go get one.  */
   gdbarch_info_init (&info);
   info.tdep_info = &tdep_info;
-  info.tdep_info->fp_register_size = fpsize;
+  ((struct gdbarch_tdep_info*)(info.tdep_info))->fp_mode = fp_mode;
   gdbarch_update_p (info);
 
   return 1;
@@ -340,7 +342,15 @@  mips_set_float_regsize (struct gdbarch *gdbarch, struct regcache *regcache)
 static int
 mips_float_regsize (struct gdbarch *gdbarch)
 {
-  return gdbarch_tdep (gdbarch)->fp_register_size;
+  switch (gdbarch_tdep (gdbarch)->fp_mode)
+    {
+    case MIPS_FPU_32:
+      return 4;
+    case MIPS_FPU_64:
+      return 8;
+    default:
+      return 0;
+    }
 }
 
 /* MIPS16/microMIPS function addresses are odd (bit 0 is set).  Here
@@ -724,7 +734,9 @@  mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   if (reggroup == all_reggroup)
     return pseudo;
   vector_p = TYPE_VECTOR (register_type (gdbarch, regnum));
-  float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT;
+  float_p = (mips_float_register_p (gdbarch, rawnum) ||
+	     rawnum == mips_regnum (gdbarch)->fp_control_status ||
+	     rawnum == mips_regnum (gdbarch)->fp_implementation_revision);
   /* FIXME: cagney/2003-04-13: Can't yet use gdbarch_num_regs
      (gdbarch), as not all architectures are multi-arch.  */
   raw_p = rawnum < gdbarch_num_regs (gdbarch);
@@ -8333,6 +8345,7 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       const struct tdesc_feature *feature;
       int valid_p;
       int fpsize;
+      enum mips_fpu_mode fpmode;
 
       feature = tdesc_find_feature (info.target_desc,
 				    "org.gnu.gdb.mips.cpu");
@@ -8405,11 +8418,12 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
          supplied the description got the current setting right wrt
          CP0 Status register's bit FR if applicable.  */
       fpsize = tdesc_register_size (feature, mips_fprs[0]) / 8;
+      fpmode = (fpsize == 8) ? MIPS_FPU_64 : MIPS_FPU_32;
 
       /* Only accept a description whose floating-point register size
          matches the requested size or if none was specified.  */
-      valid_p = (info.tdep_info->fp_register_size == 0
-		 || info.tdep_info->fp_register_size == fpsize);
+      valid_p = (info.tdep_info->fp_mode == MIPS_FPU_UNKNOWN
+		 || info.tdep_info->fp_mode == fpmode);
       for (i = 0; i < 32; i++)
 	valid_p &= tdesc_numbered_register (feature, tdesc_data,
 					    i + mips_regnum.fp0, mips_fprs[i]);
@@ -8464,8 +8478,8 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	    }
 	}
 
-      /* Fix the floating-point register size found.  */
-      info.tdep_info->fp_register_size = fpsize;
+      /* Fix the floating-point register mode found.  */
+      info.tdep_info->fp_mode = fpmode;
 
       /* It would be nice to detect an attempt to use a 64-bit ABI
 	 when only 32-bit registers are provided.  */
@@ -8678,9 +8692,9 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       if (gdbarch_tdep (arches->gdbarch)->mips_fpu_type != fpu_type)
 	continue;
       /* Ditto the requested floating-point register size if any.  */
-      if (info.tdep_info->fp_register_size != 0
-	  && (gdbarch_tdep (arches->gdbarch)->fp_register_size)
-	      != info.tdep_info->fp_register_size)
+      if (((struct gdbarch_tdep_info*)(info.tdep_info))->fp_mode != MIPS_FPU_UNKNOWN
+	  && (gdbarch_tdep (arches->gdbarch)->fp_mode)
+	      != ((struct gdbarch_tdep_info*)(info.tdep_info))->fp_mode)
 	continue;
 
       if (tdesc_data != NULL)
@@ -8699,8 +8713,8 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->mips_fpu_type = fpu_type;
   tdep->register_size_valid_p = 0;
   tdep->register_size = 0;
-  tdep->fp_register_size = info.tdep_info->fp_register_size;
-  tdep->fp_register_size_fixed_p = 0;
+  tdep->fp_mode = ((struct gdbarch_tdep_info*)(info.tdep_info))->fp_mode;
+  tdep->fp_register_mode_fixed_p = 0;
   tdep->config5_type = NULL;
 
   if (info.target_desc)
@@ -8721,8 +8735,8 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* If we haven't figured out the size of floating-point registers
      by now yet, then assume it is the same as for general-purpose
      registers.  */
-  if (tdep->fp_register_size == 0)
-    tdep->fp_register_size = mips_isa_regsize (gdbarch);
+  if (tdep->fp_mode == MIPS_FPU_UNKNOWN)
+    tdep->fp_mode = mips_isa_regsize (gdbarch) == 8 ? MIPS_FPU_64 : MIPS_FPU_32;
 
   /* Initially set everything according to the default ABI/ISA.  */
   set_gdbarch_short_bit (gdbarch, 16);
diff --git a/gdb/mips-tdep.h b/gdb/mips-tdep.h
index 97bfab3..b6f99f2 100644
--- a/gdb/mips-tdep.h
+++ b/gdb/mips-tdep.h
@@ -84,6 +84,13 @@  enum mips_fpu_type
   MIPS_FPU_NONE			/* No floating point.  */
 };
 
+enum mips_fpu_mode
+{
+  MIPS_FPU_UNKNOWN = 0,
+  MIPS_FPU_32,		/* FR=0, 32bit FP regs, doubles in pairs.  */
+  MIPS_FPU_64,		/* FR=1, 64bit FP regs.  */
+};
+
 /* MIPS specific per-architecture information.  */
 struct gdbarch_tdep
 {
@@ -115,11 +122,11 @@  struct gdbarch_tdep
   int register_size_valid_p;
   int register_size;
 
-  /* The size of floating-point registers determined at the run time.
-     This corresponds to CP0 Status register's bit FR setting if
-     implemented unless fixed_p is set.  */
-  int fp_register_size_fixed_p;
-  int fp_register_size;
+  /* The floating-point register mode determined at run time.
+     This corresponds to CP0 Status register's FR bit unless fixed_p is
+     set.  */
+  int fp_register_mode_fixed_p;
+  enum mips_fpu_mode fp_mode;
 
   /* ISA-specific data types.  */
   struct type *config5_type;
@@ -135,8 +142,8 @@  struct gdbarch_tdep_info
   /* Target description data.  */
   struct tdesc_arch_data *tdesc_data;
 
-  /* The size of floating-point registers determined at the run time.  */
-  int fp_register_size;
+  /* The floating-point register mode determined at run time.  */
+  enum mips_fpu_mode fp_mode;
 };
 
 /* Register numbers of various important registers.  */