2003-06-15 Andrew Cagney * mips-tdep.c: Include "reggroups.h". (mips_register_name): Map NUM_REGS..2*NUM_REGS onto 0..NUM_REGS. (mips_register_reggroup_p): New function. (mips_pseudo_register_write): New function. (mips_pseudo_register_read): New function. (mips_register_raw_size): For NUM_REGS..2*NUM_REGS return the size based on the registers type. (mips_register_byte): New function. Use MIPS_REGISTER_BYTE. (mips_register_type): Replace mips_register_virtual_type. Map NUM_REGS..2*NUM_REGS onto 0..NUM_REGS. Use MIPS_REGISTER_TYPE when available. (set_reg_offset): Also save the offset in NUM_REGS..2*NUM_REGS. (mips_print_register): Use gdbarch_register_type instead of REGISTER_VIRTUAL_TYPE. (print_gp_register_row, mips_print_registers_info): Ditto. (mips_stab_reg_to_regnum): Map onto NUM_REGS..2*NUM_REGS. (mips_dwarf_dwarf2_ecoff_reg_to_regnum): Ditto. (mips_gdbarch_init): Set deprecated_register_byte, register_group_p, pseudo_register_write, pseudo_register_read, and num_pseudo_regs. Set register_type, instead of register_virtual_type. * Makefile.in (mips-tdep.o): Update dependencies. * config/mips/tm-mips64.h (MIPS_REGISTER_TYPE): Rename REGISTER_VIRTUAL_TYPE. * config/mips/tm-mips.h (MIPS_REGISTER_TYPE): Ditto. * config/mips/tm-irix5.h (MIPS_REGISTER_TYPE): Ditto. * config/mips/tm-mips.h (MIPS_REGISTER_BYTE): Rename REGISTER_BYTE. * config/mips/tm-irix6.h (MIPS_REGISTER_BYTE): Ditto. * config/mips/tm-irix5.h (MIPS_REGISTER_BYTE): Ditto. Index: Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/Makefile.in,v retrieving revision 1.406 diff -u -r1.406 Makefile.in --- Makefile.in 15 Jun 2003 00:27:54 -0000 1.406 +++ Makefile.in 16 Jun 2003 15:21:50 -0000 @@ -1999,8 +1999,8 @@ $(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) + $(osabi_h) $(mips_tdep_h) $(block_h) $(reggroups_h) \ + $(opcode_mips_h) $(elf_mips_h) $(elf_bfd_h) $(symcat_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: mips-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/mips-tdep.c,v retrieving revision 1.216 diff -u -r1.216 mips-tdep.c --- mips-tdep.c 15 Jun 2003 00:27:54 -0000 1.216 +++ mips-tdep.c 16 Jun 2003 15:21:51 -0000 @@ -42,7 +42,7 @@ #include "osabi.h" #include "mips-tdep.h" #include "block.h" - +#include "reggroups.h" #include "opcode/mips.h" #include "elf/mips.h" #include "elf-bfd.h" @@ -440,21 +440,25 @@ enum mips_abi abi = mips_abi (current_gdbarch); + /* For moment, map [NUM_REGS .. 2*NUM_REGS) onto the same raw + registers. Even return the same name. */ + int rawnum = regno % NUM_REGS; + /* 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) + if (0 <= rawnum && rawnum < 32) { if (abi == MIPS_ABI_N32 || abi == MIPS_ABI_N64) - return mips_n32_n64_gpr_names[regno]; + return mips_n32_n64_gpr_names[rawnum]; else - return mips_gpr_names[regno]; + return mips_gpr_names[rawnum]; } - else if (32 <= regno && regno < NUM_REGS) - return mips_processor_reg_names[regno - 32]; + else if (32 <= rawnum && rawnum < NUM_REGS) + return mips_processor_reg_names[rawnum - 32]; else internal_error (__FILE__, __LINE__, - "mips_register_name: bad register number %d", regno); + "mips_register_name: bad register number %d", rawnum); } /* *INDENT-OFF* */ @@ -524,8 +528,66 @@ }; /* *INDENT-ON* */ +/* Return the groups that a MIPS register can be categorised into. */ +static int +mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *reggroup) +{ + int vector_p; + int float_p; + int raw_p; + int rawnum = regnum % NUM_REGS; + int pseudo = regnum / NUM_REGS; + if (reggroup == all_reggroup) + return pseudo; + vector_p = TYPE_VECTOR (register_type (gdbarch, regnum)); + float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT; + /* FIXME: cagney/2003-04-13: Can't yet use gdbarch_num_regs + (gdbarch), as not all architectures are multi-arch. */ + raw_p = rawnum < NUM_REGS; + if (REGISTER_NAME (rawnum) == NULL + || REGISTER_NAME (rawnum)[0] == '\0') + return 0; + if (reggroup == float_reggroup) + return float_p && pseudo; + if (reggroup == vector_reggroup) + return vector_p && pseudo; + if (reggroup == general_reggroup) + return (!vector_p && !float_p) && pseudo; + /* Save the raw registers. If the architecture reads a cooked + pseudo register from the raw register cache, the regcache will + "do the right thing" (map the cooked pseudo back onto a raw + register). */ + if (reggroup == save_reggroup) + return raw_p && !pseudo; + /* Restore using the symbol table registers? Not yet. At present + this scrambles the code that tries to restore the registers after + an inferior function call. */ + if (reggroup == restore_reggroup) + return raw_p && !pseudo; + return 0; +} + +/* Map the symbol table registers which live in the range [1 * + NUM_REGS .. 2 * NUM_REGS) back onto the corresponding raw + registers. */ + +static void +mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, + int cookednum, void *buf) +{ + gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS); + return regcache_raw_read (regcache, cookednum % NUM_REGS, buf); +} +static void +mips_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, + int cookednum, const void *buf) +{ + gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS); + return regcache_raw_write (regcache, cookednum % NUM_REGS, buf); +} /* Table to translate MIPS16 register field to actual register number. */ static int mips16_to_32_reg[8] = @@ -575,22 +637,73 @@ /* Number of bytes of storage in the actual machine representation for register N. NOTE: This indirectly defines the register size - transfered by the GDB protocol. */ + transfered by the GDB protocol. */ static int mips64_transfers_32bit_regs_p = 0; static int -mips_register_raw_size (int reg_nr) +mips_register_raw_size (int regnum) { - 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; + gdb_assert (regnum >= 0); + if (regnum < NUM_REGS) + { + /* For compatibility with old code, implemnt the broken register raw + size map for the raw registers. + + NOTE: cagney/2003-06-15: This is so bogus. The register's + raw size is changing according to the ABI + (FP_REGISTER_DOUBLE). Also, GDB's protocol is defined by a + combination of REGISTER_RAW_SIZE and REGISTER_BYTE. */ + if (mips64_transfers_32bit_regs_p) + return REGISTER_VIRTUAL_SIZE (regnum); + else if (regnum >= FP0_REGNUM && regnum < 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; + } + else if (regnum < 2 * NUM_REGS) + { + /* For the moment map [NUM_REGS .. 2*NUM_REGS) onto the same raw + registers, but always return the virtual size. */ + int rawnum = regnum % NUM_REGS; + return TYPE_LENGTH (MIPS_REGISTER_TYPE (rawnum)); + } + else + internal_error (__FILE__, __LINE__, "Register %d out of range", regnum); +} + +/* Register offset in a buffer for each register. + + FIXME: cagney/2003-06-15: This is so bogus. Instead REGISTER_TYPE + should strictly return the layout of the buffer. Unfortunatly + remote.c and the MIPS have come to rely on a custom layout that + doesn't 1:1 map onto the register type. */ + +static int +mips_register_byte (int regnum) +{ + gdb_assert (regnum >= 0); + if (regnum < NUM_REGS) + /* Pick up the relevant per-tm file register byte method. */ + return MIPS_REGISTER_BYTE (regnum); + else if (regnum < 2 * NUM_REGS) + { + int reg; + int byte; + /* Start with the end of the raw register buffer - assum that + MIPS_REGISTER_BYTE (NUM_REGS) returns that end. */ + byte = MIPS_REGISTER_BYTE (NUM_REGS); + /* Add space for all the proceeding registers based on their + real size. */ + for (reg = NUM_REGS; reg < regnum; reg++) + byte += TYPE_LENGTH (MIPS_REGISTER_TYPE ((reg % NUM_REGS))); + return byte; + } else - return MIPS_REGSIZE; + internal_error (__FILE__, __LINE__, "Register %d out of range", regnum); } /* Convert between RAW and VIRTUAL registers. The RAW register size @@ -660,20 +773,20 @@ put_frame_register (frame, regnum + 1, (const char *) from + 0); } -/* 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. */ +/* Return the GDB type object for the "standard" data type of data in + register REG. */ static struct type * -mips_register_virtual_type (int reg) +mips_register_type (struct gdbarch *gdbarch, int regnum) { - if (FP0_REGNUM <= reg && reg < FP0_REGNUM + 32) + /* For moment, map [NUM_REGS .. 2*NUM_REGS) onto the same raw + registers. Even return the same type. */ + int rawnum = regnum % NUM_REGS; + gdb_assert (rawnum >= 0 && rawnum < NUM_REGS); +#ifdef MIPS_REGISTER_TYPE + return MIPS_REGISTER_TYPE (rawnum); +#else + if (FP0_REGNUM <= rawnum && rawnum < FP0_REGNUM + 32) { /* Floating point registers... */ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) @@ -681,9 +794,9 @@ else return builtin_type_ieee_double_little; } - else if (reg == PS_REGNUM /* CR */) + else if (rawnum == PS_REGNUM /* CR */) return builtin_type_uint32; - else if (FCRCS_REGNUM <= reg && reg <= LAST_EMBED_REGNUM) + else if (FCRCS_REGNUM <= rawnum && rawnum <= LAST_EMBED_REGNUM) return builtin_type_uint32; else { @@ -694,6 +807,7 @@ else return builtin_type_uint32; } +#endif } /* TARGET_READ_SP -- Remove useless bits from the stack pointer. */ @@ -1794,13 +1908,22 @@ /* Set a register's saved stack address in temp_saved_regs. If an address has already been set for this register, do nothing; this way we will only recognize the first save of a given register in a - function prologue. */ + function prologue. + + For simplicity, save the address in both [0 .. NUM_REGS) and + [NUM_REGS .. 2*NUM_REGS). Strictly speaking, only the second range + is used as it is only second range (the ABI instead of ISA + registers) that comes into play when finding saved registers in a + frame. */ static void set_reg_offset (CORE_ADDR *saved_regs, int regno, CORE_ADDR offset) { if (saved_regs[regno] == 0) - saved_regs[regno] = offset; + { + saved_regs[regno + 0 * NUM_REGS] = offset; + saved_regs[regno + 1 * NUM_REGS] = offset; + } } @@ -4073,10 +4196,11 @@ mips_print_register (struct ui_file *file, struct frame_info *frame, int regnum, int all) { + struct gdbarch *gdbarch = get_frame_arch (frame); char raw_buffer[MAX_REGISTER_SIZE]; int offset; - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT) + if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT) { mips_print_fp_register (file, frame, regnum); return; @@ -4105,8 +4229,7 @@ else offset = 0; - print_scalar_formatted (raw_buffer + offset, - REGISTER_VIRTUAL_TYPE (regnum), + print_scalar_formatted (raw_buffer + offset, gdbarch_register_type (gdbarch, regnum), 'x', 0, file); } @@ -4130,6 +4253,7 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame, int regnum) { + struct gdbarch *gdbarch = get_frame_arch (frame); /* do values for GP (int) regs */ char raw_buffer[MAX_REGISTER_SIZE]; int ncols = (MIPS_REGSIZE == 8 ? 4 : 8); /* display cols per row */ @@ -4144,7 +4268,7 @@ { if (*REGISTER_NAME (regnum) == '\0') continue; /* unused register */ - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT) + if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT) break; /* end the row: reached FP register */ fprintf_filtered (file, MIPS_REGSIZE == 8 ? "%17s" : "%9s", REGISTER_NAME (regnum)); @@ -4160,7 +4284,7 @@ { if (*REGISTER_NAME (regnum) == '\0') continue; /* unused register */ - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT) + if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT) break; /* end row: reached FP register */ /* OK: get the data in raw format. */ if (!frame_register_read (frame, regnum, raw_buffer)) @@ -4208,7 +4332,7 @@ regnum = 0; while (regnum < NUM_REGS) { - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT) + if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT) { if (all) /* true for "INFO ALL-REGISTERS" command */ regnum = print_fp_register_row (file, frame, regnum); @@ -5475,48 +5599,49 @@ } -/* Convert a dbx stab register number (from `r' declaration) to a gdb - REGNUM */ +/* Convert a dbx stab register number (from `r' declaration) to a GDB + [1 * NUM_REGS .. 2 * NUM_REGS) REGNUM. */ static int mips_stab_reg_to_regnum (int num) { + int regnum; if (num >= 0 && num < 32) - return num; + regnum = num; else if (num >= 38 && num < 70) - return num + FP0_REGNUM - 38; + regnum = num + FP0_REGNUM - 38; else if (num == 70) - return HI_REGNUM; + regnum = HI_REGNUM; else if (num == 71) - return LO_REGNUM; + regnum = LO_REGNUM; else - { - /* This will hopefully (eventually) provoke a warning. Should - we be calling complaint() here? */ - return NUM_REGS + NUM_PSEUDO_REGS; - } + /* This will hopefully (eventually) provoke a warning. Should + we be calling complaint() here? */ + return NUM_REGS + NUM_PSEUDO_REGS; + return NUM_REGS + regnum; } -/* Convert a dwarf, dwarf2, or ecoff register number to a gdb REGNUM */ +/* Convert a dwarf, dwarf2, or ecoff register number to a GDB [1 * + NUM_REGS .. 2 * NUM_REGS) REGNUM. */ static int mips_dwarf_dwarf2_ecoff_reg_to_regnum (int num) { + int regnum; if (num >= 0 && num < 32) - return num; + regnum = num; else if (num >= 32 && num < 64) - return num + FP0_REGNUM - 32; + regnum = num + FP0_REGNUM - 32; else if (num == 64) - return HI_REGNUM; + regnum = HI_REGNUM; else if (num == 65) - return LO_REGNUM; + regnum = LO_REGNUM; else - { - /* This will hopefully (eventually) provoke a warning. Should - we be calling complaint() here? */ - return NUM_REGS + NUM_PSEUDO_REGS; - } + /* This will hopefully (eventually) provoke a warning. Should we + be calling complaint() here? */ + return NUM_REGS + NUM_PSEUDO_REGS; + return NUM_REGS + regnum; } @@ -5583,6 +5708,7 @@ struct gdbarch_tdep *tdep; int elf_flags; enum mips_abi mips_abi, found_abi, wanted_abi; + int num_regs; /* Reset the disassembly info, in case it was set to something non-default. */ @@ -5736,16 +5862,23 @@ set_gdbarch_double_bit (gdbarch, 64); set_gdbarch_long_double_bit (gdbarch, 64); set_gdbarch_deprecated_register_raw_size (gdbarch, mips_register_raw_size); + set_gdbarch_deprecated_register_byte (gdbarch, mips_register_byte); + set_gdbarch_register_reggroup_p (gdbarch, mips_register_reggroup_p); + set_gdbarch_pseudo_register_read (gdbarch, mips_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, mips_pseudo_register_write); tdep->found_abi = found_abi; tdep->mips_abi = mips_abi; set_gdbarch_elf_make_msymbol_special (gdbarch, mips_elf_make_msymbol_special); + if (info.osabi == GDB_OSABI_IRIX) - set_gdbarch_num_regs (gdbarch, 71); + num_regs = 71; else - set_gdbarch_num_regs (gdbarch, 90); + num_regs = 90; + set_gdbarch_num_regs (gdbarch, num_regs); + set_gdbarch_num_pseudo_regs (gdbarch, num_regs); switch (mips_abi) { @@ -5973,9 +6106,7 @@ 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_deprecated_register_virtual_type (gdbarch, mips_register_virtual_type); + set_gdbarch_register_type (gdbarch, mips_register_type); set_gdbarch_print_registers_info (gdbarch, mips_print_registers_info); set_gdbarch_pc_in_sigtramp (gdbarch, mips_pc_in_sigtramp); Index: config/mips/tm-irix5.h =================================================================== RCS file: /cvs/src/src/gdb/config/mips/tm-irix5.h,v retrieving revision 1.10 diff -u -r1.10 tm-irix5.h --- config/mips/tm-irix5.h 1 Jun 2003 15:45:57 -0000 1.10 +++ config/mips/tm-irix5.h 16 Jun 2003 15:21:51 -0000 @@ -30,16 +30,16 @@ * Irix 6 (n32 ABI) has 32-bit GP regs and 64-bit FP regs */ -#undef REGISTER_BYTE -#define REGISTER_BYTE(N) \ +#undef MIPS_REGISTER_BYTE +#define MIPS_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) \ +#undef MIPS_REGISTER_TYPE +#define MIPS_REGISTER_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 \ Index: config/mips/tm-irix6.h =================================================================== RCS file: /cvs/src/src/gdb/config/mips/tm-irix6.h,v retrieving revision 1.13 diff -u -r1.13 tm-irix6.h --- config/mips/tm-irix6.h 1 Jun 2003 15:45:57 -0000 1.13 +++ config/mips/tm-irix6.h 16 Jun 2003 15:21:51 -0000 @@ -62,8 +62,8 @@ #define FCRIR_REGNUM 70 /* FP implementation/revision */ -#undef REGISTER_BYTE -#define REGISTER_BYTE(N) \ +#undef MIPS_REGISTER_BYTE +#define MIPS_REGISTER_BYTE(N) \ (((N) < FP0_REGNUM) ? (N) * MIPS_REGSIZE : \ ((N) < FP0_REGNUM + 32) ? \ FP0_REGNUM * MIPS_REGSIZE + \ @@ -94,4 +94,4 @@ #define SIGFRAME_REG_SIZE 8 /* Undefine those methods which have been multiarched. */ -#undef REGISTER_VIRTUAL_TYPE +#undef MIPS_REGISTER_TYPE Index: config/mips/tm-mips.h =================================================================== RCS file: /cvs/src/src/gdb/config/mips/tm-mips.h,v retrieving revision 1.50 diff -u -r1.50 tm-mips.h --- config/mips/tm-mips.h 1 Jun 2003 15:45:57 -0000 1.50 +++ config/mips/tm-mips.h 16 Jun 2003 15:21:51 -0000 @@ -98,13 +98,13 @@ /* Index within `registers' of the first byte of the space for register N. */ -#define REGISTER_BYTE(N) ((N) * MIPS_REGSIZE) +#define MIPS_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) \ +#ifndef MIPS_REGISTER_TYPE +#define MIPS_REGISTER_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 \ Index: config/mips/tm-mips64.h =================================================================== RCS file: /cvs/src/src/gdb/config/mips/tm-mips64.h,v retrieving revision 1.5 diff -u -r1.5 tm-mips64.h --- config/mips/tm-mips64.h 5 Jun 2002 19:18:25 -0000 1.5 +++ config/mips/tm-mips64.h 16 Jun 2003 15:21:51 -0000 @@ -23,7 +23,7 @@ #define MIPS_REGSIZE 8 /* define 8 byte register type */ -#define REGISTER_VIRTUAL_TYPE(N) \ +#define MIPS_REGISTER_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 \