This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[commit] Make all MIPS registers cooked


Hello,

This is the final patch for making all MIPS registers cooked. Even when saving/restoring frames, it uses the cooked register values.

This means that the register buffer, and ISAs register layout are [relativly] cleanly separated from the ABI and its expected register layout.

committed,
Andrew
2003-06-21  Andrew Cagney  <cagney@redhat.com>

	* mips-tdep.c: Include "reggroups.h" and "sim-regno.h".
	(mips_register_name): Return names for NUM_REGS..2*NUM_REGS
	instead of 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 register's type.
	(read_next_frame_reg): Simplify.  Assert that REGNO is a pseudo /
	cooked.
	(mips_get_saved_register): Simplify.  Assert that REGNO is a
	pseudo / cooked.
	(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.
	(read_next_frame_reg): Simplify, but handle SP_REGNUM.  Assert
	that the register is cooked / virtual.
	(mips_frame_saved_pc): Fetch the cooked PC, and not the raw PC.
	Only get the extra info when needed.
	(set_reg_offset): Save the offset in NUM_REGS..2*NUM_REGS as well.
	(mips32_heuristic_proc_desc): Fetch the cooked register.
	(heuristic_proc_desc, mips_pop_frame, get_frame_pointer): Ditto.
	(mips_init_extra_frame_info, get_frame_pointer): Ditto.
	(mips_print_register): Use gdbarch_register_type, instead of
	REGISTER_VIRTUAL_TYPE.
	(print_gp_register_row): Use gdbarch_register_type, instead of
	REGISTER_VIRTUAL_TYPE.  Allow for a pseudo / cooked REGNUM.
	(mips_print_registers_info): Assert REGNO is pseodo / cooked.
	Print the pseudo / cooked registers.
	(mips_print_registers_info): Assert REGNO is pseodo / cooked.
	Print the pseudo / cooked registers.
	(mips_xfer_register): Use regcache_cooked_read_part.  Assert that
	REG_NUM is pseudo / cooked.
	(mips_o32_xfer_return_value): Xfer the pseudo / cooked register.
	(mips_n32n64_xfer_return_value): Ditto.
	(mips_stab_reg_to_regnum): Map onto NUM_REGS..2*NUM_REGS.
	(mips_dwarf_dwarf2_ecoff_reg_to_regnum): Ditto.
	(mips_register_sim_regno): New function.
	(mips_gdbarch_init): Set deprecated_register_byte,
	register_group_p, pseudo_register_write, pseudo_register_read,
	register_sim_regno, 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.408
diff -u -r1.408 Makefile.in
--- Makefile.in	19 Jun 2003 22:52:03 -0000	1.408
+++ Makefile.in	21 Jun 2003 22:54:00 -0000
@@ -2001,10 +2001,10 @@
 mips-nat.o: mips-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(regcache_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)
+	$(language_h) $(gdbcore_h) $(symfile_h) $(objfiles_h) $(gdbtypes_h) \
+	$(target_h) $(arch_utils_h) $(regcache_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.220
diff -u -r1.220 mips-tdep.c
--- mips-tdep.c	21 Jun 2003 18:02:54 -0000	1.220
+++ mips-tdep.c	21 Jun 2003 22:54:44 -0000
@@ -42,11 +42,12 @@
 #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"
 #include "symcat.h"
+#include "sim-regno.h"
 
 static void set_reg_offset (CORE_ADDR *saved_regs, int regnum, CORE_ADDR off);
 
@@ -270,6 +271,7 @@
 {
   bfd_byte reg[MAX_REGISTER_SIZE];
   int reg_offset = 0;
+  gdb_assert (reg_num >= NUM_REGS);
   /* Need to transfer the left or right part of the register, based on
      the targets byte order.  */
   switch (endian)
@@ -298,9 +300,9 @@
 	fprintf_unfiltered (gdb_stdlog, "%02x", out[buf_offset + i]);
     }
   if (in != NULL)
-    regcache_raw_read_part (regcache, reg_num, reg_offset, length, in + buf_offset);
+    regcache_cooked_read_part (regcache, reg_num, reg_offset, length, in + buf_offset);
   if (out != NULL)
-    regcache_raw_write_part (regcache, reg_num, reg_offset, length, out + buf_offset);
+    regcache_cooked_write_part (regcache, reg_num, reg_offset, length, out + buf_offset);
   if (mips_debug && in != NULL)
     {
       int i;
@@ -440,21 +442,27 @@
 
   enum mips_abi abi = mips_abi (current_gdbarch);
 
+  /* Map [NUM_REGS .. 2*NUM_REGS) onto the raw registers, but then
+     don't make the raw register names visible.  */
+  int rawnum = regno % NUM_REGS;
+  if (regno < NUM_REGS)
+    return "";
+
   /* 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 +532,63 @@
 };
 /* *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 (regnum) == NULL
+      || REGISTER_NAME (regnum)[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 pseudo registers.  Need to make certain that any code
+     extracting register values from a saved register cache also uses
+     pseudo registers.  */
+  if (reggroup == save_reggroup)
+    return raw_p && pseudo;
+  /* Restore the same pseudo register.  */
+  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 +638,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
-    return MIPS_REGSIZE;
+    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
+    internal_error (__FILE__, __LINE__, "Register %d out of range", regnum);
 }
 
 /* Convert between RAW and VIRTUAL registers.  The RAW register size
@@ -660,20 +774,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 +795,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 +808,7 @@
       else
 	return builtin_type_uint32;
     }
+#endif
 }
 
 /* TARGET_READ_SP -- Remove useless bits from the stack pointer.  */
@@ -1658,37 +1773,22 @@
 static CORE_ADDR
 read_next_frame_reg (struct frame_info *fi, int regno)
 {
-  int optimized;
-  CORE_ADDR addr;
-  int realnum;
-  enum lval_type lval;
-  char raw_buffer[MAX_REGISTER_SIZE];
-
+  /* Always a pseudo.  */
+  gdb_assert (regno >= NUM_REGS);
   if (fi == NULL)
     {
-      regcache_cooked_read (current_regcache, regno, raw_buffer);
-    }
+      LONGEST val;
+      regcache_cooked_read_signed (current_regcache, regno, &val);
+      return val;
+    }
+  else if ((regno % NUM_REGS) == SP_REGNUM)
+    /* The SP_REGNUM is extra special, its value is stored in
+       saved_regs.  In fact, it is so special that it must be fetched
+       using a raw register number!  */
+    return frame_unwind_register_signed (fi, regno % NUM_REGS);
   else
-    {
-      frame_register_unwind (fi, regno, &optimized, &lval, &addr, &realnum,
-			     raw_buffer);
-      /* FIXME: cagney/2002-09-13: This is just soooo bad.  The MIPS
-	 should have a pseudo register range that correspons to the ABI's,
-	 rather than the ISA's, view of registers.  These registers would
-	 then implicitly describe their size and hence could be used
-	 without the below munging.  */
-      if (lval == lval_memory)
-	{
-	  if (regno < 32)
-	    {
-	      /* Only MIPS_SAVED_REGSIZE bytes of GP registers are
-		 saved. */
-	      return read_memory_integer (addr, MIPS_SAVED_REGSIZE);
-	    }
-	}
-    }
+    return frame_unwind_register_signed (fi, regno);
 
-  return extract_signed_integer (raw_buffer, REGISTER_VIRTUAL_SIZE (regno));
 }
 
 /* mips_addr_bits_remove - remove useless address bits  */
@@ -1778,23 +1878,29 @@
 mips_frame_saved_pc (struct frame_info *frame)
 {
   CORE_ADDR saved_pc;
-  mips_extra_func_info_t proc_desc = get_frame_extra_info (frame)->proc_desc;
-  /* 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);
 
   if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame), 0, 0))
     {
       LONGEST tmp;
-      frame_unwind_signed_register (frame, PC_REGNUM, &tmp);
+      /* Always unwind the cooked PC register value.  */
+      frame_unwind_signed_register (frame, NUM_REGS + PC_REGNUM, &tmp);
       saved_pc = tmp;
     }
-  else if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
-    saved_pc = read_memory_integer (get_frame_base (frame) - MIPS_SAVED_REGSIZE, MIPS_SAVED_REGSIZE);
   else
-    saved_pc = read_next_frame_reg (frame, pcreg);
-
+    {
+      mips_extra_func_info_t proc_desc
+	= get_frame_extra_info (frame)->proc_desc;
+      if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
+	saved_pc = read_memory_integer (get_frame_base (frame) - MIPS_SAVED_REGSIZE, MIPS_SAVED_REGSIZE);
+      else
+	{
+	  /* 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);
+	  saved_pc = read_next_frame_reg (frame, NUM_REGS + pcreg);
+	}
+    }
   return ADDR_BITS_REMOVE (saved_pc);
 }
 
@@ -1810,13 +1916,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;
+    }
 }
 
 
@@ -2168,7 +2283,7 @@
 	    {
 	      unsigned alloca_adjust;
 	      PROC_FRAME_REG (&temp_proc_desc) = 30;
-	      frame_addr = read_next_frame_reg (next_frame, 30);
+	      frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30);
 	      alloca_adjust = (unsigned) (frame_addr - (sp + low_word));
 	      if (alloca_adjust > 0)
 		{
@@ -2191,7 +2306,7 @@
 	    {
 	      unsigned alloca_adjust;
 	      PROC_FRAME_REG (&temp_proc_desc) = 30;
-	      frame_addr = read_next_frame_reg (next_frame, 30);
+	      frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30);
 	      alloca_adjust = (unsigned) (frame_addr - sp);
 	      if (alloca_adjust > 0)
 		{
@@ -2219,7 +2334,7 @@
   CORE_ADDR sp;
 
   if (cur_frame)
-    sp = read_next_frame_reg (next_frame, SP_REGNUM);
+    sp = read_next_frame_reg (next_frame, NUM_REGS + SP_REGNUM);
   else
     sp = 0;
 
@@ -2492,7 +2607,7 @@
 get_frame_pointer (struct frame_info *frame,
 		   mips_extra_func_info_t proc_desc)
 {
-  return (read_next_frame_reg (frame, PROC_FRAME_REG (proc_desc))
+  return (read_next_frame_reg (frame, NUM_REGS + PROC_FRAME_REG (proc_desc))
 	  + PROC_FRAME_OFFSET (proc_desc)
 	  - PROC_FRAME_ADJUST (proc_desc));
 }
@@ -2578,7 +2693,7 @@
          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), NUM_REGS + 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
@@ -4089,10 +4204,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;
@@ -4121,8 +4237,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);
 }
 
@@ -4144,39 +4259,43 @@
 
 static int
 print_gp_register_row (struct ui_file *file, struct frame_info *frame,
-		       int regnum)
+		       int start_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 */
   int col, byte;
-  int start_regnum = regnum;
-  int numregs = NUM_REGS;
-
+  int regnum;
 
   /* For GP registers, we print a separate row of names above the vals */
   fprintf_filtered (file, "     ");
-  for (col = 0; col < ncols && regnum < numregs; regnum++)
+  for (col = 0, regnum = start_regnum;
+       col < ncols && regnum < NUM_REGS + NUM_PSEUDO_REGS;
+       regnum++)
     {
       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));
       col++;
     }
+  /* print the R0 to R31 names */
   fprintf_filtered (file,
-		    start_regnum < MIPS_NUMREGS ? "\n R%-4d" : "\n      ",
-		    start_regnum);	/* print the R0 to R31 names */
+		    (start_regnum % NUM_REGS) < MIPS_NUMREGS
+		    ? "\n R%-4d" : "\n      ",
+		    start_regnum);
 
-  regnum = start_regnum;	/* go back to start of row */
   /* now print the values in hex, 4 or 8 to the row */
-  for (col = 0; col < ncols && regnum < numregs; regnum++)
+  for (col = 0, regnum = start_regnum;
+       col < ncols && regnum < NUM_REGS + NUM_PSEUDO_REGS;
+       regnum++)
     {
       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))
@@ -4212,6 +4331,7 @@
 {
   if (regnum != -1)		/* do one specified register */
     {
+      gdb_assert (regnum >= NUM_REGS);
       if (*(REGISTER_NAME (regnum)) == '\0')
 	error ("Not a valid register for the current processor type");
 
@@ -4221,10 +4341,10 @@
   else
     /* do all (or most) registers */
     {
-      regnum = 0;
-      while (regnum < NUM_REGS)
+      regnum = NUM_REGS;
+      while (regnum < NUM_REGS + NUM_PSEUDO_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);
@@ -4711,30 +4831,30 @@
          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, NUM_REGS + FP0_REGNUM, TYPE_LENGTH (type),
 			  TARGET_BYTE_ORDER, in, out, 0);
     }
   else if (TYPE_CODE (type) == TYPE_CODE_FLT
 	   && TYPE_LENGTH (type) == 8
 	   && tdep->mips_fpu_type != MIPS_FPU_NONE)
     {
-      /* A double-precision floating-point value.  It fits in the
-         least significant part of FP0/FP1 but with byte ordering
-         based on the target (???).  */
+      /* A double-precision floating-point value.  The most
+         significant part goes in FP1, and the least significant in
+         FP0.  */
       if (mips_debug)
-	fprintf_unfiltered (gdb_stderr, "Return float in $fp0/$fp1\n");
+	fprintf_unfiltered (gdb_stderr, "Return float in $fp1/$fp0\n");
       switch (TARGET_BYTE_ORDER)
 	{
 	case BFD_ENDIAN_LITTLE:
-	  mips_xfer_register (regcache, FP0_REGNUM + 0, 4,
+	  mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 0, 4,
 			      TARGET_BYTE_ORDER, in, out, 0);
-	  mips_xfer_register (regcache, FP0_REGNUM + 1, 4,
+	  mips_xfer_register (regcache, NUM_REGS + 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, NUM_REGS + FP0_REGNUM + 1, 4,
 			      TARGET_BYTE_ORDER, in, out, 0);
-	  mips_xfer_register (regcache, FP0_REGNUM + 0, 4,
+	  mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 0, 4,
 			      TARGET_BYTE_ORDER, in, out, 4);
 	  break;
 	default:
@@ -4769,7 +4889,8 @@
 			/ TARGET_CHAR_BIT);
 	  if (mips_debug)
 	    fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", offset);
-	  mips_xfer_register (regcache, regnum, TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
+	  mips_xfer_register (regcache, NUM_REGS + regnum,
+			      TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
 			      TARGET_BYTE_ORDER, in, out, offset);
 	}
     }
@@ -4793,8 +4914,8 @@
 	  if (mips_debug)
 	    fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n",
 				offset, xfer, regnum);
-	  mips_xfer_register (regcache, regnum, xfer, BFD_ENDIAN_UNKNOWN,
-			      in, out, offset);
+	  mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+			      BFD_ENDIAN_UNKNOWN, in, out, offset);
 	}
     }
 #endif
