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]

[wip/rfc] Merge REGISTER_TO_VALUE and REGISTER_TO_TYPE


Hello,

I've been looking at merging the MIPS specific REGISTER_TO_TYPE with REGISTER_TO_VALUE but first some background.

GDB currently has three register<->type conversion methods (I'm only looking at the forward conversions here):

REGISTER_CONVERTIBLE:
REGISTER_CONVERT_TO_RAW:
REGISTER_CONVERT_TO_VIRTUAL:
Used by value_/of/_register.
They date back to when GDB was trying to raw register values into an internal form. For instance (from memory), the m68k was converting it's floating point registers into strict ieee.
These methods are no longer needed, Instead, registers are always exactly described by their type and the register's underlying contents are left unchanged. If, as with the MIPS, a register has multiple views, then it is handled by having multiple pseudo registers.


CONVERT_REGISTER_P
REGISTER_TO_VALUE
VALUE_TO_REGISTER
Use by value_/from/_register.
These methods are used to perform single register <-> value conversions. For instance, the Alpha will store integer values (variables) in floating point registers. When GDB goes to extract an integer's value it needs to perform an Alpha specific float<->integer conversion. The original code re-used REGISTER_CONVERTIBLE but was later separated out.


REGISTER_TO_TYPE
TYPE_TO_REGISTER
Used by value_/from/_register.
The MIPS uses this to convert a value spread across multiple registers (REGISTER_TO_VALUE applies to a single register only).


So ...

The REGISTER_CONVERTIBLE series is ``dead''. I should at least deprecate them. The only thing really making them stay around is the MIPS and there Kevins stuff should eliminate it. The other architectures still using them can (as the Alpha just did) simply switch to REGISTER_TO_VALUE.

As for REGISTER_TO_TYPE and REGISTER_TO_VALUE, they very much have overlapping functionality. The only significant difference is that one applies to a single register, while the second applies to multiple registers. Even the condition selecting which to apply is ``magic''.
num_storage_locs = (len > REGISTER_VIRTUAL_SIZE (regnum) ?
((len - 1) / REGISTER_RAW_SIZE (regnum)) + 1 :
1);
if (num_storage_locs > 1
... REGISTER_TO_TYPE ...
else
... REGISTER_TO_VALUE ...
(remember a register can still have different raw and virtual sizes :-()


With this in mind, I'm thinking that REGISTER_TO_TYPE and REGISTER_TO_VALUE should be merged. To that end, I can see several ways of doing it:

- Don't merge - add REGISTER_TO_TYPE to the architecture vector

- Retain the current logic - just apply REGISTER_TO_VALUE to values stored across multiple registers

- Add a frame parameter to REGISTER_TO_VALUE and make it responsible for both extracting the bytes from the register[s] and then storing them in the ``struct value''.

The last option is interesting, it would let the target draw the value from any register based on REGNUM. The i386 with its long-long problem might be interested in this (you'll notice in the patch I made an attempt at doing this only I didn't see it affect the test results).

Thoughts?

Andrew
2003-06-04  Andrew Cagney  <cagney@redhat.com>

	* mips-tdep.c (mips_value_to_register): Replace
	mips_register_convert_to_raw.

	* mips-tdep.c (mips_register_to_value): Replace
	mips_register_convert_to_virtual.
	(mips_gdbarch_init): Set conver_register_p, value_to_register and
	register_to_value.

	* i386-tdep.c (i386_convert_register_p): Replace
	i386_register_convertible.
	(i386_register_to_value): Replace
	i386_register_convert_to_virtual.
	(i386_value_to_register): Replace i386_register_convert_to_raw.

	* arch-utils.c (legacy_convert_register_p): Update.
	(legacy_register_to_value): Update.  Use "frame" to get the
	register value.

	* arch-utils.h (legacy_convert_register_p): Add "type" parameter.
	(legacy_register_to_value): Add "frame" parameter, drop "from"
	parameter.
	
	* valops.c (value_assign): Pass the value's type to
	CONVERT_REGISTER_P.

	* findvar.c (value_from_register): Rewrite.  Eliminate use of
	REGISTER_CONVERT_TO_TYPE.  Pass "type" to CONVERT_REGISTER_P.
	Pass "frame" to REGISTER_TO_VALUE.

	* gdbarch.sh (CONVERT_REGISTER_P): Add "type" parameter.
	(REGISTER_TO_VALUE): Add a "frame" and drop "from" parameter.
	* gdbarch.h, gdbarch.c: Re-generate.
	
Index: arch-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.c,v
retrieving revision 1.83
diff -u -r1.83 arch-utils.c
--- arch-utils.c	15 May 2003 22:58:36 -0000	1.83
+++ arch-utils.c	4 Jun 2003 18:34:52 -0000
@@ -440,16 +440,18 @@
 }
 
 int
-legacy_convert_register_p (int regnum)
+legacy_convert_register_p (int regnum, struct type *type)
 {
   return REGISTER_CONVERTIBLE (regnum);
 }
 
 void
-legacy_register_to_value (int regnum, struct type *type,
-			  char *from, char *to)
+legacy_register_to_value (struct frame_info *frame, int regnum,
+			  struct type *type, void *buf)
 {
-  REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to);
+  char tmp[MAX_REGISTER_SIZE];
+  frame_read_register (frame, regnum, tmp);
+  REGISTER_CONVERT_TO_VIRTUAL (regnum, type, tmp, buf);
 }
 
 void
Index: arch-utils.h
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.h,v
retrieving revision 1.46
diff -u -r1.46 arch-utils.h
--- arch-utils.h	15 May 2003 22:58:36 -0000	1.46
+++ arch-utils.h	4 Jun 2003 18:34:52 -0000
@@ -165,8 +165,8 @@
    (something that is discouraged); and to convert a register to the
    type of a corresponding variable.  These legacy functions preserve
    that overloaded behavour in existing targets.  */
-extern int legacy_convert_register_p (int regnum);
-extern void legacy_register_to_value (int regnum, struct type *type, char *from, char *to);
+extern int legacy_convert_register_p (int regnum, struct type *type);
+extern void legacy_register_to_value (struct frame_info *frame, int regnum, struct type *type, void *buf);
 extern void legacy_value_to_register (struct type *type, int regnum, char *from, char *to);
 
 /* For compatibility with older architectures, returns
Index: findvar.c
===================================================================
RCS file: /cvs/src/src/gdb/findvar.c,v
retrieving revision 1.57
diff -u -r1.57 findvar.c
--- findvar.c	2 Jun 2003 02:09:39 -0000	1.57
+++ findvar.c	4 Jun 2003 18:34:52 -0000
@@ -624,145 +624,80 @@
 struct value *
 value_from_register (struct type *type, int regnum, struct frame_info *frame)
 {
-  char raw_buffer[MAX_REGISTER_SIZE];
-  CORE_ADDR addr;
-  int optim;
   struct value *v = allocate_value (type);
-  char *value_bytes = 0;
-  int value_bytes_copied = 0;
-  int num_storage_locs;
-  enum lval_type lval;
-  int len;
-
   CHECK_TYPEDEF (type);
-  len = TYPE_LENGTH (type);
-
-  VALUE_REGNO (v) = regnum;
-
-  num_storage_locs = (len > REGISTER_VIRTUAL_SIZE (regnum) ?
-		      ((len - 1) / REGISTER_RAW_SIZE (regnum)) + 1 :
-		      1);
 
-  if (num_storage_locs > 1
-#if 0
-      // OBSOLETE #ifdef GDB_TARGET_IS_H8500
-      // OBSOLETE       || TYPE_CODE (type) == TYPE_CODE_PTR
-      // OBSOLETE #endif
-#endif
-    )
+  if (CONVERT_REGISTER_P (regnum, type))
+    {
+      int realnum;
+      int optim;
+      enum lval_type lval;
+      CORE_ADDR addr;
+      /* The ISA/ABI need to something weird when obtaining the
+         specified value from this register.  It might need to combine
+         several registers, starting with REGNUM, in a strange way
+         (see MIPS and i386).  It might need to convert the [float]
+         register into the corresponding [integer] type (see Alpha).  */
+      /* Probe the ABI to find out where this first register lives.
+         Don't fetch the value.  Use that information to describe the
+         variable location.  Then ask the ABI for the actual value.  */
+      /* Is this the best way of doing this?  The alternative would be
+         to make REGISTER_TO_VALUE entirely responsible for populating
+         the value.  */
+      frame_register (frame, regnum, &optim, &lval, &addr, &realnum, NULL);
+      REGISTER_TO_VALUE (frame, regnum, type, VALUE_CONTENTS_RAW (v));
+      VALUE_REGNO (v) = realnum;
+      VALUE_OPTIMIZED_OUT (v) = optim;
+      VALUE_LVAL (v) = lval;
+      VALUE_ADDRESS (v) = addr;
+    }
+  else
     {
-      /* Value spread across multiple storage locations.  */
-
       int local_regnum;
       int mem_stor = 0, reg_stor = 0;
       int mem_tracking = 1;
       CORE_ADDR last_addr = 0;
       CORE_ADDR first_addr = 0;
-
-      value_bytes = (char *) alloca (len + MAX_REGISTER_SIZE);
+      int first_realnum = regnum;
+      int len = TYPE_LENGTH (type);
+      int value_bytes_copied;
+      int optimized = 0;
+      char *value_bytes = (char *) alloca (len + MAX_REGISTER_SIZE);
 
       /* Copy all of the data out, whereever it may be.  */
-
-#if 0
-      // OBSOLETE #ifdef GDB_TARGET_IS_H8500
-      // OBSOLETE /* This piece of hideosity is required because the H8500 treats registers
-      // OBSOLETE    differently depending upon whether they are used as pointers or not.  As a
-      // OBSOLETE    pointer, a register needs to have a page register tacked onto the front.
-      // OBSOLETE    An alternate way to do this would be to have gcc output different register
-      // OBSOLETE    numbers for the pointer & non-pointer form of the register.  But, it
-      // OBSOLETE    doesn't, so we're stuck with this.  */
-      // OBSOLETE 
-      // OBSOLETE       if (TYPE_CODE (type) == TYPE_CODE_PTR
-      // OBSOLETE 	  && len > 2)
-      // OBSOLETE 	{
-      // OBSOLETE 	  int page_regnum;
-      // OBSOLETE 
-      // OBSOLETE 	  switch (regnum)
-      // OBSOLETE 	    {
-      // OBSOLETE 	    case R0_REGNUM:
-      // OBSOLETE 	    case R1_REGNUM:
-      // OBSOLETE 	    case R2_REGNUM:
-      // OBSOLETE 	    case R3_REGNUM:
-      // OBSOLETE 	      page_regnum = SEG_D_REGNUM;
-      // OBSOLETE 	      break;
-      // OBSOLETE 	    case R4_REGNUM:
-      // OBSOLETE 	    case R5_REGNUM:
-      // OBSOLETE 	      page_regnum = SEG_E_REGNUM;
-      // OBSOLETE 	      break;
-      // OBSOLETE 	    case R6_REGNUM:
-      // OBSOLETE 	    case R7_REGNUM:
-      // OBSOLETE 	      page_regnum = SEG_T_REGNUM;
-      // OBSOLETE 	      break;
-      // OBSOLETE 	    }
-      // OBSOLETE 
-      // OBSOLETE 	  value_bytes[0] = 0;
-      // OBSOLETE 	  get_saved_register (value_bytes + 1,
-      // OBSOLETE 			      &optim,
-      // OBSOLETE 			      &addr,
-      // OBSOLETE 			      frame,
-      // OBSOLETE 			      page_regnum,
-      // OBSOLETE 			      &lval);
-      // OBSOLETE 
-      // OBSOLETE 	  if (register_cached (page_regnum) == -1)
-      // OBSOLETE 	    return NULL;	/* register value not available */
-      // OBSOLETE 
-      // OBSOLETE 	  if (lval == lval_register)
-      // OBSOLETE 	    reg_stor++;
-      // OBSOLETE 	  else
-      // OBSOLETE 	    mem_stor++;
-      // OBSOLETE 	  first_addr = addr;
-      // OBSOLETE 	  last_addr = addr;
-      // OBSOLETE 
-      // OBSOLETE 	  get_saved_register (value_bytes + 2,
-      // OBSOLETE 			      &optim,
-      // OBSOLETE 			      &addr,
-      // OBSOLETE 			      frame,
-      // OBSOLETE 			      regnum,
-      // OBSOLETE 			      &lval);
-      // OBSOLETE 
-      // OBSOLETE 	  if (register_cached (regnum) == -1)
-      // OBSOLETE 	    return NULL;	/* register value not available */
-      // OBSOLETE 
-      // OBSOLETE 	  if (lval == lval_register)
-      // OBSOLETE 	    reg_stor++;
-      // OBSOLETE 	  else
-      // OBSOLETE 	    {
-      // OBSOLETE 	      mem_stor++;
-      // OBSOLETE 	      mem_tracking = mem_tracking && (addr == last_addr);
-      // OBSOLETE 	    }
-      // OBSOLETE 	  last_addr = addr;
-      // OBSOLETE 	}
-      // OBSOLETE       else
-      // OBSOLETE #endif /* GDB_TARGET_IS_H8500 */
-#endif
-	for (local_regnum = regnum;
-	     value_bytes_copied < len;
-	     (value_bytes_copied += REGISTER_RAW_SIZE (local_regnum),
-	      ++local_regnum))
-	  {
-	    int realnum;
-	    frame_register (frame, local_regnum, &optim, &lval, &addr,
-			    &realnum, value_bytes + value_bytes_copied);
-
-	    if (register_cached (local_regnum) == -1)
-	      return NULL;	/* register value not available */
-
-	    if (regnum == local_regnum)
+      for (local_regnum = regnum, value_bytes_copied = 0;
+	   value_bytes_copied < len;
+	   (value_bytes_copied += REGISTER_RAW_SIZE (local_regnum),
+	    ++local_regnum))
+	{
+	  int realnum;
+	  int optim;
+	  enum lval_type lval;
+	  CORE_ADDR addr;
+	  frame_register (frame, local_regnum, &optim, &lval, &addr,
+			  &realnum, value_bytes + value_bytes_copied);
+	  optimized += optim;
+	  if (register_cached (local_regnum) == -1)
+	    return NULL;	/* register value not available */
+	  
+	  if (regnum == local_regnum)
+	    {
 	      first_addr = addr;
-	    if (lval == lval_register)
-	      reg_stor++;
-	    else
-	      {
-		mem_stor++;
-
-		mem_tracking =
-		  (mem_tracking
-		   && (regnum == local_regnum
-		       || addr == last_addr));
-	      }
-	    last_addr = addr;
-	  }
-
+	      first_realnum = realnum;
+	    }
+	  if (lval == lval_register)
+	    reg_stor++;
+	  else
+	    {
+	      mem_stor++;
+	      
+	      mem_tracking = (mem_tracking
+			      && (regnum == local_regnum
+				  || addr == last_addr));
+	    }
+	  last_addr = addr;
+	}
+      
       if ((reg_stor && mem_stor)
 	  || (mem_stor && !mem_tracking))
 	/* Mixed storage; all of the hassle we just went through was
@@ -781,67 +716,29 @@
 	{
 	  VALUE_LVAL (v) = lval_register;
 	  VALUE_ADDRESS (v) = first_addr;
+	  VALUE_REGNO (v) = first_realnum;
 	}
       else
 	internal_error (__FILE__, __LINE__,
 			"value_from_register: Value not stored anywhere!");
-
-      VALUE_OPTIMIZED_OUT (v) = optim;
-
+      
+      VALUE_OPTIMIZED_OUT (v) = optimized;
+      
       /* Any structure stored in more than one register will always be
-         an integral number of registers.  Otherwise, you'd need to do
+         an integral number of registers.  Otherwise, you need to do
          some fiddling with the last register copied here for little
          endian machines.  */
-
-      /* Copy into the contents section of the value.  */
-      memcpy (VALUE_CONTENTS_RAW (v), value_bytes, len);
-
-      /* Finally do any conversion necessary when extracting this
-         type from more than one register.  */
-#ifdef REGISTER_CONVERT_TO_TYPE
-      REGISTER_CONVERT_TO_TYPE (regnum, type, VALUE_CONTENTS_RAW (v));
-#endif
-      return v;
-    }
-
-  /* Data is completely contained within a single register.  Locate the
-     register's contents in a real register or in core;
-     read the data in raw format.  */
-
-  {
-    int realnum;
-    frame_register (frame, regnum, &optim, &lval, &addr, &realnum, raw_buffer);
-  }
-
-  if (register_cached (regnum) == -1)
-    return NULL;		/* register value not available */
-
-  VALUE_OPTIMIZED_OUT (v) = optim;
-  VALUE_LVAL (v) = lval;
-  VALUE_ADDRESS (v) = addr;
-
-  /* Convert the raw register to the corresponding data value's memory
-     format, if necessary.  */
-
-  if (CONVERT_REGISTER_P (regnum))
-    {
-      REGISTER_TO_VALUE (regnum, type, raw_buffer, VALUE_CONTENTS_RAW (v));
-    }
-  else
-    {
-      /* Raw and virtual formats are the same for this register.  */
-
-      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG && len < REGISTER_RAW_SIZE (regnum))
-	{
-	  /* Big-endian, and we want less than full size.  */
-	  VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len;
-	}
-
-      memcpy (VALUE_CONTENTS_RAW (v), raw_buffer + VALUE_OFFSET (v), len);
+      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+	  && len < REGISTER_RAW_SIZE (regnum))
+	/* Big-endian, and we want less than full size.  */
+	VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len;
+      else
+	VALUE_OFFSET (v) = 0;
+      memcpy (VALUE_CONTENTS_RAW (v), value_bytes + VALUE_OFFSET (v), len);
     }
-
   return v;
 }
+
 
 /* Given a struct symbol for a variable or function,
    and a stack frame id, 
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.218
diff -u -r1.218 gdbarch.c
--- gdbarch.c	2 Jun 2003 02:54:33 -0000	1.218
+++ gdbarch.c	4 Jun 2003 18:34:53 -0000
@@ -990,8 +990,8 @@
 #ifdef CONVERT_REGISTER_P
   fprintf_unfiltered (file,
                       "gdbarch_dump: %s # %s\n",
-                      "CONVERT_REGISTER_P(regnum)",
-                      XSTRING (CONVERT_REGISTER_P (regnum)));
+                      "CONVERT_REGISTER_P(regnum, type)",
+                      XSTRING (CONVERT_REGISTER_P (regnum, type)));
   if (GDB_MULTI_ARCH)
     fprintf_unfiltered (file,
                         "gdbarch_dump: CONVERT_REGISTER_P = <0x%08lx>\n",
@@ -2140,8 +2140,8 @@
   /* Macro might contain `[{}]' when not multi-arch */
   fprintf_unfiltered (file,
                       "gdbarch_dump: %s # %s\n",
-                      "REGISTER_TO_VALUE(regnum, type, from, to)",
-                      XSTRING (REGISTER_TO_VALUE (regnum, type, from, to)));
+                      "REGISTER_TO_VALUE(frame, regnum, type, buf)",
+                      XSTRING (REGISTER_TO_VALUE (frame, regnum, type, buf)));
 #endif
   if (GDB_MULTI_ARCH)
     fprintf_unfiltered (file,
@@ -4114,7 +4114,7 @@
 }
 
 int
-gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum)
+gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type)
 {
   gdb_assert (gdbarch != NULL);
   if (gdbarch->convert_register_p == 0)
@@ -4122,7 +4122,7 @@
                     "gdbarch: gdbarch_convert_register_p invalid");
   if (gdbarch_debug >= 2)
     fprintf_unfiltered (gdb_stdlog, "gdbarch_convert_register_p called\n");
-  return gdbarch->convert_register_p (regnum);
+  return gdbarch->convert_register_p (regnum, type);
 }
 
 void
@@ -4133,7 +4133,7 @@
 }
 
 void
-gdbarch_register_to_value (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to)
+gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, void *buf)
 {
   gdb_assert (gdbarch != NULL);
   if (gdbarch->register_to_value == 0)
@@ -4141,7 +4141,7 @@
                     "gdbarch: gdbarch_register_to_value invalid");
   if (gdbarch_debug >= 2)
     fprintf_unfiltered (gdb_stdlog, "gdbarch_register_to_value called\n");
-  gdbarch->register_to_value (regnum, type, from, to);
+  gdbarch->register_to_value (frame, regnum, type, buf);
 }
 
 void
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.188
diff -u -r1.188 gdbarch.h
--- gdbarch.h	2 Jun 2003 02:54:33 -0000	1.188
+++ gdbarch.h	4 Jun 2003 18:34:53 -0000
@@ -1451,32 +1451,32 @@
 
 /* Default (function) for non- multi-arch platforms. */
 #if (!GDB_MULTI_ARCH) && !defined (CONVERT_REGISTER_P)
-#define CONVERT_REGISTER_P(regnum) (legacy_convert_register_p (regnum))
+#define CONVERT_REGISTER_P(regnum, type) (legacy_convert_register_p (regnum, type))
 #endif
 
-typedef int (gdbarch_convert_register_p_ftype) (int regnum);
-extern int gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum);
+typedef int (gdbarch_convert_register_p_ftype) (int regnum, struct type *type);
+extern int gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type);
 extern void set_gdbarch_convert_register_p (struct gdbarch *gdbarch, gdbarch_convert_register_p_ftype *convert_register_p);
 #if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CONVERT_REGISTER_P)
 #error "Non multi-arch definition of CONVERT_REGISTER_P"
 #endif
 #if !defined (CONVERT_REGISTER_P)
-#define CONVERT_REGISTER_P(regnum) (gdbarch_convert_register_p (current_gdbarch, regnum))
+#define CONVERT_REGISTER_P(regnum, type) (gdbarch_convert_register_p (current_gdbarch, regnum, type))
 #endif
 
 /* Default (function) for non- multi-arch platforms. */
 #if (!GDB_MULTI_ARCH) && !defined (REGISTER_TO_VALUE)
-#define REGISTER_TO_VALUE(regnum, type, from, to) (legacy_register_to_value (regnum, type, from, to))
+#define REGISTER_TO_VALUE(frame, regnum, type, buf) (legacy_register_to_value (frame, regnum, type, buf))
 #endif
 
-typedef void (gdbarch_register_to_value_ftype) (int regnum, struct type *type, char *from, char *to);
-extern void gdbarch_register_to_value (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to);
+typedef void (gdbarch_register_to_value_ftype) (struct frame_info *frame, int regnum, struct type *type, void *buf);
+extern void gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, void *buf);
 extern void set_gdbarch_register_to_value (struct gdbarch *gdbarch, gdbarch_register_to_value_ftype *register_to_value);
 #if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_TO_VALUE)
 #error "Non multi-arch definition of REGISTER_TO_VALUE"
 #endif
 #if !defined (REGISTER_TO_VALUE)
-#define REGISTER_TO_VALUE(regnum, type, from, to) (gdbarch_register_to_value (current_gdbarch, regnum, type, from, to))
+#define REGISTER_TO_VALUE(frame, regnum, type, buf) (gdbarch_register_to_value (current_gdbarch, frame, regnum, type, buf))
 #endif
 
 /* Default (function) for non- multi-arch platforms. */
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.240
diff -u -r1.240 gdbarch.sh
--- gdbarch.sh	2 Jun 2003 02:54:34 -0000	1.240
+++ gdbarch.sh	4 Jun 2003 18:34:55 -0000
@@ -557,8 +557,8 @@
 f:2:REGISTER_CONVERT_TO_VIRTUAL:void:register_convert_to_virtual:int regnum, struct type *type, char *from, char *to:regnum, type, from, to:::0::0
 f:2:REGISTER_CONVERT_TO_RAW:void:register_convert_to_raw:struct type *type, int regnum, char *from, char *to:type, regnum, from, to:::0::0
 #
-f:1:CONVERT_REGISTER_P:int:convert_register_p:int regnum:regnum::0:legacy_convert_register_p::0
-f:1:REGISTER_TO_VALUE:void:register_to_value:int regnum, struct type *type, char *from, char *to:regnum, type, from, to::0:legacy_register_to_value::0
+f:1:CONVERT_REGISTER_P:int:convert_register_p:int regnum, struct type *type:regnum, type::0:legacy_convert_register_p::0
+f:1:REGISTER_TO_VALUE:void:register_to_value:struct frame_info *frame, int regnum, struct type *type, void *buf:frame, regnum, type, buf::0:legacy_register_to_value::0
 f:1:VALUE_TO_REGISTER:void:value_to_register:struct type *type, int regnum, char *from, char *to:type, regnum, from, to::0:legacy_value_to_register::0
 #
 f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, const void *buf:type, buf:::unsigned_pointer_to_address::0
Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.151
diff -u -r1.151 i386-tdep.c
--- i386-tdep.c	2 Jun 2003 02:54:35 -0000	1.151
+++ i386-tdep.c	4 Jun 2003 18:34:56 -0000
@@ -1326,52 +1326,55 @@
    this is still sloppy.  */
 
 static int
-i386_register_convertible (int regnum)
+i386_convert_register_p (int regnum, struct type *type)
 {
-  return i386_fp_regnum_p (regnum);
+  if (i386_fp_regnum_p (regnum)
+      && TYPE_CODE (type) != TYPE_CODE_FLT)
+    /* Floating point registers have different register and memory
+       representations and hence need converting.  */
+    return 1;
+  if (regnum < 3
+      && TYPE_CODE (type) == TYPE_CODE_INT
+      && TYPE_LENGTH (type) == 8)
+    /* A long long in registers, apparently GCC uses a set pair of
+       registers but they are not contigious.  */
+    return 1;
+  /* Nothing interesting.  */
+  return 0;
 }
 
 /* Convert data from raw format for register REGNUM in buffer FROM to
    virtual format with type TYPE in buffer TO.  */
 
+/* GCC allocates registers in the following order.  */
+static int next_int64_regnum[] = {  /*ax,dx,cx,bx*/ 2, 1, 3, };
+
 static void
-i386_register_convert_to_virtual (int regnum, struct type *type,
-				  char *from, char *to)
+i386_register_to_value (struct frame_info *frame, int regnum,
+			struct type *type, void *to)
 {
-  gdb_assert (i386_fp_regnum_p (regnum));
-
-  /* We only support floating-point values.  */
-  if (TYPE_CODE (type) != TYPE_CODE_FLT)
+  if (i386_fp_regnum_p (regnum))
     {
-      warning ("Cannot convert floating-point register value "
-	       "to non-floating-point type.");
-      memset (to, 0, TYPE_LENGTH (type));
-      return;
+      char from[MAX_REGISTER_SIZE];
+      /* Read/convert to TYPE.  This should be a no-op if TYPE is
+	 equivalent to the extended floating-point format used by the
+	 FPU.  */
+      frame_read_register (frame, regnum, from);
+      convert_typed_floating (from, builtin_type_i387_ext, to, type);
+    }
+  else if (regnum < 3)
+    {
+      frame_read_register (frame, regnum, to);
+      frame_read_register (frame, next_int64_regnum[regnum], (char *) to + 4);
     }
-
-  /* Convert to TYPE.  This should be a no-op if TYPE is equivalent to
-     the extended floating-point format used by the FPU.  */
-  convert_typed_floating (from, builtin_type_i387_ext, to, type);
 }
 
 /* Convert data from virtual format with type TYPE in buffer FROM to
    raw format for register REGNUM in buffer TO.  */
 
 static void
-i386_register_convert_to_raw (struct type *type, int regnum,
-			      char *from, char *to)
+i386_value_to_register (struct type *type, int regnum, char *from, char *to)
 {
-  gdb_assert (i386_fp_regnum_p (regnum));
-
-  /* We only support floating-point values.  */
-  if (TYPE_CODE (type) != TYPE_CODE_FLT)
-    {
-      warning ("Cannot convert non-floating-point type "
-	       "to floating-point register value.");
-      memset (to, 0, TYPE_LENGTH (type));
-      return;
-    }
-
   /* Convert from TYPE.  This should be a no-op if TYPE is equivalent
      to the extended floating-point format used by the FPU.  */
   convert_typed_floating (from, type, to, builtin_type_i387_ext);
@@ -1686,10 +1689,9 @@
   /* Call dummy code.  */
   set_gdbarch_push_dummy_call (gdbarch, i386_push_dummy_call);
 
-  set_gdbarch_register_convertible (gdbarch, i386_register_convertible);
-  set_gdbarch_register_convert_to_virtual (gdbarch,
-					   i386_register_convert_to_virtual);
-  set_gdbarch_register_convert_to_raw (gdbarch, i386_register_convert_to_raw);
+  set_gdbarch_convert_register_p (gdbarch, i386_convert_register_p);
+  set_gdbarch_register_to_value (gdbarch, i386_register_to_value);
+  set_gdbarch_value_to_register (gdbarch, i386_value_to_register);
 
   set_gdbarch_extract_return_value (gdbarch, i386_extract_return_value);
   set_gdbarch_store_return_value (gdbarch, i386_store_return_value);
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.207
diff -u -r1.207 mips-tdep.c
--- mips-tdep.c	1 Jun 2003 19:02:19 -0000	1.207
+++ mips-tdep.c	4 Jun 2003 18:34:57 -0000
@@ -634,9 +634,28 @@
 	    TYPE_LENGTH (virtual_type));
 }
 
+static int
+mips_convert_register_p (int regnum, struct type *type)
+{
+  return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+	  && REGISTER_RAW_SIZE (regnum) == 4
+	  && (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
+	  && TYPE_CODE(type) == TYPE_CODE_FLT
+	  && TYPE_LENGTH(type) == 8);
+}
+
+void
+mips_register_to_value (struct frame_info *frame, int regnum,
+			struct type *type, void *buffer)
+{
+  frame_read_register (frame, regnum + 0, (char *) buffer + 4);
+  frame_read_register (frame, regnum + 1, buffer);
+}
+
 void
-mips_register_convert_to_type (int regnum, struct type *type, char *buffer)
+mips_value_to_register (struct type *type, int regnum, char *in, char *out)
 {
+#if 0
   if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
       && REGISTER_RAW_SIZE (regnum) == 4
       && (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
@@ -646,24 +665,9 @@
       char temp[4];
       memcpy (temp, ((char *)(buffer))+4, 4);
       memcpy (((char *)(buffer))+4, (buffer), 4);
-      memcpy (((char *)(buffer)), temp, 4); 
+      memcpy (((char *)(buffer)), temp, 4);
     }
-}
-
-void
-mips_register_convert_from_type (int regnum, struct type *type, char *buffer)
-{
-if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
-    && REGISTER_RAW_SIZE (regnum) == 4
-    && (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
-    && TYPE_CODE(type) == TYPE_CODE_FLT
-    && TYPE_LENGTH(type) == 8) 
-  {
-    char temp[4];
-    memcpy (temp, ((char *)(buffer))+4, 4);
-    memcpy (((char *)(buffer))+4, (buffer), 4);
-    memcpy (((char *)(buffer)), temp, 4);
-  }
+#endif
 }
 
 /* Return the GDB type object for the "standard" data type
@@ -5961,11 +5965,9 @@
   set_gdbarch_deprecated_pop_frame (gdbarch, mips_pop_frame);
   set_gdbarch_frame_align (gdbarch, mips_frame_align);
   set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
-  set_gdbarch_register_convertible (gdbarch, mips_register_convertible);
-  set_gdbarch_register_convert_to_virtual (gdbarch, 
-					   mips_register_convert_to_virtual);
-  set_gdbarch_register_convert_to_raw (gdbarch, 
-				       mips_register_convert_to_raw);
+  set_gdbarch_convert_register_p (gdbarch, mips_convert_register_p);
+  set_gdbarch_register_to_value (gdbarch, mips_register_to_value);
+  set_gdbarch_value_to_register (gdbarch, mips_value_to_register);
 
   set_gdbarch_deprecated_frame_chain (gdbarch, mips_frame_chain);
   set_gdbarch_frameless_function_invocation (gdbarch, 
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.109
diff -u -r1.109 valops.c
--- valops.c	14 May 2003 17:43:20 -0000	1.109
+++ valops.c	4 Jun 2003 18:34:58 -0000
@@ -501,10 +501,13 @@
      convert FROMVAL's contents now, with result in `raw_buffer',
      and set USE_BUFFER to the number of bytes to write.  */
 
+  /* FIXME: Should instead do this in the below switch when it is
+     clear that this really is a lval_register that needs conversion.  */
+
   if (VALUE_REGNO (toval) >= 0)
     {
       int regno = VALUE_REGNO (toval);
-      if (CONVERT_REGISTER_P (regno))
+      if (CONVERT_REGISTER_P (regno, VALUE_TYPE (toval)))
 	{
 	  struct type *fromtype = check_typedef (VALUE_TYPE (fromval));
 	  VALUE_TO_REGISTER (fromtype, regno, VALUE_CONTENTS (fromval), raw_buffer);
@@ -661,9 +664,11 @@
 		    TYPE_LENGTH (type));
 	    /* Do any conversion necessary when storing this type to
 	       more than one register.  */
+#if 0
 #ifdef REGISTER_CONVERT_FROM_TYPE
 	    REGISTER_CONVERT_FROM_TYPE (value_reg, type,
 					(buffer + byte_offset));
+#endif
 #endif
 	  }
 

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