mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-25 13:09:48 +00:00
2002-03-10 Daniel Jacobowitz <drow@mvista.com>
Don Howard <dhoward@redhat.com> * mips-tdep.c (ST0_FR): Define. (mips2_fp_compat): New function, temporarily disabled. (mips_read_fp_register_single): New function. (mips_read_fp_register_double): New function. (mips_print_register): Use them. (do_fp_register_row): Likewise.
This commit is contained in:
parent
3029f9b89c
commit
dd824b049b
@ -1,3 +1,13 @@
|
||||
2002-03-10 Daniel Jacobowitz <drow@mvista.com>
|
||||
Don Howard <dhoward@redhat.com>
|
||||
|
||||
* mips-tdep.c (ST0_FR): Define.
|
||||
(mips2_fp_compat): New function, temporarily disabled.
|
||||
(mips_read_fp_register_single): New function.
|
||||
(mips_read_fp_register_double): New function.
|
||||
(mips_print_register): Use them.
|
||||
(do_fp_register_row): Likewise.
|
||||
|
||||
2002-03-09 Andrew Cagney <ac131313@redhat.com>
|
||||
|
||||
* MAINTAINERS: Add Jim Ingham and Klee Dienes to ``write after
|
||||
|
209
gdb/mips-tdep.c
209
gdb/mips-tdep.c
@ -44,6 +44,10 @@
|
||||
#include "elf-bfd.h"
|
||||
#include "symcat.h"
|
||||
|
||||
/* A useful bit in the CP0 status register (PS_REGNUM). */
|
||||
/* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip. */
|
||||
#define ST0_FR (1 << 26)
|
||||
|
||||
/* The sizes of floating point registers. */
|
||||
|
||||
enum
|
||||
@ -174,6 +178,31 @@ mips_saved_regsize (void)
|
||||
return 4;
|
||||
}
|
||||
|
||||
/* Determine if a MIPS3 or later cpu is operating in MIPS{1,2} FPU
|
||||
compatiblity mode. A return value of 1 means that we have
|
||||
physical 64-bit registers, but should treat them as 32-bit registers. */
|
||||
|
||||
static int
|
||||
mips2_fp_compat (void)
|
||||
{
|
||||
/* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not
|
||||
meaningful. */
|
||||
if (REGISTER_RAW_SIZE (FP0_REGNUM) == 4)
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
/* FIXME drow 2002-03-10: This is disabled until we can do it consistently,
|
||||
in all the places we deal with FP registers. PR gdb/413. */
|
||||
/* Otherwise check the FR bit in the status register - it controls
|
||||
the FP compatiblity mode. If it is clear we are in compatibility
|
||||
mode. */
|
||||
if ((read_register (PS_REGNUM) & ST0_FR) == 0)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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
|
||||
@ -257,6 +286,9 @@ find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int cur_frame);
|
||||
static CORE_ADDR after_prologue (CORE_ADDR pc,
|
||||
mips_extra_func_info_t proc_desc);
|
||||
|
||||
static void mips_read_fp_register_single (int regno, char *rare_buffer);
|
||||
static void mips_read_fp_register_double (int regno, char *rare_buffer);
|
||||
|
||||
/* This value is the model of MIPS in use. It is derived from the value
|
||||
of the PrID register. */
|
||||
|
||||
@ -2676,6 +2708,104 @@ mips_pop_frame (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Floating point register management.
|
||||
|
||||
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.
|
||||
|
||||
The way this works is:
|
||||
- If we are in 32-bit mode or on a 32-bit processor, then a 64-bit
|
||||
double-precision value will be split across two logical registers.
|
||||
The lower-numbered logical register will hold the low-order bits,
|
||||
regardless of the processor's endianness.
|
||||
- If we are on a 64-bit processor, and we are looking for a
|
||||
single-precision value, it will be in the low ordered bits
|
||||
of a 64-bit GPR (after mfc1, for example) or a 64-bit register
|
||||
save slot in memory.
|
||||
- If we are in 64-bit mode, everything is straightforward.
|
||||
|
||||
Note that this code 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). */
|
||||
|
||||
/* Copy a 32-bit single-precision value from the current frame
|
||||
into rare_buffer. */
|
||||
|
||||
static void
|
||||
mips_read_fp_register_single (int regno, char *rare_buffer)
|
||||
{
|
||||
int raw_size = REGISTER_RAW_SIZE (regno);
|
||||
char *raw_buffer = alloca (raw_size);
|
||||
|
||||
if (read_relative_register_raw_bytes (regno, raw_buffer))
|
||||
error ("can't read register %d (%s)", regno, REGISTER_NAME (regno));
|
||||
if (raw_size == 8)
|
||||
{
|
||||
/* We have a 64-bit value for this register. Find the low-order
|
||||
32 bits. */
|
||||
int offset;
|
||||
|
||||
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
|
||||
offset = 4;
|
||||
else
|
||||
offset = 0;
|
||||
|
||||
memcpy (rare_buffer, raw_buffer + offset, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (rare_buffer, raw_buffer, 4);
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy a 64-bit double-precision value from the current frame into
|
||||
rare_buffer. This may include getting half of it from the next
|
||||
register. */
|
||||
|
||||
static void
|
||||
mips_read_fp_register_double (int regno, char *rare_buffer)
|
||||
{
|
||||
int raw_size = REGISTER_RAW_SIZE (regno);
|
||||
|
||||
if (raw_size == 8 && !mips2_fp_compat ())
|
||||
{
|
||||
/* We have a 64-bit value for this register, and we should use
|
||||
all 64 bits. */
|
||||
if (read_relative_register_raw_bytes (regno, rare_buffer))
|
||||
error ("can't read register %d (%s)", regno, REGISTER_NAME (regno));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((regno - FP0_REGNUM) & 1)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"mips_read_fp_register_double: bad access to "
|
||||
"odd-numbered FP register");
|
||||
|
||||
/* mips_read_fp_register_single will find the correct 32 bits from
|
||||
each register. */
|
||||
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
|
||||
{
|
||||
mips_read_fp_register_single (regno, rare_buffer + 4);
|
||||
mips_read_fp_register_single (regno + 1, rare_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
mips_read_fp_register_single (regno, rare_buffer);
|
||||
mips_read_fp_register_single (regno + 1, rare_buffer + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mips_print_register (int regnum, int all)
|
||||
{
|
||||
@ -2688,22 +2818,23 @@ mips_print_register (int regnum, int all)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If an even floating point register, also print as double. */
|
||||
/* If we have a actual 32-bit floating point register (or we are in
|
||||
32-bit compatibility mode), and the register is even-numbered,
|
||||
also print it as a double (spanning two registers). */
|
||||
if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT
|
||||
&& (REGISTER_RAW_SIZE (regnum) == 4
|
||||
|| mips2_fp_compat ())
|
||||
&& !((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];
|
||||
{
|
||||
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);
|
||||
mips_read_fp_register_double (regnum, 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 ("); ");
|
||||
}
|
||||
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);
|
||||
|
||||
/* The problem with printing numeric register names (r26, etc.) is that
|
||||
@ -2717,8 +2848,10 @@ 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)
|
||||
{ /* show 8-byte floats as float AND double: */
|
||||
if (REGISTER_RAW_SIZE (regnum) == 8 && !mips2_fp_compat ())
|
||||
{
|
||||
/* We have a meaningful 64-bit value in this register. Show
|
||||
it as a 32-bit float and a 64-bit double. */
|
||||
int offset = 4 * (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG);
|
||||
|
||||
printf_filtered (" (float) ");
|
||||
@ -2753,35 +2886,25 @@ mips_print_register (int regnum, int all)
|
||||
static int
|
||||
do_fp_register_row (int regnum)
|
||||
{ /* do values for FP (float) regs */
|
||||
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 == BFD_ENDIAN_BIG);
|
||||
int LO = (TARGET_BYTE_ORDER != BFD_ENDIAN_BIG);
|
||||
char *raw_buffer;
|
||||
double doub, flt1, flt2; /* doubles extracted from raw hex data */
|
||||
int inv1, inv2, inv3;
|
||||
|
||||
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));
|
||||
raw_buffer = (char *) alloca (2 * REGISTER_RAW_SIZE (FP0_REGNUM));
|
||||
|
||||
/* Get the data in raw format. */
|
||||
if (read_relative_register_raw_bytes (regnum, raw_buffer[HI]))
|
||||
error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
|
||||
if (REGISTER_RAW_SIZE (regnum) == 4)
|
||||
if (REGISTER_RAW_SIZE (regnum) == 4 || mips2_fp_compat ())
|
||||
{
|
||||
/* 4-byte registers: we can fit two registers per row. */
|
||||
/* Also print every pair of 4-byte regs as an 8-byte double. */
|
||||
if (read_relative_register_raw_bytes (regnum + 1, raw_buffer[LO]))
|
||||
error ("can't read register %d (%s)",
|
||||
regnum + 1, REGISTER_NAME (regnum + 1));
|
||||
/* 4-byte registers: we can fit two registers per row. */
|
||||
/* Also print every pair of 4-byte regs as an 8-byte double. */
|
||||
mips_read_fp_register_single (regnum, raw_buffer);
|
||||
flt1 = unpack_double (builtin_type_float, raw_buffer, &inv1);
|
||||
|
||||
/* copy the two floats into one double, and unpack both */
|
||||
memcpy (dbl_buffer, raw_buffer, 2 * REGISTER_RAW_SIZE (FP0_REGNUM));
|
||||
flt1 = unpack_double (builtin_type_float, raw_buffer[HI], &inv1);
|
||||
flt2 = unpack_double (builtin_type_float, raw_buffer[LO], &inv2);
|
||||
doub = unpack_double (builtin_type_double, dbl_buffer, &inv3);
|
||||
mips_read_fp_register_single (regnum + 1, raw_buffer);
|
||||
flt2 = unpack_double (builtin_type_float, raw_buffer, &inv2);
|
||||
|
||||
mips_read_fp_register_double (regnum, raw_buffer);
|
||||
doub = unpack_double (builtin_type_double, raw_buffer, &inv3);
|
||||
|
||||
printf_filtered (" %-5s", REGISTER_NAME (regnum));
|
||||
if (inv1)
|
||||
printf_filtered (": <invalid float>");
|
||||
@ -2805,14 +2928,14 @@ do_fp_register_row (int regnum)
|
||||
regnum += 2;
|
||||
}
|
||||
else
|
||||
{ /* eight byte registers: print each one as float AND as double. */
|
||||
int offset = 4 * (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG);
|
||||
|
||||
memcpy (dbl_buffer, raw_buffer[HI], 2 * REGISTER_RAW_SIZE (FP0_REGNUM));
|
||||
flt1 = unpack_double (builtin_type_float,
|
||||
&raw_buffer[HI][offset], &inv1);
|
||||
doub = unpack_double (builtin_type_double, dbl_buffer, &inv3);
|
||||
{
|
||||
/* Eight byte registers: print each one as float AND as double. */
|
||||
mips_read_fp_register_single (regnum, raw_buffer);
|
||||
flt1 = unpack_double (builtin_type_double, raw_buffer, &inv1);
|
||||
|
||||
mips_read_fp_register_double (regnum, raw_buffer);
|
||||
doub = unpack_double (builtin_type_double, raw_buffer, &inv3);
|
||||
|
||||
printf_filtered (" %-5s: ", REGISTER_NAME (regnum));
|
||||
if (inv1)
|
||||
printf_filtered ("<invalid float>");
|
||||
|
Loading…
Reference in New Issue
Block a user