This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

mips-tdep.c: Unification of FPR size detection


Hello,

 This is a set of changes to put code to determine the width of floating 
point registers into a single place.  This is required for the support for 
MIPS32r2 64-bit FPRs to be added in a sensible way.

 I think the changes are mostly obvious.  If not, then please enquire.  
Modifications to mips_o32_return_value(), mips_o32_push_dummy_call() and 
mips_register_type() change the semantics somewhat, but this is correct as 
for 64-bit processors in the compatibility mode FPRs are seen as 32-bit.  
The rest just shuffles code for consistency.

 One note: the mips2_fp_compat() function is meant to detect the size of 
floating point registers based on the setting of the cp0.Status.FR bit as 
applicable.  However the function currently always returns 0.  So I 
decided to include a change that ifdefs out the entire body.  Enabling the 
body does not trigger any new regressions.  I also added a note on a 
problem with the frame being NULL -- it may have to be dealt with in a 
better way once this code is reenabled.  A possible way is by caching the 
value of cp0.Status.FR elsewhere.

 Tested for using the mipsisa32-sde-elf target, with the 
mips-sim-sde32/-EB, mips-sim-sde32/-EL, mips-sim-sde64/-mips64/-EB and 
mips-sim-sde64/-mips64/-EL boards with no regressions.

2007-11-21  Nigel Stephens  <nigel@mips.com>
            David Ung  <davidu@mips.com>
            Maciej W. Rozycki  <macro@mips.com>

	* mips-tdep.c (mips_float_register_p): New function.
	(mips_float_regsize): Likewise.
	(mips2_fp_compat): Handle a NULL pointer possibly passed.  Ifdef 
	out pointless code.
	(mips_convert_register_p): Use mips_float_register_p().
	(mips_register_type): Likewise.  Use mips_float_regsize()
	instead of mips_isa_regsize() for FP registers.
	(mips_o32_push_dummy_call): Use mips_float_regsize() instead of
	register_size() for FP registers.
	(mips_print_fp_register): Likewise.
	(mips_print_register): Likewise.
	(print_gp_register_row): Likewise.
	(mips_o32_return_value): Use mips_float_regsize() instead of
	hardcoding the expected width of FP registers.

 OK to apply?

  Maciej

14440-2.diff
Index: binutils-quilt/src/gdb/mips-tdep.c
===================================================================
--- binutils-quilt.orig/src/gdb/mips-tdep.c	2007-11-21 11:37:00.000000000 +0000
+++ binutils-quilt/src/gdb/mips-tdep.c	2007-11-21 11:47:35.000000000 +0000
@@ -62,6 +62,8 @@
 
 static struct type *mips_register_type (struct gdbarch *gdbarch, int regnum);
 
+static int mips2_fp_compat (struct frame_info *frame);
+
 /* A useful bit in the CP0 status register (MIPS_PS_REGNUM).  */
 /* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip.  */
 #define ST0_FR (1 << 26)
@@ -211,6 +213,24 @@
   return mips_regnum (gdbarch)->fp0 + 12;
 }
 
+static int
+mips_float_register_p (struct gdbarch *gdbarch, int regnum)
+{
+  return ((regnum % gdbarch_num_regs (gdbarch))
+	  >= mips_regnum (gdbarch)->fp0
+	  && (regnum % gdbarch_num_regs (gdbarch))
+	     < mips_regnum (gdbarch)->fp0 + 32);
+}
+
+static int
+mips_float_regsize (struct gdbarch *gdbarch, struct frame_info *frame)
+{
+  if (mips_isa_regsize (gdbarch) == 8 && ! mips2_fp_compat (frame))
+    /* 64-bit ISA with 32-bit compatibility mode FPU.  */
+    return 8;
+  return 4;
+}
+
 #define MIPS_EABI (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI32 \
 		   || gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI64)
 
