2002-04-29 Elena Zannoni <ezannoni@redhat.com>
authorElena Zannoni <ezannoni@kwikemart.cygnus.com>
Mon, 29 Apr 2002 15:10:06 +0000 (15:10 +0000)
committerElena Zannoni <ezannoni@kwikemart.cygnus.com>
Mon, 29 Apr 2002 15:10:06 +0000 (15:10 +0000)
* rs6000-tdep.c (rs6000_extract_return_value,
rs6000_store_return_value): Handle returning vectors.
(rs6000_gdbarch_init): Use
ppc_sysv_abi_broken_use_struct_convention for native sysv cases.
* ppc-linux-tdep.c (ppc_sysv_abi_broken_use_struct_convention):
New function.
(ppc_sysv_abi_use_struct_convention): Deal with functions returning
vectors.
(ppc_sysv_abi_push_arguments): Handle vector parameters.
* ppc-tdep.h (ppc_sysv_abi_broken_use_struct_convention): Export.

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

index 6499ae9444bed4f710773aeca28c9f8cfe345a58..a5e4e951b1616c8e49facee52d175f68a7fa66b6 100644 (file)
        * target.c (do_xfer_memory): Correct reference to the new option
        "trust-readonly-sections".
 
+2002-04-26  Elena Zannoni  <ezannoni@redhat.com>
+
+       * rs6000-tdep.c (rs6000_extract_return_value,
+       rs6000_store_return_value): Handle returning vectors.
+       (rs6000_gdbarch_init): Use
+       ppc_sysv_abi_broken_use_struct_convention for native sysv cases.
+       * ppc-linux-tdep.c (ppc_sysv_abi_broken_use_struct_convention):
+       New function.
+       (ppc_sysv_abi_use_struct_convention): Deal with functions returning
+       vectors.
+       (ppc_sysv_abi_push_arguments): Handle vector parameters.
+       * ppc-tdep.h (ppc_sysv_abi_broken_use_struct_convention): Export.
+        
+2002-04-26  Elena Zannoni  <ezannoni@redhat.com>
+
+        * Makefile.in (thread-db.o): This file cannot be built with
+       ,-Werror enabled.
+
 2002-04-26  Elena Zannoni  <ezannoni@redhat.com>
 
        * gdbtypes.h (TYPE_FLAG_VECTOR, TYPE_VECTOR): Define.
index bd765990cf3647cc2d8106ff0c21fd0fdb03d882..f358274140bf7d6afee135fa8b04572484f78e49 100644 (file)
@@ -415,11 +415,29 @@ ppc_linux_frame_chain (struct frame_info *thisframe)
    it may be used generically by ports which use either the SysV ABI or
    the EABI */
 
+/* Until November 2001, gcc was not complying to the SYSV ABI for
+   returning structures less than or equal to 8 bytes in size.  It was
+   returning everything in memory.  When this was corrected, it wasn't
+   fixed for native platforms.  */
+int
+ppc_sysv_abi_broken_use_struct_convention (int gcc_p, struct type *value_type)
+{
+  if (TYPE_LENGTH (value_type) == 16
+      && TYPE_VECTOR (value_type))
+    return 0;
+
+  return generic_use_struct_convention (gcc_p, value_type);
+}
+
 /* Structures 8 bytes or less long are returned in the r3 & r4
    registers, according to the SYSV ABI. */
 int
 ppc_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
 {
+  if (TYPE_LENGTH (value_type) == 16
+      && TYPE_VECTOR (value_type))
+    return 0;
+
   return (TYPE_LENGTH (value_type) > 8);
 }
 
@@ -445,7 +463,12 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
                             int struct_return, CORE_ADDR struct_addr)
 {
   int argno;
-  int greg, freg;
+  /* Next available general register for non-float, non-vector arguments. */
+  int greg;
+  /* Next available floating point register for float arguments. */
+  int freg;
+  /* Next available vector register for vector arguments. */
+  int vreg;
   int argstkspace;
   int structstkspace;
   int argoffset;
@@ -458,6 +481,7 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
 
   greg = struct_return ? 4 : 3;
   freg = 1;
+  vreg = 2;
   argstkspace = 0;
   structstkspace = 0;
 
@@ -500,21 +524,38 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
              greg += 2;
            }
        }
-      else
-       {
+      else if (!TYPE_VECTOR (type))
+        {
          if (len > 4
              || TYPE_CODE (type) == TYPE_CODE_STRUCT
              || TYPE_CODE (type) == TYPE_CODE_UNION)
            {
              /* Rounding to the nearest multiple of 8 may not be necessary,
-                but it is safe.  Particularly since we don't know the
-                field types of the structure */
+                but it is safe.  Particularly since we don't know the
+                field types of the structure */
              structstkspace += round2 (len, 8);
            }
          if (greg <= 10)
            greg++;
          else
            argstkspace += 4;
+       }
+      else
+        {
+          if (len == 16
+             && TYPE_CODE (type) == TYPE_CODE_ARRAY
+             && TYPE_VECTOR (type))
+           {
+             if (vreg <= 13)
+               vreg++;
+             else
+               {
+                 /* Vector arguments must be aligned to 16 bytes on
+                     the stack. */
+                 argstkspace += round2 (argstkspace, 16);
+                 argstkspace += 16;
+               }
+           }
        }
     }
 
@@ -540,6 +581,7 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
   structoffset = argoffset + argstkspace;
   freg = 1;
   greg = 3;
+  vreg = 2;
   /* Fill in r3 with the return structure, if any */
   if (struct_return)
     {
@@ -561,7 +603,7 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
            {
              if (len > 8)
                printf_unfiltered (
-                                   "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
+                                  "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
              memcpy (&registers[REGISTER_BYTE (FP0_REGNUM + freg)],
                      VALUE_CONTENTS (arg), len);
              freg++;
@@ -599,7 +641,7 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
              greg += 2;
            }
        }
-      else
+      else if (!TYPE_VECTOR (type))
        {
          char val_buf[4];
          if (len > 4
@@ -617,7 +659,6 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
            }
          if (greg <= 10)
            {
-             *(int *) &registers[REGISTER_BYTE (greg)] = 0;
              memcpy (&registers[REGISTER_BYTE (greg)], val_buf, 4);
              greg++;
            }
@@ -627,6 +668,30 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
              argoffset += 4;
            }
        }
+      else
+       {
+         if (len == 16
+             && 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);
+             if (vreg <= 13)
+               {
+                 memcpy (&registers[REGISTER_BYTE (tdep->ppc_vr0_regnum
+                                                   + vreg)],
+                         v_val_buf, 16);
+                 vreg++;
+               }
+             else
+               {
+                 write_memory (sp + argoffset, v_val_buf, 16);
+                 argoffset += 16;
+               }
+           }
+        }
     }
 
   target_store_registers (-1);
index 5dc2db25d36fe00be29fae82b2bc6e66c74c2793..3da66ad1405977ceb743739134929dcdac0c6376 100644 (file)
@@ -32,6 +32,7 @@ int ppc_linux_frameless_function_invocation (struct frame_info *);
 void ppc_linux_frame_init_saved_regs (struct frame_info *);
 CORE_ADDR ppc_linux_frame_chain (struct frame_info *);
 int ppc_sysv_abi_use_struct_convention (int, struct type *);
+int ppc_sysv_abi_broken_use_struct_convention (int, struct type *);
 CORE_ADDR ppc_sysv_abi_push_arguments (int, struct value **, CORE_ADDR, int,
                                       CORE_ADDR);
 int ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache);
index 97b936dd87323e1a92525922d8c255e005cac169..8ccfb99efe5e9f4e42a381e8ad220b3e7416ef4d 100644 (file)
@@ -1144,6 +1144,7 @@ static void
 rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
 {
   int offset = 0;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
 
   if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
     {
@@ -1165,6 +1166,13 @@ rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
          memcpy (valbuf, &ff, sizeof (float));
        }
     }
+  else if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY
+           && TYPE_LENGTH (valtype) == 16
+           && TYPE_VECTOR (valtype))
+    {
+      memcpy (valbuf, regbuf + REGISTER_BYTE (tdep->ppc_vr0_regnum + 2),
+             TYPE_LENGTH (valtype));
+    }
   else
     {
       /* return value is copied starting from r3. */
@@ -1909,6 +1917,8 @@ rs6000_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
 static void
 rs6000_store_return_value (struct type *type, char *valbuf)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
   if (TYPE_CODE (type) == TYPE_CODE_FLT)
 
     /* Floating point values are returned starting from FPR1 and up.
@@ -1917,6 +1927,13 @@ rs6000_store_return_value (struct type *type, char *valbuf)
 
     write_register_bytes (REGISTER_BYTE (FP0_REGNUM + 1), valbuf,
                          TYPE_LENGTH (type));
+  else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+    {
+      if (TYPE_LENGTH (type) == 16
+          && TYPE_VECTOR (type))
+       write_register_bytes (REGISTER_BYTE (tdep->ppc_vr0_regnum + 2),
+                             valbuf, TYPE_LENGTH (type));
+    }
   else
     /* Everything else is returned in GPR3 and up. */
     write_register_bytes (REGISTER_BYTE (gdbarch_tdep (current_gdbarch)->ppc_gp0_regnum + 3),
@@ -2706,7 +2723,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
           || osabi == ELFOSABI_NETBSD
           || osabi == ELFOSABI_FREEBSD)
        set_gdbarch_use_struct_convention (gdbarch,
-                                          generic_use_struct_convention);
+                                          ppc_sysv_abi_broken_use_struct_convention);
       else
        set_gdbarch_use_struct_convention (gdbarch,
                                           ppc_sysv_abi_use_struct_convention);