Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFA] MIPS: Introduce struct mips_regnums and accessors
@ 2003-05-15 23:51 Kevin Buettner
  2003-05-21 19:39 ` Andrew Cagney
  0 siblings, 1 reply; 6+ messages in thread
From: Kevin Buettner @ 2003-05-15 23:51 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

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 */


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFA] MIPS: Introduce struct mips_regnums and accessors
  2003-05-15 23:51 [RFA] MIPS: Introduce struct mips_regnums and accessors Kevin Buettner
@ 2003-05-21 19:39 ` Andrew Cagney
  2003-05-21 20:40   ` Kevin Buettner
  0 siblings, 1 reply; 6+ messages in thread
From: Andrew Cagney @ 2003-05-21 19:39 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb-patches

Kevin,

I think the struct contains too many redudnant fields.  Instead it can 
be be trimmed back to identify just the boundaries between the different 
register groups vis:

- gp0 (gp31?)
- fp0
- hi, lo
- pc
- various status registers
- others?

As for assigning meaning to specific registers (v0, a0, ...) within a 
group, offsets can be used vis:

	v0_regnum (regnums) === regnums->gp0 + offset;

With regard to having only 16 o32 FP registers, is that right?  Does it 
just confuse things?  Doesn't the o32 debug info assume a bank of 32 
contigious 32 bit registers?  A location expression for a double in 
``f0'' would be f0:f1 for instance.

Andrew


> +/* 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.  */
> +  };



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFA] MIPS: Introduce struct mips_regnums and accessors
  2003-05-21 19:39 ` Andrew Cagney
@ 2003-05-21 20:40   ` Kevin Buettner
  2003-05-22 19:41     ` Andrew Cagney
  0 siblings, 1 reply; 6+ messages in thread
From: Kevin Buettner @ 2003-05-21 20:40 UTC (permalink / raw)
  To: Andrew Cagney, Kevin Buettner; +Cc: gdb-patches

On May 21,  3:38pm, Andrew Cagney wrote:

> I think the struct contains too many redudnant fields.

Redundant?  In what way?

> Instead it can 
> be be trimmed back to identify just the boundaries between the different 
> register groups vis:
> 
> - gp0 (gp31?)
> - fp0
> - hi, lo
> - pc
> - various status registers
> - others?

With the exception of fplast (which I added), the member names are
identical to the macro names used in tm-mips.h.  I did this to make
it easier to convert *_REGNUM to using the struct members.

> As for assigning meaning to specific registers (v0, a0, ...) within a 
> group, offsets can be used vis:
> 
> 	v0_regnum (regnums) === regnums->gp0 + offset;

This makes it much more difficult to do an obvious conversion from
(e.g.) V0_REGNUM to rawnums->v0_regnum.  Also, do you really think
it's preferable to have to say:

    regnums->gp0 + regnumoffsets->v0_offset

instead of

    regnums->v0_regnum

?

I like the last one better due to it's being more concise.  The
initialization may be a little bit harder, but using them will be
easier and more error free.  E.g, with the style you advocate, it's
possible to say ``regnums->fp0 + regnumoffsets->v0_offset'', but
that was very likely an error on the part of the author.

Anyway, I am firmly against the offset idea.

I _do_ think, however, it would be useful to have gp0_regnum
and gplast_regnum members at some point.  I considered adding them,
but decided against it on the grounds that the first step to
converting from _REGNUM to rawnums->_regnum should be as obvious
and straightforward as possible.

> With regard to having only 16 o32 FP registers, is that right?

I think so, yes.  I've been told that for o32 you only really have
16 FP registers.

> Does it just confuse things?  Doesn't the o32 debug info assume a bank of 32 
> contigious 32 bit registers? 

As I understand it, the odd register numbers are never used.

I have the {stab,ecoff,dwarf,dwarf2}_reg_to_regnum functions convert to
the appropriate cooked numbers.

I think things will end up being much more confused if you somehow
throw the odd registers into the mix.  Consider iterating over the set
of cooked floating point registers.  If we throw the odd numbered
registers in somehow, we'll have to arrange to skip them in most
circumstances.

Also, if we do throw in the odd registers, what should their types
be?

> A location expression for a double in 
> ``f0'' would be f0:f1 for instance.

I don't think that's the representation.  I.e, you only see the f0, not
the f1.  I can arrange for a warning or error for odd registers if you
like.

> > +/* 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.  */
> > +  };


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFA] MIPS: Introduce struct mips_regnums and accessors
  2003-05-21 20:40   ` Kevin Buettner
@ 2003-05-22 19:41     ` Andrew Cagney
  2003-05-22 20:16       ` Kevin Buettner
  0 siblings, 1 reply; 6+ messages in thread
From: Andrew Cagney @ 2003-05-22 19:41 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb-patches

> On May 21,  3:38pm, Andrew Cagney wrote:
> 
> 
>> I think the struct contains too many redudnant fields.
> 
> 
> Redundant?  In what way?
> 
> 
>> Instead it can 
>> be be trimmed back to identify just the boundaries between the different 
>> register groups vis:
>> 
>> - gp0 (gp31?)
>> - fp0
>> - hi, lo
>> - pc
>> - various status registers
>> - others?
> 
> 
> With the exception of fplast (which I added), the member names are
> identical to the macro names used in tm-mips.h.  I did this to make
> it easier to convert *_REGNUM to using the struct members.
> 
> 
>> As for assigning meaning to specific registers (v0, a0, ...) within a 
>> group, offsets can be used vis:
>> 
>> 	v0_regnum (regnums) === regnums->gp0 + offset;
> 
> 
> This makes it much more difficult to do an obvious conversion from
> (e.g.) V0_REGNUM to rawnums->v0_regnum.  Also, do you really think
> it's preferable to have to say:
> 
>     regnums->gp0 + regnumoffsets->v0_offset
> 
> instead of
> 
>     regnums->v0_regnum
> 
> ?

Sorry, I'm lost.  The patch contains:

+  /* 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;

and, at least for v0_regnum, it doesn't change.  V0 is an offset in the 
selected block of registers.  It could be either:

	enum { V0_OFFSET = 2 };

	cookednum->gp0 + V0_OFFSET
or
	rawnum->gp0 + V0_OFFSET

however, either way, it doesn't change.  The only thing that changes is 
things like where the general purpose, for floating point, registers start.

Andrew


> I like the last one better due to it's being more concise.  The
> initialization may be a little bit harder, but using them will be
> easier and more error free.  E.g, with the style you advocate, it's
> possible to say ``regnums->fp0 + regnumoffsets->v0_offset'', but
> that was very likely an error on the part of the author.
> 
> Anyway, I am firmly against the offset idea.
> 
> I _do_ think, however, it would be useful to have gp0_regnum
> and gplast_regnum members at some point.  I considered adding them,
> but decided against it on the grounds that the first step to
> converting from _REGNUM to rawnums->_regnum should be as obvious
> and straightforward as possible.
> 
> 
>> With regard to having only 16 o32 FP registers, is that right?
> 
> 
> I think so, yes.  I've been told that for o32 you only really have
> 16 FP registers.
> 
> 
>> Does it just confuse things?  Doesn't the o32 debug info assume a bank of 32 
>> contigious 32 bit registers? 
> 
> 
> As I understand it, the odd register numbers are never used.
> 
> I have the {stab,ecoff,dwarf,dwarf2}_reg_to_regnum functions convert to
> the appropriate cooked numbers.
> 
> I think things will end up being much more confused if you somehow
> throw the odd registers into the mix.  Consider iterating over the set
> of cooked floating point registers.  If we throw the odd numbered
> registers in somehow, we'll have to arrange to skip them in most
> circumstances.
> 
> Also, if we do throw in the odd registers, what should their types
> be?
> 
> 
>> A location expression for a double in 
>> ``f0'' would be f0:f1 for instance.
> 
> 
> I don't think that's the representation.  I.e, you only see the f0, not
> the f1.  I can arrange for a warning or error for odd registers if you
> like.
> 
> 
>> > +/* 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.  */
>> > +  };
> 
> 



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFA] MIPS: Introduce struct mips_regnums and accessors
  2003-05-22 19:41     ` Andrew Cagney
@ 2003-05-22 20:16       ` Kevin Buettner
  2003-06-15 18:37         ` Andrew Cagney
  0 siblings, 1 reply; 6+ messages in thread
From: Kevin Buettner @ 2003-05-22 20:16 UTC (permalink / raw)
  To: Andrew Cagney, Kevin Buettner; +Cc: gdb-patches

On May 22,  3:40pm, Andrew Cagney wrote:

> +  /* 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;
> 
> and, at least for v0_regnum, it doesn't change.  V0 is an offset in the 
> selected block of registers.  It could be either:
> 
> 	enum { V0_OFFSET = 2 };
> 
> 	cookednum->gp0 + V0_OFFSET
> or
> 	rawnum->gp0 + V0_OFFSET
> 
> however, either way, it doesn't change.  The only thing that changes is 
> things like where the general purpose, for floating point, registers start.

I have the following objections to the use of offsets:

    1) They don't work for floating point registers.  (That's assuming
       that I can convince you that it's desirable to have 16 cooked
       registers for o32...)  The reason that it won't work is that,
       e.g, an FPA0_OFFSET will need to have different values for the
       raw and cooked cases.
    2) The conversion from *_REGNUM is much less transparent.
    3) The use of offsets is more error prone.  There's nothing to
       prevent you from adding an offset to the wrong boundary start.
    4) The notation is more cumbersome.

Furthermore, I really don't understand the problem that you had with
my proposed layout.  Could you please explain the underlying reasons
for proposing the offset idea?  E.g, are you concerned about the
initialization and the maintenance thereof?  Or do you just want to
present a minimal view of the raw register numbers to clients outside
of mips-tdep.c?  Or something else altogether?

Kevin


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFA] MIPS: Introduce struct mips_regnums and accessors
  2003-05-22 20:16       ` Kevin Buettner
@ 2003-06-15 18:37         ` Andrew Cagney
  0 siblings, 0 replies; 6+ messages in thread
From: Andrew Cagney @ 2003-06-15 18:37 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb-patches


> I have the following objections to the use of offsets:
> 
>     1) They don't work for floating point registers.  (That's assuming
>        that I can convince you that it's desirable to have 16 cooked
>        registers for o32...)  The reason that it won't work is that,
>        e.g, an FPA0_OFFSET will need to have different values for the
>        raw and cooked cases.

I think the MIPS has the following:

- raw registers
These are pretty messed up.  register_raw_size, for instance returns a 
value determined by the ABI.  In theory though, this is just a raw buffer.

- ABI / debug info registers
Currently represented by the virtual registers [sort of].  This is the 
first view onto the raw registers and is ment to provide something that 
the ABI / debug info, rather than ISA, expects.  For o32 there would be 
32 32 bit GPRs and 32 32 bit FPRs.

- cli registers
This is further layer, providing a view into the above raw (and possibly 
ABI) registers.  These are the $registers that the user manipulates from 
the CLI.  Here, having 64 bit word-swapping o32 FPRs would be useful 
(but I don't think their usefulness extends back to the ABI - that would 
result in cross purposes and unnecessary complexity).

I get the feeling here that you're trying to fix the third problem, 
addressing the second as a side effect, while I'm worried about fixing 
the second (improving the third as a side effect).

Re-thinking the problem, and given the above, I think it might be better 
to provide three register maps:

[0 * NUM_REGS .. 1 * NUM_REGS):
The raw register buffer.
[1 * NUM_REGS .. 2 * NUM_REGS):
The ABI registers, mapped onto the raw register set.
[2 * NUM_REGS .. 3 * NUM_REGS):
The CLI register view, mapped onto RAW (also ABI?) registers.
(Perhaps the CLI can steal some of the ABI registers).

It should be possible to brute force the second map (I'll try for a 
patch), and then layer the CLI map onto that and the raw registers.

Andrew


>     2) The conversion from *_REGNUM is much less transparent.
>     3) The use of offsets is more error prone.  There's nothing to
>        prevent you from adding an offset to the wrong boundary start.
>     4) The notation is more cumbersome.
> 
> Furthermore, I really don't understand the problem that you had with
> my proposed layout.  Could you please explain the underlying reasons
> for proposing the offset idea?  E.g, are you concerned about the
> initialization and the maintenance thereof?  Or do you just want to
> present a minimal view of the raw register numbers to clients outside
> of mips-tdep.c?  Or something else altogether?
> 
> Kevin
> 



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2003-06-15 18:37 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-05-15 23:51 [RFA] MIPS: Introduce struct mips_regnums and accessors Kevin Buettner
2003-05-21 19:39 ` Andrew Cagney
2003-05-21 20:40   ` Kevin Buettner
2003-05-22 19:41     ` Andrew Cagney
2003-05-22 20:16       ` Kevin Buettner
2003-06-15 18:37         ` Andrew Cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox