Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFA] Mips fp register display
@ 2001-03-27  1:01 Don Howard
  0 siblings, 0 replies; 7+ messages in thread
From: Don Howard @ 2001-03-27  1:01 UTC (permalink / raw)
  To: gdb-patches

This is a re-implemented patch for an obscure mips fp register display
problem. This patch addresses insight as well as cli gdb.  Insight is not 100%
correct: single precision floats are displayed in double format =( (cli gdb
displays both float and double).  I can change REGISTER_VIRTUAL_TYPE() to try
to guess the the intended type (builtin_type_{float,double}), but that is
really not the right place to fix this problem.

Has anyone considered adding float/double options to the insight register
window format menu?  I think that would be the right place to fix this.  


2001-03-27  Don Howard  <dhoward@pobox.com>

	
	* mips-tdep.c (mips2_read_fp_register): New function.  Reads a
	64-bit float value stored as two 32-bit fragments in consecutive
	float registers.
	(mips2_fp_compat): New function.  Determine if a MIPS3 or later
	cpu is operating in MIPS{1,2} float-compat mode.
	(mips_get_saved_register): Modified to use new
	mips2-compat float support.
	(mips_print_register): Modified to display 64-bit float regs in
	single and double precision.


Index: mips-tdep.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/mips-tdep.c,v
retrieving revision 1.239.2.3
diff -p -u -w -r1.239.2.3 mips-tdep.c
--- mips-tdep.c	2001/01/08 16:16:39	1.239.2.3
+++ mips-tdep.c	2001/03/27 08:19:51
@@ -173,6 +173,21 @@ mips_saved_regsize (void)
     return 4;
 }
 
