From d6dafb7c8efcd4625de119bffece9907e5b69a8e Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 8 Feb 2011 13:25:01 +0000 Subject: [PATCH] ChangeLog: * ppc-sysv-tdep.c (ppc64_sysv_abi_push_dummy_call): Implement correct ABI for AltiVec vector arguments. testsuite/ChangeLog: * gdb.arch/altivec-abi.c (vec_func): Make use of intv_on_stack_f when computing result. * gdb.arch/altivec-abi.exp: Update expected results. --- gdb/ChangeLog | 5 +++ gdb/ppc-sysv-tdep.c | 58 +++++++++++--------------- gdb/testsuite/ChangeLog | 6 +++ gdb/testsuite/gdb.arch/altivec-abi.c | 2 +- gdb/testsuite/gdb.arch/altivec-abi.exp | 5 ++- 5 files changed, 39 insertions(+), 37 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 641f22563d9..0197e8bce1d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2011-02-08 Ulrich Weigand + + * ppc-sysv-tdep.c (ppc64_sysv_abi_push_dummy_call): Implement + correct ABI for AltiVec vector arguments. + 2011-02-07 Pedro Alves * valprint.c (val_print): Extend comment. diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c index 1200b61cd20..300dcac6f1f 100644 --- a/gdb/ppc-sysv-tdep.c +++ b/gdb/ppc-sysv-tdep.c @@ -902,9 +902,6 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, ULONGEST back_chain; /* See for-loop comment below. */ int write_pass; - /* Size of the Altivec's vector parameter region, the final value is - computed in the for-loop below. */ - LONGEST vparam_size = 0; /* Size of the general parameter region, the final value is computed in the for-loop below. */ LONGEST gparam_size = 0; @@ -948,28 +945,21 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, /* Next available vector register for vector arguments. */ int vreg = 2; /* The address, at which the next general purpose parameter - (integer, struct, float, ...) should be saved. */ + (integer, struct, float, vector, ...) should be saved. */ CORE_ADDR gparam; - /* Address, at which the next Altivec vector parameter should be - saved. */ - CORE_ADDR vparam; if (!write_pass) { - /* During the first pass, GPARAM and VPARAM are more like - offsets (start address zero) than addresses. That way - they accumulate the total stack space each region - requires. */ + /* 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. */ gparam = 0; - vparam = 0; } else { - /* Decrement the stack pointer making space for the Altivec - and general on-stack parameters. Set vparam and gparam - to their corresponding regions. */ - vparam = align_down (sp - vparam_size, 16); - gparam = align_down (vparam - gparam_size, 16); + /* Decrement the stack pointer making space for the on-stack + stack parameters. Set gparam to that region. */ + gparam = align_down (sp - 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); @@ -1147,24 +1137,25 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, && TYPE_CODE (type) == TYPE_CODE_ARRAY && tdep->ppc_vr0_regnum >= 0) { - /* In the Altivec ABI, vectors go in the vector - registers v2 .. v13, or when that runs out, a vector - annex which goes above all the normal parameters. - NOTE: cagney/2003-09-21: This is a guess based on the - PowerOpen Altivec ABI. */ - if (vreg <= 13) + /* In the Altivec ABI, vectors go in the vector registers + v2 .. v13, as well as the parameter area -- always at + 16-byte aligned addresses. */ + + gparam = align_up (gparam, 16); + greg += greg & 1; + + if (write_pass) { - if (write_pass) + if (vreg <= 13) regcache_cooked_write (regcache, tdep->ppc_vr0_regnum + vreg, val); - vreg++; - } - else - { - if (write_pass) - write_memory (vparam, val, TYPE_LENGTH (type)); - vparam = align_up (vparam + TYPE_LENGTH (type), 16); + + write_memory (gparam, val, TYPE_LENGTH (type)); } + + greg += 2; + vreg++; + gparam += 16; } else if ((TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_ENUM @@ -1307,9 +1298,8 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, if (!write_pass) { - /* Save the true region sizes ready for the second pass. */ - vparam_size = vparam; - /* Make certain that the general parameter save area is at + /* Save the true region sizes ready for the second pass. + 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; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 6314f508ba4..3cb8d41f5ef 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-02-08 Ulrich Weigand + + * gdb.arch/altivec-abi.c (vec_func): Make use of intv_on_stack_f + when computing result. + * gdb.arch/altivec-abi.exp: Update expected results. + 2011-02-07 Thiago Jung Bauermann * gdb.base/break-interp.exp: Remove ${objdir} from test messages. diff --git a/gdb/testsuite/gdb.arch/altivec-abi.c b/gdb/testsuite/gdb.arch/altivec-abi.c index f68ec255642..61931a04ce5 100644 --- a/gdb/testsuite/gdb.arch/altivec-abi.c +++ b/gdb/testsuite/gdb.arch/altivec-abi.c @@ -71,7 +71,7 @@ vec_func (vector short vshort_f, /* goes in v2 */ vector unsigned char vuchar_res; vint_res = vec_add (vint_f, intv_on_stack_f); - vint_res = vec_add (vint_f, y_f); + vint_res = vec_add (vint_res, y_f); vuint_res = vec_add (vuint_f, ((vector unsigned int) {5,6,7,8})); vshort_res = vec_add (vshort_f, x_f); vushort_res = vec_add (vushort_f, diff --git a/gdb/testsuite/gdb.arch/altivec-abi.exp b/gdb/testsuite/gdb.arch/altivec-abi.exp index 061e4770ffd..480af73e7ff 100644 --- a/gdb/testsuite/gdb.arch/altivec-abi.exp +++ b/gdb/testsuite/gdb.arch/altivec-abi.exp @@ -91,7 +91,8 @@ proc altivec_abi_tests { extra_flags force_abi } { # the last one will go on the stack. set msg "call inferior function with vectors (1)" gdb_test "p vec_func(vshort,vushort,vint,vuint,vchar,vuchar,vfloat,x,y,a,b,c,intv_on_stack)" \ - ".\[0-9\]+ = .2, 2, 2, 2." "call inferior function with vectors (1)" + ".\[0-9\]+ = .14, 36, 58, 80." "call inferior function with vectors (1)" + # Let's call the function again with dummy arguments. This is to clean # up the contents of the vector registers before the next call. @@ -114,7 +115,7 @@ proc altivec_abi_tests { extra_flags force_abi } { "step into vec_fun" set pattern2 $pattern - append pattern2 " at.*altivec-abi.c.*main.*result = vec_func .vshort,.*goes in v2.*Value returned is.*= .2, 2, 2, 2." + 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" \ -- 2.30.2