From 24e9cda06816c3952f81c930777710da5870b5fd Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 15 Mar 2011 14:42:34 +0000 Subject: 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. --- gdb/ChangeLog | 8 ++++- gdb/ppc-sysv-tdep.c | 56 ++++++++++++++++++++++++++++------ gdb/testsuite/ChangeLog | 7 +++++ gdb/testsuite/gdb.arch/altivec-abi.exp | 27 +++++++++++++--- 4 files changed, 82 insertions(+), 16 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cb45680..d1d81bf 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,4 +1,10 @@ -2011-03-15 Ulrich Weigand +2011-03-15 Ulrich Weigand + + * 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. + +2011-03-15 Ulrich Weigand * infcall.c (call_function_by_hand): Function return value is always a non_lval, even when using struct_return. 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); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index a99789f..0472ab7 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-03-15 Ulrich Weigand + + * 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. + 2010-03-14 Phil Muldoon * gdb.python/py-breakpoint.exp: Add Python stop operations tests. diff --git a/gdb/testsuite/gdb.arch/altivec-abi.exp b/gdb/testsuite/gdb.arch/altivec-abi.exp index 480af73..5feff09 100644 --- a/gdb/testsuite/gdb.arch/altivec-abi.exp +++ b/gdb/testsuite/gdb.arch/altivec-abi.exp @@ -118,8 +118,17 @@ proc altivec_abi_tests { extra_flags force_abi } { append pattern2 " at.*altivec-abi.c.*main.*result = vec_func .vshort,.*goes in v2.*Value returned is.*= .14, 36, 58, 80." # Let's see if the result is returned correctly. - gdb_test "finish" "Run till exit from .0.*$pattern2" \ - "vector value returned correctly" + set message "vector value returned correctly" + gdb_test_multiple "finish" $message { + -re "Run till exit from .0.*$pattern2.*$gdb_prompt $" { + pass $message + } + -re "Run till exit from .0.*Cannot determine contents.*$gdb_prompt $" { + # This happens in those cases where the vector is returned by + # reference (generic vectors on 64-bit GNU/Linux). + pass $message + } + } # can we print the args correctly for this function? gdb_test "break struct_of_vector_func" "" "" @@ -150,9 +159,17 @@ if [test_compiler_info gcc*] { # On GNU/Linux, we can mix -mabi=no-altivec and -mabi=altivec. # So test some combinations. if { [istarget "powerpc*-linux*"] } { - set binfile ${objdir}/${subdir}/${testfile}-ge-ge - set pf_prefix "${saved_prefix} generic ABI, forced:" - altivec_abi_tests "additional_flags=-maltivec additional_flags=-mabi=no-altivec" "generic" + # On 64-bit GNU/Linux with GCC 4.1 and 4.2, -mabi=no-altivec + # was broken, so skip those tests there. + if { ![is_lp64_target] || ![test_compiler_info "gcc-4-\[12\]-*"] } { + set binfile ${objdir}/${subdir}/${testfile}-ge-ge + set pf_prefix "${saved_prefix} generic ABI, forced:" + altivec_abi_tests "additional_flags=-maltivec additional_flags=-mabi=no-altivec" "generic" + + set binfile ${objdir}/${subdir}/${testfile}-ge-auto + set pf_prefix "${saved_prefix} generic ABI, auto:" + altivec_abi_tests "additional_flags=-maltivec additional_flags=-mabi=no-altivec" "auto" + } set binfile ${objdir}/${subdir}/${testfile}-av-av set pf_prefix "${saved_prefix} AltiVec ABI, forced:" -- cgit v1.1