* [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* Re: [RFA] mips fp register display
2001-06-21 14:41 [RFA] mips fp register display Don Howard
@ 2001-06-21 16:01 ` Daniel Jacobowitz
2001-06-22 10:26 ` Don Howard
2001-06-23 11:09 ` Andrew Cagney
1 sibling, 1 reply; 7+ messages in thread
From: Daniel Jacobowitz @ 2001-06-21 16:01 UTC (permalink / raw)
To: gdb-patches
On Thu, Jun 21, 2001 at 03:42:10PM -0700, Don Howard wrote:
>
> 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.
I see why this is necessary, but it doesn't address the problem I was
talking about. I also don't think it's really the right solution.
If you look a few lines higher in mips_print_register, you see:
/* If an even floating point register, also print as double. */
if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT
&& !((regnum - FP0_REGNUM) & 1))
if (REGISTER_RAW_SIZE (regnum) == 4) /* this would be silly on MIPS64 or N32 (Irix 6) */
{
char dbuffer[2 * MAX_REGISTER_RAW_SIZE];
read_relative_register_raw_bytes (regnum, dbuffer);
read_relative_register_raw_bytes (regnum + 1, dbuffer + MIPS_REGSIZE);
REGISTER_CONVERT_TO_TYPE (regnum, builtin_type_double, dbuffer);
printf_filtered ("(d%d: ", regnum - FP0_REGNUM);
val_print (builtin_type_double, dbuffer, 0, 0,
gdb_stdout, 0, 1, 0, Val_pretty_default);
printf_filtered ("); ");
}
fputs_filtered (REGISTER_NAME (regnum), gdb_stdout);
Well, obviously it's not always silly on N32. Change the
if (REGISTER_RAW_SIZE (regnum) == 4)
to something like
if (mips_small_float_registers ())
On the other hand, I think that perhaps if FR is set
REGISTER_RAW_SIZE (regnum) ought to be 4. Isn't that what it means?
Also, we already have REGISTER_CONVERT_TO_TYPE. Rather than hacking in
a third or perhaps fourth copy of this sort of thing, why not extend
REGISTER_CONVERT_TO_TYPE?
--
Daniel Jacobowitz Carnegie Mellon University
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [RFA] mips fp register display
2001-06-21 16:01 ` Daniel Jacobowitz
@ 2001-06-22 10:26 ` Don Howard
2001-06-23 11:03 ` Andrew Cagney
0 siblings, 1 reply; 7+ messages in thread
From: Don Howard @ 2001-06-22 10:26 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Thu, 21 Jun 2001, Daniel Jacobowitz wrote:
> On Thu, Jun 21, 2001 at 03:42:10PM -0700, Don Howard wrote:
> >
> > 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.
>
> I see why this is necessary, but it doesn't address the problem I was
> talking about. I also don't think it's really the right solution.
> If you look a few lines higher in mips_print_register, you see:
>
> /* If an even floating point register, also print as double. */
> if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT
> && !((regnum - FP0_REGNUM) & 1))
> if (REGISTER_RAW_SIZE (regnum) == 4) /* this would be silly on MIPS64 or N32 (Irix 6) */
> {
> char dbuffer[2 * MAX_REGISTER_RAW_SIZE];
>
> read_relative_register_raw_bytes (regnum, dbuffer);
> read_relative_register_raw_bytes (regnum + 1, dbuffer + MIPS_REGSIZE);
> REGISTER_CONVERT_TO_TYPE (regnum, builtin_type_double, dbuffer);
>
> printf_filtered ("(d%d: ", regnum - FP0_REGNUM);
> val_print (builtin_type_double, dbuffer, 0, 0,
> gdb_stdout, 0, 1, 0, Val_pretty_default);
> printf_filtered ("); ");
> }
> fputs_filtered (REGISTER_NAME (regnum), gdb_stdout);
>
> Well, obviously it's not always silly on N32. Change the
> if (REGISTER_RAW_SIZE (regnum) == 4)
> to something like
> if (mips_small_float_registers ())
>
> On the other hand, I think that perhaps if FR is set
> REGISTER_RAW_SIZE (regnum) ought to be 4. Isn't that what it means?
It seems to me that REGISTER_VIRTUAL_SIZE() is the macro that should provide
this info, as the raw register doesn't change. Neither of these check the FR
bit.
>
> Also, we already have REGISTER_CONVERT_TO_TYPE. Rather than hacking in
> a third or perhaps fourth copy of this sort of thing, why not extend
> REGISTER_CONVERT_TO_TYPE?
I would guess (I'm no authority though) that REGISTER_CONVERT_TO_VIRTUAL() and
REGISTER_CONVERT_TO_RAW() might be better places to do this.
I chose to implement a new read_fp_register() function so that insight could
benifit from the fix also. print_register() and do_register_row() affect cli
gdb only.
--
-Don
dhoward@redhat.com
gdb engineering
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [RFA] mips fp register display
2001-06-22 10:26 ` Don Howard
@ 2001-06-23 11:03 ` Andrew Cagney
0 siblings, 0 replies; 7+ messages in thread
From: Andrew Cagney @ 2001-06-23 11:03 UTC (permalink / raw)
To: Don Howard; +Cc: Daniel Jacobowitz, gdb-patches
>>
>> On the other hand, I think that perhaps if FR is set
>> REGISTER_RAW_SIZE (regnum) ought to be 4. Isn't that what it means?
>
> It seems to me that REGISTER_VIRTUAL_SIZE() is the macro that should provide
> this info, as the raw register doesn't change. Neither of these check the FR
> bit.
FYI, REGISTER_RAW_SIZE() returns the number of bytes used to store the targets _raw_
register. When a MIPS3/4/5 is executing MIPS2 code, the raw FP register still contains
64 bits. It is just that only the low 32 bits is being used. This is
very like a 64 bit MIPS cpu running a 32 bit program. This typically
only occures in embedded environments.
With regard to REGISTER_RAW_SIZE and REGISTER_CONVERT_TO_TYPE. They are
about to be deprecated .... (see TODO). The methods
gdbarch_register_{read,write} were recently added and they really clean
up that mess. I wouldn't be too worried about using them here.
Andrew
>> Also, we already have REGISTER_CONVERT_TO_TYPE. Rather than hacking in
>> a third or perhaps fourth copy of this sort of thing, why not extend
>> REGISTER_CONVERT_TO_TYPE?
>
>
> I would guess (I'm no authority though) that REGISTER_CONVERT_TO_VIRTUAL() and
> REGISTER_CONVERT_TO_RAW() might be better places to do this.
>
> I chose to implement a new read_fp_register() function so that insight could
> benifit from the fix also. print_register() and do_register_row() affect cli
> gdb only.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFA] mips fp register display
2001-06-21 14:41 [RFA] mips fp register display Don Howard
2001-06-21 16:01 ` Daniel Jacobowitz
@ 2001-06-23 11:09 ` Andrew Cagney
1 sibling, 0 replies; 7+ messages in thread
From: Andrew Cagney @ 2001-06-23 11:09 UTC (permalink / raw)
To: Don Howard; +Cc: gdb-patches
Don,
Approved with notes. At least this fixes the most common case and
gets GDB to print out the correct value. Fixing the case where GDB is
three levels down on a stack frame is a different problem.
> + /* Otherwise check the FR bit in the status register - it controls
> + the fp compatiblity mode */
> + return !(read_register (PS_REGNUM) & 1 << 26);
>
Is there a constant with ``1 << 26'' in it somewhere? If not, can you
please add one. Also, some extra paren so I don't need to strain my
brain trying to figure out the operator order is useful.
Andrew
^ 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-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
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-06-21 14:41 [RFA] mips fp register display 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
-- strict thread matches above, loose matches on Subject: below --
2001-05-10 10:48 [RFA] Mips " Don Howard
2001-03-27 1:01 Don Howard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox