diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2011-03-15 14:42:34 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@de.ibm.com> | 2011-03-15 14:42:34 +0000 |
commit | 24e9cda06816c3952f81c930777710da5870b5fd (patch) | |
tree | 584614e368bcfdd211a9a7c423419fc44be8c227 /gdb/ppc-sysv-tdep.c | |
parent | 81b4675a00a6cef0e3e4e965dd70d41d178180e0 (diff) | |
download | gdb-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.c | 56 |
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); |