@@ -4816,8 +4937,8 @@
 	  if (mips_debug)
 	    fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n",
 				offset, xfer, regnum);
-	  mips_xfer_register (regcache, regnum, xfer, TARGET_BYTE_ORDER,
-			      in, out, offset);
+	  mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+			      TARGET_BYTE_ORDER, in, out, offset);
 	}
     }
 }
@@ -4851,7 +4972,7 @@
          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, NUM_REGS + FP0_REGNUM, TYPE_LENGTH (type),
 			  TARGET_BYTE_ORDER, in, out, 0);
     }
   else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
@@ -4881,7 +5002,8 @@
 			/ TARGET_CHAR_BIT);
 	  if (mips_debug)
 	    fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", offset);
-	  mips_xfer_register (regcache, regnum, TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
+	  mips_xfer_register (regcache, NUM_REGS + regnum,
+			      TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
 			      TARGET_BYTE_ORDER, in, out, offset);
 	}
     }
@@ -4903,8 +5025,8 @@
 	  if (mips_debug)
 	    fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n",
 				offset, xfer, regnum);
-	  mips_xfer_register (regcache, regnum, xfer, BFD_ENDIAN_UNKNOWN,
-			      in, out, offset);
+	  mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+			      BFD_ENDIAN_UNKNOWN, in, out, offset);
 	}
     }
   else
