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]

[RFA] MIPS: Introduce struct mips_regnums and accessors


This is the first of many patches to come.  It introduces ``struct
mips_regnums'', adds some members to the mips gdbarch_tdep struct, and
adds some accessors for getting at the members.

I decided to add both the "cooked" and "raw" accessors right away
so that upcoming patches which replace references to the various
*_REGNUM macros with references to members of struct mips_regnums
will be able to use the correct set of register numbers.

For the time being, the set of cooked numbers is initialized to
be the same as the raw numbers.

I've reorganized the order of the fields in struct mips_regnums from
my WIP patch.  I've also rearranged the initializations to follow the
order of these members in the struct.  And, just to be sure that
things don't bit-rot (too badly), I've added a batch of asserts to
make sure that each member has actually been initialized.

Okay?

	* mips-tdep.h (mips_regnums): New struct declaration.
	* mips-tdep.h, mips-tdep.c (mips_raw_regnums, mips_cooked_regnums):
	New functions.
	* mips-tdep.c (struct gdbarch_tdep): Add new members ``raw_regnums''
	and ``cooked_regnums''.
	(mips_gdbarch_init): Initialize raw and cooked register numbers.
	(mips_dump_regnums): New function.
	(mips_dump_tdep): Dump the cooked and raw register numbers.

Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.199
diff -u -p -r1.199 mips-tdep.c
--- mips-tdep.c	14 May 2003 17:43:18 -0000	1.199
+++ mips-tdep.c	15 May 2003 23:09:14 -0000
@@ -131,6 +131,9 @@ struct gdbarch_tdep
     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;
   };
 
 #define MIPS_EABI (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI32 \
@@ -187,6 +190,20 @@ mips_abi (struct gdbarch *gdbarch)
   return gdbarch_tdep (gdbarch)->mips_abi;
 }
 
+/* Fetch the MIPS "raw" register numbers.  */
+const struct mips_regnums *
+mips_raw_regnums (struct gdbarch *gdbarch)
+{
+  return &(gdbarch_tdep (gdbarch)->raw_regnums);
+}
+
+/* Fetch the MIPS "cooked" register numbers.  */
+const struct mips_regnums *
+mips_cooked_regnums (struct gdbarch *gdbarch)
+{
+  return &(gdbarch_tdep (gdbarch)->cooked_regnums);
+}
+
 static unsigned int
 mips_saved_regsize (void)
 {
@@ -5731,10 +5748,59 @@ mips_gdbarch_init (struct gdbarch_info i
   set_gdbarch_elf_make_msymbol_special (gdbarch, 
 					mips_elf_make_msymbol_special);
 
+  /* Zero out all of the raw register numbers.  Later on, we will use
+    gdb_assert() to verify that they've all been set.  */
+  memset (&tdep->raw_regnums, 0, sizeof (tdep->raw_regnums));
+
+  /* Raw register number initializations.  They are initialized in the
+     same order that they appear in the struct to make it easier to
+     verify that they're all initialized.  */
+  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;
+
   if (info.osabi == GDB_OSABI_IRIX)
-    set_gdbarch_num_regs (gdbarch, 71);
+    {
+      set_gdbarch_num_regs (gdbarch, 71);
+
+      tdep->raw_regnums.ps_regnum = -1;
+      tdep->raw_regnums.hi_regnum = 67;
+      tdep->raw_regnums.lo_regnum = 68;
+      tdep->raw_regnums.badvaddr_regnum = 66;
+      tdep->raw_regnums.cause_regnum = 65;
+      tdep->raw_regnums.pc_regnum = 64;
+      tdep->raw_regnums.fcrcs_regnum = 69;
+      tdep->raw_regnums.fcrir_regnum = 70;
+      tdep->raw_regnums.fp0_regnum = 32;
+      tdep->raw_regnums.fplast_regnum = tdep->raw_regnums.fp0_regnum + 31;
+      tdep->raw_regnums.fpa0_regnum = tdep->raw_regnums.fp0_regnum + 12;
+      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);
+
+      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.fp0_regnum = 38;
+      tdep->raw_regnums.fplast_regnum = tdep->raw_regnums.fp0_regnum + 31;
+      tdep->raw_regnums.fpa0_regnum = tdep->raw_regnums.fp0_regnum + 12;
+      tdep->raw_regnums.first_embed_regnum = 74;
+      tdep->raw_regnums.last_embed_regnum = 89;
+      tdep->raw_regnums.prid_regnum = 89;
+    }
+
 
   switch (mips_abi)
     {
@@ -5745,8 +5811,10 @@ 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->mips_last_arg_regnum = A0_REGNUM + 4 - 1;  /* delete in next patch */
+      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 4 - 1; /* delete in next patch */
+      tdep->raw_regnums.last_arg_regnum = tdep->raw_regnums.a0_regnum + 4 - 1;
+      tdep->raw_regnums.last_fp_arg_regnum = tdep->raw_regnums.fpa0_regnum + 4 - 1;
       tdep->gdb_target_is_mips64 = 0;
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 32);
@@ -5764,8 +5832,10 @@ 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->mips_last_arg_regnum = A0_REGNUM + 4 - 1; /* delete in next patch */
+      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 4 - 1; /* delete in next patch */
+      tdep->raw_regnums.last_arg_regnum = tdep->raw_regnums.a0_regnum + 4 - 1;
+      tdep->raw_regnums.last_fp_arg_regnum = tdep->raw_regnums.fpa0_regnum + 4 - 1;
       tdep->gdb_target_is_mips64 = 1;
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 32);
@@ -5783,8 +5853,10 @@ 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->mips_last_arg_regnum = A0_REGNUM + 8 - 1; /* delete in next patch */
+      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1; /* delete in next patch */
+      tdep->raw_regnums.last_arg_regnum = tdep->raw_regnums.a0_regnum + 8 - 1;
+      tdep->raw_regnums.last_fp_arg_regnum = tdep->raw_regnums.fpa0_regnum + 8 - 1;
       tdep->gdb_target_is_mips64 = 0;
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 32);
@@ -5802,8 +5874,10 @@ 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->mips_last_arg_regnum = A0_REGNUM + 8 - 1; /* delete in next patch */
+      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1; /* delete in next patch */
+      tdep->raw_regnums.last_arg_regnum = tdep->raw_regnums.a0_regnum + 8 - 1;
+      tdep->raw_regnums.last_fp_arg_regnum = tdep->raw_regnums.fpa0_regnum + 8 - 1;
       tdep->gdb_target_is_mips64 = 1;
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 64);
@@ -5821,8 +5895,10 @@ 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->mips_last_arg_regnum = A0_REGNUM + 8 - 1; /* delete in next patch */
+      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1; /* delete in next patch */
+      tdep->raw_regnums.last_arg_regnum = tdep->raw_regnums.a0_regnum + 8 - 1;
+      tdep->raw_regnums.last_fp_arg_regnum = tdep->raw_regnums.fpa0_regnum + 8 - 1;
       tdep->gdb_target_is_mips64 = 1;
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 32);
@@ -5840,8 +5916,10 @@ 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->mips_last_arg_regnum = A0_REGNUM + 8 - 1; /* delete in next patch */
+      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1; /* delete in next patch */
+      tdep->raw_regnums.last_arg_regnum = tdep->raw_regnums.a0_regnum + 8 - 1;
+      tdep->raw_regnums.last_fp_arg_regnum = tdep->raw_regnums.fpa0_regnum + 8 - 1;
       tdep->gdb_target_is_mips64 = 1;
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 64);
@@ -5857,6 +5935,32 @@ mips_gdbarch_init (struct gdbarch_info i
 		      "unknown ABI in switch");
     }
 
+  /* All raw register number initializations should now be done.  Check
+     to make sure we didn't inadvertently miss any.  Only zero_regnum
+     should still be zero.  */
+  gdb_assert (tdep->raw_regnums.zero_regnum == 0);
+  gdb_assert (tdep->raw_regnums.v0_regnum != 0);
+  gdb_assert (tdep->raw_regnums.a0_regnum != 0);
+  gdb_assert (tdep->raw_regnums.t9_regnum != 0);
+  gdb_assert (tdep->raw_regnums.sp_regnum != 0);
+  gdb_assert (tdep->raw_regnums.ra_regnum != 0);
+  gdb_assert (tdep->raw_regnums.ps_regnum != 0);
+  gdb_assert (tdep->raw_regnums.hi_regnum != 0);
+  gdb_assert (tdep->raw_regnums.lo_regnum != 0);
+  gdb_assert (tdep->raw_regnums.badvaddr_regnum != 0);
+  gdb_assert (tdep->raw_regnums.cause_regnum != 0);
+  gdb_assert (tdep->raw_regnums.pc_regnum != 0);
+  gdb_assert (tdep->raw_regnums.fcrcs_regnum != 0);
+  gdb_assert (tdep->raw_regnums.fcrir_regnum != 0);
+  gdb_assert (tdep->raw_regnums.fp0_regnum != 0);
+  gdb_assert (tdep->raw_regnums.fplast_regnum != 0);
+  gdb_assert (tdep->raw_regnums.first_embed_regnum != 0);
+  gdb_assert (tdep->raw_regnums.last_embed_regnum != 0);
+  gdb_assert (tdep->raw_regnums.prid_regnum != 0);
+  gdb_assert (tdep->raw_regnums.fpa0_regnum != 0);
+  gdb_assert (tdep->raw_regnums.last_arg_regnum != 0);
+  gdb_assert (tdep->raw_regnums.last_fp_arg_regnum != 0);
+
   /* FIXME: jlarmour/2000-04-07: There *is* a flag EF_MIPS_32BIT_MODE
      that could indicate -gp32 BUT gas/config/tc-mips.c contains the
      comment:
@@ -5992,6 +6096,11 @@ 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);
 
+  /* For many registers, the cooked and raw register numbers are the same.
+     (This set of initializations has to wait until the mips_fpu_type and
+     mips_fp_register_double determinations have been made.)  */
+  tdep->cooked_regnums = tdep->raw_regnums;
+
   return gdbarch;
 }
 
@@ -6040,6 +6149,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,
+                      "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,
+                      "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,
+                      "fpa0_regnum", regnums->fpa0_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);
+  fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+                      "last_arg_regnum", regnums->last_arg_regnum);
+  fprintf_unfiltered (file, "%s%s = %d\n", prefix,
+                      "last_fp_arg_regnum", regnums->last_fp_arg_regnum);
+}
+
+static void
 mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
@@ -6085,6 +6244,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",
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	15 May 2003 23:09:14 -0000
@@ -40,4 +40,83 @@ enum mips_abi
 /* Return the MIPS ABI associated with GDBARCH.  */
 enum mips_abi mips_abi (struct gdbarch *gdbarch);
 
+/* MIPS register numbers.  */
+struct mips_regnums
+  {
+    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 fp0_regnum;		/* First floating point register.  */
+    int fplast_regnum;		/* Last floating point register.  */
+    int fpa0_regnum;		/* First floating point register used for
+    				   passing floating point arguments.  */
+    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.  */
+
+    int last_arg_regnum;	/* Last general purpose register used for
+    				   passing arguments.  (a0_regnum is the
+				   first.)  */
+    int last_fp_arg_regnum;	/* Last floating point register used for
+    				   passing floating point arguments.  */
+  };
+
+/* There are two sets of MIPS register numbers, the "raw" numbers and
+   the "cooked" numbers.  These terms correspond roughly to the usage
+   of "cooked" vs. "raw" in the regcache code.  In many cases the
+   raw and cooked numbers will be identical.  In the cases where they
+   differ, the cooked number is a pseudo register number and the
+   corresponding raw register is used in whole or in part to determine
+   the "cooked" value.
+
+   Raw register numbers are restricted to being in the range
+   [0, NUM_REGS).  Cooked register numbers may be in the range
+   [0, NUM_REGS + NUM_PSEUDO_REGS).
+
+   Raw register numbers should be used by those (lower) layers in GDB
+   which communicate with the target and are responsible for keeping
+   GDB's regcache and the target's registers in sync.  I.e, all calls
+   to supply_register() and regcache_collect() should be using raw
+   numbers.
+
+   The cooked numbers *should* be used almost everywhere else.  They
+   aren't at the moment because substantial portions of mips-tdep.c have
+   yet to be rewritten to use the cooked numbers.  (Basically anything
+   in mips-tdep.c which is concerned with byte order and/or the
+   necessary amount to shift a register's value for putting it back
+   into it's container should probably be rewritten to use the cooked
+   numbers. 
+
+   The following conventions are used for the names of variables
+   with type ``struct mips_regnums *'':
+
+        rawnums         - the code in question uses raw numbers and
+                          should continue to use raw numbers.  I.e,
+                          it should not be converted to using cooked
+                          numbers.
+        rawnums_c       - for code which uses raw numbers, but which
+                          should be converted at some point to use
+                          cooked numbers instead.
+        cookednums      - for code which uses cooked register numbers.  */
+
+/* Fetch the MIPS "raw" register numbers.  */
+const struct mips_regnums *mips_raw_regnums (struct gdbarch *gdbarch);
+
+/* Fetch the MIPS "cooked" register numbers.  */
+const struct mips_regnums *mips_cooked_regnums (struct gdbarch *gdbarch);
+
 #endif /* MIPS_TDEP_H */


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