+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.
/* 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
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;
/* 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
/* 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.
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)
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)
}
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;
}
}
break;
- case DW_TAG_array_type:;
- size = dwarf_bytesize (typedie);
- if (size < 0)
- return 9;
+ case DW_TAG_array_type:
if (size == 0)
break;
= 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:
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)
/* 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
#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. */
*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)
{
/* 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[] =
};
#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. */
#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)
{
*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;
/* 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
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;
/* 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
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;