+/* Determine if a MIPS3 or later cpu is operating in MIPS{1,2} FPU
+   compatiblitiy mode. */
+
+static int
+mips2_fp_compat (void) 
+{
+  if (REGISTER_RAW_SIZE (FP0_REGNUM) != 8) /* MIPS2 has 32 bit fp regs */
+    return 0;
+
+  /* Otherwise check the FR bit in the status register - it controls
+     the fp compatiblity mode */
+  return !(read_register (PS_REGNUM) & 1 << 26);
+}
+
+
 /* Indicate that the ABI makes use of double-precision registers
    provided by the FPU (rather than combining pairs of registers to
    form double-precision values).  Do not use "TARGET_IS_MIPS64" to
@@ -2572,6 +2587,58 @@ mips_pop_frame (void)
     }
 }
 
+
+/* Read a MIPS{1,2} floating point register.  This is for use on MIPS3 or
+   later cpus operating in MIPS2 fpu compatiblity mode.
+
+   Background: MIPS1 & 2 fp registers are 32 bits wide.  To support
+   64bit operations, these early MIPS cpus treat fp register pairs
+   (f0,f1) as a single register (d0).  Later MIPS cpu's have 64 bit fp
+   registers and offer a compatibility mode that emulates the MIPS2 fp
+   model.  When operating in MIPS2 fp compat mode, later cpu's split
+   double precision floats into two 32-bit chunks and store them in
+   consecutive fp regs.  To display 64-bit floats stored in this
+   fashion, we have to combine 32 bits from f0 and 32 bits from f1.
+   Throw in user-configurable endianness and you have a real mess.
+
+   Note that this only deals with "live" registers at the top of the
+   stack.  We will attempt to deal with saved registers later, when
+   the raw/cooked register interface is in place. (We need a general
+   interface that can deal with dynamic saved register sizes -- fp
+   regs could be 32 bits wide in one frame and 64 on the frame above
+   and below) */
+
+void 
+mips2_read_fp_register (int regno, char * rare_buffer)
+{
+  char * raw_buffer = alloca (REGISTER_RAW_SIZE (FP0_REGNUM));
+  int HI = (TARGET_BYTE_ORDER == BIG_ENDIAN);
+  int LO = (TARGET_BYTE_ORDER != BIG_ENDIAN);
+
+  if (mips_debug)
+    fprintf_unfiltered (gdb_stdlog, "%s(regno=%d, rare_buffer=0x%x) [%s]\n", 
+			__FUNCTION__, regno, rare_buffer, (HI ? "BE" : "LE"));
+    
+  memset (rare_buffer, 0, REGISTER_RAW_SIZE (FP0_REGNUM));
+
+
+  if ((regno - FP0_REGNUM) & 1)
+    {
+      read_register_gen (regno, raw_buffer);
+      memcpy (&rare_buffer[HI * 4], &raw_buffer[HI * 4], 4);
+    }
+  else
+    {
+      read_register_gen (regno, raw_buffer);
+      memcpy (&rare_buffer[HI * 4], &raw_buffer[HI * 4], 4);
+
+      read_register_gen (regno + 1, raw_buffer);
+      memcpy (&rare_buffer[LO * 4], &raw_buffer[HI * 4], 4);
+    }
+  return;
+}
+
+
 static void
 mips_print_register (int regnum, int all)
 {
@@ -2613,7 +2680,7 @@ mips_print_register (int regnum, int all
 
   /* If virtual format is floating, print it that way.  */
   if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
-    if (FP_REGISTER_DOUBLE)
+    if (FP_REGISTER_DOUBLE || mips2_fp_compat ())
       {				/* show 8-byte floats as float AND double: */
 	int offset = 4 * (TARGET_BYTE_ORDER == BIG_ENDIAN);
 
@@ -3899,7 +3966,14 @@ mips_get_saved_register (char *raw_buffe
 	*lval = lval_register;
       addr = REGISTER_BYTE (regnum);
       if (raw_buffer != NULL)
+	{
+	  if (TYPE_CODE_FLT == TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum))
+	      && mips2_fp_compat ())
+	    mips2_read_fp_register(regnum, raw_buffer);
+
+	  else
 	read_register_gen (regnum, raw_buffer);
+	}
     }
   if (addrp != NULL)
     *addrp = addr;














-- 
-Don
dhoward@redhat.com









^ permalink raw reply	[flat|nested] 7+ messages in thread
* [RFA] Mips fp register display
@ 2001-05-10 10:48 Don Howard
  0 siblings, 0 replies; 7+ messages in thread
From: Don Howard @ 2001-05-10 10:48 UTC (permalink / raw)
  To: gdb-patches

I've not received any feedback on the patch included below, so I'm
resubmitting it.  

-- 
-Don					
dhoward@redhat.com
gdb engineering




From dhoward@redhat.com Wed May  9 13:14:49 2001
Date: Tue, 27 Mar 2001 00:53:15 +0000 (PDT)
From: Don Howard <dhoward@redhat.com>
To: gdb-patches@sources.redhat.com
Subject: [RFA] Mips fp register display



This is a patch for an obscure mips fp register display problem: some mips
variants use 2 32 bit float registers to store 64 bit values.  gdb does not
display these values correctly. 

This patch addresses insight as well as cli gdb.  Insight is not 100% correct:
single precision floats are displayed in double format. CLI gdb displays both
float and double.  I can change REGISTER_VIRTUAL_TYPE() to try to guess the
the intended type (builtin_type_{float,double}), but that is really not the
right place to fix this problem.

Has anyone considered adding float/double options to the insight register
window format menu?  I think that would be the right place to fix this.  


2001-03-27  Don Howard  <dhoward@redhat.com>

	
	* mips-tdep.c (mips2_read_fp_register): New function.  Reads a
	64-bit float value stored as two 32-bit fragments in consecutive
	float registers.
	(mips2_fp_compat): New function.  Determine if a MIPS3 or later
	cpu is operating in MIPS{1,2} float-compat mode.
	(mips_get_saved_register): Modified to use new
	mips2-compat float support.
	(mips_print_register): Modified to display 64-bit float regs in
	single and double precision.


Index: mips-tdep.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/mips-tdep.c,v
retrieving revision 1.239.2.3
diff -p -u -w -r1.239.2.3 mips-tdep.c
--- mips-tdep.c	2001/01/08 16:16:39	1.239.2.3
+++ mips-tdep.c	2001/03/27 08:19:51
@@ -173,6 +173,21 @@ mips_saved_regsize (void)
     return 4;
 }
 
+/* Determine if a MIPS3 or later cpu is operating in MIPS{1,2} FPU
+   compatiblitiy mode. */
+
+static int
+mips2_fp_compat (void) 
+{
+  if (REGISTER_RAW_SIZE (FP0_REGNUM) != 8) /* MIPS2 has 32 bit fp regs */
+    return 0;
+
+  /* Otherwise check the FR bit in the status register - it controls
+     the fp compatiblity mode */
+  return !(read_register (PS_REGNUM) & 1 << 26);
+}
+
+
 /* Indicate that the ABI makes use of double-precision registers
    provided by the FPU (rather than combining pairs of registers to
    form double-precision values).  Do not use "TARGET_IS_MIPS64" to
@@ -2572,6 +2587,58 @@ mips_pop_frame (void)
     }
 }
 
+
+/* Read a MIPS{1,2} floating point register.  This is for use on MIPS3 or
+   later cpus operating in MIPS2 fpu compatiblity mode.
+
+   Background: MIPS1 & 2 fp registers are 32 bits wide.  To support
+   64bit operations, these early MIPS cpus treat fp register pairs
+   (f0,f1) as a single register (d0).  Later MIPS cpu's have 64 bit fp
+   registers and offer a compatibility mode that emulates the MIPS2 fp
+   model.  When operating in MIPS2 fp compat mode, later cpu's split
+   double precision floats into two 32-bit chunks and store them in
+   consecutive fp regs.  To display 64-bit floats stored in this
+   fashion, we have to combine 32 bits from f0 and 32 bits from f1.
+   Throw in user-configurable endianness and you have a real mess.
+
+   Note that this only deals with "live" registers at the top of the
+   stack.  We will attempt to deal with saved registers later, when
+   the raw/cooked register interface is in place. (We need a general
+   interface that can deal with dynamic saved register sizes -- fp
+   regs could be 32 bits wide in one frame and 64 on the frame above
+   and below) */
+
+void 
+mips2_read_fp_register (int regno, char * rare_buffer)
+{
+  char * raw_buffer = alloca (REGISTER_RAW_SIZE (FP0_REGNUM));
+  int HI = (TARGET_BYTE_ORDER == BIG_ENDIAN);
+  int LO = (TARGET_BYTE_ORDER != BIG_ENDIAN);
+
+  if (mips_debug)
+    fprintf_unfiltered (gdb_stdlog, "%s(regno=%d, rare_buffer=0x%x) [%s]\n", 
+			__FUNCTION__, regno, rare_buffer, (HI ? "BE" : "LE"));
+    
+  memset (rare_buffer, 0, REGISTER_RAW_SIZE (FP0_REGNUM));
+
+
+  if ((regno - FP0_REGNUM) & 1)
+    {
+      read_register_gen (regno, raw_buffer);
+      memcpy (&rare_buffer[HI * 4], &raw_buffer[HI * 4], 4);
+    }
+  else
+    {
+      read_register_gen (regno, raw_buffer);
+      memcpy (&rare_buffer[HI * 4], &raw_buffer[HI * 4], 4);
+
+      read_register_gen (regno + 1, raw_buffer);
+      memcpy (&rare_buffer[LO * 4], &raw_buffer[HI * 4], 4);
+    }
+  return;
+}
+
+
 static void
 mips_print_register (int regnum, int all)
 {
@@ -2613,7 +2680,7 @@ mips_print_register (int regnum, int all
 
   /* If virtual format is floating, print it that way.  */
   if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
-    if (FP_REGISTER_DOUBLE)
+    if (FP_REGISTER_DOUBLE || mips2_fp_compat ())
       {				/* show 8-byte floats as float AND double: */
 	int offset = 4 * (TARGET_BYTE_ORDER == BIG_ENDIAN);
 
@@ -3899,7 +3966,14 @@ mips_get_saved_register (char *raw_buffe
 	*lval = lval_register;
       addr = REGISTER_BYTE (regnum);
       if (raw_buffer != NULL)
+	{
+	  if (TYPE_CODE_FLT == TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum))
+	      && mips2_fp_compat ())
+	    mips2_read_fp_register(regnum, raw_buffer);
+
+	  else
 	read_register_gen (regnum, raw_buffer);
+	}
     }
   if (addrp != NULL)
     *addrp = addr;









^ permalink raw reply	[flat|nested] 7+ messages in thread
* [RFA] mips fp register display
@ 2001-06-21 14:41 Don Howard
  2001-06-21 16:01 ` Daniel Jacobowitz
  2001-06-23 11:09 ` Andrew Cagney
  0 siblings, 2 replies; 7+ messages in thread
From: Don Howard @ 2001-06-21 14:41 UTC (permalink / raw)
  To: gdb-patches

This is a patch for an obscure mips fp register display problem.  32 bit mips
chips support 64 bit float operations using two fp registers.  64 bit mips
chips provide a backward compatiblity mode where 64 bit float ops are also
supported using 2 float regsiters -- 32 bits stored in each of the 2 64bit fp
regs.

This patch addresses insight as well as cli gdb.  Insight is not 100% correct:
single precision floats are displayed in double format =( (cli gdb displays
both float and double).  I can change REGISTER_VIRTUAL_TYPE() to try to guess
the the intended type (builtin_type_{float,double}), but that is really not
the right place to fix this problem.


2001-06-21  Don Howard  <dhoward@redhat.com>


        * mips-tdep.c (mips2_read_fp_register): New function.  Reads a
        64-bit float value stored as two 32-bit fragments in consecutive
        float registers.
        (mips2_fp_compat): New function.  Determine if a MIPS3 or later
        cpu is operating in MIPS{1,2} float-compat mode.
        (mips_get_saved_register): Modified to use new
        mips2-compat float support.
        (mips_print_register): Modified to display 64-bit float regs in
        single and double precision.


Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.54
diff -p -u -w -r1.54 mips-tdep.c
--- mips-tdep.c	2001/06/16 20:00:24	1.54
+++ mips-tdep.c	2001/06/21 21:25:48
@@ -174,6 +174,21 @@ mips_saved_regsize (void)
     return 4;
 }

+/* Determine if a MIPS3 or later cpu is operating in MIPS{1,2} FPU
+   compatiblitiy mode. */
+
+static int
+mips2_fp_compat (void)
+{
+  if (REGISTER_RAW_SIZE (FP0_REGNUM) != 8) /* MIPS2 has 32 bit fp regs */
+    return 0;
+
+  /* Otherwise check the FR bit in the status register - it controls
+     the fp compatiblity mode */
+  return !(read_register (PS_REGNUM) & 1 << 26);
+}
+
+
 /* Indicate that the ABI makes use of double-precision registers
    provided by the FPU (rather than combining pairs of registers to
    form double-precision values).  Do not use "TARGET_IS_MIPS64" to
@@ -2572,6 +2587,63 @@ mips_pop_frame (void)
     }
 }

+
+/* Read a MIPS{1,2} floating point register.  This is for use on MIPS3 or
+   later cpus operating in MIPS2 fpu compatiblity mode.
+
+   Background: MIPS1 & 2 fp registers are 32 bits wide.  To support
+   64bit operations, these early MIPS cpus treat fp register pairs
+   (f0,f1) as a single register (d0).  Later MIPS cpu's have 64 bit fp
+   registers and offer a compatibility mode that emulates the MIPS2 fp
+   model.  When operating in MIPS2 fp compat mode, later cpu's split
+   double precision floats into two 32-bit chunks and store them in
+   consecutive fp regs.  To display 64-bit floats stored in this
+   fashion, we have to combine 32 bits from f0 and 32 bits from f1.
+   Throw in user-configurable endianness and you have a real mess.
+
+   Note that this only deals with "live" registers at the top of the
+   stack.  We will attempt to deal with saved registers later, when
+   the raw/cooked register interface is in place. (We need a general
+   interface that can deal with dynamic saved register sizes -- fp
+   regs could be 32 bits wide in one frame and 64 on the frame above
+   and below) */
+
+void
+mips2_read_fp_register (int regno, char *rare_buffer)
+{
+  char *raw_buffer = alloca (REGISTER_RAW_SIZE (FP0_REGNUM));
+  int hi = (TARGET_BYTE_ORDER == BIG_ENDIAN);
+  int lo = (TARGET_BYTE_ORDER != BIG_ENDIAN);
+
+  if (mips_debug)
+    fprintf_unfiltered (gdb_stdlog, "%s(regno=%d, rare_buffer=0x%x) [%s]\n",
+			__FUNCTION__, regno, rare_buffer, (hi ? "BE" : "LE"));
+
+  memset (rare_buffer, 0, REGISTER_RAW_SIZE (FP0_REGNUM));
+
+
+  if ((regno - FP0_REGNUM) & 1)
+    {
+      /* Odd numbered registers are the lower half of a 64 bit value,
+         when in mips2 compat mode.  We print them out here just as an
+         attempt to do something useful.  Note also that rare_buffer
+         has been memset to 0. */
+      read_register_gen (regno, raw_buffer);
+      memcpy (&rare_buffer[hi * 4], &raw_buffer[hi * 4], 4);
+    }
+  else
+    {
+      read_register_gen (regno, raw_buffer);
+      memcpy (&rare_buffer[hi * 4], &raw_buffer[hi * 4], 4);
+
+      read_register_gen (regno + 1, raw_buffer);
+      memcpy (&rare_buffer[lo * 4], &raw_buffer[hi * 4], 4);
+    }
+  return;
+}
+
+
+
 static void
 mips_print_register (int regnum, int all)
 {
@@ -2613,7 +2685,7 @@ mips_print_register (int regnum, int all

   /* If virtual format is floating, print it that way.  */
   if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
-    if (FP_REGISTER_DOUBLE)
+    if (FP_REGISTER_DOUBLE || mips2_fp_compat ())
       {				/* show 8-byte floats as float AND double: */
 	int offset = 4 * (TARGET_BYTE_ORDER == BIG_ENDIAN);

@@ -3819,7 +3891,14 @@ mips_get_saved_register (char *raw_buffe
 	*lval = lval_register;
       addr = REGISTER_BYTE (regnum);
       if (raw_buffer != NULL)
+	{
+	  if (TYPE_CODE_FLT == TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum))
+	      && mips2_fp_compat ())
+	    mips2_read_fp_register(regnum, raw_buffer);
+
+	  else
 	read_register_gen (regnum, raw_buffer);
+	}
     }
   if (addrp != NULL)
     *addrp = addr;

-- 
-Don
dhoward@redhat.com
gdb engineering




^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2001-06-23 11:09 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-03-27  1:01 [RFA] Mips fp register display Don Howard
2001-05-10 10:48 Don Howard
2001-06-21 14:41 [RFA] mips " Don Howard
2001-06-21 16:01 ` Daniel Jacobowitz
2001-06-22 10:26   ` Don Howard
2001-06-23 11:03     ` Andrew Cagney
2001-06-23 11:09 ` Andrew Cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox