gdb/
authorUlrich Weigand <uweigand@de.ibm.com>
Tue, 15 Mar 2011 14:42:34 +0000 (14:42 +0000)
committerUlrich Weigand <uweigand@de.ibm.com>
Tue, 15 Mar 2011 14:42:34 +0000 (14:42 +0000)
* 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
gdb/ppc-sysv-tdep.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.arch/altivec-abi.exp

index cb45680906984095ae3fff6fe2390892e78c859a..d1d81bf1d63e2335a28f4cf5484ce45417602f1d 100644 (file)
@@ -1,4 +1,10 @@
-2011-03-15  Ulrich Weigand  <ulrich.weigand@linaro.org>
+2011-03-15  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * 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  <uweigand@de.ibm.com>
 
        * infcall.c (call_function_by_hand): Function return value is
        always a non_lval, even when using struct_return.
index 872117df31932b2229187220ba9348ef12590f69..e4313633c8d0cba2d91293aff45aa63e1e74c175 100644 (file)
@@ -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);
index a99789f8311e08b5452aa00056701634084dcea6..0472ab7fa7614cbfa0dfe17b650b8cc2844dfb69 100644 (file)
@@ -1,3 +1,10 @@
+2011-03-15  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * 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  <pmuldoon@redhat.com>
 
        * gdb.python/py-breakpoint.exp: Add Python stop operations tests.
index 480af73e7ff3a93a95633c34acc197c3a38ce136..5feff090e990c0fad9680ca343c7fc12ac2830ff 100644 (file)
@@ -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:"