@@ -370,13 +390,21 @@
 static int
 mips2_fp_compat (struct frame_info *frame)
 {
-  struct gdbarch *gdbarch = get_frame_arch (frame);
+#if 0
+  struct gdbarch *gdbarch;
+
+  /* FIXME macro 2007-11-15: If we have no frame, then we cannot really
+     get it or gdbarch_data() will be called recursively (through
+     data->post_init()).  Assume the native size.  */
+  if (frame == NULL)
+    return 0;
+  gdbarch = get_frame_arch (frame);
+
   /* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not
      meaningful.  */
   if (register_size (gdbarch, mips_regnum (gdbarch)->fp0) == 4)
     return 0;
 
-#if 0
   /* FIXME drow 2002-03-10: This is disabled until we can do it consistently,
      in all the places we deal with FP registers.  PR gdb/413.  */
   /* Otherwise check the FR bit in the status register - it controls
@@ -664,10 +692,7 @@
 {
   return (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
 	  && register_size (gdbarch, regnum) == 4
-	  && (regnum % gdbarch_num_regs (gdbarch))
-		>= mips_regnum (gdbarch)->fp0
-	  && (regnum % gdbarch_num_regs (gdbarch))
-		< mips_regnum (gdbarch)->fp0 + 32
+	  && mips_float_register_p (gdbarch, regnum)
 	  && TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8);
 }
 
@@ -694,13 +719,11 @@
 mips_register_type (struct gdbarch *gdbarch, int regnum)
 {
   gdb_assert (regnum >= 0 && regnum < 2 * gdbarch_num_regs (gdbarch));
-  if ((regnum % gdbarch_num_regs (gdbarch)) >= mips_regnum (gdbarch)->fp0
-      && (regnum % gdbarch_num_regs (gdbarch))
-	 < mips_regnum (gdbarch)->fp0 + 32)
+  if (mips_float_register_p (gdbarch, regnum))
     {
       /* The floating-point registers raw, or cooked, always match
          mips_isa_regsize(), and also map 1:1, byte for byte.  */
-      if (mips_isa_regsize (gdbarch) == 4)
+      if (mips_float_regsize (gdbarch, NULL) == 4)
 	return builtin_type_ieee_single;
       else
 	return builtin_type_ieee_double;
@@ -3512,7 +3535,7 @@
       if (fp_register_arg_p (typecode, arg_type)
 	  && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
 	{
-	  if (register_size (gdbarch, float_argreg) < 8 && len == 8)
+	  if (mips_float_regsize (gdbarch, NULL) < 8 && len == 8)
 	    {
 	      int low_offset = gdbarch_byte_order (gdbarch)
 			       == BFD_ENDIAN_BIG ? 4 : 0;
@@ -3721,7 +3744,8 @@
       || TYPE_CODE (type) == TYPE_CODE_ARRAY)
     return RETURN_VALUE_STRUCT_CONVENTION;
   else if (TYPE_CODE (type) == TYPE_CODE_FLT
-	   && TYPE_LENGTH (type) == 4 && tdep->mips_fpu_type != MIPS_FPU_NONE)
+	   && TYPE_LENGTH (type) <= mips_float_regsize (gdbarch, NULL)
+	   && tdep->mips_fpu_type != MIPS_FPU_NONE)
     {
       /* A single-precision floating-point value.  It fits in the
          least significant part of FP0.  */
@@ -4275,14 +4299,14 @@
   double doub, flt1;	/* doubles extracted from raw hex data */
   int inv1, inv2;
 
-  raw_buffer = alloca (2 * register_size (gdbarch, mips_regnum (gdbarch)->fp0));
+  raw_buffer = alloca (2 * mips_float_regsize (gdbarch, frame));
 
   fprintf_filtered (file, "%s:", gdbarch_register_name (gdbarch, regnum));
   fprintf_filtered (file, "%*s",
 		    4 - (int) strlen (gdbarch_register_name (gdbarch, regnum)),
 		    "");
 
-  if (register_size (gdbarch, regnum) == 4 || mips2_fp_compat (frame))
+  if (mips_float_regsize (gdbarch, frame) == 4)
     {
       /* 4-byte registers: Print hex and floating.  Also print even
          numbered registers as doubles.  */
@@ -4346,7 +4370,7 @@
   gdb_byte raw_buffer[MAX_REGISTER_SIZE];
   int offset;
 
-  if (TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
+  if (mips_float_register_p (gdbarch, regnum))
     {
       mips_print_fp_register (file, frame, regnum);
       return;
@@ -4417,8 +4441,7 @@
     {
       if (*gdbarch_register_name (gdbarch, regnum) == '\0')
 	continue;		/* unused register */
-      if (TYPE_CODE (register_type (gdbarch, regnum)) ==
-	  TYPE_CODE_FLT)
+      if (mips_float_register_p (gdbarch, regnum))
 	break;			/* end the row: reached FP register */
       /* Large registers are handled separately.  */
       if (register_size (gdbarch, regnum) > mips_abi_regsize (gdbarch))
@@ -4457,8 +4480,7 @@
     {
       if (*gdbarch_register_name (gdbarch, regnum) == '\0')
 	continue;		/* unused register */
-      if (TYPE_CODE (register_type (gdbarch, regnum)) ==
-	  TYPE_CODE_FLT)
+      if (mips_float_register_p (gdbarch, regnum))
 	break;			/* end row: reached FP register */
       if (register_size (gdbarch, regnum) > mips_abi_regsize (gdbarch))
 	break;			/* End row: large register.  */
@@ -4513,8 +4535,7 @@
       while (regnum < gdbarch_num_regs (gdbarch)
 		      + gdbarch_num_pseudo_regs (gdbarch))
 	{
-	  if (TYPE_CODE (register_type (gdbarch, regnum)) ==
-	      TYPE_CODE_FLT)
+	  if (mips_float_register_p (gdbarch, regnum))
 	    {
 	      if (all)		/* true for "INFO ALL-REGISTERS" command */
 		regnum = print_fp_register_row (file, frame, regnum);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]