aboutsummaryrefslogtreecommitdiff
path: root/gdb/ppc-sysv-tdep.c
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2011-03-15 14:42:34 +0000
committerUlrich Weigand <uweigand@de.ibm.com>2011-03-15 14:42:34 +0000
commit24e9cda06816c3952f81c930777710da5870b5fd (patch)
tree584614e368bcfdd211a9a7c423419fc44be8c227 /gdb/ppc-sysv-tdep.c
parent81b4675a00a6cef0e3e4e965dd70d41d178180e0 (diff)
downloadgdb-24e9cda06816c3952f81c930777710da5870b5fd.zip
gdb-24e9cda06816c3952f81c930777710da5870b5fd.tar.gz
gdb-24e9cda06816c3952f81c930777710da5870b5fd.tar.bz2
gdb/
* ppc-sysv-tdep.c (ppc64_sysv_abi_push_dummy_call): Add support for the "generic" vector ABI used with GCC 4.3 and later. (ppc64_sysv_abi_return_value): Likewise. gdb/testsuite: * gdb.arch/altivec-abi.exp: Skip "generic" tests on 64-bit when using a GCC 4.1 or 4.2 compiler. Add an additional test variant "generic ABI, auto". (altivec_abi_tests): Accept vectors returned by reference.
Diffstat (limited to 'gdb/ppc-sysv-tdep.c')
-rw-r--r--gdb/ppc-sysv-tdep.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index 872117d..e431363 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -1119,6 +1119,9 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch,
ULONGEST back_chain;
/* See for-loop comment below. */
int write_pass;
+ /* Size of the by-reference parameter copy region, the final value is
+ computed in the for-loop below. */
+ LONGEST refparam_size = 0;
/* Size of the general parameter region, the final value is computed
in the for-loop below. */
LONGEST gparam_size = 0;
@@ -1171,19 +1174,26 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch,
/* The address, at which the next general purpose parameter
(integer, struct, float, vector, ...) should be saved. */
CORE_ADDR gparam;
+ /* The address, at which the next by-reference parameter
+ (non-Altivec vector, variably-sized type) should be saved. */
+ CORE_ADDR refparam;
if (!write_pass)
{
- /* During the first pass, GPARAM is more like an offset
- (start address zero) than an address. That way it
- accumulates the total stack space required. */
+ /* During the first pass, GPARAM and REFPARAM are more like
+ offsets (start address zero) than addresses. That way
+ they accumulate the total stack space each region
+ requires. */
gparam = 0;
+ refparam = 0;
}
else
{
- /* Decrement the stack pointer making space for the on-stack
- stack parameters. Set gparam to that region. */
- gparam = align_down (sp - gparam_size, 16);
+ /* Decrement the stack pointer making space for the Altivec
+ and general on-stack parameters. Set refparam and gparam
+ to their corresponding regions. */
+ refparam = align_down (sp - refparam_size, 16);
+ gparam = align_down (refparam - gparam_size, 16);
/* Add in space for the TOC, link editor double word,
compiler double word, LR save area, CR save area. */
sp = align_down (gparam - 48, 16);
@@ -1462,7 +1472,7 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch,
}
else if (TYPE_LENGTH (type) == 16 && TYPE_VECTOR (type)
&& TYPE_CODE (type) == TYPE_CODE_ARRAY
- && tdep->ppc_vr0_regnum >= 0)
+ && tdep->vector_abi == POWERPC_VEC_ALTIVEC)
{
/* In the Altivec ABI, vectors go in the vector registers
v2 .. v13, as well as the parameter area -- always at
@@ -1484,6 +1494,30 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch,
vreg++;
gparam += 16;
}
+ else if (TYPE_LENGTH (type) >= 16 && TYPE_VECTOR (type)
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ /* Non-Altivec vectors are passed by reference. */
+
+ /* Copy value onto the stack ... */
+ refparam = align_up (refparam, 16);
+ if (write_pass)
+ write_memory (refparam, val, TYPE_LENGTH (type));
+
+ /* ... and pass a pointer to the copy as parameter. */
+ if (write_pass)
+ {
+ if (greg <= 10)
+ regcache_cooked_write_unsigned (regcache,
+ tdep->ppc_gp0_regnum +
+ greg, refparam);
+ write_memory_unsigned_integer (gparam, tdep->wordsize,
+ byte_order, refparam);
+ }
+ greg++;
+ gparam = align_up (gparam + tdep->wordsize, tdep->wordsize);
+ refparam = align_up (refparam + TYPE_LENGTH (type), tdep->wordsize);
+ }
else if ((TYPE_CODE (type) == TYPE_CODE_INT
|| TYPE_CODE (type) == TYPE_CODE_ENUM
|| TYPE_CODE (type) == TYPE_CODE_BOOL
@@ -1625,8 +1659,9 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch,
if (!write_pass)
{
- /* Save the true region sizes ready for the second pass.
- Make certain that the general parameter save area is at
+ /* Save the true region sizes ready for the second pass. */
+ refparam_size = refparam;
+ /* Make certain that the general parameter save area is at
least the minimum 8 registers (or doublewords) in size. */
if (greg < 8)
gparam_size = 8 * tdep->wordsize;
@@ -1849,7 +1884,8 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *func_type,
}
/* A VMX vector is returned in v2. */
if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY
- && TYPE_VECTOR (valtype) && tdep->ppc_vr0_regnum >= 0)
+ && TYPE_VECTOR (valtype)
+ && tdep->vector_abi == POWERPC_VEC_ALTIVEC)
{
if (readbuf)
regcache_cooked_read (regcache, tdep->ppc_vr0_regnum + 2, readbuf);