* [RFA] MIPS2 float register display
@ 2001-03-23 13:18 Don Howard
2001-03-23 18:29 ` Don Howard
0 siblings, 1 reply; 2+ messages in thread
From: Don Howard @ 2001-03-23 13:18 UTC (permalink / raw)
To: gdb-patches
This patch fixes an obscure MIPS floating point register display bug.
It's been tested on linux-cross-mips with both big and little endian
executables.
2001-03-21 Don Howard <dhoward@redhat.com>
* mips-tdep.c (print_mips2_fp_register): New function. Properly
displays floating point registers on MIPS3 or later cpus operating
in MIPS2 fp emulation mode.
(mips2_fp_compat): New function. Determines if a MIPS3 or later
cpu is operating in MIPS2 fp emulation mode.
(mips_print_register): Added MIPS2 emulation check and handling.
(do_fp_register_row): Ditto.
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.45
diff -p -u -w -r1.45 mips-tdep.c
--- mips-tdep.c 2001/03/20 18:16:10 1.45
+++ mips-tdep.c 2001/03/23 21:08:31
@@ -2572,11 +2572,136 @@ mips_pop_frame (void)
}
}
+
+/* Determine if a MIPS3 or later cpu is operating in MIPS2 FPU
+ compatiblitiy mode. */
+
+static int
+mips2_fp_compat ()
+{
+ if (8 != REGISTER_RAW_SIZE (FP0_REGNUM)) /* MIPS2 has 32 bit fp regs */
+ return 0;
+
+ /* Read the status register and check the FR bit.
+ 0 == MIPS2; 1 == NORMAL */
+
+#define FR_BIT (1 << 26)
+ return !(read_register (PS_REGNUM) & FR_BIT);
+}
+
+/* Display a MIPS2 floating point register (or register row). This is
+ for use on MIPS3 or later cpus operating in MIPS2 fpu compatiblity
+ mode.
+
+ Background: MIPS2 fp registers are 32 bits wide. To support 64bit
+ operations, MIPS2 cpus treat fp register pairs (f0,f1) as a single
+ register (d0). Later 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 2 32 bit chunks and store them in consecutive
+ fp regs. To display 64bit 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) */
+
+static int
+print_mips2_fp_register (int regnum, int printrow)
+{
+ char *raw_buffer[2];
+ char *dbl_buffer;
+ /* use HI and LO to control the order of combining two flt regs */
+ int HI = (TARGET_BYTE_ORDER == BIG_ENDIAN);
+ int LO = (TARGET_BYTE_ORDER != BIG_ENDIAN);
+ double doub, flt1, flt2; /* doubles extracted from raw hex data */
+ int inv1, inv2, inv3;
+ int even_regnum = regnum;
+
+
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stdlog, "MIPS II compatibility (%s)\n",
+ HI ? "BE" : "LE");
+
+ if (regnum & 1)
+ {
+ if (printrow)
+ return regnum + 1;
+
+ else
+ even_regnum = regnum - 1;
+ }
+
+
+ if (0 == selected_frame_level)
+ {
+ raw_buffer[0] = (char *) alloca (REGISTER_RAW_SIZE (FP0_REGNUM));
+ raw_buffer[1] = (char *) alloca (REGISTER_RAW_SIZE (FP0_REGNUM));
+ dbl_buffer = (char *) alloca (2 * REGISTER_RAW_SIZE (FP0_REGNUM));
+
+ read_register_gen (even_regnum, raw_buffer[LO]);
+ read_register_gen (even_regnum + 1, raw_buffer[HI]);
+
+ memcpy (&dbl_buffer[HI * 4], &raw_buffer[LO][HI * 4], 4);
+ memcpy (&dbl_buffer[LO * 4], &raw_buffer[HI][HI * 4], 4);
+
+ flt1 =
+ unpack_double (builtin_type_float, &raw_buffer[LO][HI * 4], &inv1);
+ flt2 =
+ unpack_double (builtin_type_float, &raw_buffer[HI][HI * 4], &inv2);
+ doub = unpack_double (builtin_type_double, dbl_buffer, &inv3);
+
+ if (printrow)
+ {
+ printf_filtered (inv1 ? " %-5s: <invalid float>" :
+ " %-5s%-17.9g", REGISTER_NAME (even_regnum), flt1);
+ printf_filtered (inv2 ? " %-5s: <invalid float>" :
+ " %-5s%-17.9g", REGISTER_NAME (even_regnum + 1),
+ flt2);
+ printf_filtered (inv3 ? " dbl: <invalid double>\n" :
+ " dbl: %-24.17g\n", doub);
+ regnum += 2;
+ }
+ else
+ {
+ int even_or_odd = regnum & 1;
+
+ printf_filtered ("%-5s: (float) ", REGISTER_NAME (regnum));
+ val_print (builtin_type_float, &raw_buffer[even_or_odd][HI * 4], 0,
+ 0, gdb_stdout, 0, 1, 0, Val_pretty_default);
+ printf_filtered (", (double) ");
+ val_print (builtin_type_double, dbl_buffer, 0, 0,
+ gdb_stdout, 0, 1, 0, Val_pretty_default);
+
+ regnum++;
+ }
+ }
+ else
+ {
+ printf_filtered ("%-5s: <invalid float/double>",
+ REGISTER_NAME (regnum));
+ regnum++;
+ }
+
+ return regnum;
+}
+
static void
mips_print_register (int regnum, int all)
{
char raw_buffer[MAX_REGISTER_RAW_SIZE];
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT &&
+ mips2_fp_compat ())
+ {
+ print_mips2_fp_register (regnum, 0);
+ return;
+ }
+
/* Get the data in raw format. */
if (read_relative_register_raw_bytes (regnum, raw_buffer))
{
@@ -2656,6 +2781,9 @@ do_fp_register_row (int regnum)
int LO = (TARGET_BYTE_ORDER != BIG_ENDIAN);
double doub, flt1, flt2; /* doubles extracted from raw hex data */
int inv1, inv2, inv3;
+
+ if (mips2_fp_compat ())
+ return print_mips2_fp_register (regnum, 1);
raw_buffer[0] = (char *) alloca (REGISTER_RAW_SIZE (FP0_REGNUM));
raw_buffer[1] = (char *) alloca (REGISTER_RAW_SIZE (FP0_REGNUM));
--
-Don
dhoward@redhat.com
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [RFA] MIPS2 float register display
2001-03-23 13:18 [RFA] MIPS2 float register display Don Howard
@ 2001-03-23 18:29 ` Don Howard
0 siblings, 0 replies; 2+ messages in thread
From: Don Howard @ 2001-03-23 18:29 UTC (permalink / raw)
To: gdb-patches
Please disregard this patch, as it does not fix the fp display problem for
insight. I'll post a more general patch shortly.
On Fri, 23 Mar 2001, Don Howard wrote:
>
> This patch fixes an obscure MIPS floating point register display bug.
> It's been tested on linux-cross-mips with both big and little endian
> executables.
>
> 2001-03-21 Don Howard <dhoward@redhat.com>
>
> * mips-tdep.c (print_mips2_fp_register): New function. Properly
> displays floating point registers on MIPS3 or later cpus operating
> in MIPS2 fp emulation mode.
> (mips2_fp_compat): New function. Determines if a MIPS3 or later
> cpu is operating in MIPS2 fp emulation mode.
> (mips_print_register): Added MIPS2 emulation check and handling.
> (do_fp_register_row): Ditto.
>
>
--
-Don
dhoward@redhat.com
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2001-03-23 18:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-03-23 13:18 [RFA] MIPS2 float register display Don Howard
2001-03-23 18:29 ` Don Howard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox