From: Don Howard <dhoward@redhat.com>
To: gdb-patches@sources.redhat.com
Subject: [RFA] MIPS2 float register display
Date: Fri, 23 Mar 2001 13:18:00 -0000 [thread overview]
Message-ID: <Pine.LNX.4.21.0103231256230.6874-100000@cassidy.fidalgo.net> (raw)
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
next reply other threads:[~2001-03-23 13:18 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-03-23 13:18 Don Howard [this message]
2001-03-23 18:29 ` Don Howard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.21.0103231256230.6874-100000@cassidy.fidalgo.net \
--to=dhoward@redhat.com \
--cc=gdb-patches@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox