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]

Re: [rfa] Add e500 function call support to PPC



For the time being, how about introducing a predicate (function) to
ppc-sysv-tdep.c (or perhaps rs6000-tdep.c) named
have_floating_point_registers_p() (or something along those lines).

In the short term this could be defined as:

int
have_floating_point_registers_p (struct gdbarch *gdbarch)
{
  const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);

  /* Note: It has been proposed that a ``ppc_fp0_regnum'' member be added
     to the ppc tdep struct.  If/when this occurs, it may be preferable to
     implement this as:

struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

       return tdep->ppc_fp0_regnum >= 0;
   */

  return arch_info->mach != bfd_mach_ppc_e500;
}

I called it ppc_floating_point_unit_p().


It occurs to me that such a predicate would be useful for checking
the state of a global variable in the event that a command similar to
``set nomipsfpu'' were added for the powerpc.  (Well, maybe.  Then
again, maybe it'd be better to just set ppc_fp0_regnum to -1 when
such a setting were made.)

It is definitly better than a ppc_fp0_regnum test. As with the MIPS, it's one thing to have FP registers, it is another to use them.


In any event, a name like have_floating_point_registers_p() is
reasonably self docuementing whereas ``tdep->ppc_fp0_regnum >= 0''
requires a little bit more thought to discern the meaning.

How about the attached?


Andrew

2003-03-17  Andrew Cagney  <cagney at redhat dot com>

	* rs6000-tdep.c (ppc_floating_point_unit_p): New function.
	* ppc-tdep.h (ppc_floating_point_unit_p): Declare.

	From Elena Zannoni  <ezannoni at redhat dot com>
	* ppc-sysv-tdep.c (ppc_sysv_abi_push_arguments): Handle e500
	vector and floating-point parameters.
	(ppc_sysv_abi_use_struct_convention): Handle e500 struct return
	convention.
	(ppc_sysv_abi_broken_use_struct_convention): Ditto.

Index: ppc-sysv-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-sysv-tdep.c,v
retrieving revision 1.3
diff -u -r1.3 ppc-sysv-tdep.c
--- ppc-sysv-tdep.c	14 Nov 2002 20:37:28 -0000	1.3
+++ ppc-sysv-tdep.c	17 Mar 2003 16:43:36 -0000
@@ -61,11 +61,12 @@
   int structstkspace;
   int argoffset;
   int structoffset;
-  struct value *arg;
   struct type *type;
   int len;
   char old_sp_buf[4];
   CORE_ADDR saved_sp;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (current_gdbarch);
 
   greg = struct_return ? 4 : 3;
   freg = 1;
@@ -79,11 +80,12 @@
      are put in registers. */
   for (argno = 0; argno < nargs; argno++)
     {
-      arg = args[argno];
+      struct value *arg = args[argno];
       type = check_typedef (VALUE_TYPE (arg));
       len = TYPE_LENGTH (type);
 
-      if (TYPE_CODE (type) == TYPE_CODE_FLT)
+      if (TYPE_CODE (type) == TYPE_CODE_FLT
+          && ppc_floating_point_unit_p (current_gdbarch))
 	{
 	  if (freg <= 8)
 	    freg++;
@@ -96,7 +98,10 @@
 	      argstkspace += 8;
 	    }
 	}
-      else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8)	/* long long */
+      else if (len == 8 
+               && (TYPE_CODE (type) == TYPE_CODE_INT /* long long */
+                   || (!ppc_floating_point_unit_p (current_gdbarch)
+                       && TYPE_CODE (type) == TYPE_CODE_FLT))) /* double */
 	{
 	  if (greg > 9)
 	    {
@@ -144,6 +149,20 @@
 		  argstkspace += 16;
 		}
 	    }
+          else if (len == 8 
+                   && TYPE_CODE (type) == TYPE_CODE_ARRAY
+                   && TYPE_VECTOR (type))
+            {
+              if (greg <= 10)
+                greg++;
+              else
+                {
+                  /* Vector arguments must be aligned to 8 bytes on
+                     the stack. */
+                  argstkspace += round2 (argstkspace, 8);
+                  argstkspace += 8;
+                }
+            }
 	}
     }
 
@@ -170,30 +189,33 @@
   freg = 1;
   greg = 3;
   vreg = 2;
+
   /* Fill in r3 with the return structure, if any */
   if (struct_return)
     {
-      char val_buf[4];
-      store_address (val_buf, 4, struct_addr);
-      memcpy (&deprecated_registers[REGISTER_BYTE (greg)], val_buf, 4);
+      write_register (tdep->ppc_gp0_regnum + greg, struct_addr);
       greg++;
     }
+
   /* Now fill in the registers and stack... */
   for (argno = 0; argno < nargs; argno++)
     {
-      arg = args[argno];
+      struct value *arg = args[argno];
+      char *val = VALUE_CONTENTS (arg);
       type = check_typedef (VALUE_TYPE (arg));
       len = TYPE_LENGTH (type);
 
-      if (TYPE_CODE (type) == TYPE_CODE_FLT)
+      if (TYPE_CODE (type) == TYPE_CODE_FLT
+          && ppc_floating_point_unit_p (current_gdbarch))
 	{
 	  if (freg <= 8)
 	    {
+	      ULONGEST regval;
 	      if (len > 8)
 		printf_unfiltered (
 				   "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
-	      memcpy (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM + freg)],
-		      VALUE_CONTENTS (arg), len);
+              regval = extract_unsigned_integer (val, len);
+              write_register (FP0_REGNUM + freg, regval);
 	      freg++;
 	    }
 	  else
@@ -203,29 +225,32 @@
 	      /* FIXME: Convert floats to doubles */
 	      if (argoffset & 0x4)
 		argoffset += 4;
-	      write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+	      write_memory (sp + argoffset, val, len);
 	      argoffset += 8;
 	    }
 	}
-      else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8)	/* long long */
+      else if (len == 8 
+               && (TYPE_CODE (type) == TYPE_CODE_INT /* long long */
+                   || (!ppc_floating_point_unit_p (current_gdbarch)
+                        && TYPE_CODE (type) == TYPE_CODE_FLT))) /* double */
 	{
 	  if (greg > 9)
 	    {
 	      greg = 11;
 	      if (argoffset & 0x4)
 		argoffset += 4;
-	      write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+	      write_memory (sp + argoffset, val, len);
 	      argoffset += 8;
 	    }
 	  else
 	    {
+	      ULONGEST regval;
 	      if ((greg & 1) == 0)
 		greg++;
-
-	      memcpy (&deprecated_registers[REGISTER_BYTE (greg)],
-		      VALUE_CONTENTS (arg), 4);
-	      memcpy (&deprecated_registers[REGISTER_BYTE (greg + 1)],
-		      VALUE_CONTENTS (arg) + 4, 4);
+              regval = extract_unsigned_integer (val, 4);
+              write_register (tdep->ppc_gp0_regnum + greg, regval);
+              regval = extract_unsigned_integer (val + 4, 4);
+              write_register (tdep->ppc_gp0_regnum + greg + 1, regval);
 	      greg += 2;
 	    }
 	}
@@ -236,18 +261,19 @@
 	      || TYPE_CODE (type) == TYPE_CODE_STRUCT
 	      || TYPE_CODE (type) == TYPE_CODE_UNION)
 	    {
-	      write_memory (sp + structoffset, VALUE_CONTENTS (arg), len);
+	      write_memory (sp + structoffset, val, len);
 	      store_address (val_buf, 4, sp + structoffset);
 	      structoffset += round2 (len, 8);
 	    }
 	  else
 	    {
 	      memset (val_buf, 0, 4);
-	      memcpy (val_buf, VALUE_CONTENTS (arg), len);
+	      memcpy (val_buf, val, len);
 	    }
 	  if (greg <= 10)
 	    {
-	      memcpy (&deprecated_registers[REGISTER_BYTE (greg)], val_buf, 4);
+              ULONGEST regval = extract_unsigned_integer (val_buf, 4);
+              write_register (tdep->ppc_gp0_regnum + greg, regval);
 	      greg++;
 	    }
 	  else
@@ -262,15 +288,14 @@
 	      && TYPE_CODE (type) == TYPE_CODE_ARRAY
 	      && TYPE_VECTOR (type))
 	    {
-	      struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
 	      char *v_val_buf = alloca (16);
 	      memset (v_val_buf, 0, 16);
-	      memcpy (v_val_buf, VALUE_CONTENTS (arg), len);
+	      memcpy (v_val_buf, val, len);
 	      if (vreg <= 13)
 		{
-		  memcpy (&deprecated_registers[REGISTER_BYTE (tdep->ppc_vr0_regnum
-						    + vreg)],
-			  v_val_buf, 16);
+		  regcache_cooked_write (current_regcache,
+					 tdep->ppc_vr0_regnum + vreg,
+					 v_val_buf);
 		  vreg++;
 		}
 	      else
@@ -279,6 +304,26 @@
 		  argoffset += 16;
 		}
 	    }
+          else if (len == 8 
+		   && TYPE_CODE (type) == TYPE_CODE_ARRAY
+		   && TYPE_VECTOR (type))
+            {
+              char *v_val_buf = alloca (8);
+              memset (v_val_buf, 0, 8);
+              memcpy (v_val_buf, val, len);
+              if (greg <= 10)
+                {
+		  regcache_cooked_write (current_regcache,
+					 tdep->ppc_ev0_regnum + greg,
+					 v_val_buf);
+                  greg++;
+                }
+              else
+                {
+                  write_memory (sp + argoffset, v_val_buf, 8);
+                  argoffset += 8;
+                }
+            }
         }
     }
 
@@ -293,7 +338,7 @@
 int     
 ppc_sysv_abi_broken_use_struct_convention (int gcc_p, struct type *value_type)
 {  
-  if (TYPE_LENGTH (value_type) == 16 
+  if ((TYPE_LENGTH (value_type) == 16 || TYPE_LENGTH (value_type) == 8)
       && TYPE_VECTOR (value_type))
     return 0;                            
 
@@ -305,7 +350,7 @@
 int
 ppc_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
 {
-  if (TYPE_LENGTH (value_type) == 16
+  if ((TYPE_LENGTH (value_type) == 16 || TYPE_LENGTH (value_type) == 8)
       && TYPE_VECTOR (value_type))
     return 0;
 
Index: ppc-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/ppc-tdep.h,v
retrieving revision 1.14
diff -u -r1.14 ppc-tdep.h
--- ppc-tdep.h	4 Jan 2003 23:38:45 -0000	1.14
+++ ppc-tdep.h	17 Mar 2003 16:43:36 -0000
@@ -49,6 +49,11 @@
 CORE_ADDR rs6000_frame_chain (struct frame_info *);
 int altivec_register_p (int regno);
 
+
+/* Return non-zero when the architecture has an FPU (or at least when
+   the ABI is using the FPU).  */
+int ppc_floating_point_unit_p (struct gdbarch *gdbarch);
+
 /* Private data that this module attaches to struct gdbarch. */
 
 struct gdbarch_tdep
Index: rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.111
diff -u -r1.111 rs6000-tdep.c
--- rs6000-tdep.c	13 Mar 2003 21:45:41 -0000	1.111
+++ rs6000-tdep.c	17 Mar 2003 16:43:38 -0000
@@ -137,6 +137,18 @@
     return (regno >= tdep->ppc_vr0_regnum && regno <= tdep->ppc_vrsave_regnum);
 }
 
+/* Use the architectures FP registers?  */
+int
+ppc_floating_point_unit_p (struct gdbarch *gdbarch)
+{
+  const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch);
+  if (info->arch == bfd_arch_powerpc)
+    return (info->mach != bfd_mach_ppc_e500);
+  if (info->arch == bfd_arch_rs6000)
+    return 1;
+  return 0;
+}
+
 /* Read a LEN-byte address from debugged memory address MEMADDR. */
 
 static CORE_ADDR

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