@@ -4924,8 +5046,8 @@
 	  if (mips_debug)
 	    fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n",
 				offset, xfer, regnum);
-	  mips_xfer_register (regcache, regnum, xfer, TARGET_BYTE_ORDER,
-			      in, out, offset);
+	  mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+			      TARGET_BYTE_ORDER, in, out, offset);
 	}
     }
 }
@@ -5448,8 +5570,8 @@
   int optimizedx;
   int realnumx;
 
-  if (!target_has_registers)
-    error ("No registers.");
+  /* Always a pseudo.  */
+  gdb_assert (regnum >= NUM_REGS);
 
   /* Make certain that all needed parameters are present.  */
   if (addrp == NULL)
@@ -5458,28 +5580,19 @@
     lvalp = &lvalx;
   if (optimizedp == NULL)
     optimizedp = &optimizedx;
-  frame_register_unwind (deprecated_get_next_frame_hack (frame),
-			 regnum, optimizedp, lvalp, addrp,
-			 &realnumx, raw_buffer);
-
-  /* FIXME: cagney/2002-09-13: This is just so bad.  The MIPS should
-     have a pseudo register range that correspons to the ABI's, rather
-     than the ISA's, view of registers.  These registers would then
-     implicitly describe their size and hence could be used without
-     the below munging.  */
-  if ((*lvalp) == lval_memory)
-    {
-      if (raw_buffer != NULL)
-	{
-	  if (regnum < 32)
-	    {
-	      /* Only MIPS_SAVED_REGSIZE bytes of GP registers are
-		 saved. */
-	      LONGEST val = read_memory_integer ((*addrp), MIPS_SAVED_REGSIZE);
-	      store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), val);
-	    }
-	}
-    }
+
+  if ((regnum % NUM_REGS) == SP_REGNUM)
+    /* The SP_REGNUM is extra special, its value is stored in
+       saved_regs.  In fact, it is so special that it must be fetched
+       using a raw register number!  */
+    frame_register_unwind (deprecated_get_next_frame_hack (frame),
+			   regnum % NUM_REGS, optimizedp, lvalp, addrp,
+			   &realnumx, raw_buffer);
+  else
+    /* Get it from the next frame.  */
+    frame_register_unwind (deprecated_get_next_frame_hack (frame),
+			   regnum, optimizedp, lvalp, addrp,
+			   &realnumx, raw_buffer);
 }
 
 /* Immediately after a function call, return the saved pc.
@@ -5494,48 +5607,64 @@
 }
 
 
-/* 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;
+}
+
+static int
+mips_register_sim_regno (int regnum)
+{
+  /* Only makes sense to supply raw registers.  */
+  gdb_assert (regnum >= 0 && regnum < NUM_REGS);
+  /* FIXME: cagney/2002-05-13: Need to look at the pseudo register to
+     decide if it is valid.  Should instead define a standard sim/gdb
+     register numbering scheme.  */
+  if (REGISTER_NAME (NUM_REGS + regnum) != NULL
+      && REGISTER_NAME (NUM_REGS + regnum)[0] != '\0')
+    return regnum;
+  else
+    return LEGACY_SIM_REGNO_IGNORE;    
 }
 
 
@@ -5602,6 +5731,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.  */
@@ -5755,16 +5885,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)
     {
@@ -5956,6 +6093,7 @@
   set_gdbarch_ecoff_reg_to_regnum (gdbarch, mips_dwarf_dwarf2_ecoff_reg_to_regnum);
   set_gdbarch_dwarf_reg_to_regnum (gdbarch, mips_dwarf_dwarf2_ecoff_reg_to_regnum);
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, mips_dwarf_dwarf2_ecoff_reg_to_regnum);
+  set_gdbarch_register_sim_regno (gdbarch, mips_register_sim_regno);
 
   /* Initialize a frame */
   set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, mips_find_saved_regs);
@@ -5992,9 +6130,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	21 Jun 2003 22:54:46 -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	21 Jun 2003 22:54:46 -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.51
diff -u -r1.51 tm-mips.h
--- config/mips/tm-mips.h	20 Jun 2003 04:04:44 -0000	1.51
+++ config/mips/tm-mips.h	21 Jun 2003 22:54:46 -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	21 Jun 2003 22:54:46 -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 \

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]