2003-03-17 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Mon, 17 Mar 2003 18:27:07 +0000 (18:27 +0000)
committerAndrew Cagney <cagney@redhat.com>
Mon, 17 Mar 2003 18:27:07 +0000 (18:27 +0000)
* rs6000-tdep.c (ppc_floating_point_unit_p): New function.
* ppc-tdep.h (ppc_floating_point_unit_p): Declare.

From Elena Zannoni  <ezannoni@redhat.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.

gdb/ChangeLog
gdb/ppc-sysv-tdep.c
gdb/ppc-tdep.h
gdb/rs6000-tdep.c

index aaee5c2..7818695 100644 (file)
@@ -1,3 +1,15 @@
+2003-03-17  Andrew Cagney  <cagney@redhat.com>
+
+       * rs6000-tdep.c (ppc_floating_point_unit_p): New function.
+       * ppc-tdep.h (ppc_floating_point_unit_p): Declare.
+
+       From Elena Zannoni  <ezannoni@redhat.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.
+
 2003-03-17  Fernando Nasser  <fnasser@redhat.com>
 
        * MAINTAINERS: Remove my name from several maintainership roles.
index 1f01706..9894a58 100644 (file)
@@ -61,11 +61,11 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
   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);
 
   greg = struct_return ? 4 : 3;
   freg = 1;
@@ -79,11 +79,12 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
      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 +97,10 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
              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 +148,20 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
                  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 +188,33 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
   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 +224,32 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
              /* 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 +260,19 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
              || 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 +287,14 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
              && 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 +303,26 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
                  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 +337,7 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
 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 +349,7 @@ ppc_sysv_abi_broken_use_struct_convention (int gcc_p, struct type *value_type)
 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 cf81eb9..f3c022c 100644 (file)
@@ -49,6 +49,11 @@ void rs6000_frame_init_saved_regs (struct frame_info *);
 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 46733a3..6d95aaf 100644 (file)
@@ -137,6 +137,18 @@ altivec_register_p (int regno)
     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