* [WIP/RFC] MIPS registers overhaul
@ 2003-05-10 0:25 Kevin Buettner
2003-05-10 20:30 ` Andrew Cagney
0 siblings, 1 reply; 46+ messages in thread
From: Kevin Buettner @ 2003-05-10 0:25 UTC (permalink / raw)
To: gdb-patches
The patch below represents the results of trying to fix two problems
related to floating point registers, stumbling at various points along
the way, and realizing that I needed to fix even more...
The two problems related to floating point registers that I started out
trying to fix are the following:
1) On mips64, it's not possible to set a floating point register to
a single precision value.
2) Again, on mips64, when running a program using the o32 ABI, floating
point doubles were not being fetched from GDB's regcache correctly.
For o32, floating point doubles are represented using register pairs,
but, for mips64, each register is stored in a 64-bit container. When
attempting to retrieve the value of a 64-bit double that should
be retrieved by taking 32-bits from a pair, the single 64-bit container
was being considered to be the value of the double.
Problem 1 was solved by introducing a union type for floating point
registers. When attempting to display a value using ``print'', you'll
see (with my patch) something like this:
(gdb) p $f20
$1 = {i = 4621199872640208077, f = -107374184, d = 8.9000000000000004}
(If someone can think of more meaningful, but still terse field names for
the above, please let me know.)
If you want to set the register, you can do it as follows:
(gdb) set $f20.d=2.3
(gdb) p $f20
$2 = {i = 4612361558371493478, f = 2.72008302e+23, d = 2.2999999999999998}
(gdb) set $f20.f=2.2
(gdb) p $f20
$3 = {i = 4612361557728087245, f = 2.20000005, d = 2.2999997142702342}
(gdb) set $f20.i=42
(gdb) p $f20
$4 = {i = 42, f = 5.88545355e-44, d = 2.0750757125332355e-322}
Also, you can still do:
(gdb) set $f20=3.3
(gdb) p $f20
$5 = {i = 4614613358185178726, f = 2.72008302e+23, d = 3.2999999999999998}
Problem 2 was solved by introducing pseudo-registers for the floating point
registers. Along the way (last Friday, I think), I ran into an assertion
failure which caused me to make even more extensive changes to the MIPS code.
BTW, the raw floating point registers are still accessible. Doing
"info registers raw" will display all of the raw registers. Or, if
you know the names of the registers you want to display, you can do,
e.g, "info registers raw_f20".
Which reminds me... I've introduced two sets of register numbers. I
called these the "cooked" and "raw" regnums. In many cases, the
cooked and raw numbers are the same. (They'll usually be the same
when the raw and cooked types are the same.) In the cases where the
numbers are different, the cooked number is a pseudo register number
and the corresponding raw register is (usually) used to determine the
value of cooked value. Raw registers numbers should be used by the
lower layers of GDB which communicate with the target and need to
populate GDB's regcache. The cooked registers *should* be used almost
everywhere else. Except they aren't at the moment. In particular,
most of mips-tdep.c wants to still operate on "raw" register data.
(Anywhere you see a byte order check, that's a clue that raw register
numbers should still be used.) So, in order to prevent this patch from
becoming even larger than it already is, much of mips-tdep.c still
uses raw register numbers. These should (probably) be cleaned up some
day to use cooked numbers instead. (I need to check to make sure I
have this as a comment in the code somewhere...)
For the o32 case that I was originally trying to fix, we end up
creating 16 64-bit cooked floating point registers of the union type
mentioned above. The raw floating point registers (in pairs) are used
to construct the cooked value. It's also possible to end up with no
cooked floating point registers or 32-floating floating point
registers, either 32- or 64-bit. (The values of FP_REGISTER_DOUBLE
and MIPS_FPU_TYPE influence what exactly gets done.)
Anyway, here it is. Any suggestions on how to break this patch up so
that it can be sensibly reviewed will be very much appreciated. (It
seems that much of what I've done is interdependent...)
* mdebugread.c, mips-linux-nat.c, mips-linux-tdep.c, mips-nat.c,
mips-tdep.c, mipsnbsd-nat.c, remote-mips.c, config/mips/nm-riscos.h
(ZERO_REGNUM, V0_REGNUM, A0_REGNUM, T9_REGNUM, SP_REGNUM, RA_REGNUM)
(PS_REGNUM, HI_REGNUM, LO_REGNUM, BADVADDR_REGNUM, CAUSE_REGNUM)
(PC_REGNUM, FP0_REGNUM, FPA0_REGNUM, FCRCS_REGNUM, FIRST_EMBED_REGNUM)
(PRID_REGNUM, LAST_EMBED_REGNUM, MIPS_LAST_ARG_REGNUM)
(MIPS_LAST_FP_ARG_REGNUM: Replace references to these macros
with references to members in the mips_regnums struct.
* Makefile.in (mdebugread.o, mips-linux-nat.o, mips-nat.o): Add
dependency on $(mips_tdep_h).
(mips-tdep.o): Add dependency on $(reggroups_h).
* mdebugread.c (mips-tdep.h): Include.
(RA_REGNUM): Revise definition.
* mips-linux-nat.c (mips-tdep.h): Include.
* mips-nat.c (mips-tdep.h): Include.
(REGISTER_PTRACE_ADDR): Rewrite macro into function.
* mips-tdep.c (reggroups.h): Include.
(struct gdbarch_tdep): Move ``mips_last_arg_regnum'' and
``mips_last_fp_arg_regnum'' members (renamed slightly) to
the mips_regnums struct. Add new members ``raw_regnums''
and ``cooked_regnums''.
(MIPS_LAST_FP_ARG_REGNUM, MIPS_LAST_ARG_REGNUM): Delete
macros.
(FP_REGISTER_DOUBLE): Move location of macro definition earlier
in the file.
(mips_raw_regnums, mips_cooked_regnums): New accessor functions.
(mips2_fp_compat): Use FP_REGISTER_DOUBLE to help determine
return value.
(mips_type_float_double_register_big)
(mips_type_float_double_register_little)
(mips_type_float_single_register_big)
(mips_type_float_single_register_little): New static variables
representing types for MIPS (cooked) floating point registers.
(mips_generic_embed_reg_names): New static variable.
(mips_processor_reg_names): Rename to mips_embed_reg_names.
(reg_name): New function.
(mips_register_name): Rewritten to use reg_name().
(mips_tx39_embed_reg_names): New static array listing names
of tx39 embedded registers.
(mips_r3041_reg_names): Rename to mips_r3041_embed_reg_names.
Prune names to just those of the embedded registers.
(mips_r3051_reg_names): Rename to mips_r3051_embed_reg_names.
Prune names to just those of the embedded registers.
(mips_r3081_reg_names): Rename to mips_r3081_embed_reg_names.
Prune names to just those of the embedded registers.
(mips_lsi33k_reg_names): Disable this broken code.
(mips_processor_type_table): Change all ``regnames'' references
to those listed above. Add entry for "tx39".
(mips_register_raw_size, mips_register_convertible)
(mips_register_convert_to_virtual, mips_register_convert_to_raw)
(mips_register_convert_to_type, mips_register_convert_from_type):
Delete.
(mips_register_virtual_type): Rewrite so that registers in
range [0, NUM_REGS) have a type whose size is the same as
that expected by the remote protocol. Pseudo-registers
above this range are give more user-friendly types.
(mips_find_saved_regs): For the floating point registers, put
references to both the cooked and raw regnums in the ``saved_regs''
array.
(mips_raw_reggroup): New static global.
(mips_init_reggroups, mips_add_reggroups, mips_register_reggroup_p)
(mips_is_floating_point_register, mips_is_raw_register)
(mips_is_general_purpose_register)
(build_mips_type_float_double_register_big)
(build_mips_type_float_double_register_little)
(build_mips_type_float_single_register_big)
(build_mips_type_float_single_register_little)
(cooked_regnum_to_raw_regnum, mips_pseudo_register_read)
(mips_psuedo_register_write): New functions.
(mips_read_fp_register_double): Simplify.
(mips_print_fp_register): Revise, taking into account the
fact that floating point registers are now pseudo registers.
(mips_print_register): Eliminate references to
REGISTER_VIRTUAL_TYPE().
(do_fp_register_row): Return early for no-name registers.
(do_gp_register_row): Eliminate references to REGISTER_VIRTUAL_TYPE().
Change logic to not break out of row printing loop when a non-general
purpose register is seen.
(mips_do_registers_info): Account for the fact that we now have
pseudo registers. Print the general purpose registers and the
floating point registers in seperate passes.
(mips_set_processor_type): Refer to ``mips_embed_reg_names''
instead of ``mips_processor_reg_names''.
(mips_stab_reg_to_regnum, mips_dwarf_dwarf2_ecoff_reg_to_regnum):
Add case for dealing with 16 cooked floating point registers.
(mips_gdbarch_init): Don't call set_gdbarch_register_raw_size(),
set_gdbarch_register_convertible(),
set_gdbarch_register_convert_to_virtual(), or
set_gdbarch_register_convert_to_raw() any longer. Initialize
tdep->raw_regnums and tdep->cooked_regnums. Initialize register
groups. Invoke set_gdbarch_sp_regnum() and set_gdbarch_pc_regnum().
(mips_dump_regnums): New function.
(mips_dump_tdep): Call mips_dump_regnums() to dump new members
of struct gdbarch_tdep. Don't dump things which've been deleted.
(_initialize_mips_tdep): Invoke mips_init_reggroups ().
Initialize mips_type_float_double_register_big,
mips_type_float_double_register_little,
mips_type_float_single_register_big, and
mips_type_float_single_register_little.
* mips-tdep.h (mips_regnums): New struct.
(mips_raw_regnums, mips_cooked_regnums): New functions.
* mipsnbsd-nat.c (mips-tdep.h): Include.
* remote-mips.c (mips-tdep.h): Include.
* config/mips/tm-irix3.h (MIPS_REGISTER_NAMES, FP0_REGNUM)
(PC_REGNUM, CAUSE_REGNUM, BADVADDR_REGNUM, HI_REGNUM, LO_REGNUM)
(FCRCS_REGNUM, FCRIR_REGNUM): Delete.
* config/mips/tm-irix5.h (REGISTER_BYTES, REGISTER_BYTE)
(REGISTER_VIRTUAL_TYPE): Delete.
* config/mips/tm-irix6.h (MIPS_REGISTER_NAMES, FP0_REGNUM)
(PC_REGNUM, CAUSE_REGNUM, BADVADDR_REGNUM, HI_REGNUM, LO_REGNUM)
(FCRCS_REGNUM, FCRIR_REGNUM, REGISTER_BYTE): Delete.
(REGISTER_VIRTUAL_TYPE): Delete #undef.
* config/mips/tmp-mips.h (MIPS_REGISTER_NAMES, ZERO_REGNUM)
(V0_REGNUM, A0_REGNUM, T9_REGNUM, SP_REGNUM, RA_REGNUM, PS_REGNUM)
(HI_REGNUM, LO_REGNUM, BADVADDR_REGNUM, CAUSE_REGNUM, PC_REGNUM)
(FP0_REGNUM, FPA0_REGNUM, FCRCS_REGNUM, FCRIR_REGNUM)
(UNUSED_REGNUM, FIRST_EMBED_REGNUM, PRID_REGNUM, LAST_EMBED_REGNUM)
(REGISTER_BYTE, REGISTER_VIRTUAL_TYPE)
(mips_register_convert_to_type, mips_register_convert_from_type)
(MIPS_REGISTER_CONVERT_TO_TYPE, MIPS_REGISTER_CONVERT_FROM_TYPE):
Delete.
* config/mips/tm-mips64.h (REGISTER_VIRTUAL_TYPE): Delete.
* config/mips/tm-tx39.h, config/mips/tm-tx39l.h
(MIPS_REGISTER_NAMES): Delete.
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.374
diff -u -p -r1.374 Makefile.in
--- Makefile.in 5 May 2003 18:33:10 -0000 1.374
+++ Makefile.in 9 May 2003 23:36:30 -0000
@@ -1953,7 +1953,7 @@ mdebugread.o: mdebugread.c $(defs_h) $(s
$(block_h) \
$(coff_sym_h) $(coff_symconst_h) $(gdb_stat_h) $(gdb_string_h) \
$(bfd_h) $(coff_ecoff_h) $(libaout_h) $(aout_aout64_h) \
- $(aout_stab_gnu_h) $(expression_h) $(language_h)
+ $(aout_stab_gnu_h) $(expression_h) $(language_h) $(mips_tdep_h)
mem-break.o: mem-break.c $(defs_h) $(symtab_h) $(breakpoint_h) $(inferior_h) \
$(target_h)
memattr.o: memattr.c $(defs_h) $(command_h) $(gdbcmd_h) $(memattr_h) \
@@ -1961,17 +1961,18 @@ memattr.o: memattr.c $(defs_h) $(command
minsyms.o: minsyms.c $(defs_h) $(gdb_string_h) $(symtab_h) $(bfd_h) \
$(symfile_h) $(objfiles_h) $(demangle_h) $(value_h) $(cp_abi_h)
mips-irix-tdep.o: mips-irix-tdep.c $(defs_h) $(osabi_h) $(elf_bfd_h)
-mips-linux-nat.o: mips-linux-nat.c $(defs_h)
+mips-linux-nat.o: mips-linux-nat.c $(defs_h) $(mips_tdep_h)
mips-linux-tdep.o: mips-linux-tdep.c $(defs_h) $(gdbcore_h) $(target_h) \
$(solib_svr4_h) $(osabi_h) $(gdb_string_h) $(mips_tdep_h) \
$(gdb_assert_h)
-mips-nat.o: mips-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(regcache_h)
+mips-nat.o: mips-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(regcache_h) \
+ $(mips_tdep_h)
mips-tdep.o: mips-tdep.c $(defs_h) $(gdb_string_h) $(gdb_assert_h) \
$(frame_h) $(inferior_h) $(symtab_h) $(value_h) $(gdbcmd_h) \
$(language_h) $(gdbcore_h) $(symfile_h) $(objfiles_h) \
$(gdbtypes_h) $(target_h) $(arch_utils_h) $(regcache_h) \
$(osabi_h) $(mips_tdep_h) $(block_h) $(opcode_mips_h) \
- $(elf_mips_h) $(elf_bfd_h) $(symcat_h)
+ $(elf_mips_h) $(elf_bfd_h) $(symcat_h) $(reggroups_h)
mipsm3-nat.o: mipsm3-nat.c $(defs_h) $(inferior_h) $(regcache_h)
mipsnbsd-nat.o: mipsnbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
$(mipsnbsd_tdep_h)
Index: mdebugread.c
===================================================================
RCS file: /cvs/src/src/gdb/mdebugread.c,v
retrieving revision 1.44
diff -u -p -r1.44 mdebugread.c
--- mdebugread.c 19 Mar 2003 19:45:49 -0000 1.44
+++ mdebugread.c 9 May 2003 23:36:32 -0000
@@ -55,6 +55,9 @@
#include "gdb_assert.h"
#include "block.h"
+#include "mips-tdep.h"
+#define RA_REGNUM (mips_cooked_regnums (current_gdbarch)->ra_regnum)
+
/* These are needed if the tm.h file does not contain the necessary
mips specific definitions. */
@@ -69,9 +72,6 @@ typedef struct mips_extra_func_info
PDR pdr;
}
*mips_extra_func_info_t;
-#ifndef RA_REGNUM
-#define RA_REGNUM 0
-#endif
#endif
#ifdef USG
Index: mips-linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-linux-nat.c,v
retrieving revision 1.4
diff -u -p -r1.4 mips-linux-nat.c
--- mips-linux-nat.c 30 Oct 2002 04:10:06 -0000 1.4
+++ mips-linux-nat.c 9 May 2003 23:36:32 -0000
@@ -20,6 +20,7 @@
Boston, MA 02111-1307, USA. */
#include "defs.h"
+#include "mips-tdep.h"
/* Pseudo registers can not be read. ptrace does not provide a way to
read (or set) PS_REGNUM, and there's no point in reading or setting
@@ -29,11 +30,13 @@
int
mips_linux_cannot_fetch_register (int regno)
{
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
if (REGISTER_NAME (regno)[0] == 0)
return 1;
- if (regno == PS_REGNUM)
+ if (regno == regnums->ps_regnum)
return 1;
- else if (regno == ZERO_REGNUM)
+ else if (regno == regnums->zero_regnum)
return 1;
else
return 0;
@@ -42,17 +45,19 @@ mips_linux_cannot_fetch_register (int re
int
mips_linux_cannot_store_register (int regno)
{
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
if (REGISTER_NAME (regno)[0] == 0)
return 1;
- if (regno == PS_REGNUM)
+ if (regno == regnums->ps_regnum)
return 1;
- else if (regno == ZERO_REGNUM)
+ else if (regno == regnums->zero_regnum)
return 1;
- else if (regno == BADVADDR_REGNUM)
+ else if (regno == regnums->badvaddr_regnum)
return 1;
- else if (regno == CAUSE_REGNUM)
+ else if (regno == regnums->cause_regnum)
return 1;
- else if (regno == FCRIR_REGNUM)
+ else if (regno == regnums->fcrir_regnum)
return 1;
else
return 0;
Index: mips-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-linux-tdep.c,v
retrieving revision 1.9
diff -u -p -r1.9 mips-linux-tdep.c
--- mips-linux-tdep.c 24 Dec 2002 19:21:10 -0000 1.9
+++ mips-linux-tdep.c 9 May 2003 23:36:32 -0000
@@ -72,8 +72,9 @@ mips_linux_get_longjmp_target (CORE_ADDR
{
CORE_ADDR jb_addr;
char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
- jb_addr = read_register (A0_REGNUM);
+ jb_addr = read_register (regnums->a0_regnum);
if (target_read_memory (jb_addr
+ MIPS_LINUX_JB_PC * MIPS_LINUX_JB_ELEMENT_SIZE,
@@ -105,23 +106,25 @@ supply_gregset (elf_gregset_t *gregsetp)
int regi;
elf_greg_t *regp = *gregsetp;
char *zerobuf = alloca (MAX_REGISTER_RAW_SIZE);
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
for (regi = EF_REG0; regi <= EF_REG31; regi++)
supply_32bit_reg ((regi - EF_REG0), (char *)(regp + regi));
- supply_32bit_reg (LO_REGNUM, (char *)(regp + EF_LO));
- supply_32bit_reg (HI_REGNUM, (char *)(regp + EF_HI));
+ supply_32bit_reg (regnums->lo_regnum, (char *)(regp + EF_LO));
+ supply_32bit_reg (regnums->hi_regnum, (char *)(regp + EF_HI));
- supply_32bit_reg (PC_REGNUM, (char *)(regp + EF_CP0_EPC));
- supply_32bit_reg (BADVADDR_REGNUM, (char *)(regp + EF_CP0_BADVADDR));
- supply_32bit_reg (PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
- supply_32bit_reg (CAUSE_REGNUM, (char *)(regp + EF_CP0_CAUSE));
+ supply_32bit_reg (regnums->pc_regnum, (char *)(regp + EF_CP0_EPC));
+ supply_32bit_reg (regnums->badvaddr_regnum, (char *)(regp + EF_CP0_BADVADDR));
+ supply_32bit_reg (regnums->ps_regnum, (char *)(regp + EF_CP0_STATUS));
+ supply_32bit_reg (regnums->cause_regnum, (char *)(regp + EF_CP0_CAUSE));
/* Fill inaccessible registers with zero. */
- supply_register (UNUSED_REGNUM, zerobuf);
- for (regi = FIRST_EMBED_REGNUM; regi < LAST_EMBED_REGNUM; regi++)
+ for (regi = regnums->first_embed_regnum;
+ regi < regnums->last_embed_regnum;
+ regi++)
supply_register (regi, zerobuf);
}
@@ -133,18 +136,19 @@ fill_gregset (elf_gregset_t *gregsetp, i
int regaddr, regi;
elf_greg_t *regp = *gregsetp;
void *dst;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
if (regno == -1)
{
memset (regp, 0, sizeof (elf_gregset_t));
for (regi = 0; regi < 32; regi++)
fill_gregset (gregsetp, regi);
- fill_gregset (gregsetp, LO_REGNUM);
- fill_gregset (gregsetp, HI_REGNUM);
- fill_gregset (gregsetp, PC_REGNUM);
- fill_gregset (gregsetp, BADVADDR_REGNUM);
- fill_gregset (gregsetp, PS_REGNUM);
- fill_gregset (gregsetp, CAUSE_REGNUM);
+ fill_gregset (gregsetp, regnums->lo_regnum);
+ fill_gregset (gregsetp, regnums->hi_regnum);
+ fill_gregset (gregsetp, regnums->pc_regnum);
+ fill_gregset (gregsetp, regnums->badvaddr_regnum);
+ fill_gregset (gregsetp, regnums->ps_regnum);
+ fill_gregset (gregsetp, regnums->cause_regnum);
return;
}
@@ -157,27 +161,18 @@ fill_gregset (elf_gregset_t *gregsetp, i
}
regaddr = -1;
- switch (regno)
- {
- case LO_REGNUM:
- regaddr = EF_LO;
- break;
- case HI_REGNUM:
- regaddr = EF_HI;
- break;
- case PC_REGNUM:
- regaddr = EF_CP0_EPC;
- break;
- case BADVADDR_REGNUM:
- regaddr = EF_CP0_BADVADDR;
- break;
- case PS_REGNUM:
- regaddr = EF_CP0_STATUS;
- break;
- case CAUSE_REGNUM:
- regaddr = EF_CP0_CAUSE;
- break;
- }
+ if (regno == regnums->lo_regnum)
+ regaddr = EF_LO;
+ else if (regno == regnums->hi_regnum)
+ regaddr = EF_HI;
+ else if (regno == regnums->pc_regnum)
+ regaddr = EF_CP0_EPC;
+ else if (regno == regnums->badvaddr_regnum)
+ regaddr = EF_CP0_BADVADDR;
+ else if (regno == regnums->ps_regnum)
+ regaddr = EF_CP0_STATUS;
+ else if (regno == regnums->cause_regnum)
+ regaddr = EF_CP0_CAUSE;
if (regaddr != -1)
{
@@ -193,17 +188,17 @@ supply_fpregset (elf_fpregset_t *fpregse
{
register int regi;
char *zerobuf = alloca (MAX_REGISTER_RAW_SIZE);
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
for (regi = 0; regi < 32; regi++)
- supply_register (FP0_REGNUM + regi,
- (char *)(*fpregsetp + regi));
+ supply_register (regnums->fp0_regnum + regi, (char *)(*fpregsetp + regi));
- supply_register (FCRCS_REGNUM, (char *)(*fpregsetp + 32));
+ supply_register (regnums->fcrcs_regnum, (char *)(*fpregsetp + 32));
- /* FIXME: how can we supply FCRIR_REGNUM? The ABI doesn't tell us. */
- supply_register (FCRIR_REGNUM, zerobuf);
+ /* FIXME: how can we supply FCRIR? The ABI doesn't tell us. */
+ supply_register (regnums->fcrir_regnum, zerobuf);
}
/* Likewise, pack one or all floating point registers into an
@@ -213,14 +208,15 @@ void
fill_fpregset (elf_fpregset_t *fpregsetp, int regno)
{
char *from, *to;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
- if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
+ if ((regno >= regnums->fp0_regnum) && (regno < regnums->fp0_regnum + 32))
{
from = (char *) &deprecated_registers[REGISTER_BYTE (regno)];
- to = (char *) (*fpregsetp + regno - FP0_REGNUM);
- memcpy (to, from, REGISTER_RAW_SIZE (regno - FP0_REGNUM));
+ to = (char *) (*fpregsetp + regno - regnums->fp0_regnum);
+ memcpy (to, from, REGISTER_RAW_SIZE (regno - regnums->fp0_regnum));
}
- else if (regno == FCRCS_REGNUM)
+ else if (regno == regnums->fcrcs_regnum)
{
from = (char *) &deprecated_registers[REGISTER_BYTE (regno)];
to = (char *) (*fpregsetp + 32);
@@ -231,8 +227,8 @@ fill_fpregset (elf_fpregset_t *fpregsetp
int regi;
for (regi = 0; regi < 32; regi++)
- fill_fpregset (fpregsetp, FP0_REGNUM + regi);
- fill_fpregset(fpregsetp, FCRCS_REGNUM);
+ fill_fpregset (fpregsetp, regnums->fp0_regnum + regi);
+ fill_fpregset(fpregsetp, regnums->fcrcs_regnum);
}
}
@@ -243,27 +239,28 @@ static CORE_ADDR
mips_linux_register_addr (int regno, CORE_ADDR blockend)
{
int regaddr;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
if (regno < 0 || regno >= NUM_REGS)
error ("Bogon register number %d.", regno);
if (regno < 32)
regaddr = regno;
- else if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
- regaddr = FPR_BASE + (regno - FP0_REGNUM);
- else if (regno == PC_REGNUM)
+ else if ((regno >= regnums->fp0_regnum) && (regno < regnums->fp0_regnum + 32))
+ regaddr = FPR_BASE + (regno - regnums->fp0_regnum);
+ else if (regno == regnums->pc_regnum)
regaddr = PC;
- else if (regno == CAUSE_REGNUM)
+ else if (regno == regnums->cause_regnum)
regaddr = CAUSE;
- else if (regno == BADVADDR_REGNUM)
+ else if (regno == regnums->badvaddr_regnum)
regaddr = BADVADDR;
- else if (regno == LO_REGNUM)
+ else if (regno == regnums->lo_regnum)
regaddr = MMLO;
- else if (regno == HI_REGNUM)
+ else if (regno == regnums->hi_regnum)
regaddr = MMHI;
- else if (regno == FCRCS_REGNUM)
+ else if (regno == regnums->fcrcs_regnum)
regaddr = FPC_CSR;
- else if (regno == FCRIR_REGNUM)
+ else if (regno == regnums->fcrir_regnum)
regaddr = FPC_EIR;
else
error ("Unknowable register number %d.", regno);
@@ -360,8 +357,9 @@ mips64_linux_get_longjmp_target (CORE_AD
CORE_ADDR jb_addr;
void *buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
int element_size = TARGET_PTR_BIT == 32 ? 4 : 8;
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
- jb_addr = read_register (A0_REGNUM);
+ jb_addr = read_register (regnums->a0_regnum);
if (target_read_memory (jb_addr + MIPS64_LINUX_JB_PC * element_size,
buf, TARGET_PTR_BIT / TARGET_CHAR_BIT))
@@ -380,23 +378,25 @@ mips64_supply_gregset (mips64_elf_gregse
int regi;
mips64_elf_greg_t *regp = *gregsetp;
char *zerobuf = alloca (MAX_REGISTER_RAW_SIZE);
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
for (regi = MIPS64_EF_REG0; regi <= MIPS64_EF_REG31; regi++)
supply_register ((regi - MIPS64_EF_REG0), (char *)(regp + regi));
- supply_register (LO_REGNUM, (char *)(regp + MIPS64_EF_LO));
- supply_register (HI_REGNUM, (char *)(regp + MIPS64_EF_HI));
+ supply_register (regnums->lo_regnum, (char *)(regp + MIPS64_EF_LO));
+ supply_register (regnums->hi_regnum, (char *)(regp + MIPS64_EF_HI));
- supply_register (PC_REGNUM, (char *)(regp + MIPS64_EF_CP0_EPC));
- supply_register (BADVADDR_REGNUM, (char *)(regp + MIPS64_EF_CP0_BADVADDR));
- supply_register (PS_REGNUM, (char *)(regp + MIPS64_EF_CP0_STATUS));
- supply_register (CAUSE_REGNUM, (char *)(regp + MIPS64_EF_CP0_CAUSE));
+ supply_register (regnums->pc_regnum, (char *)(regp + MIPS64_EF_CP0_EPC));
+ supply_register (regnums->badvaddr_regnum, (char *)(regp + MIPS64_EF_CP0_BADVADDR));
+ supply_register (regnums->ps_regnum, (char *)(regp + MIPS64_EF_CP0_STATUS));
+ supply_register (regnums->cause_regnum, (char *)(regp + MIPS64_EF_CP0_CAUSE));
/* Fill inaccessible registers with zero. */
- supply_register (UNUSED_REGNUM, zerobuf);
- for (regi = FIRST_EMBED_REGNUM; regi < LAST_EMBED_REGNUM; regi++)
+ for (regi = regnums->first_embed_regnum;
+ regi < regnums->last_embed_regnum;
+ regi++)
supply_register (regi, zerobuf);
}
@@ -408,18 +408,19 @@ mips64_fill_gregset (mips64_elf_gregset_
int regaddr, regi;
mips64_elf_greg_t *regp = *gregsetp;
void *src, *dst;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
if (regno == -1)
{
memset (regp, 0, sizeof (mips64_elf_gregset_t));
for (regi = 0; regi < 32; regi++)
mips64_fill_gregset (gregsetp, regi);
- mips64_fill_gregset (gregsetp, LO_REGNUM);
- mips64_fill_gregset (gregsetp, HI_REGNUM);
- mips64_fill_gregset (gregsetp, PC_REGNUM);
- mips64_fill_gregset (gregsetp, BADVADDR_REGNUM);
- mips64_fill_gregset (gregsetp, PS_REGNUM);
- mips64_fill_gregset (gregsetp, CAUSE_REGNUM);
+ mips64_fill_gregset (gregsetp, regnums->lo_regnum);
+ mips64_fill_gregset (gregsetp, regnums->hi_regnum);
+ mips64_fill_gregset (gregsetp, regnums->pc_regnum);
+ mips64_fill_gregset (gregsetp, regnums->badvaddr_regnum);
+ mips64_fill_gregset (gregsetp, regnums->ps_regnum);
+ mips64_fill_gregset (gregsetp, regnums->cause_regnum);
return;
}
@@ -432,27 +433,18 @@ mips64_fill_gregset (mips64_elf_gregset_
}
regaddr = -1;
- switch (regno)
- {
- case LO_REGNUM:
+ if (regno == regnums->lo_regnum)
regaddr = MIPS64_EF_LO;
- break;
- case HI_REGNUM:
+ else if (regno == regnums->hi_regnum)
regaddr = MIPS64_EF_HI;
- break;
- case PC_REGNUM:
+ else if (regno == regnums->pc_regnum)
regaddr = MIPS64_EF_CP0_EPC;
- break;
- case BADVADDR_REGNUM:
+ else if (regno == regnums->badvaddr_regnum)
regaddr = MIPS64_EF_CP0_BADVADDR;
- break;
- case PS_REGNUM:
+ else if (regno == regnums->ps_regnum)
regaddr = MIPS64_EF_CP0_STATUS;
- break;
- case CAUSE_REGNUM:
+ else if (regno == regnums->cause_regnum)
regaddr = MIPS64_EF_CP0_CAUSE;
- break;
- }
if (regaddr != -1)
{
@@ -468,17 +460,17 @@ mips64_supply_fpregset (mips64_elf_fpreg
{
register int regi;
char *zerobuf = alloca (MAX_REGISTER_RAW_SIZE);
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
for (regi = 0; regi < 32; regi++)
- supply_register (FP0_REGNUM + regi,
- (char *)(*fpregsetp + regi));
+ supply_register (regnums->fp0_regnum + regi, (char *)(*fpregsetp + regi));
- supply_register (FCRCS_REGNUM, (char *)(*fpregsetp + 32));
+ supply_register (regnums->fcrcs_regnum, (char *)(*fpregsetp + 32));
- /* FIXME: how can we supply FCRIR_REGNUM? The ABI doesn't tell us. */
- supply_register (FCRIR_REGNUM, zerobuf);
+ /* FIXME: how can we supply FCRIR? The ABI doesn't tell us. */
+ supply_register (regnums->fcrir_regnum, zerobuf);
}
/* Likewise, pack one or all floating point registers into an
@@ -488,14 +480,15 @@ static void
mips64_fill_fpregset (mips64_elf_fpregset_t *fpregsetp, int regno)
{
char *from, *to;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
- if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
+ if ((regno >= regnums->fp0_regnum) && (regno < regnums->fp0_regnum + 32))
{
from = (char *) &deprecated_registers[REGISTER_BYTE (regno)];
- to = (char *) (*fpregsetp + regno - FP0_REGNUM);
- memcpy (to, from, REGISTER_RAW_SIZE (regno - FP0_REGNUM));
+ to = (char *) (*fpregsetp + regno - regnums->fp0_regnum);
+ memcpy (to, from, REGISTER_RAW_SIZE (regno - regnums->fp0_regnum));
}
- else if (regno == FCRCS_REGNUM)
+ else if (regno == regnums->fcrcs_regnum)
{
from = (char *) &deprecated_registers[REGISTER_BYTE (regno)];
to = (char *) (*fpregsetp + 32);
@@ -506,8 +499,8 @@ mips64_fill_fpregset (mips64_elf_fpregse
int regi;
for (regi = 0; regi < 32; regi++)
- mips64_fill_fpregset (fpregsetp, FP0_REGNUM + regi);
- mips64_fill_fpregset(fpregsetp, FCRCS_REGNUM);
+ mips64_fill_fpregset (fpregsetp, regnums->fp0_regnum + regi);
+ mips64_fill_fpregset(fpregsetp, regnums->fcrcs_regnum);
}
}
@@ -519,27 +512,28 @@ static CORE_ADDR
mips64_linux_register_addr (int regno, CORE_ADDR blockend)
{
int regaddr;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
if (regno < 0 || regno >= NUM_REGS)
error ("Bogon register number %d.", regno);
if (regno < 32)
regaddr = regno;
- else if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
- regaddr = MIPS64_FPR_BASE + (regno - FP0_REGNUM);
- else if (regno == PC_REGNUM)
+ else if ((regno >= regnums->fp0_regnum) && (regno < regnums->fp0_regnum + 32))
+ regaddr = MIPS64_FPR_BASE + (regno - regnums->fp0_regnum);
+ else if (regno == regnums->pc_regnum)
regaddr = MIPS64_PC;
- else if (regno == CAUSE_REGNUM)
+ else if (regno == regnums->cause_regnum)
regaddr = MIPS64_CAUSE;
- else if (regno == BADVADDR_REGNUM)
+ else if (regno == regnums->badvaddr_regnum)
regaddr = MIPS64_BADVADDR;
- else if (regno == LO_REGNUM)
+ else if (regno == regnums->lo_regnum)
regaddr = MIPS64_MMLO;
- else if (regno == HI_REGNUM)
+ else if (regno == regnums->hi_regnum)
regaddr = MIPS64_MMHI;
- else if (regno == FCRCS_REGNUM)
+ else if (regno == regnums->fcrcs_regnum)
regaddr = MIPS64_FPC_CSR;
- else if (regno == FCRIR_REGNUM)
+ else if (regno == regnums->fcrir_regnum)
regaddr = MIPS64_FPC_EIR;
else
error ("Unknowable register number %d.", regno);
Index: mips-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-nat.c,v
retrieving revision 1.10
diff -u -p -r1.10 mips-nat.c
--- mips-nat.c 29 Apr 2003 01:49:47 -0000 1.10
+++ mips-nat.c 9 May 2003 23:36:32 -0000
@@ -1,5 +1,5 @@
/* Low level DECstation interface to ptrace, for GDB when running native.
- Copyright 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1999, 2000, 2001
+ Copyright 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1999, 2000, 2001, 2003
Free Software Foundation, Inc.
Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
@@ -43,6 +43,7 @@
#undef JB_SR
#undef NJBREGS
#include <setjmp.h> /* For JB_XXX. */
+#include <mips-tdep.h>
/* Size of elements in jmpbuf */
@@ -51,16 +52,22 @@
/* Map gdb internal register number to ptrace ``address''.
These ``addresses'' are defined in DECstation <sys/ptrace.h> */
-#define REGISTER_PTRACE_ADDR(regno) \
- (regno < 32 ? GPR_BASE + regno \
- : regno == PC_REGNUM ? PC \
- : regno == CAUSE_REGNUM ? CAUSE \
- : regno == HI_REGNUM ? MMHI \
- : regno == LO_REGNUM ? MMLO \
- : regno == FCRCS_REGNUM ? FPC_CSR \
- : regno == FCRIR_REGNUM ? FPC_EIR \
- : regno >= FP0_REGNUM ? FPR_BASE + (regno - FP0_REGNUM) \
+static int
+register_ptrace_addr (int regno)
+{
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
+ return
+ (regno < 32 ? GPR_BASE + regno
+ : regno == regnums->pc_regnum ? PC
+ : regno == regnums->cause_regnum ? CAUSE
+ : regno == regnums->hi_regnum ? MMHI
+ : regno == regnums->lo_regnum ? MMLO
+ : regno == regnums->fcrcs_regnum ? FPC_CSR
+ : regno == regnums->fcrir_regnum ? FPC_EIR
+ : regno >= regnums->fp0_regnum ? FPR_BASE + (regno - regnums->fp0_regnum)
: 0)
+}
static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
@@ -73,13 +80,15 @@ fetch_inferior_registers (int regno)
char *buf = alloca (max_register_size (current_gdbarch));
register int i;
char *zerobuf = alloca (max_register_size (current_gdbarch));
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
memset (zerobuf, 0, max_register_size (current_gdbarch));
deprecated_registers_fetched ();
for (regno = 1; regno < NUM_REGS; regno++)
{
- regaddr = REGISTER_PTRACE_ADDR (regno);
+ regaddr = register_ptrace_addr (regno);
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
{
*(int *) &buf[i] = ptrace (PT_READ_U, PIDGET (inferior_ptid),
@@ -89,7 +98,7 @@ fetch_inferior_registers (int regno)
supply_register (regno, buf);
}
- supply_register (ZERO_REGNUM, zerobuf);
+ supply_register (regnums->zero_regnum, zerobuf);
/* Frame ptr reg must appear to be 0; it is faked by stack handling code. */
supply_register (DEPRECATED_FP_REGNUM, zerobuf);
}
@@ -103,15 +112,20 @@ store_inferior_registers (int regno)
{
register unsigned int regaddr;
char buf[80];
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
if (regno > 0)
{
- if (regno == ZERO_REGNUM || regno == PS_REGNUM
- || regno == BADVADDR_REGNUM || regno == CAUSE_REGNUM
- || regno == FCRIR_REGNUM || regno == DEPRECATED_FP_REGNUM
- || (regno >= FIRST_EMBED_REGNUM && regno <= LAST_EMBED_REGNUM))
+ if (regno == regnums->zero_regnum
+ || regno == regnums->ps_regnum
+ || regno == regnums->badvaddr_regnum
+ || regnums->regno == regnums->cause_regnum
+ || regno == regnums->fcrir_regnum
+ || regno == DEPRECATED_FP_REGNUM
+ || (regno >= regnums->first_embed_regnum
+ && regno <= regnums->last_embed_regnum))
return;
- regaddr = REGISTER_PTRACE_ADDR (regno);
+ regaddr = register_ptrace_addr (regno);
errno = 0;
ptrace (PT_WRITE_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr,
read_register (regno));
@@ -139,9 +153,10 @@ get_longjmp_target (CORE_ADDR *pc)
{
CORE_ADDR jb_addr;
char *buf;
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
- jb_addr = read_register (A0_REGNUM);
+ jb_addr = read_register (regnums->a0_regnum);
if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
TARGET_PTR_BIT / TARGET_CHAR_BIT))
@@ -173,6 +188,7 @@ fetch_core_registers (char *core_reg_sec
register unsigned int addr;
int bad_reg = -1;
register reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
char *zerobuf = alloca (max_register_size (current_gdbarch));
memset (zerobuf, 0, max_register_size (current_gdbarch));
@@ -208,7 +224,7 @@ fetch_core_registers (char *core_reg_sec
{
error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
}
- supply_register (ZERO_REGNUM, zerobuf);
+ supply_register (regnums->zero_regnum, zerobuf);
/* Frame ptr reg must appear to be 0; it is faked by stack handling code. */
supply_register (DEPRECATED_FP_REGNUM, zerobuf);
}
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.195
diff -u -p -r1.195 mips-tdep.c
--- mips-tdep.c 5 May 2003 17:56:55 -0000 1.195
+++ mips-tdep.c 9 May 2003 23:36:34 -0000
@@ -42,6 +42,7 @@
#include "osabi.h"
#include "mips-tdep.h"
#include "block.h"
+#include "reggroups.h"
#include "opcode/mips.h"
#include "elf/mips.h"
@@ -124,24 +125,30 @@ struct gdbarch_tdep
enum mips_abi mips_abi;
enum mips_abi found_abi;
enum mips_fpu_type mips_fpu_type;
- int mips_last_arg_regnum;
- int mips_last_fp_arg_regnum;
int mips_default_saved_regsize;
int mips_fp_register_double;
int mips_default_stack_argsize;
int gdb_target_is_mips64;
int default_mask_address_p;
+
+ struct mips_regnums raw_regnums;
+ struct mips_regnums cooked_regnums;
+
+ char **regnames;
};
#define MIPS_EABI (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI32 \
|| gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI64)
-#define MIPS_LAST_FP_ARG_REGNUM (gdbarch_tdep (current_gdbarch)->mips_last_fp_arg_regnum)
-
-#define MIPS_LAST_ARG_REGNUM (gdbarch_tdep (current_gdbarch)->mips_last_arg_regnum)
-
#define MIPS_FPU_TYPE (gdbarch_tdep (current_gdbarch)->mips_fpu_type)
+/* 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
+ determine if the ABI is using double-precision registers. See also
+ MIPS_FPU_TYPE. */
+#define FP_REGISTER_DOUBLE (gdbarch_tdep (current_gdbarch)->mips_fp_register_double)
+
/* Return the currently configured (or set) saved register size. */
#define MIPS_DEFAULT_SAVED_REGSIZE (gdbarch_tdep (current_gdbarch)->mips_default_saved_regsize)
@@ -157,6 +164,18 @@ mips_abi (struct gdbarch *gdbarch)
return gdbarch_tdep (gdbarch)->mips_abi;
}
+const struct mips_regnums *
+mips_raw_regnums (struct gdbarch *gdbarch)
+{
+ return &(gdbarch_tdep (gdbarch)->raw_regnums);
+}
+
+const struct mips_regnums *
+mips_cooked_regnums (struct gdbarch *gdbarch)
+{
+ return &(gdbarch_tdep (gdbarch)->cooked_regnums);
+}
+
static unsigned int
mips_saved_regsize (void)
{
@@ -266,9 +285,11 @@ mips_xfer_register (struct regcache *reg
static int
mips2_fp_compat (void)
{
+ const struct mips_regnums *cooked_regnums
+ = mips_cooked_regnums (current_gdbarch);
/* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not
meaningful. */
- if (REGISTER_RAW_SIZE (FP0_REGNUM) == 4)
+ if (REGISTER_RAW_SIZE (cooked_regnums->fp0_regnum) == 4)
return 0;
#if 0
@@ -277,20 +298,13 @@ mips2_fp_compat (void)
/* 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)
+ if ((read_register (cooked_regnums->ps_regnum) & ST0_FR) == 0)
return 1;
#endif
- return 0;
+ return !FP_REGISTER_DOUBLE;
}
-/* 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
- determine if the ABI is using double-precision registers. See also
- MIPS_FPU_TYPE. */
-#define FP_REGISTER_DOUBLE (gdbarch_tdep (current_gdbarch)->mips_fp_register_double)
-
/* The amount of space reserved on the stack for registers. This is
different to MIPS_SAVED_REGSIZE as it determines the alignment of
data allocated after the registers have run out. */
@@ -348,6 +362,14 @@ static void mips_read_fp_register_double
static struct type *mips_float_register_type (void);
static struct type *mips_double_register_type (void);
+/* Types used for cooked floating point registers. These are union
+ types which allow the user to view (or set) the floating point
+ register in a variety of ways. */
+static struct type *mips_type_float_double_register_big;
+static struct type *mips_type_float_double_register_little;
+static struct type *mips_type_float_single_register_big;
+static struct type *mips_type_float_single_register_little;
+
/* This value is the model of MIPS in use. It is derived from the value
of the PrID register. */
@@ -360,19 +382,20 @@ char *tmp_mips_processor_type;
static struct cmd_list_element *setmipscmdlist = NULL;
static struct cmd_list_element *showmipscmdlist = NULL;
-/* A set of original names, to be used when restoring back to generic
- registers from a specific set. */
-static char *mips_generic_reg_names[] = MIPS_REGISTER_NAMES;
-
-/* Integer registers 0 thru 31 are handled explicitly by
- mips_register_name(). Processor specific registers 32 and above
- are listed in the sets of register names assigned to
- mips_processor_reg_names. */
-static char **mips_processor_reg_names = mips_generic_reg_names;
+/* Names of generic embedded registers. */
+char *mips_generic_embed_reg_names[] = {
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+};
-/* Return the name of the register corresponding to REGNO. */
+/* Names of special purpose (embedded) registers. */
+static char **mips_embed_reg_names = mips_generic_embed_reg_names;
+
+/* Given a register number REGNO and set of register numbers assignments
+ REGNUMS, return the name for REGNO. If no name can be determined,
+ return NULL. */
static const char *
-mips_register_name (int regno)
+reg_name (int regno, const struct mips_regnums *regnums)
{
/* GPR names for all ABIs other than n32/n64. */
static char *mips_gpr_names[] = {
@@ -390,67 +413,135 @@ mips_register_name (int regno)
"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
};
+ /* FPR names */
+ static char *mips_fpr_names[] = {
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+ };
+
enum mips_abi abi = mips_abi (current_gdbarch);
- /* The MIPS integer registers are always mapped from 0 to 31. The
- names of the registers (which reflects the conventions regarding
- register use) vary depending on the ABI. */
- if (0 <= regno && regno < 32)
+ /* ``zero_regnum'' is the first GPR. ``ra_regnum'' is the last GPR.
+ The names of the general purpose registers (which reflects the
+ conventions regarding register use) vary depending on the ABI. */
+ if (regnums->zero_regnum <= regno && regno <= regnums->ra_regnum)
{
if (abi == MIPS_ABI_N32 || abi == MIPS_ABI_N64)
- return mips_n32_n64_gpr_names[regno];
+ return mips_n32_n64_gpr_names[regno - regnums->zero_regnum];
else
- return mips_gpr_names[regno];
+ return mips_gpr_names[regno - regnums->zero_regnum];
}
- else if (32 <= regno && regno < NUM_REGS)
- return mips_processor_reg_names[regno - 32];
+ else if (regnums->fp0_regnum <= regno && regno <= regnums->fplast_regnum)
+ {
+ if (regnums->fplast_regnum - regnums->fp0_regnum + 1 == 16)
+ return mips_fpr_names[2 * (regno - regnums->fp0_regnum)];
+ else
+ return mips_fpr_names[regno - regnums->fp0_regnum];
+ }
+ else if (regno == regnums->ps_regnum)
+ return "sr";
+ else if (regno == regnums->lo_regnum)
+ return "lo";
+ else if (regno == regnums->hi_regnum)
+ return "hi";
+ else if (regno == regnums->badvaddr_regnum)
+ return "bad";
+ else if (regno == regnums->cause_regnum)
+ return "cause";
+ else if (regno == regnums->pc_regnum)
+ return "pc";
+ else if (regno == regnums->fcrcs_regnum)
+ return "fsr";
+ else if (regno == regnums->fcrir_regnum)
+ return "fir";
+ else if (regnums->first_embed_regnum <= regno
+ && regno <= regnums->last_embed_regnum)
+ return mips_embed_reg_names[regno - regnums->first_embed_regnum];
else
- internal_error (__FILE__, __LINE__,
- "mips_register_name: bad register number %d", regno);
+ return NULL;
+}
+
+/* Return the name of the register corresponding to REGNO. */
+static const char *
+mips_register_name (int regno)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ const char *name;
+
+ if (tdep->regnames == NULL)
+ tdep->regnames = xcalloc (NUM_REGS + NUM_PSEUDO_REGS, sizeof (char *));
+
+ gdb_assert (0 <= regno && regno < NUM_REGS + NUM_PSEUDO_REGS);
+
+ if (tdep->regnames[regno])
+ return tdep->regnames[regno];
+
+ name = reg_name (regno, mips_cooked_regnums (current_gdbarch));
+
+ if (name != NULL)
+ {
+ tdep->regnames[regno] = xstrdup (name);
+ return name;
+ }
+
+ name = reg_name (regno, mips_raw_regnums (current_gdbarch));
+
+ if (name != NULL && *name != '\0')
+ {
+ char *raw_name = xmalloc (strlen (name) + 4 /* for "raw_" */ + 1);
+ strcpy (raw_name, "raw_");
+ strcat (raw_name, name);
+ tdep->regnames[regno] = raw_name;
+ return raw_name;
+ }
+
+ /* Couldn't find a name. Use the empty string. */
+ name = "";
+ tdep->regnames[regno] = xstrdup (name);
+ return name;
}
/* *INDENT-OFF* */
-/* Names of IDT R3041 registers. */
-char *mips_r3041_reg_names[] = {
- "sr", "lo", "hi", "bad", "cause","pc",
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
- "fsr", "fir", "",/*"fp"*/ "",
+
+/* Names of tx39 embedded registers. */
+
+char *mips_tx39_embed_reg_names[] = {
+ "", "", "", "", "", "", "", "",
+ "", "", "config", "cache", "debug", "depc", "epc", ""
+};
+
+/* Names of IDT R3041 embedded registers. */
+
+char *mips_r3041_embed_reg_names[] = {
"", "", "bus", "ccfg", "", "", "", "",
"", "", "port", "cmp", "", "", "epc", "prid",
};
-/* Names of IDT R3051 registers. */
+/* Names of IDT R3051 embedded registers. */
-char *mips_r3051_reg_names[] = {
- "sr", "lo", "hi", "bad", "cause","pc",
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
- "fsr", "fir", ""/*"fp"*/, "",
+char *mips_r3051_embed_reg_names[] = {
"inx", "rand", "elo", "", "ctxt", "", "", "",
"", "", "ehi", "", "", "", "epc", "prid",
};
-/* Names of IDT R3081 registers. */
+/* Names of IDT R3081 embedded registers. */
-char *mips_r3081_reg_names[] = {
- "sr", "lo", "hi", "bad", "cause","pc",
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
- "fsr", "fir", ""/*"fp"*/, "",
+char *mips_r3081_embed_reg_names[] = {
"inx", "rand", "elo", "cfg", "ctxt", "", "", "",
"", "", "ehi", "", "", "", "epc", "prid",
};
+#if 0
/* Names of LSI 33k registers. */
+/* Note: kevinb/2003-05-06: These are all of the names following the GPRs.
+ "baddvaddr" is in the position where "pc" would normally appear, so
+ I don't see how this ever could have worked. I've disabled this code
+ until someone who understands it better than I do can take a look... */
+
char *mips_lsi33k_reg_names[] = {
"epc", "hi", "lo", "sr", "cause","badvaddr",
"dcic", "bpc", "bda", "", "", "", "", "",
@@ -461,17 +552,21 @@ char *mips_lsi33k_reg_names[] = {
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
};
+#endif
struct {
char *name;
char **regnames;
} mips_processor_type_table[] = {
- { "generic", mips_generic_reg_names },
- { "r3041", mips_r3041_reg_names },
- { "r3051", mips_r3051_reg_names },
- { "r3071", mips_r3081_reg_names },
- { "r3081", mips_r3081_reg_names },
- { "lsi33k", mips_lsi33k_reg_names },
+ { "generic", mips_generic_embed_reg_names },
+ { "r3041", mips_r3041_embed_reg_names },
+ { "r3051", mips_r3051_embed_reg_names },
+ { "r3071", mips_r3081_embed_reg_names },
+ { "r3081", mips_r3081_embed_reg_names },
+#if 0
+ { "lsi33k", mips_lsi33k_embed_reg_names },
+#endif
+ { "tx39", mips_tx39_embed_reg_names },
{ NULL, NULL }
};
/* *INDENT-ON* */
@@ -531,126 +626,119 @@ mips_print_extra_frame_info (struct fram
static int mips64_transfers_32bit_regs_p = 0;
-static int
-mips_register_raw_size (int reg_nr)
-{
- if (mips64_transfers_32bit_regs_p)
- return REGISTER_VIRTUAL_SIZE (reg_nr);
- else if (reg_nr >= FP0_REGNUM && reg_nr < FP0_REGNUM + 32
- && FP_REGISTER_DOUBLE)
- /* For MIPS_ABI_N32 (for example) we need 8 byte floating point
- registers. */
- return 8;
- else
- return MIPS_REGSIZE;
-}
-
-/* Convert between RAW and VIRTUAL registers. The RAW register size
- defines the remote-gdb packet. */
-
-static int
-mips_register_convertible (int reg_nr)
-{
- if (mips64_transfers_32bit_regs_p)
- return 0;
- else
- return (REGISTER_RAW_SIZE (reg_nr) > REGISTER_VIRTUAL_SIZE (reg_nr));
-}
-
-static void
-mips_register_convert_to_virtual (int n, struct type *virtual_type,
- char *raw_buf, char *virt_buf)
-{
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
- memcpy (virt_buf,
- raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
- TYPE_LENGTH (virtual_type));
- else
- memcpy (virt_buf,
- raw_buf,
- TYPE_LENGTH (virtual_type));
-}
-
-static void
-mips_register_convert_to_raw (struct type *virtual_type, int n,
- char *virt_buf, char *raw_buf)
-{
- memset (raw_buf, 0, REGISTER_RAW_SIZE (n));
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
- memcpy (raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
- virt_buf,
- TYPE_LENGTH (virtual_type));
- else
- memcpy (raw_buf,
- virt_buf,
- TYPE_LENGTH (virtual_type));
-}
-
-void
-mips_register_convert_to_type (int regnum, struct type *type, char *buffer)
-{
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
- && REGISTER_RAW_SIZE (regnum) == 4
- && (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
- && TYPE_CODE(type) == TYPE_CODE_FLT
- && TYPE_LENGTH(type) == 8)
- {
- char temp[4];
- memcpy (temp, ((char *)(buffer))+4, 4);
- memcpy (((char *)(buffer))+4, (buffer), 4);
- memcpy (((char *)(buffer)), temp, 4);
- }
-}
-
-void
-mips_register_convert_from_type (int regnum, struct type *type, char *buffer)
-{
-if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
- && REGISTER_RAW_SIZE (regnum) == 4
- && (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
- && TYPE_CODE(type) == TYPE_CODE_FLT
- && TYPE_LENGTH(type) == 8)
- {
- char temp[4];
- memcpy (temp, ((char *)(buffer))+4, 4);
- memcpy (((char *)(buffer))+4, (buffer), 4);
- memcpy (((char *)(buffer)), temp, 4);
- }
-}
-
/* Return the GDB type object for the "standard" data type
of data in register REG.
- Note: kevinb/2002-08-01: The definition below should faithfully
- reproduce the behavior of each of the REGISTER_VIRTUAL_TYPE
- definitions found in config/mips/tm-*.h. I'm concerned about the
- ``FCRCS_REGNUM <= reg && reg <= LAST_EMBED_REGNUM'' clause though.
- In some cases DEPRECATED_FP_REGNUM is in this range, and I doubt
- that this code is correct for the 64-bit case. */
+ As noted below, the types returned in the [0, NUM_REGS) range are
+ constrained by the remote protocol. */
static struct type *
-mips_register_virtual_type (int reg)
+mips_register_type (struct gdbarch *gdbarch, int regno)
{
- if (FP0_REGNUM <= reg && reg < FP0_REGNUM + 32)
+ const struct mips_regnums *raw_regnums = mips_raw_regnums (gdbarch);
+ const struct mips_regnums *cooked_regnums = mips_cooked_regnums (gdbarch);
+
+ gdb_assert (0 <= regno && regno <= NUM_REGS + NUM_PSEUDO_REGS);
+
+ if (regno < NUM_REGS)
{
- /* Floating point registers... */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
- return builtin_type_ieee_double_big;
+ /* We must be careful with the sizes of these types because
+ they influence the layout of the remote protocol. */
+ if (MIPS_REGSIZE == 4)
+ {
+ /* The type length of each of the types returned in this
+ block is 4. */
+ if (raw_regnums->fp0_regnum <= regno
+ && regno <= raw_regnums->fplast_regnum)
+ {
+ /* It's tempting to make these some kind of floating
+ point type, but it's actually more useful to just
+ print the raw fp registers as ints. The cooked
+ regnums provide access to multiple representations. */
+ return builtin_type_uint32;
+ }
+ else if (regno == raw_regnums->ps_regnum /* SR */
+ || regno == raw_regnums->fcrcs_regnum
+ || regno == raw_regnums->fcrir_regnum
+ || (raw_regnums->first_embed_regnum <= regno
+ && regno <= raw_regnums->last_embed_regnum))
+ return builtin_type_uint32;
+ else
+ return builtin_type_int32;
+ }
+ else if (MIPS_REGSIZE == 8)
+ {
+ /* The type lengths of each of the types returned in this
+ block is 8 except when ``mips64_transfers_32_bit_regs_p''
+ is true. When ``mips64_transfers_32_bit_regs_p'' is true,
+ certain registers are only 4 bytes wide. */
+ if (raw_regnums->fp0_regnum <= regno
+ && regno <= raw_regnums->fplast_regnum)
+ {
+ return builtin_type_uint64;
+ }
+ else if (regno == raw_regnums->ps_regnum /* SR */
+ || regno == raw_regnums->fcrcs_regnum
+ || regno == raw_regnums->fcrir_regnum
+ || (raw_regnums->first_embed_regnum <= regno
+ && regno <= raw_regnums->last_embed_regnum))
+ {
+ if (mips64_transfers_32bit_regs_p)
+ return builtin_type_uint32;
+ else
+ return builtin_type_uint64;
+ }
+ else
+ return builtin_type_uint64;
+ }
else
- return builtin_type_ieee_double_little;
+ {
+ internal_error (__FILE__, __LINE__,
+ "mips_register_type: bad MIPS_REGSIZE value");
+ }
}
- else if (reg == PS_REGNUM /* CR */)
- return builtin_type_uint32;
- else if (FCRCS_REGNUM <= reg && reg <= LAST_EMBED_REGNUM)
- return builtin_type_uint32;
else
{
- /* Everything else...
- Return type appropriate for width of register. */
- if (MIPS_REGSIZE == TYPE_LENGTH (builtin_type_uint64))
- return builtin_type_uint64;
- else
+ /* These registers are pseudo-registers. We are (more or less)
+ free to define them to be whatever we want them to be. */
+ if (cooked_regnums->fp0_regnum <= regno
+ && regno <= cooked_regnums->fplast_regnum)
+ {
+ if (MIPS_FPU_TYPE == MIPS_FPU_SINGLE)
+ {
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ return mips_type_float_single_register_big;
+ else
+ return mips_type_float_single_register_little;
+ }
+ else if (MIPS_FPU_TYPE == MIPS_FPU_DOUBLE)
+ {
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ return mips_type_float_double_register_big;
+ else
+ return mips_type_float_double_register_little;
+ }
+ else
+ {
+ /* The other choice is that MIPS_FPU_TYPE is MIPS_FPU_NONE,
+ but that shouldn't happen because fp0_regnum and
+ fplast_regnum should've been set to -1. */
+ internal_error (__FILE__, __LINE__,
+ "mips_register_type: bad MIPS_FPU_TYPE value");
+ }
+ }
+ else if (regno == cooked_regnums->ps_regnum /* SR */
+ || regno == cooked_regnums->fcrcs_regnum
+ || regno == cooked_regnums->fcrir_regnum
+ || (cooked_regnums->first_embed_regnum <= regno
+ && cooked_regnums->last_embed_regnum))
return builtin_type_uint32;
+ else
+ {
+ internal_error (__FILE__, __LINE__,
+ "mips_register_type: unknown pseudo register %d [%s]\n",
+ regno, REGISTER_NAME (regno));
+ }
}
}
@@ -659,7 +747,9 @@ mips_register_virtual_type (int reg)
static CORE_ADDR
mips_read_sp (void)
{
- return read_signed_register (SP_REGNUM);
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
+
+ return read_signed_register (regnums->sp_regnum);
}
/* Should the upper word of 64-bit addresses be zeroed? */
@@ -781,7 +871,9 @@ pc_is_mips16 (bfd_vma memaddr)
static CORE_ADDR
mips_read_pc (ptid_t ptid)
{
- return read_signed_register_pid (PC_REGNUM, ptid);
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
+
+ return read_signed_register_pid (regnums->pc_regnum, ptid);
}
/* This returns the PC of the first inst after the prologue. If we can't
@@ -793,6 +885,7 @@ after_prologue (CORE_ADDR pc,
{
struct symtab_and_line sal;
CORE_ADDR func_addr, func_end;
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
/* Pass cur_frame == 0 to find_proc_desc. We should not attempt
to read the stack pointer from the current machine state, because
@@ -806,7 +899,7 @@ after_prologue (CORE_ADDR pc,
{
/* If function is frameless, then we need to do it the hard way. I
strongly suspect that frameless always means prologueless... */
- if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
+ if (PROC_FRAME_REG (proc_desc) == regnums->sp_regnum
&& PROC_FRAME_OFFSET (proc_desc) == 0)
return 0;
}
@@ -866,6 +959,8 @@ mips32_decode_reg_save (t_inst inst, uns
static void
mips16_decode_reg_save (t_inst inst, unsigned long *gen_mask)
{
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
if ((inst & 0xf800) == 0xd000) /* sw reg,n($sp) */
{
int reg = mips16_to_32_reg[(inst & 0x700) >> 8];
@@ -878,7 +973,7 @@ mips16_decode_reg_save (t_inst inst, uns
}
else if ((inst & 0xff00) == 0x6200 /* sw $ra,n($sp) */
|| (inst & 0xff00) == 0xfa00) /* sd $ra,n($sp) */
- *gen_mask |= (1 << RA_REGNUM);
+ *gen_mask |= (1 << (regnums->ra_regnum - regnums->zero_regnum));
}
@@ -943,6 +1038,8 @@ mips32_next_pc (CORE_ADDR pc)
{
unsigned long inst;
int op;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
inst = mips_fetch_instruction (pc);
if ((inst & 0xe0000000) != 0) /* Not a special, jump or branch instruction */
{
@@ -969,7 +1066,7 @@ mips32_next_pc (CORE_ADDR pc)
{
int tf = itype_rt (inst) & 0x01;
int cnum = itype_rt (inst) >> 2;
- int fcrcs = read_signed_register (FCRCS_REGNUM);
+ int fcrcs = read_signed_register (regnums->fcrcs_regnum);
int cond = ((fcrcs >> 24) & 0x0e) | ((fcrcs >> 23) & 0x01);
if (((cond >> cnum) & 0x01) == tf)
@@ -1420,6 +1517,8 @@ mips_find_saved_regs (struct frame_info
unsigned long gen_mask, float_mask;
mips_extra_func_info_t proc_desc;
t_inst inst;
+ const struct mips_regnums *raw_regnums = mips_raw_regnums (current_gdbarch);
+ const struct mips_regnums *cooked_regnums = mips_cooked_regnums (current_gdbarch);
frame_saved_regs_zalloc (fci);
@@ -1453,9 +1552,9 @@ mips_find_saved_regs (struct frame_info
{
reg_position = get_frame_base (fci) + SIGFRAME_FPREGSAVE_OFF
+ ireg * SIGFRAME_REG_SIZE;
- get_frame_saved_regs (fci)[FP0_REGNUM + ireg] = reg_position;
+ get_frame_saved_regs (fci)[raw_regnums->fp0_regnum + ireg] = reg_position;
}
- get_frame_saved_regs (fci)[PC_REGNUM] = get_frame_base (fci) + SIGFRAME_PC_OFF;
+ get_frame_saved_regs (fci)[raw_regnums->pc_regnum] = get_frame_base (fci) + SIGFRAME_PC_OFF;
return;
}
@@ -1581,11 +1680,25 @@ mips_find_saved_regs (struct frame_info
for (ireg = MIPS_NUMREGS - 1; float_mask; --ireg, float_mask <<= 1)
if (float_mask & 0x80000000)
{
- get_frame_saved_regs (fci)[FP0_REGNUM + ireg] = reg_position;
+ get_frame_saved_regs (fci)[raw_regnums->fp0_regnum + ireg]
+ = reg_position;
+
+ /* Now take care of the cooked register number. */
+ if (!FP_REGISTER_DOUBLE && MIPS_FPU_TYPE == MIPS_FPU_DOUBLE)
+ {
+ if ((ireg & 1) == 0)
+ get_frame_saved_regs (fci)[cooked_regnums->fp0_regnum + ireg / 2]
+ = reg_position;
+ }
+ else
+ get_frame_saved_regs (fci)[cooked_regnums->fp0_regnum + ireg]
+ = reg_position;
+
reg_position -= MIPS_SAVED_REGSIZE;
}
- get_frame_saved_regs (fci)[PC_REGNUM] = get_frame_saved_regs (fci)[RA_REGNUM];
+ get_frame_saved_regs (fci)[raw_regnums->pc_regnum]
+ = get_frame_saved_regs (fci)[raw_regnums->ra_regnum];
}
/* Set up the 'saved_regs' array. This is a data structure containing
@@ -1598,11 +1711,13 @@ mips_find_saved_regs (struct frame_info
static void
mips_frame_init_saved_regs (struct frame_info *frame)
{
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
if (get_frame_saved_regs (frame) == NULL)
{
mips_find_saved_regs (frame);
}
- get_frame_saved_regs (frame)[SP_REGNUM] = get_frame_base (frame);
+ get_frame_saved_regs (frame)[regnums->sp_regnum] = get_frame_base (frame);
}
static CORE_ADDR
@@ -1697,10 +1812,11 @@ mips_software_single_step (enum target_s
typedef char binsn_quantum[BREAKPOINT_MAX];
static binsn_quantum break_mem;
CORE_ADDR pc;
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
if (insert_breakpoints_p)
{
- pc = read_register (PC_REGNUM);
+ pc = read_register (regnums->pc_regnum);
next_pc = mips_next_pc (pc);
target_insert_breakpoint (next_pc, break_mem);
@@ -1729,15 +1845,17 @@ mips_frame_saved_pc (struct frame_info *
{
CORE_ADDR saved_pc;
mips_extra_func_info_t proc_desc = get_frame_extra_info (frame)->proc_desc;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
/* We have to get the saved pc from the sigcontext
if it is a signal handler frame. */
- int pcreg = (get_frame_type (frame) == SIGTRAMP_FRAME) ? PC_REGNUM
- : (proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM);
+ int pcreg = (get_frame_type (frame) == SIGTRAMP_FRAME) ? regnums->pc_regnum
+ : (proc_desc ? PROC_PC_REG (proc_desc) : regnums->ra_regnum);
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame), 0, 0))
{
LONGEST tmp;
- frame_unwind_signed_register (frame, PC_REGNUM, &tmp);
+ frame_unwind_signed_register (frame, regnums->pc_regnum, &tmp);
saved_pc = tmp;
}
else if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
@@ -1933,6 +2051,7 @@ mips16_heuristic_proc_desc (CORE_ADDR st
unsigned inst = 0; /* current instruction */
unsigned entry_inst = 0; /* the entry instruction */
int reg, offset;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
PROC_FRAME_OFFSET (&temp_proc_desc) = 0; /* size of stack frame */
PROC_FRAME_ADJUST (&temp_proc_desc) = 0; /* offset of FP from SP */
@@ -1974,14 +2093,14 @@ mips16_heuristic_proc_desc (CORE_ADDR st
else if ((inst & 0xff00) == 0x6200) /* sw $ra,n($sp) */
{
offset = mips16_get_imm (prev_inst, inst, 8, 4, 0);
- PROC_REG_MASK (&temp_proc_desc) |= (1 << RA_REGNUM);
- set_reg_offset (RA_REGNUM, sp + offset);
+ PROC_REG_MASK (&temp_proc_desc) |= (1 << regnums->ra_regnum);
+ set_reg_offset (regnums->ra_regnum, sp + offset);
}
else if ((inst & 0xff00) == 0xfa00) /* sd $ra,n($sp) */
{
offset = mips16_get_imm (prev_inst, inst, 8, 8, 0);
- PROC_REG_MASK (&temp_proc_desc) |= (1 << RA_REGNUM);
- set_reg_offset (RA_REGNUM, sp + offset);
+ PROC_REG_MASK (&temp_proc_desc) |= (1 << regnums->ra_regnum);
+ set_reg_offset (regnums->ra_regnum, sp + offset);
}
else if (inst == 0x673d) /* move $s1, $sp */
{
@@ -2045,8 +2164,8 @@ mips16_heuristic_proc_desc (CORE_ADDR st
offset = -4;
if (entry_inst & 0x20)
{
- PROC_REG_MASK (&temp_proc_desc) |= 1 << RA_REGNUM;
- set_reg_offset (RA_REGNUM, sp + offset);
+ PROC_REG_MASK (&temp_proc_desc) |= 1 << regnums->ra_regnum;
+ set_reg_offset (regnums->ra_regnum, sp + offset);
offset -= MIPS_SAVED_REGSIZE;
}
@@ -2066,6 +2185,8 @@ mips32_heuristic_proc_desc (CORE_ADDR st
{
CORE_ADDR cur_pc;
CORE_ADDR frame_addr = 0; /* Value of $r30. Used by gcc for frame-pointer */
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
restart:
temp_saved_regs = xrealloc (temp_saved_regs, SIZEOF_FRAME_SAVED_REGS);
memset (temp_saved_regs, '\0', SIZEOF_FRAME_SAVED_REGS);
@@ -2114,7 +2235,7 @@ restart:
/* Old gcc frame, r30 is virtual frame pointer. */
if ((long) low_word != PROC_FRAME_OFFSET (&temp_proc_desc))
frame_addr = sp + low_word;
- else if (PROC_FRAME_REG (&temp_proc_desc) == SP_REGNUM)
+ else if (PROC_FRAME_REG (&temp_proc_desc) == regnums->sp_regnum)
{
unsigned alloca_adjust;
PROC_FRAME_REG (&temp_proc_desc) = 30;
@@ -2137,7 +2258,7 @@ restart:
else if (inst == 0x03A0F021 || inst == 0x03a0f025 || inst == 0x03a0f02d)
{
/* New gcc frame, virtual frame pointer is at r30 + frame_size. */
- if (PROC_FRAME_REG (&temp_proc_desc) == SP_REGNUM)
+ if (PROC_FRAME_REG (&temp_proc_desc) == regnums->sp_regnum)
{
unsigned alloca_adjust;
PROC_FRAME_REG (&temp_proc_desc) = 30;
@@ -2167,9 +2288,10 @@ heuristic_proc_desc (CORE_ADDR start_pc,
struct frame_info *next_frame, int cur_frame)
{
CORE_ADDR sp;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
if (cur_frame)
- sp = read_next_frame_reg (next_frame, SP_REGNUM);
+ sp = read_next_frame_reg (next_frame, regnums->sp_regnum);
else
sp = 0;
@@ -2179,8 +2301,8 @@ heuristic_proc_desc (CORE_ADDR start_pc,
temp_saved_regs = xrealloc (temp_saved_regs, SIZEOF_FRAME_SAVED_REGS);
memset (temp_saved_regs, '\0', SIZEOF_FRAME_SAVED_REGS);
PROC_LOW_ADDR (&temp_proc_desc) = start_pc;
- PROC_FRAME_REG (&temp_proc_desc) = SP_REGNUM;
- PROC_PC_REG (&temp_proc_desc) = RA_REGNUM;
+ PROC_FRAME_REG (&temp_proc_desc) = regnums->sp_regnum;
+ PROC_PC_REG (&temp_proc_desc) = regnums->ra_regnum;
if (start_pc + 200 < limit_pc)
limit_pc = start_pc + 200;
@@ -2455,6 +2577,7 @@ mips_frame_chain (struct frame_info *fra
mips_extra_func_info_t proc_desc;
CORE_ADDR tmp;
CORE_ADDR saved_pc = DEPRECATED_FRAME_SAVED_PC (frame);
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
if (saved_pc == 0 || inside_entry_file (saved_pc))
return 0;
@@ -2482,7 +2605,7 @@ mips_frame_chain (struct frame_info *fra
/* If no frame pointer and frame size is zero, we must be at end
of stack (or otherwise hosed). If we don't check frame size,
we loop forever if we see a zero size frame. */
- if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
+ if (PROC_FRAME_REG (proc_desc) == regnums->sp_regnum
&& PROC_FRAME_OFFSET (proc_desc) == 0
/* The previous frame from a sigtramp frame might be frameless
and have frame size zero. */
@@ -2500,6 +2623,7 @@ mips_init_extra_frame_info (int fromleaf
{
int regnum;
mips_extra_func_info_t proc_desc;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
if (get_frame_type (fci) == DUMMY_FRAME)
return;
@@ -2528,7 +2652,8 @@ mips_init_extra_frame_info (int fromleaf
interrupted by a signal at it's very start. */
if (get_frame_pc (fci) == PROC_LOW_ADDR (proc_desc)
&& !PROC_DESC_IS_DUMMY (proc_desc))
- deprecated_update_frame_base_hack (fci, read_next_frame_reg (get_next_frame (fci), SP_REGNUM));
+ deprecated_update_frame_base_hack (fci,
+ read_next_frame_reg (get_next_frame (fci), regnums->sp_regnum));
else if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fci), 0, 0))
/* Do not ``fix'' fci->frame. It will have the value of the
generic dummy frame's top-of-stack (since the draft
@@ -2557,25 +2682,28 @@ mips_init_extra_frame_info (int fromleaf
{
frame_saved_regs_zalloc (fci);
memcpy (get_frame_saved_regs (fci), temp_saved_regs, SIZEOF_FRAME_SAVED_REGS);
- get_frame_saved_regs (fci)[PC_REGNUM]
- = get_frame_saved_regs (fci)[RA_REGNUM];
+ get_frame_saved_regs (fci)[regnums->pc_regnum]
+ = get_frame_saved_regs (fci)[regnums->ra_regnum];
/* Set value of previous frame's stack pointer. Remember that
saved_regs[SP_REGNUM] is special in that it contains the
value of the stack pointer register. The other saved_regs
values are addresses (in the inferior) at which a given
register's value may be found. */
- get_frame_saved_regs (fci)[SP_REGNUM] = get_frame_base (fci);
+ get_frame_saved_regs (fci)[regnums->sp_regnum] = get_frame_base (fci);
}
}
/* hack: if argument regs are saved, guess these contain args */
/* assume we can't tell how many args for now */
get_frame_extra_info (fci)->num_args = -1;
- for (regnum = MIPS_LAST_ARG_REGNUM; regnum >= A0_REGNUM; regnum--)
+ for (regnum = regnums->last_arg_regnum;
+ regnum >= regnums->a0_regnum;
+ regnum--)
{
if (PROC_REG_MASK (proc_desc) & (1 << regnum))
{
- get_frame_extra_info (fci)->num_args = regnum - A0_REGNUM + 1;
+ get_frame_extra_info (fci)->num_args
+ = regnum - regnums->a0_regnum + 1;
break;
}
}
@@ -2678,6 +2806,7 @@ mips_eabi_push_arguments (int nargs,
int argnum;
int len = 0;
int stack_offset = 0;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
/* First ensure that the stack and structure return address (if any)
are properly aligned. The stack has to be at least 64-bit
@@ -2702,8 +2831,8 @@ mips_eabi_push_arguments (int nargs,
paddr_nz (sp), ROUND_UP (len, 16));
/* Initialize the integer and float register pointers. */
- argreg = A0_REGNUM;
- float_argreg = FPA0_REGNUM;
+ argreg = regnums->a0_regnum;
+ float_argreg = regnums->first_fp_arg_regnum;
/* The struct_return pointer occupies the first parameter-passing reg. */
if (struct_return)
@@ -2772,7 +2901,7 @@ mips_eabi_push_arguments (int nargs,
point value into an FP register instead of pushing it onto the
stack. */
if (fp_register_arg_p (typecode, arg_type)
- && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
+ && float_argreg <= regnums->last_fp_arg_regnum)
{
if (!FP_REGISTER_DOUBLE && len == 8)
{
@@ -2832,7 +2961,7 @@ mips_eabi_push_arguments (int nargs,
partial_len);
/* Write this portion of the argument to the stack. */
- if (argreg > MIPS_LAST_ARG_REGNUM
+ if (argreg > regnums->last_arg_regnum
|| odd_sized_struct
|| fp_register_arg_p (typecode, arg_type))
{
@@ -2883,7 +3012,7 @@ mips_eabi_push_arguments (int nargs,
arguments will not. */
/* Write this portion of the argument to a general
purpose register. */
- if (argreg <= MIPS_LAST_ARG_REGNUM
+ if (argreg <= regnums->last_arg_regnum
&& !fp_register_arg_p (typecode, arg_type))
{
LONGEST regval = extract_unsigned_integer (val, partial_len);
@@ -2931,6 +3060,7 @@ mips_n32n64_push_arguments (int nargs,
int argnum;
int len = 0;
int stack_offset = 0;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
/* First ensure that the stack and structure return address (if any)
are properly aligned. The stack has to be at least 64-bit
@@ -2953,8 +3083,8 @@ mips_n32n64_push_arguments (int nargs,
paddr_nz (sp), ROUND_UP (len, 16));
/* Initialize the integer and float register pointers. */
- argreg = A0_REGNUM;
- float_argreg = FPA0_REGNUM;
+ argreg = regnums->a0_regnum;
+ float_argreg = regnums->first_fp_arg_regnum;
/* The struct_return pointer occupies the first parameter-passing reg. */
if (struct_return)
@@ -2986,7 +3116,7 @@ mips_n32n64_push_arguments (int nargs,
val = (char *) VALUE_CONTENTS (arg);
if (fp_register_arg_p (typecode, arg_type)
- && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
+ && float_argreg <= regnums->last_fp_arg_regnum)
{
/* This is a floating point value that fits entirely
in a single register. */
@@ -3029,7 +3159,7 @@ mips_n32n64_push_arguments (int nargs,
partial_len);
/* Write this portion of the argument to the stack. */
- if (argreg > MIPS_LAST_ARG_REGNUM
+ if (argreg > regnums->last_arg_regnum
|| odd_sized_struct
|| fp_register_arg_p (typecode, arg_type))
{
@@ -3076,7 +3206,7 @@ mips_n32n64_push_arguments (int nargs,
arguments will not. */
/* Write this portion of the argument to a general
purpose register. */
- if (argreg <= MIPS_LAST_ARG_REGNUM
+ if (argreg <= regnums->last_arg_regnum
&& !fp_register_arg_p (typecode, arg_type))
{
LONGEST regval = extract_unsigned_integer (val, partial_len);
@@ -3153,6 +3283,7 @@ mips_o32_push_arguments (int nargs,
int argnum;
int len = 0;
int stack_offset = 0;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
/* First ensure that the stack and structure return address (if any)
are properly aligned. The stack has to be at least 64-bit
@@ -3175,8 +3306,8 @@ mips_o32_push_arguments (int nargs,
paddr_nz (sp), ROUND_UP (len, 16));
/* Initialize the integer and float register pointers. */
- argreg = A0_REGNUM;
- float_argreg = FPA0_REGNUM;
+ argreg = regnums->a0_regnum;
+ float_argreg = regnums->first_fp_arg_regnum;
/* The struct_return pointer occupies the first parameter-passing reg. */
if (struct_return)
@@ -3231,7 +3362,7 @@ mips_o32_push_arguments (int nargs,
because those registers are normally skipped. */
if (fp_register_arg_p (typecode, arg_type)
- && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
+ && float_argreg <= regnums->last_fp_arg_regnum)
{
if (!FP_REGISTER_DOUBLE && len == 8)
{
@@ -3318,7 +3449,7 @@ mips_o32_push_arguments (int nargs,
partial_len);
/* Write this portion of the argument to the stack. */
- if (argreg > MIPS_LAST_ARG_REGNUM
+ if (argreg > regnums->last_arg_regnum
|| odd_sized_struct
|| fp_register_arg_p (typecode, arg_type))
{
@@ -3365,7 +3496,7 @@ mips_o32_push_arguments (int nargs,
arguments will not. */
/* Write this portion of the argument to a general
purpose register. */
- if (argreg <= MIPS_LAST_ARG_REGNUM
+ if (argreg <= regnums->last_arg_regnum
&& !fp_register_arg_p (typecode, arg_type))
{
LONGEST regval = extract_signed_integer (val, partial_len);
@@ -3413,7 +3544,7 @@ mips_o32_push_arguments (int nargs,
/* Prevent subsequent floating point arguments from
being passed in floating point registers. */
- float_argreg = MIPS_LAST_FP_ARG_REGNUM + 1;
+ float_argreg = regnums->last_fp_arg_regnum + 1;
}
len -= partial_len;
@@ -3452,6 +3583,7 @@ mips_o64_push_arguments (int nargs,
int argnum;
int len = 0;
int stack_offset = 0;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
/* First ensure that the stack and structure return address (if any)
are properly aligned. The stack has to be at least 64-bit
@@ -3474,8 +3606,8 @@ mips_o64_push_arguments (int nargs,
paddr_nz (sp), ROUND_UP (len, 16));
/* Initialize the integer and float register pointers. */
- argreg = A0_REGNUM;
- float_argreg = FPA0_REGNUM;
+ argreg = regnums->a0_regnum;
+ float_argreg = regnums->first_fp_arg_regnum;
/* The struct_return pointer occupies the first parameter-passing reg. */
if (struct_return)
@@ -3530,7 +3662,7 @@ mips_o64_push_arguments (int nargs,
because those registers are normally skipped. */
if (fp_register_arg_p (typecode, arg_type)
- && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
+ && float_argreg <= regnums->last_fp_arg_regnum)
{
if (!FP_REGISTER_DOUBLE && len == 8)
{
@@ -3617,7 +3749,7 @@ mips_o64_push_arguments (int nargs,
partial_len);
/* Write this portion of the argument to the stack. */
- if (argreg > MIPS_LAST_ARG_REGNUM
+ if (argreg > regnums->last_arg_regnum
|| odd_sized_struct
|| fp_register_arg_p (typecode, arg_type))
{
@@ -3664,7 +3796,7 @@ mips_o64_push_arguments (int nargs,
arguments will not. */
/* Write this portion of the argument to a general
purpose register. */
- if (argreg <= MIPS_LAST_ARG_REGNUM
+ if (argreg <= regnums->last_arg_regnum
&& !fp_register_arg_p (typecode, arg_type))
{
LONGEST regval = extract_signed_integer (val, partial_len);
@@ -3712,7 +3844,7 @@ mips_o64_push_arguments (int nargs,
/* Prevent subsequent floating point arguments from
being passed in floating point registers. */
- float_argreg = MIPS_LAST_FP_ARG_REGNUM + 1;
+ float_argreg = regnums->last_fp_arg_regnum + 1;
}
len -= partial_len;
@@ -3740,9 +3872,11 @@ mips_o64_push_arguments (int nargs,
static CORE_ADDR
mips_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
{
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
+
/* Set the return address register to point to the entry
point of the program, where a breakpoint lies in wait. */
- write_register (RA_REGNUM, CALL_DUMMY_ADDRESS ());
+ write_register (regnums->ra_regnum, CALL_DUMMY_ADDRESS ());
return sp;
}
@@ -3753,6 +3887,7 @@ mips_pop_frame (void)
struct frame_info *frame = get_current_frame ();
CORE_ADDR new_sp = get_frame_base (frame);
mips_extra_func_info_t proc_desc;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame), 0, 0))
{
@@ -3762,17 +3897,18 @@ mips_pop_frame (void)
}
proc_desc = get_frame_extra_info (frame)->proc_desc;
- write_register (PC_REGNUM, DEPRECATED_FRAME_SAVED_PC (frame));
+ write_register (regnums->pc_regnum, DEPRECATED_FRAME_SAVED_PC (frame));
if (get_frame_saved_regs (frame) == NULL)
DEPRECATED_FRAME_INIT_SAVED_REGS (frame);
for (regnum = 0; regnum < NUM_REGS; regnum++)
- if (regnum != SP_REGNUM && regnum != PC_REGNUM
+ if (regnum != regnums->sp_regnum && regnum != regnums->pc_regnum
&& get_frame_saved_regs (frame)[regnum])
{
/* Floating point registers must not be sign extended,
- in case MIPS_SAVED_REGSIZE = 4 but sizeof (FP0_REGNUM) == 8. */
+ in case MIPS_SAVED_REGSIZE = 4 but
+ REGISTER_RAW_SIZE (regnums->fp0_regnum)) == 8. */
- if (FP0_REGNUM <= regnum && regnum < FP0_REGNUM + 32)
+ if (regnums->fp0_regnum <= regnum && regnum < regnums->fplast_regnum)
write_register (regnum,
read_memory_unsigned_integer (get_frame_saved_regs (frame)[regnum],
MIPS_SAVED_REGSIZE));
@@ -3782,7 +3918,7 @@ mips_pop_frame (void)
MIPS_SAVED_REGSIZE));
}
- write_register (SP_REGNUM, new_sp);
+ write_register (regnums->sp_regnum, new_sp);
flush_cached_frames ();
if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
@@ -3807,14 +3943,14 @@ mips_pop_frame (void)
xfree (pi_ptr);
- write_register (HI_REGNUM,
+ write_register (regnums->hi_regnum,
read_memory_integer (new_sp - 2 * MIPS_SAVED_REGSIZE,
MIPS_SAVED_REGSIZE));
- write_register (LO_REGNUM,
+ write_register (regnums->lo_regnum,
read_memory_integer (new_sp - 3 * MIPS_SAVED_REGSIZE,
MIPS_SAVED_REGSIZE));
if (MIPS_FPU_TYPE != MIPS_FPU_NONE)
- write_register (FCRCS_REGNUM,
+ write_register (regnums->fcrcs_regnum,
read_memory_integer (new_sp - 4 * MIPS_SAVED_REGSIZE,
MIPS_SAVED_REGSIZE));
}
@@ -3824,9 +3960,58 @@ static void
mips_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
struct value **args, struct type *type, int gcc_p)
{
- write_register(T9_REGNUM, fun);
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
+
+ write_register(regnums->t9_regnum, fun);
+}
+
+/* mips register groups. We add "raw" to the normal groups. */
+
+static struct reggroup *mips_raw_reggroup;
+
+static void
+mips_init_reggroups (void)
+{
+ mips_raw_reggroup = reggroup_new ("raw", USER_REGGROUP);
+}
+
+static void
+mips_add_reggroups (struct gdbarch *gdbarch)
+{
+ reggroup_add (gdbarch, mips_raw_reggroup);
+ reggroup_add (gdbarch, general_reggroup);
+ reggroup_add (gdbarch, float_reggroup);
+ reggroup_add (gdbarch, all_reggroup);
+ reggroup_add (gdbarch, save_reggroup);
+ reggroup_add (gdbarch, restore_reggroup);
+ reggroup_add (gdbarch, vector_reggroup);
+ reggroup_add (gdbarch, system_reggroup);
+}
+
+static int
+mips_register_reggroup_p (struct gdbarch *gdbarch, int regno,
+ struct reggroup *group)
+{
+ int raw_p, float_p;
+ const char *regname;
+ const struct mips_regnums *cooked_regnums = mips_cooked_regnums (gdbarch);
+
+ regname = REGISTER_NAME (regno);
+
+ raw_p = (strncmp (regname, "raw_", 4) == 0);
+ float_p = (cooked_regnums->fp0_regnum <= regno
+ && regno <= cooked_regnums->fplast_regnum);
+
+ if (group == mips_raw_reggroup)
+ return raw_p;
+ if (group == float_reggroup)
+ return float_p;
+ if (group == general_reggroup)
+ return !float_p && !raw_p && *regname != '\0';
+ return default_register_reggroup_p (gdbarch, regno, group);
}
+
/* Floating point register management.
Background: MIPS1 & 2 fp registers are 32 bits wide. To support
@@ -3875,6 +4060,346 @@ mips_double_register_type (void)
return builtin_type_ieee_double_little;
}
+static int
+mips_is_floating_point_register (int regnum)
+{
+ return gdbarch_register_reggroup_p (current_gdbarch, regnum, float_reggroup);
+}
+
+static int
+mips_is_raw_register (int regnum)
+{
+ return gdbarch_register_reggroup_p (current_gdbarch, regnum, mips_raw_reggroup);
+}
+
+static int
+mips_is_general_purpose_register (int regnum)
+{
+ return gdbarch_register_reggroup_p (current_gdbarch, regnum, general_reggroup);
+}
+
+static struct type *
+build_mips_type_float_double_register_big (void)
+{
+ /* Construct a type for mips floating point registers. The type we're
+ building is (roughly) this: */
+#if 0
+ union __gdb_mips_type_float_double_register_big
+ {
+ uint64_t i;
+ float f;
+ double d;
+ };
+#endif
+
+ struct type *t;
+ struct field *f;
+
+ t = init_composite_type ("__gdb_mips_type_float_double_register_big",
+ TYPE_CODE_UNION);
+ append_composite_type_field (t, "i", builtin_type_uint64);
+ append_composite_type_field (t, "f", builtin_type_ieee_single_big);
+ f = &(TYPE_FIELDS (t))[TYPE_NFIELDS (t) - 1];
+ FIELD_BITPOS (f[0]) = 32;
+ append_composite_type_field (t, "d", builtin_type_ieee_double_big);
+
+ TYPE_NAME (t) = "mips_type_float_double_register_big";
+ return t;
+}
+
+static struct type *
+build_mips_type_float_double_register_little (void)
+{
+ /* Construct a type for mips floating point registers. The type we're
+ building is (roughly) this: */
+#if 0
+ union __gdb_mips_type_float_double_register_little
+ {
+ uint64_t i;
+ float f;
+ double d;
+ };
+#endif
+
+ struct type *t;
+
+ t = init_composite_type ("__gdb_mips_type_float_double_register_little",
+ TYPE_CODE_UNION);
+ append_composite_type_field (t, "i", builtin_type_uint64);
+ append_composite_type_field (t, "f", builtin_type_ieee_single_little);
+ append_composite_type_field (t, "d", builtin_type_ieee_double_little);
+ TYPE_NAME (t) = "mips_type_float_double_register_little";
+ return t;
+}
+
+static struct type *
+build_mips_type_float_single_register_big (void)
+{
+ /* Construct a type for mips single-precision floating point registers.
+ The type we're building is (roughly) this: */
+#if 0
+ union __gdb_mips_type_float_single_register_big
+ {
+ uint32_t i;
+ float f;
+ };
+#endif
+
+ struct type *t;
+
+ t = init_composite_type ("__gdb_mips_type_float_single_register_big",
+ TYPE_CODE_UNION);
+ append_composite_type_field (t, "i", builtin_type_uint32);
+ append_composite_type_field (t, "f", builtin_type_ieee_single_big);
+ TYPE_NAME (t) = "mips_type_float_single_register_big";
+ return t;
+}
+
+static struct type *
+build_mips_type_float_single_register_little (void)
+{
+ /* Construct a type for mips single-precision floating point registers.
+ The type we're building is (roughly) this: */
+#if 0
+ union __gdb_mips_type_float_single_register_little
+ {
+ uint32_t i;
+ float f;
+ };
+#endif
+
+ struct type *t;
+
+ t = init_composite_type ("__gdb_mips_type_float_single_register_little",
+ TYPE_CODE_UNION);
+ append_composite_type_field (t, "i", builtin_type_uint32);
+ append_composite_type_field (t, "f", builtin_type_ieee_single_little);
+ TYPE_NAME (t) = "mips_type_float_single_register_little";
+ return t;
+}
+
+/* Given a cooked regnum, find the corresponding raw regnum which should
+ be used to determine the value of the cooked register. (Or vice versa
+ if writing to the cooked register...) Returns the cooked register number
+ or -1 if there is no (known) corresponding raw register number.
+
+ Note that this could be sped up by caching the results in the gdbarch_tdep
+ struct. */
+
+static int
+cooked_regnum_to_raw_regnum (struct gdbarch *gdbarch, int cooked_regno)
+{
+ const struct mips_regnums *raw_regnums = mips_raw_regnums (gdbarch);
+ const struct mips_regnums *cooked_regnums = mips_cooked_regnums (gdbarch);
+ int raw_regno;
+
+ if (cooked_regnums->fp0_regnum <= cooked_regno
+ && cooked_regno <= cooked_regnums->fplast_regnum)
+ {
+ if (cooked_regnums->fplast_regnum - cooked_regnums->fp0_regnum + 1 == 16)
+ {
+ raw_regno = 2 * (cooked_regno - cooked_regnums->fp0_regnum)
+ + raw_regnums->fp0_regnum;
+ }
+ else
+ {
+ gdb_assert (cooked_regnums->fplast_regnum - cooked_regnums->fp0_regnum
+ == raw_regnums->fplast_regnum - raw_regnums->fp0_regnum);
+
+ raw_regno = raw_regnums->fp0_regnum
+ + (cooked_regno - cooked_regnums->fp0_regnum);
+ }
+ }
+ else if (cooked_regno == cooked_regnums->ps_regnum)
+ {
+ gdb_assert (raw_regnums->ps_regnum != -1);
+ raw_regno = raw_regnums->ps_regnum;
+ }
+ else if (cooked_regno == cooked_regnums->fcrcs_regnum)
+ {
+ gdb_assert (raw_regnums->fcrcs_regnum != -1);
+ raw_regno = raw_regnums->fcrcs_regnum;
+ }
+ else if (cooked_regno == cooked_regnums->fcrir_regnum)
+ {
+ gdb_assert (raw_regnums->fcrir_regnum != -1);
+ raw_regno = raw_regnums->fcrir_regnum;
+ }
+ else if (cooked_regnums->first_embed_regnum <= cooked_regno
+ && cooked_regno <= cooked_regnums->last_embed_regnum)
+ {
+ gdb_assert (raw_regnums->first_embed_regnum != -1
+ && (cooked_regnums->last_embed_regnum
+ - cooked_regnums->first_embed_regnum
+ == raw_regnums->last_embed_regnum
+ - raw_regnums->first_embed_regnum));
+ raw_regno = raw_regnums->first_embed_regnum
+ + (cooked_regno - cooked_regnums->first_embed_regnum);
+ }
+ else
+ {
+ raw_regno = -1;
+ }
+
+ return raw_regno;
+}
+
+static void
+mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+ int cooked_regno, void *buffer)
+{
+ const struct mips_regnums *raw_regnums = mips_raw_regnums (gdbarch);
+ const struct mips_regnums *cooked_regnums = mips_cooked_regnums (gdbarch);
+ int raw_regno;
+ char *raw_buf;
+ int raw_size, raw_offset, cooked_size;
+
+
+ raw_regno = cooked_regnum_to_raw_regnum (gdbarch, cooked_regno);
+ if (raw_regno == -1)
+ {
+ warning ("mips_pseudo_register_read: Don't know how to read "
+ "register %d [%s]", cooked_regno, REGISTER_NAME (cooked_regno));
+ memset (buffer, 0, REGISTER_RAW_SIZE (cooked_regno));
+ return;
+ }
+
+ cooked_size = REGISTER_VIRTUAL_SIZE (cooked_regno);
+ raw_size = REGISTER_VIRTUAL_SIZE (raw_regno);
+ raw_buf = alloca (raw_size);
+
+ if (raw_regnums->fp0_regnum <= raw_regno
+ && raw_regno <= raw_regnums->fplast_regnum
+ && !FP_REGISTER_DOUBLE && MIPS_FPU_TYPE == MIPS_FPU_DOUBLE)
+ {
+ int cooked_offset0, cooked_offset1;
+
+ gdb_assert (cooked_size == 8
+ && cooked_regnums->fplast_regnum
+ - cooked_regnums->fp0_regnum + 1 == 16);
+
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ if (raw_size == 8)
+ raw_offset = 4;
+ else
+ raw_offset = 0;
+ cooked_offset0 = 4;
+ cooked_offset1 = 0;
+ }
+ else
+ {
+ raw_offset = 0;
+ cooked_offset0 = 0;
+ cooked_offset1 = 4;
+ }
+
+ regcache_raw_read (regcache, raw_regno, raw_buf);
+ memcpy ((char *) buffer + cooked_offset0, raw_buf + raw_offset, 4);
+ regcache_raw_read (regcache, raw_regno + 1, raw_buf);
+ memcpy ((char *) buffer + cooked_offset1, raw_buf + raw_offset, 4);
+ }
+ else
+ {
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ raw_offset = raw_size - cooked_size;
+ else
+ raw_offset = 0;
+
+ gdb_assert (raw_offset >= 0);
+
+ regcache_raw_read (regcache, raw_regno, raw_buf);
+ memcpy (buffer, raw_buf + raw_offset, cooked_size);
+ }
+}
+
+static void
+mips_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+ int cooked_regno, const void *buffer)
+{
+ const struct mips_regnums *raw_regnums = mips_raw_regnums (gdbarch);
+ const struct mips_regnums *cooked_regnums = mips_cooked_regnums (gdbarch);
+ int raw_regno;
+ char *raw_buf;
+ int raw_size, raw_offset, cooked_size;
+
+ raw_regno = cooked_regnum_to_raw_regnum (gdbarch, cooked_regno);
+ if (raw_regno == -1)
+ {
+ warning ("mips_pseudo_register_write: Don't know how to write "
+ "register %d [%s]", cooked_regno, REGISTER_NAME (cooked_regno));
+ return;
+ }
+
+ cooked_size = REGISTER_VIRTUAL_SIZE (cooked_regno);
+ raw_size = REGISTER_VIRTUAL_SIZE (raw_regno);
+ raw_buf = alloca (raw_size);
+
+ if (raw_regnums->fp0_regnum <= raw_regno
+ && raw_regno <= raw_regnums->fplast_regnum
+ && !FP_REGISTER_DOUBLE && MIPS_FPU_TYPE == MIPS_FPU_DOUBLE)
+ {
+ int cooked_offset0, cooked_offset1;
+
+ gdb_assert (cooked_size == 8
+ && cooked_regnums->fplast_regnum
+ - cooked_regnums->fp0_regnum + 1 == 16);
+
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ if (raw_size == 8)
+ raw_offset = 4;
+ else
+ raw_offset = 0;
+ cooked_offset0 = 4;
+ cooked_offset1 = 0;
+ }
+ else
+ {
+ raw_offset = 0;
+ cooked_offset0 = 0;
+ cooked_offset1 = 4;
+ }
+
+ if (raw_size > cooked_size)
+ {
+ /* Read entire contents of register that we're going to write
+ to so as not to perturb the excess bits. */
+ regcache_raw_read (regcache, raw_regno, raw_buf);
+ }
+ memcpy (raw_buf + raw_offset, (char *) buffer + cooked_offset0, 4);
+ regcache_raw_write (regcache, raw_regno, raw_buf);
+
+ if (raw_size > cooked_size)
+ {
+ /* Read entire contents of register that we're going to write
+ to so as not to perturb the excess bits. */
+ regcache_raw_read (regcache, raw_regno + 1, raw_buf);
+ }
+ memcpy (raw_buf + raw_offset, (char *) buffer + cooked_offset1, 4);
+ regcache_raw_write (regcache, raw_regno + 1, raw_buf);
+ }
+ else
+ {
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ raw_offset = raw_size - cooked_size;
+ else
+ raw_offset = 0;
+
+ gdb_assert (raw_offset >= 0);
+
+ if (raw_size > cooked_size)
+ {
+ /* Read entire contents of register that we're going to write
+ to so as not to perturb the excess bits. */
+ regcache_raw_read (regcache, raw_regno, raw_buf);
+ }
+
+ memcpy (raw_buf + raw_offset, buffer, cooked_size);
+ regcache_raw_write (regcache, raw_regno, raw_buf);
+ }
+}
+
/* Copy a 32-bit single-precision value from the current frame
into rare_buffer. */
@@ -3912,35 +4437,8 @@ mips_read_fp_register_single (int regno,
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 (!frame_register_read (deprecated_selected_frame, 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);
- }
- }
+ if (!frame_register_read (deprecated_selected_frame, regno, rare_buffer))
+ error ("can't read register %d (%s)", regno, REGISTER_NAME (regno));
}
static void
@@ -3949,33 +4447,43 @@ mips_print_fp_register (int regnum)
char *raw_buffer;
double doub, flt1, flt2; /* doubles extracted from raw hex data */
int inv1, inv2, namelen;
+ const char *regname;
+
+ raw_buffer = (char *) alloca (REGISTER_RAW_SIZE (regnum));
- raw_buffer = (char *) alloca (2 * REGISTER_RAW_SIZE (FP0_REGNUM));
+ regname = REGISTER_NAME (regnum);
- printf_filtered ("%s:", REGISTER_NAME (regnum));
- printf_filtered ("%*s", 4 - (int) strlen (REGISTER_NAME (regnum)), "");
+ /* Print the register name. */
+ printf_filtered ("%s:", regname);
+ printf_filtered ("%*s", 4 - (int) strlen (regname), "");
- if (REGISTER_RAW_SIZE (regnum) == 4 || mips2_fp_compat ())
+ if (mips2_fp_compat ())
{
- /* 4-byte registers: Print hex and floating. Also print even
- numbered registers as doubles. */
+ /* 4-byte registers:
+
+ For even numbered registers in a double precision fpu, print
+ the even and the next odd as 64-bit hex, print the single
+ precision float value, and print the even/odd combo as a double.
+
+ Otherwise, for single precision fpus, print the register both as
+ 32-bit hex and as a float. */
+
mips_read_fp_register_single (regnum, raw_buffer);
flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1);
- print_scalar_formatted (raw_buffer, builtin_type_uint32, 'x', 'w',
- gdb_stdout);
-
- printf_filtered (" flt: ");
- if (inv1)
- printf_filtered (" <invalid float> ");
- else
- printf_filtered ("%-17.9g", flt1);
-
- if (regnum % 2 == 0)
+ if (MIPS_FPU_TYPE == MIPS_FPU_DOUBLE)
{
mips_read_fp_register_double (regnum, raw_buffer);
doub = unpack_double (mips_double_register_type (), raw_buffer,
&inv2);
+ print_scalar_formatted (raw_buffer, builtin_type_uint64, 'x', 'g',
+ gdb_stdout);
+
+ printf_filtered (" flt: ");
+ if (inv1)
+ printf_filtered (" <invalid float> ");
+ else
+ printf_filtered ("%-17.9g", flt1);
printf_filtered (" dbl: ");
if (inv2)
@@ -3983,6 +4491,18 @@ mips_print_fp_register (int regnum)
else
printf_filtered ("%-24.17g", doub);
}
+ else
+ {
+ print_scalar_formatted (raw_buffer, builtin_type_uint32, 'x', 'w',
+ gdb_stdout);
+
+ printf_filtered (" flt: ");
+ if (inv1)
+ printf_filtered (" <invalid float> ");
+ else
+ printf_filtered ("%-17.9g", flt1);
+
+ }
}
else
{
@@ -4017,7 +4537,7 @@ mips_print_register (int regnum, int all
char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
int offset;
- if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+ if (mips_is_floating_point_register (regnum))
{
mips_print_fp_register (regnum);
return;
@@ -4047,7 +4567,7 @@ mips_print_register (int regnum, int all
offset = 0;
print_scalar_formatted (raw_buffer + offset,
- REGISTER_VIRTUAL_TYPE (regnum),
+ register_type (current_gdbarch, regnum),
'x', 0, gdb_stdout);
}
@@ -4057,6 +4577,15 @@ mips_print_register (int regnum, int all
static int
do_fp_register_row (int regnum)
{
+ const char * regname;
+
+ regname = REGISTER_NAME (regnum);
+ if (regname == NULL || *regname == '\0')
+ {
+ /* Don't print *anything* for the no-name registers. */
+ return regnum + 1;
+ }
+
printf_filtered (" ");
mips_print_fp_register (regnum);
printf_filtered ("\n");
@@ -4074,7 +4603,7 @@ do_gp_register_row (int regnum)
int ncols = (MIPS_REGSIZE == 8 ? 4 : 8); /* display cols per row */
int col, byte;
int start_regnum = regnum;
- int numregs = NUM_REGS;
+ int numregs = NUM_REGS + NUM_PSEUDO_REGS;
/* For GP registers, we print a separate row of names above the vals */
@@ -4083,8 +4612,8 @@ do_gp_register_row (int regnum)
{
if (*REGISTER_NAME (regnum) == '\0')
continue; /* unused register */
- if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
- break; /* end the row: reached FP register */
+ if (!mips_is_general_purpose_register (regnum))
+ continue; /* end the row: reached FP register */
printf_filtered (MIPS_REGSIZE == 8 ? "%17s" : "%9s",
REGISTER_NAME (regnum));
col++;
@@ -4098,8 +4627,8 @@ do_gp_register_row (int regnum)
{
if (*REGISTER_NAME (regnum) == '\0')
continue; /* unused register */
- if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
- break; /* end row: reached FP register */
+ if (!mips_is_general_purpose_register (regnum))
+ continue;
/* OK: get the data in raw format. */
if (!frame_register_read (deprecated_selected_frame, regnum, raw_buffer))
error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
@@ -4142,16 +4671,28 @@ mips_do_registers_info (int regnum, int
else
/* do all (or most) registers */
{
+ /* Do the general purpose registers. */
regnum = 0;
- while (regnum < NUM_REGS)
+ while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
{
- if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
- if (fpregs) /* true for "INFO ALL-REGISTERS" command */
- regnum = do_fp_register_row (regnum); /* FP regs */
- else
- regnum += MIPS_NUMREGS; /* skip floating point regs */
- else
+ if (mips_is_general_purpose_register (regnum))
regnum = do_gp_register_row (regnum); /* GP (int) regs */
+ else
+ regnum++;
+ }
+
+ /* Do the floating point registers if requested, i.e, for
+ "info all-registers". */
+ if (fpregs) /* true for "INFO ALL-REGISTERS" command */
+ {
+ regnum = 0;
+ while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
+ {
+ if (mips_is_floating_point_register (regnum))
+ regnum = do_fp_register_row (regnum); /* FP regs */
+ else
+ regnum++;
+ }
}
}
}
@@ -4432,6 +4973,7 @@ return_value_location (struct type *valt
struct return_value_word *lo)
{
int len = TYPE_LENGTH (valtype);
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
if (TYPE_CODE (valtype) == TYPE_CODE_FLT
&& ((MIPS_FPU_TYPE == MIPS_FPU_DOUBLE && (len == 4 || len == 8))
@@ -4444,11 +4986,11 @@ return_value_location (struct type *valt
lo->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
hi->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 0 : 4;
lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
- && REGISTER_RAW_SIZE (FP0_REGNUM) == 8)
+ && REGISTER_RAW_SIZE (regnums->fp0_regnum) == 8)
? 4 : 0);
hi->reg_offset = lo->reg_offset;
- lo->reg = FP0_REGNUM + 0;
- hi->reg = FP0_REGNUM + 1;
+ lo->reg = regnums->fp0_regnum + 0;
+ hi->reg = regnums->fp0_regnum + 1;
lo->len = 4;
hi->len = 4;
}
@@ -4457,10 +4999,10 @@ return_value_location (struct type *valt
/* The floating point value fits in a single floating-point
register. */
lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
- && REGISTER_RAW_SIZE (FP0_REGNUM) == 8
+ && REGISTER_RAW_SIZE (regnums->fp0_regnum) == 8
&& len == 4)
? 4 : 0);
- lo->reg = FP0_REGNUM;
+ lo->reg = regnums->fp0_regnum;
lo->len = len;
lo->buf_offset = 0;
hi->len = 0;
@@ -4622,6 +5164,8 @@ mips_o32_xfer_return_value (struct type
bfd_byte *in, const bfd_byte *out)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
if (TYPE_CODE (type) == TYPE_CODE_FLT
&& TYPE_LENGTH (type) == 4
&& tdep->mips_fpu_type != MIPS_FPU_NONE)
@@ -4630,7 +5174,7 @@ mips_o32_xfer_return_value (struct type
least significant part of FP0. */
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
- mips_xfer_register (regcache, FP0_REGNUM, TYPE_LENGTH (type),
+ mips_xfer_register (regcache, regnums->fp0_regnum, TYPE_LENGTH (type),
TARGET_BYTE_ORDER, in, out, 0);
}
else if (TYPE_CODE (type) == TYPE_CODE_FLT
@@ -4645,15 +5189,15 @@ mips_o32_xfer_return_value (struct type
switch (TARGET_BYTE_ORDER)
{
case BFD_ENDIAN_LITTLE:
- mips_xfer_register (regcache, FP0_REGNUM + 0, 4,
+ mips_xfer_register (regcache, regnums->fp0_regnum + 0, 4,
TARGET_BYTE_ORDER, in, out, 0);
- mips_xfer_register (regcache, FP0_REGNUM + 1, 4,
+ mips_xfer_register (regcache, regnums->fp0_regnum + 1, 4,
TARGET_BYTE_ORDER, in, out, 4);
break;
case BFD_ENDIAN_BIG:
- mips_xfer_register (regcache, FP0_REGNUM + 1, 4,
+ mips_xfer_register (regcache, regnums->fp0_regnum + 1, 4,
TARGET_BYTE_ORDER, in, out, 0);
- mips_xfer_register (regcache, FP0_REGNUM + 0, 4,
+ mips_xfer_register (regcache, regnums->fp0_regnum + 0, 4,
TARGET_BYTE_ORDER, in, out, 4);
break;
default:
@@ -4680,7 +5224,7 @@ mips_o32_xfer_return_value (struct type
bfd_byte *reg = alloca (MAX_REGISTER_RAW_SIZE);
int regnum;
int field;
- for (field = 0, regnum = FP0_REGNUM;
+ for (field = 0, regnum = regnums->fp0_regnum;
field < TYPE_NFIELDS (type);
field++, regnum += 2)
{
@@ -4702,7 +5246,7 @@ mips_o32_xfer_return_value (struct type
mips_xfer_lower. */
int offset;
int regnum;
- for (offset = 0, regnum = V0_REGNUM;
+ for (offset = 0, regnum = regnums->v0_regnum;
offset < TYPE_LENGTH (type);
offset += REGISTER_RAW_SIZE (regnum), regnum++)
{
@@ -4724,7 +5268,7 @@ mips_o32_xfer_return_value (struct type
the ISA. mips_stack_argsize controls this. */
int offset;
int regnum;
- for (offset = 0, regnum = V0_REGNUM;
+ for (offset = 0, regnum = regnums->v0_regnum;
offset < TYPE_LENGTH (type);
offset += mips_stack_argsize (), regnum++)
{
@@ -4763,6 +5307,8 @@ mips_n32n64_xfer_return_value (struct ty
bfd_byte *in, const bfd_byte *out)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
if (TYPE_CODE (type) == TYPE_CODE_FLT
&& tdep->mips_fpu_type != MIPS_FPU_NONE)
{
@@ -4770,7 +5316,7 @@ mips_n32n64_xfer_return_value (struct ty
of FP0. */
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
- mips_xfer_register (regcache, FP0_REGNUM, TYPE_LENGTH (type),
+ mips_xfer_register (regcache, regnums->fp0_regnum, TYPE_LENGTH (type),
TARGET_BYTE_ORDER, in, out, 0);
}
else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
@@ -4792,7 +5338,7 @@ mips_n32n64_xfer_return_value (struct ty
bfd_byte *reg = alloca (MAX_REGISTER_RAW_SIZE);
int regnum;
int field;
- for (field = 0, regnum = FP0_REGNUM;
+ for (field = 0, regnum = regnums->fp0_regnum;
field < TYPE_NFIELDS (type);
field++, regnum += 2)
{
@@ -4812,7 +5358,7 @@ mips_n32n64_xfer_return_value (struct ty
mips_xfer_lower. */
int offset;
int regnum;
- for (offset = 0, regnum = V0_REGNUM;
+ for (offset = 0, regnum = regnums->v0_regnum;
offset < TYPE_LENGTH (type);
offset += REGISTER_RAW_SIZE (regnum), regnum++)
{
@@ -4832,7 +5378,7 @@ mips_n32n64_xfer_return_value (struct ty
justified. */
int offset;
int regnum;
- for (offset = 0, regnum = V0_REGNUM;
+ for (offset = 0, regnum = regnums->v0_regnum;
offset < TYPE_LENGTH (type);
offset += REGISTER_RAW_SIZE (regnum), regnum++)
{
@@ -4875,9 +5421,10 @@ mips_extract_struct_value_address (struc
/* FIXME: This will only work at random. The caller passes the
struct_return address in V0, but it is not preserved. It may
still be there, or this may be a random value. */
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
LONGEST val;
- regcache_cooked_read_signed (regcache, V0_REGNUM, &val);
+ regcache_cooked_read_signed (regcache, regnums->v0_regnum, &val);
return val;
}
@@ -5020,7 +5567,7 @@ mips_set_processor_type (char *str)
if (strcasecmp (str, mips_processor_type_table[i].name) == 0)
{
mips_processor_type = str;
- mips_processor_reg_names = mips_processor_type_table[i].regnames;
+ mips_embed_reg_names = mips_processor_type_table[i].regnames;
return 1;
/* FIXME tweak fpu flag too */
}
@@ -5036,8 +5583,12 @@ char *
mips_read_processor_type (void)
{
CORE_ADDR prid;
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
+
+ if (regnums->prid_regnum < 0)
+ return NULL;
- prid = read_register (PRID_REGNUM);
+ prid = read_register (regnums->prid_regnum);
if ((prid & ~0xf) == 0x700)
return savestring ("r3041", strlen ("r3041"));
@@ -5196,6 +5747,7 @@ mips_skip_stub (CORE_ADDR pc)
{
char *name;
CORE_ADDR start_addr;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
/* Find the starting address and name of the function containing the PC. */
if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0)
@@ -5205,7 +5757,7 @@ mips_skip_stub (CORE_ADDR pc)
target PC is in $31 ($ra). */
if (strcmp (name, "__mips16_ret_sf") == 0
|| strcmp (name, "__mips16_ret_df") == 0)
- return read_signed_register (RA_REGNUM);
+ return read_signed_register (regnums->ra_regnum);
if (strncmp (name, "__mips16_call_stub_", 19) == 0)
{
@@ -5426,7 +5978,9 @@ mips_get_saved_register (char *raw_buffe
static CORE_ADDR
mips_saved_pc_after_call (struct frame_info *frame)
{
- return read_signed_register (RA_REGNUM);
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
+
+ return read_signed_register (regnums->ra_regnum);
}
@@ -5436,14 +5990,21 @@ mips_saved_pc_after_call (struct frame_i
static int
mips_stab_reg_to_regnum (int num)
{
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
+
if (num >= 0 && num < 32)
return num;
else if (num >= 38 && num < 70)
- return num + FP0_REGNUM - 38;
+ {
+ if (regnums->fplast_regnum - regnums->fp0_regnum + 1 == 16)
+ return ((num - 38) / 2) + regnums->fp0_regnum;
+ else
+ return num - 38 + regnums->fp0_regnum;
+ }
else if (num == 70)
- return HI_REGNUM;
+ return regnums->hi_regnum;
else if (num == 71)
- return LO_REGNUM;
+ return regnums->lo_regnum;
else
{
/* This will hopefully (eventually) provoke a warning. Should
@@ -5458,14 +6019,21 @@ mips_stab_reg_to_regnum (int num)
static int
mips_dwarf_dwarf2_ecoff_reg_to_regnum (int num)
{
+ const struct mips_regnums *regnums = mips_cooked_regnums (current_gdbarch);
+
if (num >= 0 && num < 32)
return num;
else if (num >= 32 && num < 64)
- return num + FP0_REGNUM - 32;
+ {
+ if (regnums->fplast_regnum - regnums->fp0_regnum + 1 == 16)
+ return ((num - 32) / 2) + regnums->fp0_regnum;
+ else
+ return num - 32 + regnums->fp0_regnum;
+ }
else if (num == 64)
- return HI_REGNUM;
+ return regnums->hi_regnum;
else if (num == 65)
- return LO_REGNUM;
+ return regnums->lo_regnum;
else
{
/* This will hopefully (eventually) provoke a warning. Should
@@ -5540,6 +6108,7 @@ mips_gdbarch_init (struct gdbarch_info i
struct gdbarch_tdep *tdep;
int elf_flags;
enum mips_abi mips_abi, found_abi, wanted_abi;
+ int first_pseudo_regnum, next_available_pseudo_regnum;
/* Reset the disassembly info, in case it was set to something
non-default. */
@@ -5692,7 +6261,6 @@ mips_gdbarch_init (struct gdbarch_info i
set_gdbarch_float_bit (gdbarch, 32);
set_gdbarch_double_bit (gdbarch, 64);
set_gdbarch_long_double_bit (gdbarch, 64);
- set_gdbarch_register_raw_size (gdbarch, mips_register_raw_size);
set_gdbarch_deprecated_max_register_raw_size (gdbarch, 8);
set_gdbarch_deprecated_max_register_virtual_size (gdbarch, 8);
tdep->found_abi = found_abi;
@@ -5702,9 +6270,54 @@ mips_gdbarch_init (struct gdbarch_info i
mips_elf_make_msymbol_special);
if (info.osabi == GDB_OSABI_IRIX)
- set_gdbarch_num_regs (gdbarch, 71);
+ {
+ set_gdbarch_num_regs (gdbarch, 71);
+ first_pseudo_regnum = 71;
+ next_available_pseudo_regnum = 71;
+
+ tdep->raw_regnums.fp0_regnum = 32;
+ tdep->raw_regnums.pc_regnum = 64;
+ tdep->raw_regnums.cause_regnum = 65;
+ tdep->raw_regnums.badvaddr_regnum = 66;
+ tdep->raw_regnums.hi_regnum = 67;
+ tdep->raw_regnums.lo_regnum = 68;
+ tdep->raw_regnums.fcrcs_regnum = 69;
+ tdep->raw_regnums.fcrir_regnum = 70;
+
+ tdep->raw_regnums.ps_regnum = -1;
+ tdep->raw_regnums.first_embed_regnum = -1;
+ tdep->raw_regnums.last_embed_regnum = -1;
+ tdep->raw_regnums.prid_regnum = -1;
+ }
else
- set_gdbarch_num_regs (gdbarch, 90);
+ {
+ set_gdbarch_num_regs (gdbarch, 90);
+ first_pseudo_regnum = 90;
+ next_available_pseudo_regnum = 90;
+
+ tdep->raw_regnums.fp0_regnum = 38;
+ tdep->raw_regnums.ps_regnum = 32;
+ tdep->raw_regnums.hi_regnum = 34;
+ tdep->raw_regnums.lo_regnum = 33;
+ tdep->raw_regnums.badvaddr_regnum = 35;
+ tdep->raw_regnums.cause_regnum = 36;
+ tdep->raw_regnums.pc_regnum = 37;
+ tdep->raw_regnums.fcrcs_regnum = 70;
+ tdep->raw_regnums.fcrir_regnum = 71;
+ tdep->raw_regnums.first_embed_regnum = 74;
+ tdep->raw_regnums.last_embed_regnum = 89;
+ tdep->raw_regnums.prid_regnum = 89;
+ }
+
+ tdep->raw_regnums.fplast_regnum = tdep->raw_regnums.fp0_regnum + 31;
+ tdep->raw_regnums.first_fp_arg_regnum = tdep->raw_regnums.fp0_regnum + 12;
+
+ tdep->raw_regnums.zero_regnum = 0;
+ tdep->raw_regnums.v0_regnum = 2;
+ tdep->raw_regnums.a0_regnum = 4;
+ tdep->raw_regnums.t9_regnum = 25;
+ tdep->raw_regnums.sp_regnum = 29;
+ tdep->raw_regnums.ra_regnum = 31;
switch (mips_abi)
{
@@ -5715,8 +6328,8 @@ mips_gdbarch_init (struct gdbarch_info i
tdep->mips_default_saved_regsize = 4;
tdep->mips_default_stack_argsize = 4;
tdep->mips_fp_register_double = 0;
- tdep->mips_last_arg_regnum = A0_REGNUM + 4 - 1;
- tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 4 - 1;
+ tdep->raw_regnums.last_arg_regnum = tdep->raw_regnums.a0_regnum + 4 - 1;
+ tdep->raw_regnums.last_fp_arg_regnum = tdep->raw_regnums.first_fp_arg_regnum + 4 - 1;
tdep->gdb_target_is_mips64 = 0;
tdep->default_mask_address_p = 0;
set_gdbarch_long_bit (gdbarch, 32);
@@ -5734,8 +6347,8 @@ mips_gdbarch_init (struct gdbarch_info i
tdep->mips_default_saved_regsize = 8;
tdep->mips_default_stack_argsize = 8;
tdep->mips_fp_register_double = 1;
- tdep->mips_last_arg_regnum = A0_REGNUM + 4 - 1;
- tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 4 - 1;
+ tdep->raw_regnums.last_arg_regnum = tdep->raw_regnums.a0_regnum + 4 - 1;
+ tdep->raw_regnums.last_fp_arg_regnum = tdep->raw_regnums.first_fp_arg_regnum + 4 - 1;
tdep->gdb_target_is_mips64 = 1;
tdep->default_mask_address_p = 0;
set_gdbarch_long_bit (gdbarch, 32);
@@ -5753,8 +6366,8 @@ mips_gdbarch_init (struct gdbarch_info i
tdep->mips_default_saved_regsize = 4;
tdep->mips_default_stack_argsize = 4;
tdep->mips_fp_register_double = 0;
- tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
- tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
+ tdep->raw_regnums.last_arg_regnum = tdep->raw_regnums.a0_regnum + 8 - 1;
+ tdep->raw_regnums.last_fp_arg_regnum = tdep->raw_regnums.first_fp_arg_regnum + 8 - 1;
tdep->gdb_target_is_mips64 = 0;
tdep->default_mask_address_p = 0;
set_gdbarch_long_bit (gdbarch, 32);
@@ -5772,8 +6385,8 @@ mips_gdbarch_init (struct gdbarch_info i
tdep->mips_default_saved_regsize = 8;
tdep->mips_default_stack_argsize = 8;
tdep->mips_fp_register_double = 1;
- tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
- tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
+ tdep->raw_regnums.last_arg_regnum = tdep->raw_regnums.a0_regnum + 8 - 1;
+ tdep->raw_regnums.last_fp_arg_regnum = tdep->raw_regnums.first_fp_arg_regnum + 8 - 1;
tdep->gdb_target_is_mips64 = 1;
tdep->default_mask_address_p = 0;
set_gdbarch_long_bit (gdbarch, 64);
@@ -5791,8 +6404,8 @@ mips_gdbarch_init (struct gdbarch_info i
tdep->mips_default_saved_regsize = 8;
tdep->mips_default_stack_argsize = 8;
tdep->mips_fp_register_double = 1;
- tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
- tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
+ tdep->raw_regnums.last_arg_regnum = tdep->raw_regnums.a0_regnum + 8 - 1;
+ tdep->raw_regnums.last_fp_arg_regnum = tdep->raw_regnums.first_fp_arg_regnum + 8 - 1;
tdep->gdb_target_is_mips64 = 1;
tdep->default_mask_address_p = 0;
set_gdbarch_long_bit (gdbarch, 32);
@@ -5810,8 +6423,8 @@ mips_gdbarch_init (struct gdbarch_info i
tdep->mips_default_saved_regsize = 8;
tdep->mips_default_stack_argsize = 8;
tdep->mips_fp_register_double = 1;
- tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
- tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
+ tdep->raw_regnums.last_arg_regnum = tdep->raw_regnums.a0_regnum + 8 - 1;
+ tdep->raw_regnums.last_fp_arg_regnum = tdep->raw_regnums.first_fp_arg_regnum + 8 - 1;
tdep->gdb_target_is_mips64 = 1;
tdep->default_mask_address_p = 0;
set_gdbarch_long_bit (gdbarch, 64);
@@ -5914,11 +6527,6 @@ mips_gdbarch_init (struct gdbarch_info i
set_gdbarch_deprecated_push_return_address (gdbarch, mips_push_return_address);
set_gdbarch_frame_align (gdbarch, mips_frame_align);
set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
- set_gdbarch_register_convertible (gdbarch, mips_register_convertible);
- set_gdbarch_register_convert_to_virtual (gdbarch,
- mips_register_convert_to_virtual);
- set_gdbarch_register_convert_to_raw (gdbarch,
- mips_register_convert_to_raw);
set_gdbarch_deprecated_frame_chain (gdbarch, mips_frame_chain);
set_gdbarch_frameless_function_invocation (gdbarch,
@@ -5942,9 +6550,7 @@ mips_gdbarch_init (struct gdbarch_info i
set_gdbarch_function_start_offset (gdbarch, 0);
- /* There are MIPS targets which do not yet use this since they still
- define REGISTER_VIRTUAL_TYPE. */
- set_gdbarch_register_virtual_type (gdbarch, mips_register_virtual_type);
+ set_gdbarch_register_type (gdbarch, mips_register_type);
set_gdbarch_register_virtual_size (gdbarch, generic_register_size);
set_gdbarch_deprecated_do_registers_info (gdbarch, mips_do_registers_info);
@@ -5962,6 +6568,72 @@ mips_gdbarch_init (struct gdbarch_info i
set_gdbarch_in_solib_call_trampoline (gdbarch, mips_in_call_stub);
set_gdbarch_in_solib_return_trampoline (gdbarch, mips_in_return_stub);
+ /* Add mips register groups. */
+ mips_add_reggroups (gdbarch);
+ set_gdbarch_register_reggroup_p (gdbarch, mips_register_reggroup_p);
+
+ /* For many registers, the cooked and raw register numbers are the same. */
+ tdep->cooked_regnums = tdep->raw_regnums;
+
+ /* For those that aren't the same, initialize the cooked register numbers. */
+ if (!tdep->mips_fp_register_double &&
+ tdep->mips_fpu_type == MIPS_FPU_DOUBLE)
+ {
+ /* There are 16 64-bit cooked floating point registers. */
+ tdep->cooked_regnums.fp0_regnum = next_available_pseudo_regnum;
+ next_available_pseudo_regnum += 16;
+ tdep->cooked_regnums.fplast_regnum = next_available_pseudo_regnum - 1;
+ }
+ else if (tdep->mips_fpu_type == MIPS_FPU_NONE)
+ {
+ /* There aren't any cooked floating point registers. */
+ tdep->cooked_regnums.fp0_regnum = -1;
+ tdep->cooked_regnums.fplast_regnum = -1;
+ }
+ else
+ {
+ /* There are 32 floating (cooked) point registers. */
+ tdep->cooked_regnums.fp0_regnum = next_available_pseudo_regnum;
+ next_available_pseudo_regnum += 32;
+ tdep->cooked_regnums.fplast_regnum = next_available_pseudo_regnum - 1;
+ }
+
+ if (tdep->raw_regnums.ps_regnum != -1)
+ tdep->cooked_regnums.ps_regnum = next_available_pseudo_regnum++;
+
+ if (tdep->raw_regnums.fcrcs_regnum != -1)
+ tdep->cooked_regnums.fcrcs_regnum = next_available_pseudo_regnum++;
+
+ if (tdep->raw_regnums.fcrir_regnum != -1)
+ tdep->cooked_regnums.fcrir_regnum = next_available_pseudo_regnum++;
+
+ if (tdep->raw_regnums.first_embed_regnum != -1)
+ {
+ tdep->cooked_regnums.first_embed_regnum = next_available_pseudo_regnum;
+ next_available_pseudo_regnum += (tdep->raw_regnums.last_embed_regnum
+ - tdep->raw_regnums.first_embed_regnum);
+ tdep->cooked_regnums.last_embed_regnum = next_available_pseudo_regnum++;
+
+ tdep->cooked_regnums.prid_regnum
+ = tdep->cooked_regnums.first_embed_regnum
+ + (tdep->raw_regnums.prid_regnum
+ - tdep->raw_regnums.first_embed_regnum);
+ }
+
+ /* Set up the pseudo reg count and the pseudo register reader/writer. */
+ if (next_available_pseudo_regnum > first_pseudo_regnum)
+ {
+ set_gdbarch_num_pseudo_regs (gdbarch, next_available_pseudo_regnum
+ - first_pseudo_regnum);
+ set_gdbarch_pseudo_register_read (gdbarch, mips_pseudo_register_read);
+ set_gdbarch_pseudo_register_write (gdbarch, mips_pseudo_register_write);
+ }
+
+ /* Set the sp and pc regnums to the cooked numbers. */
+
+ set_gdbarch_sp_regnum (gdbarch, tdep->cooked_regnums.sp_regnum);
+ set_gdbarch_pc_regnum (gdbarch, tdep->cooked_regnums.pc_regnum);
+
return gdbarch;
}
@@ -6010,6 +6682,56 @@ show_mips_abi (char *ignore_args, int fr
}
static void
+mips_dump_regnums (const char *prefix, const struct mips_regnums *regnums,
+ struct ui_file *file)
+{
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "fp0_regnum", regnums->fp0_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "fplast_regnum", regnums->fplast_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "last_arg_regnum", regnums->last_arg_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "first_fp_arg_regnum", regnums->first_fp_arg_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "last_fp_arg_regnum", regnums->last_fp_arg_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "zero_regnum", regnums->zero_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "v0_regnum", regnums->v0_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "a0_regnum", regnums->a0_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "t9_regnum", regnums->t9_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "sp_regnum", regnums->sp_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "ra_regnum", regnums->ra_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "ps_regnum", regnums->ps_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "hi_regnum", regnums->hi_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "lo_regnum", regnums->lo_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "badvaddr_regnum", regnums->badvaddr_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "cause_regnum", regnums->cause_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "pc_regnum", regnums->pc_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "fcrcs_regnum", regnums->fcrcs_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "fcrir_regnum", regnums->fcrir_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "first_embed_regnum", regnums->first_embed_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "last_embed_regnum", regnums->last_embed_regnum);
+ fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+ "prid_regnum", regnums->prid_regnum);
+}
+
+static void
mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
@@ -6055,6 +6777,10 @@ mips_dump_tdep (struct gdbarch *current_
"mips_dump_tdep: mips_mask_address_p() %d (default %d)\n",
mips_mask_address_p (),
tdep->default_mask_address_p);
+ mips_dump_regnums ("mips_dump_tdep: tdep->cooked_regnums.",
+ &tdep->cooked_regnums, file);
+ mips_dump_regnums ("mips_dump_tdep: tdep->raw_regnums.",
+ &tdep->raw_regnums, file);
}
fprintf_unfiltered (file,
"mips_dump_tdep: FP_REGISTER_DOUBLE = %d\n",
@@ -6070,10 +6796,6 @@ mips_dump_tdep (struct gdbarch *current_
"mips_dump_tdep: MIPS_EABI = %d\n",
MIPS_EABI);
fprintf_unfiltered (file,
- "mips_dump_tdep: MIPS_LAST_FP_ARG_REGNUM = %d (%d regs)\n",
- MIPS_LAST_FP_ARG_REGNUM,
- MIPS_LAST_FP_ARG_REGNUM - FPA0_REGNUM + 1);
- fprintf_unfiltered (file,
"mips_dump_tdep: MIPS_FPU_TYPE = %d (%s)\n",
MIPS_FPU_TYPE,
(MIPS_FPU_TYPE == MIPS_FPU_NONE ? "none"
@@ -6096,50 +6818,26 @@ mips_dump_tdep (struct gdbarch *current_
"mips_dump_tdep: MIPS_REGSIZE = %d\n",
MIPS_REGSIZE);
fprintf_unfiltered (file,
- "mips_dump_tdep: A0_REGNUM = %d\n",
- A0_REGNUM);
- fprintf_unfiltered (file,
"mips_dump_tdep: ADDR_BITS_REMOVE # %s\n",
XSTRING (ADDR_BITS_REMOVE(ADDR)));
fprintf_unfiltered (file,
"mips_dump_tdep: ATTACH_DETACH # %s\n",
XSTRING (ATTACH_DETACH));
fprintf_unfiltered (file,
- "mips_dump_tdep: BADVADDR_REGNUM = %d\n",
- BADVADDR_REGNUM);
- fprintf_unfiltered (file,
"mips_dump_tdep: BIG_BREAKPOINT = delete?\n");
fprintf_unfiltered (file,
- "mips_dump_tdep: CAUSE_REGNUM = %d\n",
- CAUSE_REGNUM);
- fprintf_unfiltered (file,
"mips_dump_tdep: DWARF_REG_TO_REGNUM # %s\n",
XSTRING (DWARF_REG_TO_REGNUM (REGNUM)));
fprintf_unfiltered (file,
"mips_dump_tdep: ECOFF_REG_TO_REGNUM # %s\n",
XSTRING (ECOFF_REG_TO_REGNUM (REGNUM)));
fprintf_unfiltered (file,
- "mips_dump_tdep: FCRCS_REGNUM = %d\n",
- FCRCS_REGNUM);
- fprintf_unfiltered (file,
- "mips_dump_tdep: FCRIR_REGNUM = %d\n",
- FCRIR_REGNUM);
- fprintf_unfiltered (file,
- "mips_dump_tdep: FIRST_EMBED_REGNUM = %d\n",
- FIRST_EMBED_REGNUM);
- fprintf_unfiltered (file,
- "mips_dump_tdep: FPA0_REGNUM = %d\n",
- FPA0_REGNUM);
- fprintf_unfiltered (file,
"mips_dump_tdep: GDB_TARGET_IS_MIPS64 = %d\n",
GDB_TARGET_IS_MIPS64);
fprintf_unfiltered (file,
"mips_dump_tdep: HAVE_NONSTEPPABLE_WATCHPOINT # %s\n",
XSTRING (HAVE_NONSTEPPABLE_WATCHPOINT));
fprintf_unfiltered (file,
- "mips_dump_tdep: HI_REGNUM = %d\n",
- HI_REGNUM);
- fprintf_unfiltered (file,
"mips_dump_tdep: IDT_BIG_BREAKPOINT = delete?\n");
fprintf_unfiltered (file,
"mips_dump_tdep: IDT_LITTLE_BREAKPOINT = delete?\n");
@@ -6155,13 +6853,7 @@ mips_dump_tdep (struct gdbarch *current_
fprintf_unfiltered (file,
"mips_dump_tdep: IS_MIPS16_ADDR = FIXME!\n");
fprintf_unfiltered (file,
- "mips_dump_tdep: LAST_EMBED_REGNUM = %d\n",
- LAST_EMBED_REGNUM);
- fprintf_unfiltered (file,
"mips_dump_tdep: LITTLE_BREAKPOINT = delete?\n");
- fprintf_unfiltered (file,
- "mips_dump_tdep: LO_REGNUM = %d\n",
- LO_REGNUM);
#ifdef MACHINE_CPROC_FP_OFFSET
fprintf_unfiltered (file,
"mips_dump_tdep: MACHINE_CPROC_FP_OFFSET = %d\n",
@@ -6194,15 +6886,9 @@ mips_dump_tdep (struct gdbarch *current_
"mips_dump_tdep: MIPS_INSTLEN = %d\n",
MIPS_INSTLEN);
fprintf_unfiltered (file,
- "mips_dump_tdep: MIPS_LAST_ARG_REGNUM = %d (%d regs)\n",
- MIPS_LAST_ARG_REGNUM,
- MIPS_LAST_ARG_REGNUM - A0_REGNUM + 1);
- fprintf_unfiltered (file,
"mips_dump_tdep: MIPS_NUMREGS = %d\n",
MIPS_NUMREGS);
fprintf_unfiltered (file,
- "mips_dump_tdep: MIPS_REGISTER_NAMES = delete?\n");
- fprintf_unfiltered (file,
"mips_dump_tdep: MIPS_SAVED_REGSIZE = %d\n",
MIPS_SAVED_REGSIZE);
fprintf_unfiltered (file,
@@ -6214,9 +6900,6 @@ mips_dump_tdep (struct gdbarch *current_
fprintf_unfiltered (file,
"mips_dump_tdep: PMON_LITTLE_BREAKPOINT = delete?\n");
fprintf_unfiltered (file,
- "mips_dump_tdep: PRID_REGNUM = %d\n",
- PRID_REGNUM);
- fprintf_unfiltered (file,
"mips_dump_tdep: PRINT_EXTRA_FRAME_INFO # %s\n",
XSTRING (PRINT_EXTRA_FRAME_INFO (FRAME)));
fprintf_unfiltered (file,
@@ -6244,12 +6927,6 @@ mips_dump_tdep (struct gdbarch *current_
fprintf_unfiltered (file,
"mips_dump_tdep: PROC_SYMBOL = function?\n");
fprintf_unfiltered (file,
- "mips_dump_tdep: PS_REGNUM = %d\n",
- PS_REGNUM);
- fprintf_unfiltered (file,
- "mips_dump_tdep: RA_REGNUM = %d\n",
- RA_REGNUM);
- fprintf_unfiltered (file,
"mips_dump_tdep: REGISTER_CONVERT_FROM_TYPE # %s\n",
XSTRING (REGISTER_CONVERT_FROM_TYPE (REGNUM, VALTYPE, RAW_BUFFER)));
fprintf_unfiltered (file,
@@ -6323,9 +7000,6 @@ mips_dump_tdep (struct gdbarch *current_
"mips_dump_tdep: STOPPED_BY_WATCHPOINT # %s\n",
XSTRING (STOPPED_BY_WATCHPOINT (WS)));
fprintf_unfiltered (file,
- "mips_dump_tdep: T9_REGNUM = %d\n",
- T9_REGNUM);
- fprintf_unfiltered (file,
"mips_dump_tdep: TABULAR_REGISTER_OUTPUT = used?\n");
fprintf_unfiltered (file,
"mips_dump_tdep: TARGET_CAN_USE_HARDWARE_WATCHPOINT # %s\n",
@@ -6360,14 +7034,6 @@ mips_dump_tdep (struct gdbarch *current_
#endif
fprintf_unfiltered (file,
"mips_dump_tdep: UNMAKE_MIPS16_ADDR = function?\n");
-#ifdef UNUSED_REGNUM
- fprintf_unfiltered (file,
- "mips_dump_tdep: UNUSED_REGNUM = %d\n",
- UNUSED_REGNUM);
-#endif
- fprintf_unfiltered (file,
- "mips_dump_tdep: V0_REGNUM = %d\n",
- V0_REGNUM);
fprintf_unfiltered (file,
"mips_dump_tdep: VM_MIN_ADDRESS = %ld\n",
(long) VM_MIN_ADDRESS);
@@ -6377,9 +7043,6 @@ mips_dump_tdep (struct gdbarch *current_
VX_NUM_REGS);
#endif
fprintf_unfiltered (file,
- "mips_dump_tdep: ZERO_REGNUM = %d\n",
- ZERO_REGNUM);
- fprintf_unfiltered (file,
"mips_dump_tdep: _PROC_MAGIC_ = %d\n",
_PROC_MAGIC_);
}
@@ -6526,4 +7189,15 @@ that would transfer 32 bits for some reg
&mips_debug, "Set mips debugging.\n\
When non-zero, mips specific debugging is enabled.", &setdebuglist),
&showdebuglist);
+
+ mips_type_float_double_register_big
+ = build_mips_type_float_double_register_big ();
+ mips_type_float_double_register_little
+ = build_mips_type_float_double_register_little ();
+ mips_type_float_single_register_big
+ = build_mips_type_float_single_register_big ();
+ mips_type_float_single_register_little
+ = build_mips_type_float_single_register_little ();
+
+ mips_init_reggroups ();
}
Index: mips-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.h,v
retrieving revision 1.2
diff -u -p -r1.2 mips-tdep.h
--- mips-tdep.h 12 Apr 2003 17:41:25 -0000 1.2
+++ mips-tdep.h 9 May 2003 23:36:34 -0000
@@ -40,4 +40,40 @@ enum mips_abi
/* Return the MIPS ABI associated with GDBARCH. */
enum mips_abi mips_abi (struct gdbarch *gdbarch);
+struct mips_regnums
+ {
+ int fp0_regnum; /* First floating point register. */
+ int fplast_regnum; /* Last floating point register. */
+ int last_arg_regnum; /* Last general purpose register used for
+ passing arguments. (a0_regnum is the
+ first.) */
+ int first_fp_arg_regnum; /* First floating point register used for
+ passing floating point arguments. */
+ int last_fp_arg_regnum; /* Last floating point register used for
+ passing floating point arguments. */
+ int zero_regnum; /* The zero register; read-only, always 0. */
+ int v0_regnum; /* Function return value. */
+ int a0_regnum; /* First GPR used for passing arguments. */
+ int t9_regnum; /* Contains address of callee in PIC code. */
+ int sp_regnum; /* Stack pointer. */
+ int ra_regnum; /* Return address. */
+ int ps_regnum; /* Processor status. */
+ int hi_regnum; /* High portion of internal multiply/divide
+ register. */
+ int lo_regnum; /* Low portion of internal multiply/divide
+ register. */
+ int badvaddr_regnum; /* Address associated with
+ addressing exception. */
+ int cause_regnum; /* Describes last exception. */
+ int pc_regnum; /* Program counter. */
+ int fcrcs_regnum; /* FP control/status. */
+ int fcrir_regnum; /* FP implementation/revision. */
+ int first_embed_regnum; /* First CP0 register for embedded use. */
+ int last_embed_regnum; /* Last CP0 register for embedded use. */
+ int prid_regnum; /* Processor ID. */
+ };
+
+const struct mips_regnums *mips_raw_regnums (struct gdbarch *gdbarch);
+const struct mips_regnums *mips_cooked_regnums (struct gdbarch *gdbarch);
+
#endif /* MIPS_TDEP_H */
Index: mipsnbsd-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/mipsnbsd-nat.c,v
retrieving revision 1.1
diff -u -p -r1.1 mipsnbsd-nat.c
--- mipsnbsd-nat.c 21 May 2002 15:58:40 -0000 1.1
+++ mipsnbsd-nat.c 9 May 2003 23:36:34 -0000
@@ -22,6 +22,7 @@
#include "inferior.h"
#include "regcache.h"
+#include "mips-tdep.h"
#include "mipsnbsd-tdep.h"
#include <sys/types.h>
@@ -32,12 +33,16 @@
static int
getregs_supplies (int regno)
{
- return ((regno) >= ZERO_REGNUM && (regno) <= PC_REGNUM);
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
+ return (regno >= regnums->zero_regnum && regno <= regnums->pc_regnum);
}
void
fetch_inferior_registers (int regno)
{
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
if (regno == -1 || getregs_supplies (regno))
{
struct reg regs;
@@ -51,7 +56,7 @@ fetch_inferior_registers (int regno)
return;
}
- if (regno == -1 || regno >= FP0_REGNUM)
+ if (regno == -1 || regno >= regnums->fp0_regnum)
{
struct fpreg fpregs;
@@ -66,6 +71,8 @@ fetch_inferior_registers (int regno)
void
store_inferior_registers (int regno)
{
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
if (regno == -1 || getregs_supplies (regno))
{
struct reg regs;
@@ -84,7 +91,7 @@ store_inferior_registers (int regno)
return;
}
- if (regno == -1 || regno >= FP0_REGNUM)
+ if (regno == -1 || regno >= regnums->fp0_regnum)
{
struct fpreg fpregs;
Index: remote-mips.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-mips.c,v
retrieving revision 1.33
diff -u -p -r1.33 remote-mips.c
--- remote-mips.c 29 Apr 2003 01:49:47 -0000 1.33
+++ remote-mips.c 9 May 2003 23:36:35 -0000
@@ -36,6 +36,7 @@
#include "gdb_stat.h"
#include "regcache.h"
#include <ctype.h>
+#include "mips-tdep.h"
\f
/* Breakpoint types. Values 0, 1, and 2 must agree with the watch
@@ -1750,6 +1751,7 @@ mips_wait (ptid_t ptid, struct target_wa
char flags[20];
int nfields;
int i;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
interrupt_count = 0;
hit_watchpoint = 0;
@@ -1793,14 +1795,14 @@ mips_wait (ptid_t ptid, struct target_wa
{
char *buf = alloca (max_register_size (current_gdbarch));
- store_unsigned_integer (buf, REGISTER_RAW_SIZE (PC_REGNUM), rpc);
- supply_register (PC_REGNUM, buf);
+ store_unsigned_integer (buf, REGISTER_RAW_SIZE (regnums->pc_regnum), rpc);
+ supply_register (regnums->pc_regnum, buf);
- store_unsigned_integer (buf, REGISTER_RAW_SIZE (PC_REGNUM), rfp);
+ store_unsigned_integer (buf, REGISTER_RAW_SIZE (regnums->pc_regnum), rfp);
supply_register (30, buf); /* This register they are avoiding and so it is unnamed */
- store_unsigned_integer (buf, REGISTER_RAW_SIZE (SP_REGNUM), rsp);
- supply_register (SP_REGNUM, buf);
+ store_unsigned_integer (buf, REGISTER_RAW_SIZE (regnums->sp_regnum), rsp);
+ supply_register (regnums->sp_regnum, buf);
store_unsigned_integer (buf, REGISTER_RAW_SIZE (DEPRECATED_FP_REGNUM), 0);
supply_register (DEPRECATED_FP_REGNUM, buf);
@@ -1904,25 +1906,26 @@ mips_wait (ptid_t ptid, struct target_wa
static int
mips_map_regno (int regno)
{
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
if (regno < 32)
return regno;
- if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
- return regno - FP0_REGNUM + 32;
- switch (regno)
- {
- case PC_REGNUM:
- return REGNO_OFFSET + 0;
- case CAUSE_REGNUM:
- return REGNO_OFFSET + 1;
- case HI_REGNUM:
- return REGNO_OFFSET + 2;
- case LO_REGNUM:
- return REGNO_OFFSET + 3;
- case FCRCS_REGNUM:
- return REGNO_OFFSET + 4;
- case FCRIR_REGNUM:
- return REGNO_OFFSET + 5;
- default:
+ if (regno >= regnums->fp0_regnum && regno < regnums->fp0_regnum + 32)
+ return regno - regnums->fp0_regnum + 32;
+ else if (regno == regnums->pc_regnum)
+ return REGNO_OFFSET + 0;
+ else if (regno == regnums->cause_regnum)
+ return REGNO_OFFSET + 1;
+ else if (regno == regnums->hi_regnum)
+ return REGNO_OFFSET + 2;
+ else if (regno == regnums->lo_regnum)
+ return REGNO_OFFSET + 3;
+ else if (regno == regnums->fcrcs_regnum)
+ return REGNO_OFFSET + 4;
+ else if (regno == regnums->fcrir_regnum)
+ return REGNO_OFFSET + 5;
+ else
+ {
/* FIXME: Is there a way to get the status register? */
return 0;
}
@@ -1935,6 +1938,7 @@ mips_fetch_registers (int regno)
{
unsigned LONGEST val;
int err;
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
if (regno == -1)
{
@@ -1943,7 +1947,7 @@ mips_fetch_registers (int regno)
return;
}
- if (regno == DEPRECATED_FP_REGNUM || regno == ZERO_REGNUM)
+ if (regno == DEPRECATED_FP_REGNUM || regno == regnums->zero_regnum)
/* DEPRECATED_FP_REGNUM on the mips is a hack which is just
supposed to read zero (see also mips-nat.c). */
val = 0;
@@ -3426,6 +3430,8 @@ pmon_load_fast (char *file)
static void
mips_load (char *file, int from_tty)
{
+ const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
+
/* Get the board out of remote debugging mode. */
if (mips_exit_debug ())
error ("mips_load: Couldn't get into monitor mode.");
@@ -3443,7 +3449,7 @@ mips_load (char *file, int from_tty)
/* Work around problem where PMON monitor updates the PC after a load
to a different value than GDB thinks it has. The following ensures
that the write_pc() WILL update the PC value: */
- deprecated_register_valid[PC_REGNUM] = 0;
+ deprecated_register_valid[regnums->pc_regnum] = 0;
}
if (exec_bfd)
write_pc (bfd_get_start_address (exec_bfd));
Index: config/mips/nm-riscos.h
===================================================================
RCS file: /cvs/src/src/gdb/config/mips/nm-riscos.h,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 nm-riscos.h
--- config/mips/nm-riscos.h 7 Jul 1999 20:15:18 -0000 1.1.1.2
+++ config/mips/nm-riscos.h 9 May 2003 23:36:36 -0000
@@ -29,27 +29,27 @@
#define KERNEL_U_ADDR BSD43_UADDR
#define REGISTER_U_ADDR(addr, blockend, regno) \
- if (regno < FP0_REGNUM) \
+ if (regno < mips_raw_regnums (current_gdbarch)->fp0_regnum) \
addr = UPAGES*NBPG-EF_SIZE+4*((regno)+EF_AT-1); \
- else if (regno < PC_REGNUM) \
- addr = PCB_OFFSET(pcb_fpregs[0]) + 4*(regno-FP0_REGNUM); \
- else if (regno == PS_REGNUM) \
+ else if (regno < mips_raw_regnums (current_gdbarch)->pc_regnum) \
+ addr = PCB_OFFSET(pcb_fpregs[0]) + 4*(regno-mips_raw_regnums (current_gdbarch)->fp0_regnum); \
+ else if (regno == mips_raw_regnums (current_gdbarch)->ps_regnum) \
addr = UPAGES*NBPG-EF_SIZE+4*EF_SR; \
- else if (regno == BADVADDR_REGNUM) \
+ else if (regno == mips_raw_regnums (current_gdbarch)->badvaddr_regnum) \
addr = UPAGES*NBPG-EF_SIZE+4*EF_BADVADDR; \
- else if (regno == LO_REGNUM) \
+ else if (regno == mips_raw_regnums (current_gdbarch)->lo_regnum) \
addr = UPAGES*NBPG-EF_SIZE+4*EF_MDLO; \
- else if (regno == HI_REGNUM) \
+ else if (regno == mips_raw_regnums (current_gdbarch)->hi_regnum) \
addr = UPAGES*NBPG-EF_SIZE+4*EF_MDHI; \
- else if (regno == CAUSE_REGNUM) \
+ else if (regno == mips_raw_regnums (current_gdbarch)->cause_regnum) \
addr = UPAGES*NBPG-EF_SIZE+4*EF_CAUSE; \
- else if (regno == PC_REGNUM) \
+ else if (regno == mips_raw_regnums (current_gdbarch)->pc_regnum) \
addr = UPAGES*NBPG-EF_SIZE+4*EF_EPC; \
- else if (regno < FCRCS_REGNUM) \
- addr = PCB_OFFSET(pcb_fpregs[0]) + 4*(regno-FP0_REGNUM); \
- else if (regno == FCRCS_REGNUM) \
+ else if (regno < mips_raw_regnums (current_gdbarch)->fcrcs_regnum) \
+ addr = PCB_OFFSET(pcb_fpregs[0]) + 4*(regno-mips_raw_regnums (current_gdbarch)->fp0_regnum); \
+ else if (regno == mips_raw_regnums (current_gdbarch)->fcrcs_regnum) \
addr = PCB_OFFSET(pcb_fpc_csr); \
- else if (regno == FCRIR_REGNUM) \
+ else if (regno == mips_raw_regnums (current_gdbarch)->fcrir_regnum) \
addr = PCB_OFFSET(pcb_fpc_eir); \
else \
addr = 0;
Index: config/mips/tm-irix3.h
===================================================================
RCS file: /cvs/src/src/gdb/config/mips/tm-irix3.h,v
retrieving revision 1.5
diff -u -p -r1.5 tm-irix3.h
--- config/mips/tm-irix3.h 19 Mar 2003 06:21:14 -0000 1.5
+++ config/mips/tm-irix3.h 9 May 2003 23:36:36 -0000
@@ -21,44 +21,6 @@
#include "mips/tm-bigmips.h"
-/* Redefine register numbers for SGI. */
-
-#undef MIPS_REGISTER_NAMES
-#undef FP0_REGNUM
-#undef PC_REGNUM
-#undef HI_REGNUM
-#undef LO_REGNUM
-#undef CAUSE_REGNUM
-#undef BADVADDR_REGNUM
-#undef FCRCS_REGNUM
-#undef FCRIR_REGNUM
-
-/* Initializer for an array of names for registers 32 and above.
- There should be NUM_REGS-32 strings in this initializer. */
-
-#define MIPS_REGISTER_NAMES \
- { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
- "pc", "cause", "bad", "hi", "lo", "fsr", "fir" \
- }
-
-/* Register numbers of various important registers.
- Note that some of these values are "real" register numbers,
- and correspond to the general registers of the machine,
- and some are "phony" register numbers which are too large
- to be actual register numbers as far as the user is concerned
- but do serve to get the desired values when passed to read_register. */
-
-#define FP0_REGNUM 32 /* Floating point register 0 (single float) */
-#define PC_REGNUM 64 /* Contains program counter */
-#define CAUSE_REGNUM 65 /* describes last exception */
-#define BADVADDR_REGNUM 66 /* bad vaddr for addressing exception */
-#define HI_REGNUM 67 /* Multiple/divide temp */
-#define LO_REGNUM 68 /* ... */
-#define FCRCS_REGNUM 69 /* FP control/status */
-#define FCRIR_REGNUM 70 /* FP implementation/revision */
/* Offsets for register values in _sigtramp frame.
sigcontext is immediately above the _sigtramp frame on Irix. */
Index: config/mips/tm-irix5.h
===================================================================
RCS file: /cvs/src/src/gdb/config/mips/tm-irix5.h,v
retrieving revision 1.8
diff -u -p -r1.8 tm-irix5.h
--- config/mips/tm-irix5.h 20 Aug 2002 13:17:55 -0000 1.8
+++ config/mips/tm-irix5.h 9 May 2003 23:36:39 -0000
@@ -21,36 +21,6 @@
#include "mips/tm-irix3.h"
-/* FIXME: cagney/2000-04-04: Testing the _MIPS_SIM_NABI32 and
- _MIPS_SIM in a tm-*.h file is simply wrong! Those are
- host-dependant macros (provided by /usr/include) and stop any
- chance of the target being cross compiled */
-#if defined (_MIPS_SIM_NABI32) && _MIPS_SIM == _MIPS_SIM_NABI32
-/*
- * Irix 6 (n32 ABI) has 32-bit GP regs and 64-bit FP regs
- */
-
-#undef REGISTER_BYTES
-#define REGISTER_BYTES (MIPS_NUMREGS * 8 + (NUM_REGS - MIPS_NUMREGS) * MIPS_REGSIZE)
-
-#undef REGISTER_BYTE
-#define REGISTER_BYTE(N) \
- (((N) < FP0_REGNUM) ? (N) * MIPS_REGSIZE : \
- ((N) < FP0_REGNUM + 32) ? \
- FP0_REGNUM * MIPS_REGSIZE + \
- ((N) - FP0_REGNUM) * sizeof(double) : \
- 32 * sizeof(double) + ((N) - 32) * MIPS_REGSIZE)
-
-#undef REGISTER_VIRTUAL_TYPE
-#define REGISTER_VIRTUAL_TYPE(N) \
- (((N) >= FP0_REGNUM && (N) < FP0_REGNUM+32) ? builtin_type_double \
- : ((N) == 32 /*SR*/) ? builtin_type_uint32 \
- : ((N) >= 70 && (N) <= 89) ? builtin_type_uint32 \
- : builtin_type_int)
-
-#endif /* N32 */
-
-
/* The signal handler trampoline is called _sigtramp. */
#undef IN_SIGTRAMP
#define IN_SIGTRAMP(pc, name) ((name) && STREQ ("_sigtramp", name))
Index: config/mips/tm-irix6.h
===================================================================
RCS file: /cvs/src/src/gdb/config/mips/tm-irix6.h,v
retrieving revision 1.10
diff -u -p -r1.10 tm-irix6.h
--- config/mips/tm-irix6.h 19 Mar 2003 06:21:14 -0000 1.10
+++ config/mips/tm-irix6.h 9 May 2003 23:36:39 -0000
@@ -24,55 +24,9 @@
/* Redefine register numbers for SGI. */
-#undef MIPS_REGISTER_NAMES
-#undef FP0_REGNUM
-#undef PC_REGNUM
-#undef HI_REGNUM
-#undef LO_REGNUM
-#undef CAUSE_REGNUM
-#undef BADVADDR_REGNUM
-#undef FCRCS_REGNUM
-#undef FCRIR_REGNUM
-
-/* Initializer for an array of names for registers 32 and above.
- There should be NUM_REGS-32 strings in this initializer. */
-
-#define MIPS_REGISTER_NAMES \
- { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
- "pc", "cause", "bad", "hi", "lo", "fsr", "fir" \
- }
-
-/* Register numbers of various important registers.
- Note that some of these values are "real" register numbers,
- and correspond to the general registers of the machine,
- and some are "phony" register numbers which are too large
- to be actual register numbers as far as the user is concerned
- but do serve to get the desired values when passed to read_register. */
-
-#define FP0_REGNUM 32 /* Floating point register 0 (single float) */
-#define PC_REGNUM 64 /* Contains program counter */
-#define CAUSE_REGNUM 65 /* describes last exception */
-#define BADVADDR_REGNUM 66 /* bad vaddr for addressing exception */
-#define HI_REGNUM 67 /* Multiple/divide temp */
-#define LO_REGNUM 68 /* ... */
-#define FCRCS_REGNUM 69 /* FP control/status */
-#define FCRIR_REGNUM 70 /* FP implementation/revision */
-
-
#undef REGISTER_BYTES
#define REGISTER_BYTES (MIPS_NUMREGS * 8 + (NUM_REGS - MIPS_NUMREGS) * MIPS_REGSIZE)
-#undef REGISTER_BYTE
-#define REGISTER_BYTE(N) \
- (((N) < FP0_REGNUM) ? (N) * MIPS_REGSIZE : \
- ((N) < FP0_REGNUM + 32) ? \
- FP0_REGNUM * MIPS_REGSIZE + \
- ((N) - FP0_REGNUM) * sizeof(double) : \
- 32 * sizeof(double) + ((N) - 32) * MIPS_REGSIZE)
-
/* The signal handler trampoline is called _sigtramp. */
#undef IN_SIGTRAMP
#define IN_SIGTRAMP(pc, name) ((name) && STREQ ("_sigtramp", name))
@@ -99,6 +53,3 @@
/* Select the disassembler */
#undef TM_PRINT_INSN_MACH
#define TM_PRINT_INSN_MACH bfd_mach_mips8000
-
-/* Undefine those methods which have been multiarched. */
-#undef REGISTER_VIRTUAL_TYPE
Index: config/mips/tm-mips.h
===================================================================
RCS file: /cvs/src/src/gdb/config/mips/tm-mips.h,v
retrieving revision 1.48
diff -u -p -r1.48 tm-mips.h
--- config/mips/tm-mips.h 5 May 2003 17:56:56 -0000 1.48
+++ config/mips/tm-mips.h 9 May 2003 23:36:39 -0000
@@ -59,88 +59,10 @@ extern int mips_step_skips_delay (CORE_A
#define MIPS_REGSIZE 4
#endif
-/* Initializer for an array of names for registers 32 and above.
- There should be NUM_REGS-32 strings in this initializer. */
-
-#ifndef MIPS_REGISTER_NAMES
-#define MIPS_REGISTER_NAMES \
- { "sr", "lo", "hi", "bad", "cause","pc", \
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
- "fsr", "fir", ""/*"fp"*/, "", \
- "", "", "", "", "", "", "", "", \
- "", "", "", "", "", "", "", "", \
- }
-#endif
-
-/* Register numbers of various important registers.
- Note that some of these values are "real" register numbers,
- and correspond to the general registers of the machine,
- and some are "phony" register numbers which are too large
- to be actual register numbers as far as the user is concerned
- but do serve to get the desired values when passed to read_register. */
-
-#define ZERO_REGNUM 0 /* read-only register, always 0 */
-#define V0_REGNUM 2 /* Function integer return value */
-#define A0_REGNUM 4 /* Loc of first arg during a subr call */
-#define T9_REGNUM 25 /* Contains address of callee in PIC */
-#define SP_REGNUM 29 /* Contains address of top of stack */
-#define RA_REGNUM 31 /* Contains return address value */
-#define PS_REGNUM 32 /* Contains processor status */
-#define HI_REGNUM 34 /* Multiple/divide temp */
-#define LO_REGNUM 33 /* ... */
-#define BADVADDR_REGNUM 35 /* bad vaddr for addressing exception */
-#define CAUSE_REGNUM 36 /* describes last exception */
-#define PC_REGNUM 37 /* Contains program counter */
-#define FP0_REGNUM 38 /* Floating point register 0 (single float) */
-#define FPA0_REGNUM (FP0_REGNUM+12) /* First float argument register */
-#define FCRCS_REGNUM 70 /* FP control/status */
-#define FCRIR_REGNUM 71 /* FP implementation/revision */
-#define UNUSED_REGNUM 73 /* Never used, FIXME */
-#define FIRST_EMBED_REGNUM 74 /* First CP0 register for embedded use */
-#define PRID_REGNUM 89 /* Processor ID */
-#define LAST_EMBED_REGNUM 89 /* Last one */
-
/* Total amount of space needed to store our copies of the machine's
register state, the array `registers'. */
#define REGISTER_BYTES (NUM_REGS*MIPS_REGSIZE)
-
-/* Index within `registers' of the first byte of the space for
- register N. */
-
-#define REGISTER_BYTE(N) ((N) * MIPS_REGSIZE)
-
-/* Return the GDB type object for the "standard" data type of data in
- register N. */
-
-#ifndef REGISTER_VIRTUAL_TYPE
-#define REGISTER_VIRTUAL_TYPE(N) \
- (((N) >= FP0_REGNUM && (N) < FP0_REGNUM+32) ? builtin_type_float \
- : ((N) == 32 /*SR*/) ? builtin_type_uint32 \
- : ((N) >= 70 && (N) <= 89) ? builtin_type_uint32 \
- : builtin_type_int)
-#endif
-
-/* All mips targets store doubles in a register pair with the least
- significant register in the lower numbered register.
- If the target is big endian, double register values need conversion
- between memory and register formats. */
-
-extern void mips_register_convert_to_type (int regnum,
- struct type *type,
- char *buffer);
-extern void mips_register_convert_from_type (int regnum,
- struct type *type,
- char *buffer);
-
-#define REGISTER_CONVERT_TO_TYPE(n, type, buffer) \
- mips_register_convert_to_type ((n), (type), (buffer))
-
-#define REGISTER_CONVERT_FROM_TYPE(n, type, buffer) \
- mips_register_convert_from_type ((n), (type), (buffer))
\f
/* Special symbol found in blocks associated with routines. We can hang
Index: config/mips/tm-mips64.h
===================================================================
RCS file: /cvs/src/src/gdb/config/mips/tm-mips64.h,v
retrieving revision 1.5
diff -u -p -r1.5 tm-mips64.h
--- config/mips/tm-mips64.h 5 Jun 2002 19:18:25 -0000 1.5
+++ config/mips/tm-mips64.h 9 May 2003 23:36:39 -0000
@@ -22,13 +22,6 @@
/* Use eight byte registers. */
#define MIPS_REGSIZE 8
-/* define 8 byte register type */
-#define REGISTER_VIRTUAL_TYPE(N) \
- (((N) >= FP0_REGNUM && (N) < FP0_REGNUM+32) ? builtin_type_double \
- : ((N) == 32 /*SR*/) ? builtin_type_uint32 \
- : ((N) >= 70 && (N) <= 89) ? builtin_type_uint32 \
- : builtin_type_long_long)
-
/* Load double words in CALL_DUMMY. */
#define OP_LDFPR 065 /* ldc1 */
#define OP_LDGPR 067 /* ld */
Index: config/mips/tm-tx39.h
===================================================================
RCS file: /cvs/src/src/gdb/config/mips/tm-tx39.h,v
retrieving revision 1.6
diff -u -p -r1.6 tm-tx39.h
--- config/mips/tm-tx39.h 19 Mar 2003 06:21:14 -0000 1.6
+++ config/mips/tm-tx39.h 9 May 2003 23:36:39 -0000
@@ -18,15 +18,3 @@
Boston, MA 02111-1307, USA. */
#include "mips/tm-bigmips.h"
-
-#undef MIPS_REGISTER_NAMES
-#define MIPS_REGISTER_NAMES \
- { "sr", "lo", "hi", "bad", "cause","pc", \
- "", "", "", "", "", "", "", "", \
- "", "", "", "", "", "", "", "", \
- "", "", "", "", "", "", "", "", \
- "", "", "", "", "", "", "", "", \
- "", "", "", "", \
- "", "", "", "", "", "", "", "", \
- "", "", "config", "cache", "debug", "depc", "epc", "" \
- }
Index: config/mips/tm-tx39l.h
===================================================================
RCS file: /cvs/src/src/gdb/config/mips/tm-tx39l.h,v
retrieving revision 1.6
diff -u -p -r1.6 tm-tx39l.h
--- config/mips/tm-tx39l.h 19 Mar 2003 06:21:14 -0000 1.6
+++ config/mips/tm-tx39l.h 9 May 2003 23:36:39 -0000
@@ -18,15 +18,3 @@
Boston, MA 02111-1307, USA. */
#include "mips/tm-mips.h"
-
-#undef MIPS_REGISTER_NAMES
-#define MIPS_REGISTER_NAMES \
- { "sr", "lo", "hi", "bad", "cause","pc", \
- "", "", "", "", "", "", "", "", \
- "", "", "", "", "", "", "", "", \
- "", "", "", "", "", "", "", "", \
- "", "", "", "", "", "", "", "", \
- "", "", "", "", \
- "", "", "", "", "", "", "", "", \
- "", "", "config", "cache", "debug", "depc", "epc", "" \
- }
^ permalink raw reply [flat|nested] 46+ messages in thread* Re: [WIP/RFC] MIPS registers overhaul
2003-05-10 0:25 [WIP/RFC] MIPS registers overhaul Kevin Buettner
@ 2003-05-10 20:30 ` Andrew Cagney
2003-05-10 20:40 ` Daniel Jacobowitz
2003-05-14 22:00 ` Kevin Buettner
0 siblings, 2 replies; 46+ messages in thread
From: Andrew Cagney @ 2003-05-10 20:30 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
> The patch below represents the results of trying to fix two problems
> related to floating point registers, stumbling at various points along
> the way, and realizing that I needed to fix even more...
>
> The two problems related to floating point registers that I started out
> trying to fix are the following:
>
> 1) On mips64, it's not possible to set a floating point register to
> a single precision value.
Hmm, ``oops''.
> 2) Again, on mips64, when running a program using the o32 ABI, floating
> point doubles were not being fetched from GDB's regcache correctly.
> For o32, floating point doubles are represented using register pairs,
> but, for mips64, each register is stored in a 64-bit container. When
> attempting to retrieve the value of a 64-bit double that should
> be retrieved by taking 32-bits from a pair, the single 64-bit container
> was being considered to be the value of the double.
For a long long time people were trying to solve this using the
convertible methods. It never really worked.
> Problem 1 was solved by introducing a union type for floating point
> registers. When attempting to display a value using ``print'', you'll
> see (with my patch) something like this:
>
> (gdb) p $f20
> $1 = {i = 4621199872640208077, f = -107374184, d = 8.9000000000000004}
>
> (If someone can think of more meaningful, but still terse field names for
> the above, please let me know.)
I'd try to be consistent with the other register unions, uint64 for
instance. As for the d/f, I don't know.
> Problem 2 was solved by introducing pseudo-registers for the floating point
> registers. Along the way (last Friday, I think), I ran into an assertion
> failure which caused me to make even more extensive changes to the MIPS code.
Ya! Finally!
> BTW, the raw floating point registers are still accessible. Doing
> "info registers raw" will display all of the raw registers. Or, if
> you know the names of the registers you want to display, you can do,
> e.g, "info registers raw_f20".
Hmm, is this necessary? Confusing? ``maint print
{raw-,cooked-,}registers'' are already available and provide access to
the underlying values.
``info registers'' should always display the target's underlying
register set. In the case of o32 running on a 64 bit ISA, the 64 bit
registers should be displayed.
> Which reminds me... I've introduced two sets of register numbers. I
> called these the "cooked" and "raw" regnums. In many cases, the
> cooked and raw numbers are the same. (They'll usually be the same
> when the raw and cooked types are the same.) In the cases where the
> numbers are different, the cooked number is a pseudo register number
> and the corresponding raw register is (usually) used to determine the
> value of cooked value. Raw registers numbers should be used by the
> lower layers of GDB which communicate with the target and need to
> populate GDB's regcache. The cooked registers *should* be used almost
> everywhere else. Except they aren't at the moment. In particular,
> most of mips-tdep.c wants to still operate on "raw" register data.
> (Anywhere you see a byte order check, that's a clue that raw register
> numbers should still be used.) So, in order to prevent this patch from
> becoming even larger than it already is, much of mips-tdep.c still
> uses raw register numbers. These should (probably) be cleaned up some
> day to use cooked numbers instead. (I need to check to make sure I
> have this as a comment in the code somewhere...)
>
> For the o32 case that I was originally trying to fix, we end up
> creating 16 64-bit cooked floating point registers of the union type
> mentioned above. The raw floating point registers (in pairs) are used
> to construct the cooked value. It's also possible to end up with no
> cooked floating point registers or 32-floating floating point
> registers, either 32- or 64-bit. (The values of FP_REGISTER_DOUBLE
> and MIPS_FPU_TYPE influence what exactly gets done.)
Ok.
> Index: mdebugread.c
The below isn't right.
RA_REGNUM is defined by both Alpha and MIPS. There are a number of long
standing problems with mdebug read vis:
tm-alpha.h:64:#define mips_extra_func_info alpha_extra_func_info
and hard-wiring the reference to RA_REGNUM just wouldn't work.
I'd leave RA_REGNUM as is (or put the definition in tm-mips*.h so that
it is clear that it still needs to be fixed).
> ===================================================================
> RCS file: /cvs/src/src/gdb/mdebugread.c,v
> retrieving revision 1.44
> diff -u -p -r1.44 mdebugread.c
> --- mdebugread.c 19 Mar 2003 19:45:49 -0000 1.44
> +++ mdebugread.c 9 May 2003 23:36:32 -0000
> @@ -55,6 +55,9 @@
> #include "gdb_assert.h"
> #include "block.h"
>
> +#include "mips-tdep.h"
> +#define RA_REGNUM (mips_cooked_regnums (current_gdbarch)->ra_regnum)
> +
> /* These are needed if the tm.h file does not contain the necessary
> mips specific definitions. */
>
> @@ -69,9 +72,6 @@ typedef struct mips_extra_func_info
> PDR pdr;
> }
> *mips_extra_func_info_t;
> -#ifndef RA_REGNUM
> -#define RA_REGNUM 0
> -#endif
> #endif
>
> #ifdef USG
> Index: mips-tdep.h
Should there be separate raw and cooked num structures?
> +struct mips_regnums
> + {
> + int fp0_regnum; /* First floating point register. */
> + int fplast_regnum; /* Last floating point register. */
> + int last_arg_regnum; /* Last general purpose register used for
> + passing arguments. (a0_regnum is the
> + first.) */
> + int first_fp_arg_regnum; /* First floating point register used for
> + passing floating point arguments. */
> + int last_fp_arg_regnum; /* Last floating point register used for
> + passing floating point arguments. */
> + int zero_regnum; /* The zero register; read-only, always 0. */
> + int v0_regnum; /* Function return value. */
> + int a0_regnum; /* First GPR used for passing arguments. */
> + int t9_regnum; /* Contains address of callee in PIC code. */
> + int sp_regnum; /* Stack pointer. */
> + int ra_regnum; /* Return address. */
> + int ps_regnum; /* Processor status. */
> + int hi_regnum; /* High portion of internal multiply/divide
> + register. */
> + int lo_regnum; /* Low portion of internal multiply/divide
> + register. */
> + int badvaddr_regnum; /* Address associated with
> + addressing exception. */
> + int cause_regnum; /* Describes last exception. */
> + int pc_regnum; /* Program counter. */
> + int fcrcs_regnum; /* FP control/status. */
> + int fcrir_regnum; /* FP implementation/revision. */
> + int first_embed_regnum; /* First CP0 register for embedded use. */
> + int last_embed_regnum; /* Last CP0 register for embedded use. */
> + int prid_regnum; /* Processor ID. */
> + };
> +
> +const struct mips_regnums *mips_raw_regnums (struct gdbarch *gdbarch);
> +const struct mips_regnums *mips_cooked_regnums (struct gdbarch *gdbarch);
or at least keep things like "last_arg_regnum" out this space (they only
belong in one of the two spaces). Having them appear in both makes it
too easy to do the wrong thing.
Can I suggest for this code:
> mips_linux_cannot_fetch_register (int regno)
> {
> + const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
use a consistent nameing schema that makes the register's space clear vis:
rawnums = mips_raw_regnums (...);
...
if (regno == rawnums->ps_regnum)
it should be possible to apply separate patches that:
- add mips_raw_regnums() and their initialization
- roll out the mechanical change
s/BADVADDR_REGNUM/rawnums->badvaddr_regnum/
How do you know that the raw register numbers were computed correctly?
--
-#define REGISTER_PTRACE_ADDR(regno) \
+register_ptrace_addr (int regno)
is obvious (and separate also).
--
Make certain you use "mips-tdep.h" and not <mips-tdep.h>.
--
Delete the lsi33k support as Stan noted, it likely never worked
(separate also).
--
This should greatly reduce the diff to just the change adding the
cooked<->raw map, and code using it.
Andrew
^ permalink raw reply [flat|nested] 46+ messages in thread* Re: [WIP/RFC] MIPS registers overhaul
2003-05-10 20:30 ` Andrew Cagney
@ 2003-05-10 20:40 ` Daniel Jacobowitz
2003-05-14 22:00 ` Kevin Buettner
1 sibling, 0 replies; 46+ messages in thread
From: Daniel Jacobowitz @ 2003-05-10 20:40 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Kevin Buettner, gdb-patches
On Sat, May 10, 2003 at 04:29:37PM -0400, Andrew Cagney wrote:
> >Problem 1 was solved by introducing a union type for floating point
> >registers. When attempting to display a value using ``print'', you'll
> >see (with my patch) something like this:
> >
> > (gdb) p $f20
> > $1 = {i = 4621199872640208077, f = -107374184, d = 8.9000000000000004}
> >
> >(If someone can think of more meaningful, but still terse field names for
> >the above, please let me know.)
>
> I'd try to be consistent with the other register unions, uint64 for
> instance. As for the d/f, I don't know.
How about u64, flt, and dbl?
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 46+ messages in thread* Re: [WIP/RFC] MIPS registers overhaul
2003-05-10 20:30 ` Andrew Cagney
2003-05-10 20:40 ` Daniel Jacobowitz
@ 2003-05-14 22:00 ` Kevin Buettner
[not found] ` <mailpost.1052949911.28802@news-sj1-1>
` (2 more replies)
1 sibling, 3 replies; 46+ messages in thread
From: Kevin Buettner @ 2003-05-14 22:00 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
On May 10, 4:29pm, Andrew Cagney wrote:
> > Problem 1 was solved by introducing a union type for floating point
> > registers. When attempting to display a value using ``print'', you'll
> > see (with my patch) something like this:
> >
> > (gdb) p $f20
> > $1 = {i = 4621199872640208077, f = -107374184, d = 8.9000000000000004}
> >
> > (If someone can think of more meaningful, but still terse field names for
> > the above, please let me know.)
>
> I'd try to be consistent with the other register unions, uint64 for
> instance. As for the d/f, I don't know.
I like Daniel's suggestion for the names: u64, flt, and dbl. (flt and dbl
match the prefixes used by "info float".)
> > BTW, the raw floating point registers are still accessible. Doing
> > "info registers raw" will display all of the raw registers. Or, if
> > you know the names of the registers you want to display, you can do,
> > e.g, "info registers raw_f20".
>
> Hmm, is this necessary? Confusing? ``maint print
> {raw-,cooked-,}registers'' are already available and provide access to
> the underlying values.
Maybe we need to name the prefix something different than "raw_"?
Whatever we call them, I think it's still useful to have names
associated with them. E.g, you can do any of the following:
print $raw_f20
print/x ($raw_f20 >> 32)
set $raw_f20=0xbadbeef
Most of the time, you'll just want to deal with $f20 though. If you
suspect that something funny is going on with GDB's raw->cooked
translation, being able to more directly manipulate the raw values
could prove to be useful.
Also, due to the fact that most of the code in mips-tdep.c still uses
raw register numbers, you'll see the raw names showing up in "info
frame". E.g.:
(gdb) info frame
...
Saved registers:
gp at 0x7fff7d04, s8 at 0x7fff7d08, ra at 0x7fff7d0c, pc at 0x7fff7d0c,
raw_f20 at 0x7fff7d10, raw_f21 at 0x7fff7d14, f20 at 0x7fff7d10
^^^^^^
In the fullness of time, i.e, when the MIPS code is finally converted
to use cooked registers everywhere that it *should*, the above
references to the "raw" register names can probably go away.
> ``info registers'' should always display the target's underlying
> register set. In the case of o32 running on a 64 bit ISA, the 64 bit
> registers should be displayed.
Well, in this case the underlying register set really is only 32-bits
wide. Volume 1 of the MIPS64 Architecture (revision 1.00, dated
August 29, 2002) says:
For compatibility with MIPS32 processors, the FR bit in the CP0
Status register is used by a MIPS64 processor to configure the FPU
in a mode in which the FPRs are treated as 32 32-bit registers,
each of which is capable of storing only 32-bit data types. In
this mode, the double-precision floating point (type D) data type
is stored in even-odd pairs of FPRs, and the long-integer (type L)
and paired single (type PS) data types are not supported.
Figure 2-8 in this manual shows that bits 32-63 (i.e, the high 32 bits)
are "UNPREDICTABLE" in this mode.
We still *could* show these extra bits, but displaying the register in
this way would, most of the time, be next to useless. If the GDB user
really wants to see what the higher order bits are, then the raw_fN
names are useful.
[...]
> > Index: mdebugread.c
>
> The below isn't right.
>
> RA_REGNUM is defined by both Alpha and MIPS. There are a number of long
> standing problems with mdebug read vis:
> tm-alpha.h:64:#define mips_extra_func_info alpha_extra_func_info
> and hard-wiring the reference to RA_REGNUM just wouldn't work.
>
> I'd leave RA_REGNUM as is (or put the definition in tm-mips*.h so that
> it is clear that it still needs to be fixed).
I'll put RA_REGNUM back into mips-tdep.h along with a comment which
indicates that it should only used by mdebugread.c.
> > Index: mips-tdep.h
>
> Should there be separate raw and cooked num structures?
>
> > +struct mips_regnums
> > + {
> > + int fp0_regnum; /* First floating point register. */
> > + int fplast_regnum; /* Last floating point register. */
> > + int last_arg_regnum; /* Last general purpose register used for
> > + passing arguments. (a0_regnum is the
> > + first.) */
> > + int first_fp_arg_regnum; /* First floating point register used for
> > + passing floating point arguments. */
> > + int last_fp_arg_regnum; /* Last floating point register used for
> > + passing floating point arguments. */
> > + int zero_regnum; /* The zero register; read-only, always 0. */
> > + int v0_regnum; /* Function return value. */
> > + int a0_regnum; /* First GPR used for passing arguments. */
> > + int t9_regnum; /* Contains address of callee in PIC code. */
> > + int sp_regnum; /* Stack pointer. */
> > + int ra_regnum; /* Return address. */
> > + int ps_regnum; /* Processor status. */
> > + int hi_regnum; /* High portion of internal multiply/divide
> > + register. */
> > + int lo_regnum; /* Low portion of internal multiply/divide
> > + register. */
> > + int badvaddr_regnum; /* Address associated with
> > + addressing exception. */
> > + int cause_regnum; /* Describes last exception. */
> > + int pc_regnum; /* Program counter. */
> > + int fcrcs_regnum; /* FP control/status. */
> > + int fcrir_regnum; /* FP implementation/revision. */
> > + int first_embed_regnum; /* First CP0 register for embedded use. */
> > + int last_embed_regnum; /* Last CP0 register for embedded use. */
> > + int prid_regnum; /* Processor ID. */
> > + };
> > +
> > +const struct mips_regnums *mips_raw_regnums (struct gdbarch *gdbarch);
> > +const struct mips_regnums *mips_cooked_regnums (struct gdbarch *gdbarch);
>
> or at least keep things like "last_arg_regnum" out this space (they only
> belong in one of the two spaces). Having them appear in both makes it
> too easy to do the wrong thing.
Actually, I think it's useful for the layout raw and cooked regnum
structs to be identical. When initializing the cooked regnum struct,
we can do so via a single assignment:
/* For many registers, the cooked and raw register numbers are the same. */
tdep->cooked_regnums = tdep->raw_regnums;
/* Cooked regnum initializations that differ follow... */
The fact that the structs were identical made it easy and elegant to
define the reg_name() function which is used twice by mips_register_name(),
once for cooked register numbers, and a second time (assuming no suitable
cooked name was found) for the raw numbers. If the layout of the cooked
and raw structs were different, I'd need two separate functions with nearly
identical functionality. Ditto for mips_dump_regnums().
I think that you definitely want "last_arg_regnum" and
"last_fp_arg_regnum" to appear in both structs. At the moment, the
various MIPS *_push_argument() code uses the register names from the
raw regnums struct. I think it may be desirable at some point to make
this code use cooked regnums instead. (It will hopefully simplify a
bunch of code that worries about shifting values to the correct
position within a register.) For the floating point registers, where
the cooked and raw numbers are actually different, we would like
"first_fp_arg_regnum" and "last_fp_arg_regnum" to actually refer to
numbers within this space.
I think it's likely that when/if this conversion occurs, it'll be done
on an incremental basis. We want separate cooked/raw numbers so that
it can be done incrementally.
Also, putting these values in the regnum struct makes it clear exactly
which set they belong to.
> Can I suggest for this code:
>
> > mips_linux_cannot_fetch_register (int regno)
> > {
> > + const struct mips_regnums *regnums = mips_raw_regnums (current_gdbarch);
>
> use a consistent nameing schema that makes the register's space clear vis:
>
> rawnums = mips_raw_regnums (...);
> ...
> if (regno == rawnums->ps_regnum)
I'll adopt the following naming scheme:
rawnums - for code which uses and should continue to use raw numbers
cookednums - for code which uses and should continue to use cooked
numbers
regnums - for one of two cases, either code that's currently using
raw numbers that should be converted to be cooked, or
for code which I'm unsure of. (Either case, these'll
be raw numbers. When someone converts the code or decides
that the "raw" usage is correct, the name should be
changed.)
For the last category, I'm open to suggestions for some other name.
> it should be possible to apply separate patches that:
>
> - add mips_raw_regnums() and their initialization
> - roll out the mechanical change
> s/BADVADDR_REGNUM/rawnums->badvaddr_regnum/
Okay.
> How do you know that the raw register numbers were computed correctly?
I just used the same values as the macros used to use. The user can see
what they are via "maint print architecture".
(Maybe I don't understand your question.)
> -#define REGISTER_PTRACE_ADDR(regno) \
> +register_ptrace_addr (int regno)
>
> is obvious (and separate also).
Okay.
> Make certain you use "mips-tdep.h" and not <mips-tdep.h>.
Right. There was only one place that this happened. Not sure why.
It's been fixed in my sources.
> Delete the lsi33k support as Stan noted, it likely never worked
> (separate also).
I don't think that this is exactly what Stan noted, but okay.
> This should greatly reduce the diff to just the change adding the
> cooked<->raw map, and code using it.
Okay.
Kevin
^ permalink raw reply [flat|nested] 46+ messages in thread[parent not found: <mailpost.1052949911.28802@news-sj1-1>]
* Re: [WIP/RFC] MIPS registers overhaul
[not found] ` <mailpost.1052949911.28802@news-sj1-1>
@ 2003-05-14 23:35 ` cgd
2003-05-15 0:07 ` Kevin Buettner
0 siblings, 1 reply; 46+ messages in thread
From: cgd @ 2003-05-14 23:35 UTC (permalink / raw)
To: kevinb; +Cc: Andrew Cagney, gdb-patches
At Wed, 14 May 2003 22:05:11 +0000 (UTC), "Kevin Buettner" wrote:
> > ``info registers'' should always display the target's underlying
> > register set. In the case of o32 running on a 64 bit ISA, the 64 bit
> > registers should be displayed.
>
> Well, in this case the underlying register set really is only 32-bits
> wide. Volume 1 of the MIPS64 Architecture (revision 1.00, dated
> August 29, 2002) says:
>
> For compatibility with MIPS32 processors, the FR bit in the CP0
> Status register is used by a MIPS64 processor to configure the FPU
> in a mode in which the FPRs are treated as 32 32-bit registers,
> each of which is capable of storing only 32-bit data types. In
> this mode, the double-precision floating point (type D) data type
> is stored in even-odd pairs of FPRs, and the long-integer (type L)
> and paired single (type PS) data types are not supported.
>
> Figure 2-8 in this manual shows that bits 32-63 (i.e, the high 32 bits)
> are "UNPREDICTABLE" in this mode.
Indeed.
> We still *could* show these extra bits, but displaying the register in
> this way would, most of the time, be next to useless. If the GDB user
> really wants to see what the higher order bits are, then the raw_fN
> names are useful.
One possible thing to do is display the upper 32 bits *if* you know
that Status:FR is set to 1. The Status:FR value is really the thing
that determines how the bits are interpreted.
Now, if o32, Status:FR *should* be 0.
However, I don't know if for old binaries being debugged o64 will be
detected properly (or, heck, even for new binaries 8-), and I also
know people who've done Really Special Things with o32 and soft float
and using library calls for all FP and using 64-bit floating point.
8-)
In other words, the real arbiter of the unpredictability of those bits
is Status:FR, so you should probably display them consistently with
what it says (if you have Status... I forget 8-).
I don't know enough about the remote protocol to know what one would
expect from a 64-bit debug agent debugging a 32-bit program (on a
64-bit target). But i could imagine it could become ugly very
quickly... 8-)
cgd
^ permalink raw reply [flat|nested] 46+ messages in thread* Re: [WIP/RFC] MIPS registers overhaul
2003-05-14 23:35 ` cgd
@ 2003-05-15 0:07 ` Kevin Buettner
2003-05-15 0:15 ` Daniel Jacobowitz
0 siblings, 1 reply; 46+ messages in thread
From: Kevin Buettner @ 2003-05-15 0:07 UTC (permalink / raw)
To: cgd, kevinb; +Cc: Andrew Cagney, gdb-patches
On May 14, 4:34pm, cgd@broadcom.com wrote:
> In other words, the real arbiter of the unpredictability of those bits
> is Status:FR, so you should probably display them consistently with
> what it says (if you have Status... I forget 8-).
I see the following in mips2_fp_compat():
#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
I don't know the details, but it appears that there may be problems
with consistently being able to fetch the status register. (Maybe
it's not available on all MIPS targets that GDB supports?)
Anyone know?
Kevin
^ permalink raw reply [flat|nested] 46+ messages in thread* Re: [WIP/RFC] MIPS registers overhaul
2003-05-15 0:07 ` Kevin Buettner
@ 2003-05-15 0:15 ` Daniel Jacobowitz
0 siblings, 0 replies; 46+ messages in thread
From: Daniel Jacobowitz @ 2003-05-15 0:15 UTC (permalink / raw)
To: Kevin Buettner; +Cc: cgd, Andrew Cagney, gdb-patches
On Wed, May 14, 2003 at 05:07:16PM -0700, Kevin Buettner wrote:
> On May 14, 4:34pm, cgd@broadcom.com wrote:
>
> > In other words, the real arbiter of the unpredictability of those bits
> > is Status:FR, so you should probably display them consistently with
> > what it says (if you have Status... I forget 8-).
>
> I see the following in mips2_fp_compat():
>
> #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
>
> I don't know the details, but it appears that there may be problems
> with consistently being able to fetch the status register. (Maybe
> it's not available on all MIPS targets that GDB supports?)
>
> Anyone know?
Hmm, I vaguely remember writing that. I don't think that's what I
meant by consistent - I just meant that we needed to use that function
everywhere appropriate. I believe Status is always available, so we
could use it to choose which FP registers are exposed.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [WIP/RFC] MIPS registers overhaul
2003-05-14 22:00 ` Kevin Buettner
[not found] ` <mailpost.1052949911.28802@news-sj1-1>
@ 2003-05-15 22:01 ` Kevin Buettner
2003-05-16 3:24 ` Andrew Cagney
2003-05-16 4:00 ` Andrew Cagney
2 siblings, 1 reply; 46+ messages in thread
From: Kevin Buettner @ 2003-05-15 22:01 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
On May 14, 3:00pm, Kevin Buettner wrote:
> I'll adopt the following naming scheme:
>
> rawnums - for code which uses and should continue to use raw numbers
> cookednums - for code which uses and should continue to use cooked
> numbers
> regnums - for one of two cases, either code that's currently using
> raw numbers that should be converted to be cooked, or
> for code which I'm unsure of. (Either case, these'll
> be raw numbers. When someone converts the code or decides
> that the "raw" usage is correct, the name should be
> changed.)
>
> For the last category, I'm open to suggestions for some other name.
I've decided I don't like the name "regnums" that well for the last
category. I've settled on the name "rawnums_c" instead. The "_c"
suffix indicates that they *should* be cooked. (Yes, it's terse, but I
fear that anything longer will make the code unwieldy.) I'll also put
in a comment at each ``rawnums_c'' initialization indicating that the
code needs to be converted at some point to use cooked register
numbers. E.g.:
/* This function needs to be converted to use cooked register numbers. */
const struct mips_regnums *rawnums_c = mips_raw_regnums (gdbarch);
Kevin
^ permalink raw reply [flat|nested] 46+ messages in thread* Re: [WIP/RFC] MIPS registers overhaul
2003-05-15 22:01 ` Kevin Buettner
@ 2003-05-16 3:24 ` Andrew Cagney
0 siblings, 0 replies; 46+ messages in thread
From: Andrew Cagney @ 2003-05-16 3:24 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
> On May 14, 3:00pm, Kevin Buettner wrote:
>
>
>> I'll adopt the following naming scheme:
>>
>> rawnums - for code which uses and should continue to use raw numbers
>> cookednums - for code which uses and should continue to use cooked
>> numbers
>> regnums - for one of two cases, either code that's currently using
>> raw numbers that should be converted to be cooked, or
>> for code which I'm unsure of. (Either case, these'll
>> be raw numbers. When someone converts the code or decides
>> that the "raw" usage is correct, the name should be
>> changed.)
>>
>> For the last category, I'm open to suggestions for some other name.
>
>
> I've decided I don't like the name "regnums" that well for the last
> category. I've settled on the name "rawnums_c" instead. The "_c"
> suffix indicates that they *should* be cooked. (Yes, it's terse, but I
> fear that anything longer will make the code unwieldy.) I'll also put
> in a comment at each ``rawnums_c'' initialization indicating that the
> code needs to be converted at some point to use cooked register
> numbers. E.g.:
>
> /* This function needs to be converted to use cooked register numbers. */
> const struct mips_regnums *rawnums_c = mips_raw_regnums (gdbarch);
I think this is "_c" convention is getting overly complicated. Just use
"rawnums" and "cookednums" and then leave the rest to comments.
Andrew
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [WIP/RFC] MIPS registers overhaul
2003-05-14 22:00 ` Kevin Buettner
[not found] ` <mailpost.1052949911.28802@news-sj1-1>
2003-05-15 22:01 ` Kevin Buettner
@ 2003-05-16 4:00 ` Andrew Cagney
2003-05-16 17:20 ` Kevin Buettner
[not found] ` <mailpost.1053057614.17325@news-sj1-1>
2 siblings, 2 replies; 46+ messages in thread
From: Andrew Cagney @ 2003-05-16 4:00 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
> On May 10, 4:29pm, Andrew Cagney wrote:
>
>
>> > Problem 1 was solved by introducing a union type for floating point
>> > registers. When attempting to display a value using ``print'', you'll
>> > see (with my patch) something like this:
>> >
>> > (gdb) p $f20
>> > $1 = {i = 4621199872640208077, f = -107374184, d = 8.9000000000000004}
>> >
>> > (If someone can think of more meaningful, but still terse field names for
>> > the above, please let me know.)
>
>>
>> I'd try to be consistent with the other register unions, uint64 for
>> instance. As for the d/f, I don't know.
>
>
> I like Daniel's suggestion for the names: u64, flt, and dbl. (flt and dbl
> match the prefixes used by "info float".)
"flt" and "dbl" look ok, an alternative would be ieee754_{32,64} - ulgh.
"uint64", unlike "u64" is consistent with the existing convention.
>> > BTW, the raw floating point registers are still accessible. Doing
>> > "info registers raw" will display all of the raw registers. Or, if
>> > you know the names of the registers you want to display, you can do,
>> > e.g, "info registers raw_f20".
>
>>
>> Hmm, is this necessary? Confusing? ``maint print
>> {raw-,cooked-,}registers'' are already available and provide access to
>> the underlying values.
>
>
> Maybe we need to name the prefix something different than "raw_"?
>
> Whatever we call them, I think it's still useful to have names
> associated with them. E.g, you can do any of the following:
>
> print $raw_f20
> print/x ($raw_f20 >> 32)
> set $raw_f20=0xbadbeef
But how often will that actually happen?
I think a user debugging o32 on ISA64 still should expect to be
manipulating the full 64 bit register. Only on ISA32 should the
registers be restricted to their 32 bit values.
Even if the upper 32 bits of the FP registers are unpredictable, I think
they should still be displayed.
>> Should there be separate raw and cooked num structures?
>>
>
>> > +struct mips_regnums
>> > + {
>> > + int fp0_regnum; /* First floating point register. */
>> > + int fplast_regnum; /* Last floating point register. */
>> > + int last_arg_regnum; /* Last general purpose register used for
>> > + passing arguments. (a0_regnum is the
>> > + first.) */
>> > + int first_fp_arg_regnum; /* First floating point register used for
>> > + passing floating point arguments. */
>> > + int last_fp_arg_regnum; /* Last floating point register used for
>> > + passing floating point arguments. */
>> > + int zero_regnum; /* The zero register; read-only, always 0. */
>> > + int v0_regnum; /* Function return value. */
>> > + int a0_regnum; /* First GPR used for passing arguments. */
>> > + int t9_regnum; /* Contains address of callee in PIC code. */
>> > + int sp_regnum; /* Stack pointer. */
>> > + int ra_regnum; /* Return address. */
>> > + int ps_regnum; /* Processor status. */
>> > + int hi_regnum; /* High portion of internal multiply/divide
>> > + register. */
>> > + int lo_regnum; /* Low portion of internal multiply/divide
>> > + register. */
>> > + int badvaddr_regnum; /* Address associated with
>> > + addressing exception. */
>> > + int cause_regnum; /* Describes last exception. */
>> > + int pc_regnum; /* Program counter. */
>> > + int fcrcs_regnum; /* FP control/status. */
>> > + int fcrir_regnum; /* FP implementation/revision. */
>> > + int first_embed_regnum; /* First CP0 register for embedded use. */
>> > + int last_embed_regnum; /* Last CP0 register for embedded use. */
>> > + int prid_regnum; /* Processor ID. */
>> > + };
>> > +
>> > +const struct mips_regnums *mips_raw_regnums (struct gdbarch *gdbarch);
>> > +const struct mips_regnums *mips_cooked_regnums (struct gdbarch *gdbarch);
>
>>
>> or at least keep things like "last_arg_regnum" out this space (they only
>> belong in one of the two spaces). Having them appear in both makes it
>> too easy to do the wrong thing.
>
>
> Actually, I think it's useful for the layout raw and cooked regnum
> structs to be identical. When initializing the cooked regnum struct,
> we can do so via a single assignment:
>
> /* For many registers, the cooked and raw register numbers are the same. */
> tdep->cooked_regnums = tdep->raw_regnums;
>
> /* Cooked regnum initializations that differ follow... */
>
> The fact that the structs were identical made it easy and elegant to
> define the reg_name() function which is used twice by mips_register_name(),
> once for cooked register numbers, and a second time (assuming no suitable
> cooked name was found) for the raw numbers. If the layout of the cooked
> and raw structs were different, I'd need two separate functions with nearly
> identical functionality. Ditto for mips_dump_regnums().
>
> I think that you definitely want "last_arg_regnum" and
> "last_fp_arg_regnum" to appear in both structs. At the moment, the
> various MIPS *_push_argument() code uses the register names from the
> raw regnums struct. I think it may be desirable at some point to make
> this code use cooked regnums instead. (It will hopefully simplify a
> bunch of code that worries about shifting values to the correct
> position within a register.) For the floating point registers, where
> the cooked and raw numbers are actually different, we would like
> "first_fp_arg_regnum" and "last_fp_arg_regnum" to actually refer to
> numbers within this space.
The only code that should manipulate the raw register values
(regcache_raw_*) is:
- the cooked <-> raw mapping functions
- the target side code that supplies register values
The rest should use cooked values. Hence, I think the variables like
last_arg_regnum has a strictly cooked value (note that a cooked register
number can fall in the range [0 .. NUM_REGS).
>> How do you know that the raw register numbers were computed correctly?
>
>
> I just used the same values as the macros used to use. The user can see
> what they are via "maint print architecture".
I'm wondering how you know that the transformation from macro (defined
in .h files?) to variables worked?
Andrew
^ permalink raw reply [flat|nested] 46+ messages in thread* Re: [WIP/RFC] MIPS registers overhaul
2003-05-16 4:00 ` Andrew Cagney
@ 2003-05-16 17:20 ` Kevin Buettner
[not found] ` <mailpost.1053057614.17325@news-sj1-1>
1 sibling, 0 replies; 46+ messages in thread
From: Kevin Buettner @ 2003-05-16 17:20 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
On May 15, 11:57pm, Andrew Cagney wrote:
> >> > BTW, the raw floating point registers are still accessible. Doing
> >> > "info registers raw" will display all of the raw registers. Or, if
> >> > you know the names of the registers you want to display, you can do,
> >> > e.g, "info registers raw_f20".
> >
> >>
> >> Hmm, is this necessary? Confusing? ``maint print
> >> {raw-,cooked-,}registers'' are already available and provide access to
> >> the underlying values.
> >
> >
> > Maybe we need to name the prefix something different than "raw_"?
> >
> > Whatever we call them, I think it's still useful to have names
> > associated with them. E.g, you can do any of the following:
> >
> > print $raw_f20
> > print/x ($raw_f20 >> 32)
> > set $raw_f20=0xbadbeef
>
> But how often will that actually happen?
Personally, I don't think that it'll happen that often. If, however,
the 32 unpredictable bits of a floating point register (for o32) are
meaningful, it may be useful to be able to manipulate the raw register
in various ways.
> I think a user debugging o32 on ISA64 still should expect to be
> manipulating the full 64 bit register.
I disagree. When debugging o32, the FR bit in the CP0 status register
should be 0 and, according to the MIPS64 documentation, the FPRs are
treated as 32 32-bit registers.
> Only on ISA32 should the
> registers be restricted to their 32 bit values.
>
> Even if the upper 32 bits of the FP registers are unpredictable, I think
> they should still be displayed.
With my WIP patch, for o32 single precision code, you'll something like
this:
(gdb) p $f20
$2 = {i = 18446744070510660813, f = 13.3000002, d = -nan(0xfffff4154cccd)}
For double precision code, you'll instead see:
(gdb) p $f20
$3 = {i = 4623676852435261850, f = -1.58818684e-23, d = 13.300000000000001}
where the 13.3 value in both cases is the value of interest.
If I were to do as you suggest and display the full 64 bits of the raw
f20, you'd never be able to see that interesting 13.3 value for the
double case. (This is because the bits which form the double are
split between raw f20 and raw f21.) The user should expect to see
values which make sense for the mode of the processor. As I said
before, if the user suspects that something else is going on, they
still have recourse to $raw_f20 and $raw_f21 for looking at the full
64-bit register. E.g.:
(gdb) p/x $raw_f20
$5 = 0xffffffff9999999a
(gdb) p/x $raw_f21
$6 = 0x402a9999
And, for reference:
(gdb) p/x $f20.i
$7 = 0x402a99999999999a
If you really think that the $f20 name should be the full 64-bit register
regardless of the fact that 32-bits are meaningless, then lets just take
the "raw_" prefix off of them and put a prefix on the cooked names. Maybe
we should call them "cooked_f20" or "pretty_f20" or some such.
I do agree that we want to provide the user with the ability to look
at the full 64-bit value, but I think it's also important that the
user be able to see values that make the most sense for the mode that
the processor is in. My WIP patch provides you with the ability to
see both. It sounds like you may have an objection to the names that
I've chosen. If that's the case, then I'm willing to discard the
"raw_" prefix on the raw floating point registers and put a different
prefix on the cooked fp registers.
[...]
> > I think that you definitely want "last_arg_regnum" and
> > "last_fp_arg_regnum" to appear in both structs. At the moment, the
> > various MIPS *_push_argument() code uses the register names from the
> > raw regnums struct. I think it may be desirable at some point to make
> > this code use cooked regnums instead. (It will hopefully simplify a
> > bunch of code that worries about shifting values to the correct
> > position within a register.) For the floating point registers, where
> > the cooked and raw numbers are actually different, we would like
> > "first_fp_arg_regnum" and "last_fp_arg_regnum" to actually refer to
> > numbers within this space.
>
> The only code that should manipulate the raw register values
> (regcache_raw_*) is:
> - the cooked <-> raw mapping functions
> - the target side code that supplies register values
> The rest should use cooked values. Hence, I think the variables like
> last_arg_regnum has a strictly cooked value (note that a cooked register
> number can fall in the range [0 .. NUM_REGS).
Well, ideally, yes. But, I think it's going to be a while before we
get there. As a specific example, consider the various MIPS
push_arguments code. At the present time, this code is written to use
raw numbers and will need to be converted at some point to use cooked
numbers. For last_fp_arg_regnum, the raw and cooked numbers will
differ, and, I expect that the various push_arguments functions will
be converted incrementally, so it is important that this field appear
in both structs. (I should note that I have this detail wrong in my
WIP patch. I forgot to set the cooked value for last_fp_arg_regnum.
That means that the cooked value is the same as the raw value which is
wrong.)
I will also note that since last_fp_arg_regnum is _only_ used by the
push_arguments code, it would be possible to seperate this value out,
BUT, it will be necessary for the code which initializes
last_fp_arg_regnum to keep track of whether or not the appropriate
push_arguments function has been converted or not. mips_gdbarch_init()
will need to be rearranged somewhat in order for this to occur.
> >> How do you know that the raw register numbers were computed correctly?
> >
> >
> > I just used the same values as the macros used to use. The user can see
> > what they are via "maint print architecture".
>
> I'm wondering how you know that the transformation from macro (defined
> in .h files?) to variables worked?
By inspection and by testing.
Kevin
^ permalink raw reply [flat|nested] 46+ messages in thread[parent not found: <mailpost.1053057614.17325@news-sj1-1>]
* Re: [WIP/RFC] MIPS registers overhaul
[not found] ` <mailpost.1053057614.17325@news-sj1-1>
@ 2003-05-16 22:25 ` cgd
[not found] ` <mailpost.1053123913.16634@news-sj1-1>
0 siblings, 1 reply; 46+ messages in thread
From: cgd @ 2003-05-16 22:25 UTC (permalink / raw)
To: ac131313; +Cc: Kevin Buettner, gdb-patches
At Fri, 16 May 2003 04:00:14 +0000 (UTC), "Andrew Cagney" wrote:
> > Whatever we call them, I think it's still useful to have names
> > associated with them. E.g, you can do any of the following:
> >
> > print $raw_f20
> > print/x ($raw_f20 >> 32)
> > set $raw_f20=0xbadbeef
>
> But how often will that actually happen?
>
> I think a user debugging o32 on ISA64 still should expect to be
> manipulating the full 64 bit register. Only on ISA32 should the
> registers be restricted to their 32 bit values.
>
> Even if the upper 32 bits of the FP registers are unpredictable, I think
> they should still be displayed.
I assume you're talking about manipulating the full 64-bits *only* for
the raw values. I think there may be issues there, when FR == 0.
When FR == 0, reading and writing doubles from the odd registers in
unpredictable, and reading/writing doubles from the even registers **
must ** include the odd-register value.
So, for instance, when FR = 0, if you read 64 bits of $f12, you'll
get:
$f12: 0xaaaaaaaabbbbbbbb
That's guarateed.
if you read a single from $f12, you'll get 0xbbbbbbbb, a single from
$f13 you'll get 0xaaaaaaaa. Likewise, guaranteed.
but if you read a double from $f13, who *knows* what you're going to
get. You might get:
$f13: 0x????????aaaaaaaa
but who really knows, and who knows what the ???????? is.
(I think i got my word ordering right in that description. 8-)
When FR==0, there are only two valid ways to read the registers:
* for i = 0; i < 32; i++
<read 32-bits from $i>
* for i = 0; i < 32; i += 2
<read 64-bits from $i>
This MIPS specifications (M64 1.00 Volume I, page 50, section 5.6.2)
indicate that doing 64-bit reads/writes from/to odd FP registers when
FR=0 are "illegal", and that values produced by such operations are
unpredictable.
In other words, if a 64-bit target stub code really is supplying 64
bits of register data when accessing FP registers when FR == 0, then
it's broken.
(If it's attempting to write the odd 64-bit register values back, then
it's *really* broken.)
Heck, if 64-bit target code is even trying to communicate (64 * 8)
bits back when FR == 0, then it's almost certainly broken. (every
other reigster will be completely unpredictable, and who knows what'll
happen if it tries to write them back if they're changed.)
As an aside, it would probably be good if, when setting a fp register,
e.g.:
set $f12 = <value>
you were *required* to use one of the union members.
it's kinda weird (uh, quite confusing 8-) to see something like:
(gdb) info args
a = -nan(0x7fffff)
b = 2.20000005
c = 3.29999995
d = -4.4000001
(gdb) info addr b
Symbol "b" is an argument in register f13.
(gdb) set $f13 = 3.3
(gdb) info args
a = -nan(0x7fffff)
b = 2.72008302e+23
c = 3.29999995
d = -4.4000001
i.e., blind conversion (because "set $f13 = <value>" assumed
incorrectly that you meant "oh, as double") is bad.
(If you're in the situation where you're setting an even register to a
single value, if the n+1 odd reigster also a single value you also
want to do computation on, setting the even as a double could be even
worse...)
cgd
^ permalink raw reply [flat|nested] 46+ messages in thread
end of thread, other threads:[~2003-06-17 16:27 UTC | newest]
Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-05-10 0:25 [WIP/RFC] MIPS registers overhaul Kevin Buettner
2003-05-10 20:30 ` Andrew Cagney
2003-05-10 20:40 ` Daniel Jacobowitz
2003-05-14 22:00 ` Kevin Buettner
[not found] ` <mailpost.1052949911.28802@news-sj1-1>
2003-05-14 23:35 ` cgd
2003-05-15 0:07 ` Kevin Buettner
2003-05-15 0:15 ` Daniel Jacobowitz
2003-05-15 22:01 ` Kevin Buettner
2003-05-16 3:24 ` Andrew Cagney
2003-05-16 4:00 ` Andrew Cagney
2003-05-16 17:20 ` Kevin Buettner
[not found] ` <mailpost.1053057614.17325@news-sj1-1>
2003-05-16 22:25 ` cgd
[not found] ` <mailpost.1053123913.16634@news-sj1-1>
2003-05-16 22:50 ` cgd
2003-05-16 23:05 ` Kevin Buettner
[not found] ` <mailpost.1053126410.17856@news-sj1-1>
2003-05-16 23:24 ` cgd
2003-05-17 0:41 ` Kevin Buettner
2003-05-17 20:59 ` Daniel Jacobowitz
2003-05-20 20:18 ` Always remote: " Andrew Cagney
2003-05-20 20:26 ` Daniel Jacobowitz
[not found] ` <mailpost.1053132070.20348@news-sj1-1>
2003-05-20 20:37 ` cgd
2003-05-20 20:51 ` Kevin Buettner
2003-05-20 20:52 ` Andrew Cagney
2003-05-20 21:57 ` cgd
2003-05-21 15:34 ` Andrew Cagney
2003-05-21 15:41 ` Daniel Jacobowitz
2003-05-21 16:38 ` Andrew Cagney
2003-05-21 16:58 ` Daniel Jacobowitz
2003-05-21 18:32 ` Kevin Buettner
2003-05-21 19:15 ` Andrew Cagney
2003-05-21 19:45 ` Kevin Buettner
2003-05-22 0:32 ` Daniel Jacobowitz
2003-05-23 18:39 ` Andrew Cagney
2003-05-23 19:02 ` Daniel Jacobowitz
2003-05-23 20:45 ` Andrew Cagney
2003-05-20 20:25 ` Andrew Cagney
2003-05-20 20:32 ` cgd
2003-05-21 15:40 ` Andrew Cagney
2003-06-15 1:44 ` Andrew Cagney
2003-06-16 18:06 ` cgd
2003-06-16 18:47 ` Andrew Cagney
2003-06-15 17:23 ` Andrew Cagney
2003-06-16 20:06 ` cgd
2003-06-16 20:41 ` Andrew Cagney
[not found] ` <mailpost.1055796186.4097@news-sj1-1>
2003-06-17 5:04 ` cgd
2003-06-17 14:27 ` Andrew Cagney
[not found] ` <mailpost.1055860052.3406@news-sj1-1>
2003-06-17 16:27 ` cgd
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox