]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Use dwarf_aggregate_size in backend return_value functions. Observe DW_AT_GNU_vector...
authorRoland McGrath <roland@redhat.com>
Wed, 6 Jan 2010 06:59:32 +0000 (22:59 -0800)
committerRoland McGrath <roland@redhat.com>
Wed, 6 Jan 2010 06:59:32 +0000 (22:59 -0800)
backends/ChangeLog
backends/arm_retval.c
backends/ia64_retval.c
backends/ppc64_retval.c
backends/ppc_retval.c
backends/sparc_retval.c
backends/x86_64_retval.c

index 69351b323df437e845cf2608f25eb8a863611491..b52d75dd7f7674e334c0ca05f568a3e5b061596a 100644 (file)
@@ -1,3 +1,15 @@
+2010-01-05  Roland McGrath  <roland@redhat.com>
+
+       * arm_retval.c (arm_return_value_location): Use dwarf_aggregate_size.
+       * ia64_retval.c (ia64_return_value_location): Likewise.
+       * ppc_retval.c (ppc_return_value_location): Likewise.
+       * ppc64_retval.c (ppc64_return_value_location): Likewise.
+       * sparc_retval.c (sparc_return_value_location): Likewise.
+
+       * ppc64_retval.c (ppc64_return_value_location):
+       Use vr2 for DW_TAG_array_type with DW_AT_GNU_vector.
+       * ppc_retval.c (ppc_return_value_location): Likewise.
+
 2010-01-04  Roland McGrath  <roland@redhat.com>
 
        * linux-core-note.c (vmcoreinfo_items): New static const variable.
index 4ffc6e7c5d4d74fcf5f821789598ac88b07b8f40..191cb1746283708049e3aff433c377ef5a07f503 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for ARM EABI.
-   Copyright (C) 2009 Red Hat, Inc.
+   Copyright (C) 2009-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -124,8 +124,7 @@ arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_class_type:
     case DW_TAG_union_type:
     case DW_TAG_array_type:
-      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
-                                                &attr_mem), &size) == 0
+      if (dwarf_aggregate_size (typedie, &size) == 0
          && size > 0 && size <= 4)
        goto intreg;
       goto aggregate;
index 238cd9efeb2ed068864f71c8c5559866d745bcba..7645c3c89cb2567b2dc180d246fa9cedda8f29cc 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for IA64 ABI.
-   Copyright (C) 2006, 2007 Red Hat, Inc.
+   Copyright (C) 2006-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -89,7 +89,8 @@ static const Dwarf_Op loc_aggregate[] =
 /* If this type is an HFA small enough to be returned in FP registers,
    return the number of registers to use.  Otherwise 9, or -1 for errors.  */
 static int
-hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used)
+hfa_type (Dwarf_Die *typedie, Dwarf_Word size,
+         const Dwarf_Op **locp, int fpregs_used)
 {
   /* Descend the type structure, counting elements and finding their types.
      If we find a datum that's not an FP type (and not quad FP), punt.
@@ -114,10 +115,6 @@ hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used)
       return -1;
 
     case DW_TAG_base_type:;
-      int size = dwarf_bytesize (typedie);
-      if (size < 0)
-       return -1;
-
       Dwarf_Word encoding;
       if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
                                                 &attr_mem), &encoding) != 0)
@@ -178,9 +175,13 @@ hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used)
                                                             DW_AT_type,
                                                             &attr_mem),
                                       &child_type_mem);
+               Dwarf_Word child_size;
+               if (dwarf_aggregate_size (child_typedie, &child_size) != 0)
+                 return -1;
                if (tag == DW_TAG_union_type)
                  {
-                   int used = hfa_type (child_typedie, locp, fpregs_used);
+                   int used = hfa_type (child_typedie, child_size,
+                                        locp, fpregs_used);
                    if (used < 0 || used > 8)
                      return used;
                    if (used > max_used)
@@ -188,7 +189,8 @@ hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used)
                  }
                else
                  {
-                   fpregs_used = hfa_type (child_typedie, locp, fpregs_used);
+                   fpregs_used = hfa_type (child_typedie, child_size,
+                                           locp, fpregs_used);
                    if (fpregs_used < 0 || fpregs_used > 8)
                      return fpregs_used;
                  }
@@ -200,10 +202,7 @@ hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used)
        }
       break;
 
-    case DW_TAG_array_type:;
-      size = dwarf_bytesize (typedie);
-      if (size < 0)
-       return 9;
+    case DW_TAG_array_type:
       if (size == 0)
        break;
 
@@ -212,14 +211,16 @@ hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used)
        = dwarf_formref_die (dwarf_attr_integrate (typedie, DW_AT_type,
                                                   &attr_mem),
                             &base_type_mem);
+      Dwarf_Word base_size;
+      if (dwarf_aggregate_size (base_typedie, &base_size) != 0)
+       return -1;
 
-      int used = hfa_type (base_typedie, locp, 0);
+      int used = hfa_type (base_typedie, base_size, locp, 0);
       if (used < 0 || used > 8)
        return used;
       if (size % (*locp)[1].number != 0)
        return 0;
-      size /= (*locp)[1].number;
-      fpregs_used += used * size;
+      fpregs_used += used * (size / (*locp)[1].number);
       break;
 
     default:
@@ -346,13 +347,12 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_class_type:
     case DW_TAG_union_type:
     case DW_TAG_array_type:
-      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
-                                                &attr_mem), &size) != 0)
+      if (dwarf_aggregate_size (typedie, &size) != 0)
        return -1;
 
       /* If this qualifies as an homogeneous floating-point aggregate
         (HFA), then it should be returned in FP regs. */
-      int nfpreg = hfa_type (typedie, locp, 0);
+      int nfpreg = hfa_type (typedie, size, locp, 0);
       if (nfpreg < 0)
        return nfpreg;
       else if (nfpreg > 0 && nfpreg <= 8)
index 454897cccfa1fc75b2e455f2385b3c093580e928..a5fc0dc80af473c5653a65b3db9ce3805757abb5 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for Linux/PPC64 ABI.
-   Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
+   Copyright (C) 2005-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -53,6 +53,13 @@ static const Dwarf_Op loc_fpreg[] =
 #define nloc_fp2regs   4
 #define nloc_fp4regs   8
 
+/* vr2.  */
+static const Dwarf_Op loc_vmxreg[] =
+  {
+    { .atom = DW_OP_regx, .number = 1124 + 2 }
+  };
+#define nloc_vmxreg    1
+
 /* The return value is a structure and is actually stored in stack space
    passed in a hidden argument by the caller.  But, the compiler
    helpfully returns the address of that space in r3.  */
@@ -150,11 +157,21 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       *locp = loc_aggregate;
       return nloc_aggregate;
 
-    case DW_TAG_string_type:
     case DW_TAG_array_type:
-      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
-                                                &attr_mem), &size) == 0
-         && size <= 8)
+      {
+       bool is_vector;
+       if (dwarf_formflag (dwarf_attr_integrate (typedie, DW_AT_GNU_vector,
+                                                 &attr_mem), &is_vector) == 0
+           && is_vector)
+         {
+           *locp = loc_vmxreg;
+           return nloc_vmxreg;
+         }
+      }
+      /* Fall through.  */
+
+    case DW_TAG_string_type:
+      if (dwarf_aggregate_size (typedie, &size) == 0 && size <= 8)
        {
          if (tag == DW_TAG_array_type)
            {
index fa0e303cbd0d72cf65f8c1e65ea679b4cd24d92c..15a0dba809a587277dfc6c39126290dd2f2966e5 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for Linux/PPC ABI.
-   Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
+   Copyright (C) 2005, 2006, 2007, 2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
 #define SVR4_STRUCT_RETURN 0
 
 
-/* r3, or pair r3, r4.  */
+/* r3, or pair r3, r4, or quad r3-r6.  */
 static const Dwarf_Op loc_intreg[] =
   {
     { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 4 },
     { .atom = DW_OP_reg4 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg5 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg6 }, { .atom = DW_OP_piece, .number = 4 },
   };
 #define nloc_intreg    1
 #define nloc_intregpair        4
+#define nloc_intregquad        8
 
 /* f1.  */
 static const Dwarf_Op loc_fpreg[] =
@@ -54,6 +57,13 @@ static const Dwarf_Op loc_fpreg[] =
   };
 #define nloc_fpreg     1
 
+/* vr2.  */
+static const Dwarf_Op loc_vmxreg[] =
+  {
+    { .atom = DW_OP_regx, .number = 1124 + 2 }
+  };
+#define nloc_vmxreg    1
+
 /* The return value is a structure and is actually stored in stack space
    passed in a hidden argument by the caller.  But, the compiler
    helpfully returns the address of that space in r3.  */
@@ -64,6 +74,13 @@ static const Dwarf_Op loc_aggregate[] =
 #define nloc_aggregate 1
 
 
+/* XXX We should check the SHT_GNU_ATTRIBUTES bits here (or in ppc_init).  */
+static bool
+ppc_altivec_abi (void)
+{
+  return true;
+}
+
 int
 ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 {
@@ -143,13 +160,32 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       *locp = loc_aggregate;
       return nloc_aggregate;
 
+    case DW_TAG_array_type:
+      {
+       bool is_vector;
+       if (dwarf_formflag (dwarf_attr_integrate (typedie, DW_AT_GNU_vector,
+                                                 &attr_mem), &is_vector) == 0
+           && is_vector
+           && dwarf_aggregate_size (typedie, &size) == 0)
+         switch (size)
+           {
+           case 16:
+             if (ppc_altivec_abi ())
+               {
+                 *locp = loc_vmxreg;
+                 return nloc_vmxreg;
+               }
+             *locp = loc_intreg;
+             return nloc_intregquad;
+           }
+      }
+      /* Fall through.  */
+
     case DW_TAG_structure_type:
     case DW_TAG_class_type:
     case DW_TAG_union_type:
-    case DW_TAG_array_type:
       if (SVR4_STRUCT_RETURN
-         && dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
-                                                   &attr_mem), &size) == 0
+         && dwarf_aggregate_size (typedie, &size) == 0
          && size > 0 && size <= 8)
        goto intreg;
       goto aggregate;
index 7d7cbf2ce8f9fff3d523dd68f86525ade339b01d..dcff67a2c0a5eaa58b9de95efd9c403f4a21dba0 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for SPARC.
-   Copyright (C) 2006, 2007 Red Hat, Inc.
+   Copyright (C) 2006-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -154,8 +154,7 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_class_type:
     case DW_TAG_union_type:
     case DW_TAG_array_type:
-      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
-                                                &attr_mem), &size) == 0
+      if (dwarf_aggregate_size (typedie, &size) == 0
          && size > 0 && size <= 8)
        goto intreg;
       goto aggregate;
index 3109431e05c0252ef7f80a18918b9d9770b55003..ba772bb92dbaeb1fca904f30e2511639577a7999 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for Linux/x86-64 ABI.
-   Copyright (C) 2005, 2007 Red Hat, Inc.
+   Copyright (C) 2005-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -181,9 +181,8 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_class_type:
     case DW_TAG_union_type:
     case DW_TAG_array_type:
-      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
-                                                &attr_mem), &size) != 0)
-       return -1;
+      if (dwarf_aggregate_size (typedie, &size) != 0)
+       goto large;
       if (size > 16)
        goto large;