summaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2010-01-05 22:59:32 -0800
committerRoland McGrath <[email protected]>2010-01-05 22:59:32 -0800
commit0c16c58610276858702c0db8b3bc8d332fb85656 (patch)
tree775f48a18378310c7557917440cac1d794fb4e0c /backends
parentebc5c885e696cdc4961916113c50e1396d8d3d48 (diff)
Use dwarf_aggregate_size in backend return_value functions. Observe DW_AT_GNU_vector on powerpc return_value type.
Diffstat (limited to 'backends')
-rw-r--r--backends/ChangeLog12
-rw-r--r--backends/arm_retval.c5
-rw-r--r--backends/ia64_retval.c36
-rw-r--r--backends/ppc64_retval.c27
-rw-r--r--backends/ppc_retval.c46
-rw-r--r--backends/sparc_retval.c5
-rw-r--r--backends/x86_64_retval.c7
7 files changed, 100 insertions, 38 deletions
diff --git a/backends/ChangeLog b/backends/ChangeLog
index 69351b32..b52d75dd 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,15 @@
+2010-01-05 Roland McGrath <[email protected]>
+
+ * 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 <[email protected]>
* linux-core-note.c (vmcoreinfo_items): New static const variable.
diff --git a/backends/arm_retval.c b/backends/arm_retval.c
index 4ffc6e7c..191cb174 100644
--- a/backends/arm_retval.c
+++ b/backends/arm_retval.c
@@ -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;
diff --git a/backends/ia64_retval.c b/backends/ia64_retval.c
index 238cd9ef..7645c3c8 100644
--- a/backends/ia64_retval.c
+++ b/backends/ia64_retval.c
@@ -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)
diff --git a/backends/ppc64_retval.c b/backends/ppc64_retval.c
index 454897cc..a5fc0dc8 100644
--- a/backends/ppc64_retval.c
+++ b/backends/ppc64_retval.c
@@ -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)
{
diff --git a/backends/ppc_retval.c b/backends/ppc_retval.c
index fa0e303c..15a0dba8 100644
--- a/backends/ppc_retval.c
+++ b/backends/ppc_retval.c
@@ -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
@@ -38,14 +38,17 @@
#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;
diff --git a/backends/sparc_retval.c b/backends/sparc_retval.c
index 7d7cbf2c..dcff67a2 100644
--- a/backends/sparc_retval.c
+++ b/backends/sparc_retval.c
@@ -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;
diff --git a/backends/x86_64_retval.c b/backends/x86_64_retval.c
index 3109431e..ba772bb9 100644
--- a/backends/x86_64_retval.c
+++ b/backends/x86_64_retval.c
@@ -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;