MIPS: Handle the 64-bit FPU of MIPS32r2 processors

Maciej W. Rozycki macro@mips.com
Mon Dec 10 18:54:00 GMT 2007


Hello,

 Following a recent change to BFD this adds support for the 64-bit FPU 
(with a file of 32 64-bit registers) as implemented by MIPS32r2-compliant 
processors.

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

2007-12-10  Thiemo Seufer  <ths@mips.com>
            Maciej W. Rozycki  <macro@mips.com>

	* mips-tdep.c (mips_fpu_type): Add MIPS_FPU_64 flag.
	(mips_float_regsize, mips_print_float_info, show_mipsfpu_command,
	set_mipsfpu_command): Handle MIPS_FPU_64 flag.
	(set_mipsfpu_64bit_command): New function.
	(mips_gdbarch_init, mips_dump_tdep): Handle MIPS_FPU_64 flag.
	(_initialize_mips_tdep): Add 64-bit FPU command.

 It depends on a previosly submitted patch as available here:

http://sourceware.org/ml/gdb-patches/2007-11/msg00400.html

 OK to apply?

  Maciej

14440-1.diff
Index: binutils-quilt/src/gdb/mips-tdep.c
===================================================================
--- binutils-quilt.orig/src/gdb/mips-tdep.c	2007-12-10 18:34:19.000000000 +0000
+++ binutils-quilt/src/gdb/mips-tdep.c	2007-12-10 18:35:49.000000000 +0000
@@ -151,7 +151,8 @@
 {
   MIPS_FPU_DOUBLE,		/* Full double precision floating point.  */
   MIPS_FPU_SINGLE,		/* Single precision floating point (R4650).  */
-  MIPS_FPU_NONE			/* No floating point.  */
+  MIPS_FPU_NONE,		/* No floating point.  */
+  MIPS_FPU_64			/* MIPS32R2 with 64-bit FP registers.  */
 };
 
 #ifndef MIPS_DEFAULT_FPU_TYPE
@@ -228,6 +229,9 @@
   if (mips_isa_regsize (gdbarch) == 8 && ! mips2_fp_compat (frame))
     /* 64-bit ISA with 32-bit compatibility mode FPU.  */
     return 8;
+  if (gdbarch_tdep (gdbarch)->mips_fpu_type == MIPS_FPU_64)
+    /* 32-bit MIPS32R2 ISA with 64-bit mode FPU.  */
+    return 8;
   return 4;
 }
 
@@ -732,8 +736,10 @@
   gdb_assert (regnum >= 0 && regnum < 2 * gdbarch_num_regs (gdbarch));
   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.  */
+      /* The floating-point registers raw, or cooked, match
+         mips_isa_regsize(), and also map 1:1, byte for byte.
+         Unless the MIPS_FPU_64 type is selected, which indicates
+         a 64-bit FPU used with a 32-bit CPU, as supported by MIPS32r2.  */
       if (mips_float_regsize (gdbarch, NULL) == 4)
 	return builtin_type_ieee_single;
       else
@@ -3758,8 +3764,10 @@
 	   && 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.  */
+      /* If it's a single-precision floating-point value, it fits in the
+         least significant part of FP0.
+         If a 64-bit FPU is used and it's a double-precision value, it will
+         also be passed in FP0.  */
       if (mips_debug)
 	fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
       mips_xfer_register (gdbarch, regcache,
@@ -4766,6 +4774,9 @@
     case MIPS_FPU_DOUBLE:
       fpu = "double-precision";
       break;
+    case MIPS_FPU_64:
+      fpu = "64-bit";
+      break;
     case MIPS_FPU_NONE:
       fpu = "absent (none)";
       break;
@@ -4786,7 +4797,7 @@
 set_mipsfpu_command (char *args, int from_tty)
 {
   printf_unfiltered
-    ("\"set mipsfpu\" must be followed by \"double\", \"single\",\"none\" or \"auto\".\n");
+    ("\"set mipsfpu\" must be followed by \"double\", \"single\", \"64-bit\", \"none\" or \"auto\".\n");
   show_mipsfpu_command (args, from_tty);
 }
 
@@ -4819,6 +4830,20 @@
 }
 
 static void
+set_mipsfpu_64bit_command (char *args, int from_tty)
+{
+  struct gdbarch_info info;
+  gdbarch_info_init (&info);
+  mips_fpu_type = MIPS_FPU_64;
+  mips_fpu_type_auto = 0;
+  /* FIXME: cagney/2003-11-15: Should be setting a field in "info"
+     instead of relying on globals.  Doing that would let generic code
+     handle the search for this specific architecture.  */
+  if (!gdbarch_update_p (info))
+    internal_error (__FILE__, __LINE__, _("set mipsfpu failed"));
+}
+
+static void
 set_mipsfpu_none_command (char *args, int from_tty)
 {
   struct gdbarch_info info;
@@ -5572,6 +5597,9 @@
 	case 2:
 	  fpu_type = MIPS_FPU_SINGLE;
 	  break;
+	case 4:
+	  fpu_type = MIPS_FPU_64;
+	  break;
 	case 3:
 	default:
 	  /* Soft float or unknown.  */
@@ -6058,6 +6086,7 @@
 		      (MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_NONE ? "none"
 		       : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_SINGLE ? "single"
 		       : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_DOUBLE ? "double"
+		       : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_64 ? "64-bit"
 		       : "???"));
   fprintf_unfiltered (file, "mips_dump_tdep: MIPS_EABI = %d\n", MIPS_EABI);
   fprintf_unfiltered (file,
@@ -6066,6 +6095,7 @@
 		      (MIPS_FPU_TYPE == MIPS_FPU_NONE ? "none"
 		       : MIPS_FPU_TYPE == MIPS_FPU_SINGLE ? "single"
 		       : MIPS_FPU_TYPE == MIPS_FPU_DOUBLE ? "double"
+		       : MIPS_FPU_TYPE == MIPS_FPU_64 ? "64-bit"
 		       : "???"));
 }
 
@@ -6135,6 +6165,9 @@
   add_alias_cmd ("on", "double", class_support, 1, &mipsfpulist);
   add_alias_cmd ("yes", "double", class_support, 1, &mipsfpulist);
   add_alias_cmd ("1", "double", class_support, 1, &mipsfpulist);
+  add_cmd ("64-bit", class_support, set_mipsfpu_64bit_command,
+	   _("Select double-precision MIPS floating-point coprocessor with 64-bit wide registers."),
+	   &mipsfpulist);
   add_cmd ("none", class_support, set_mipsfpu_none_command,
 	   _("Select no MIPS floating-point coprocessor."), &mipsfpulist);
   add_alias_cmd ("off", "none", class_support, 1, &mipsfpulist);



More information about the Gdb-patches mailing list